jchitel
jchitel

Reputation: 3169

iOS Custom Segue Not Working

I am just starting to learn how to develop iOS apps. (Note that I am using XCode 6 beta and Swift) I think I'm good with building interfaces themselves, but I seem to be having trouble with segues.

The first page of my app is just a simple screen with a sign up button and a sign in button. I made a separate view controller for a sign up page and put a text field on it. Both of these view controllers are in my storyboard. I then made a custom segue class to simply animate the start page and the sign up page moving one screen to the left, so that the sign up page is now showing. This is my custom segue class:

class SlideFromRightSegue: UIStoryboardSegue {
    override func perform() {
        let screenWidth = UIScreen.mainScreen().bounds.width
        let center = self.sourceViewController.view!.center
        UIView.animateWithDuration(0.25,
            animations: {
                self.sourceViewController.view!.center = CGPoint(x: center.x - screenWidth, y: center.y)
                self.destinationViewController.view!.center = CGPoint(x: center.x - screenWidth, y: center.y)
            }, completion: { (finished: Bool) in
                self.sourceViewController.presentViewController(self.destinationViewController as UIViewController, animated: false, completion: nil)
            })
    }
}

I based this off a tutorial I found, and I don't think there is a problem here. I simply animate both the source and destination VC's center to be one screen to the left. I'm not entirely sure how animations work in iOS but the tutorial I found was structured similarly, so I assume that the closure passed into the "animations" parameter is called and then iOS generates all of the steps in between and draws each frame to the screen. (correct me if I'm wrong)

So I have a custom segue. I go back to my storyboard, click on the sign up button, go over to the connections tab, and drag the "Triggered Segues - action" over to the second VC, select "custom" and then select my custom class. For some reason, instead of being just "SlideFromRightSegue", it's "_TtC524SlideFromRightSegue". I'm not sure why that's happening, but I assume it has something to do with the fact that I renamed the segue class, and I hope that's not causing any problems. Anyway, doing that creates an arrow from the first VC to the second VC, so I assume it worked.

When I run the app, I get the start screen just like usual. I click the sign up button, and nothing happens. There is probably something I missed, but I put a breakpoint in the perform() function of my segue and another in the prepareForSegue() function of the first VC. Neither one was triggered. I think I have the segue set up properly, I just have something wrong with the actual implementation into my app. Anybody have any idea what's going on?

Upvotes: 1

Views: 1345

Answers (2)

rdelmar
rdelmar

Reputation: 104082

I don't know why your perform method wasn't called, but it's not due to your code, though the code does have some problems. You never add the destination view controller's view to the window (until the completion where the presentation will do that for you). So, you need to add the view, position it off-screen right, and then have it end up centered, not off screen left like you have in your code,

class SlideFromRightSegue: UIStoryboardSegue {

    override func perform() {
        let screenWidth = UIScreen.mainScreen().bounds.width
        let center = self.sourceViewController.view!.center
        let appdel: AppDelegate = UIApplication.sharedApplication().delegate as AppDelegate
        appdel.window!.addSubview(self.destinationViewController.view)
        self.destinationViewController.view!.center = CGPoint(x: center.x + screenWidth, y: center.y)

        UIView.animateWithDuration(0.25,
            animations: {
                self.sourceViewController.view!.center = CGPoint(x: center.x - screenWidth, y: center.y)
                self.destinationViewController.view!.center = center
            }, completion: { (finished: Bool) in
                self.sourceViewController.presentViewController(self.destinationViewController as UIViewController, animated: false, completion: nil)
                self.sourceViewController.view!.removeFromSuperview() 
            })
    }
}

Upvotes: 1

jchitel
jchitel

Reputation: 3169

So yea, it turns out that the problem was that I was using a custom button class as well, which had overrides for the touchesBegan, touchesEnded, and touchesCancelled functions. Those overrides did not callback to the superclass methods, so the action of pressing the button wasn't even being triggered.

I guess the lesson I can take from all this is to make sure to know which function overrides must call back to the superclass, and which should completely override the superclass. Touch event handlers likely need to call back to the superclass.

Upvotes: 1

Related Questions