yzet00
yzet00

Reputation: 511

Swift Switching To and FromTable ViewController Issue Using Custom Segue

I have run into an issue when using a custom segue. I have two tableviews that I'm an trying to switch back and forth from. When I click on a cell in tableview1 it should take me to tableview2. I have a button on tableview2 that connects to the exit of the storyboard. From there it should take me back to tableview1 but whenever I press the button, the application crashes with a BAD_ACCESS error.

Here is my custom segue class:

class TableViewSegue: UIStoryboardSegue {

override func perform() {
    scale()
}

func scale () {
   let toViewcontroller = self.destination
    let fromViewcontroller = self.source
    let containerView = fromViewcontroller.view.superview
    let originalCenter = fromViewcontroller.view.center
    toViewcontroller.view.transform = CGAffineTransform(scaleX: 0.05, y: 0.05)
    toViewcontroller.view.center = originalCenter

    containerView?.addSubview(toViewcontroller.view)

    UIView.animate(withDuration: 0.5, delay: 0, options: .curveEaseInOut, animations: {
    toViewcontroller.view.transform = CGAffineTransform.identity
    }, completion: { success in
    fromViewcontroller.present(toViewcontroller, animated: false, completion: nil) //The application crashes and highlights this line as the error.
    }) 
} 

}

I have implemented this method in my tableViewController1:

    @IBAction func prepareForUnwind(segue: UIStoryboardSegue) {

}

Not sure why the tableview2 does not dismiss.

EDIT: The issue had to do with needing a navigation controller.

Upvotes: 0

Views: 149

Answers (1)

DonMag
DonMag

Reputation: 77700

The problem is that you are presenting the toViewcontroller each time a segue is performed. So the app presents table2 over table1, and then tries again to present table1 over table2 on the unwind.

Modify your custom segue to check - essentially - which direction you're going:

class TableViewSegue: UIStoryboardSegue {

    override func perform() {
        scale()
    }

    func scale () {
        let toViewcontroller = self.destination
        let fromViewcontroller = self.source
        let containerView = fromViewcontroller.view.superview
        let originalCenter = fromViewcontroller.view.center
        toViewcontroller.view.transform = CGAffineTransform(scaleX: 0.05, y: 0.05)
        toViewcontroller.view.center = originalCenter

        containerView?.addSubview(toViewcontroller.view)

        let fromP = fromViewcontroller.presentingViewController

        UIView.animate(withDuration: 0.5, delay: 0, options: .curveEaseInOut, animations: {
            toViewcontroller.view.transform = CGAffineTransform.identity
        }, completion: { success in

            // if nil, we are presenting a new VC
            if fromP == nil {
                fromViewcontroller.present(toViewcontroller, animated: false, completion: nil)
            } else {
                fromViewcontroller.dismiss(animated: false, completion: nil)
            }

        })
    }

}

Note: This is assuming:

  1. you are not trying to push/pop within a UINavigationController ... you'd need to add some other checks to handle that.
  2. you are only going one-level-in, that is, you are not presenting, presenting, presenting, etc. and then trying to unwind.

Upvotes: 1

Related Questions