button doesn't work when pressed a second time

Hey,


i am moving between 2 VCs using a button each and i have an animation when changing VC


Now when i disable the slideAnimator everything works fine and i can press each button infinite times.

But as soon as i "turn on" the slideAnimator, this happens:

i press the first button and the second VC opens up. Now i press the button on the second VC and the first VC shows up. So everything fine. But now the first button doesnt work anymore. Neither does it show the second VC, nor does the blue text turn black (which normally happens as long as the button is selected).


I think there should be an easy fix but so far i couldnt find anything helpful.


My code:

import UIKit

class ViewController: UIViewController {
    
    let slideAnimator = SlideAnimator()
    
    override func viewDidLoad() {
        super.viewDidLoad()

    }
    
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        let destination = segue.destination
        
        destination.transitioningDelegate = slideAnimator
        
    }


}


with a slideAnimator class:

import UIKit

class SlideAnimator: NSObject, UIViewControllerAnimatedTransitioning, UIViewControllerTransitioningDelegate {
    
    var duration = 0.5
    
    func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
        return self
    }
    
    func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
        return self
    }
    
    func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
        return duration
    }
    
    func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
        guard let fromView = transitionContext.view(forKey: UITransitionContextViewKey.from) else {
            return
        }
        
        guard let toView = transitionContext.view(forKey: UITransitionContextViewKey.to) else {
            return
        }
        
        let container = transitionContext.containerView
        
        let screenOffUp = CGAffineTransform(translationX: 0, y: -container.frame.height)
        let screenOffDown = CGAffineTransform(translationX: 0, y: container.frame.height)
        
        container.addSubview(fromView)
        container.addSubview(toView)
        
        toView.transform = screenOffUp
        
        UIView.animate(withDuration: duration, delay: 0.0, usingSpringWithDamping: 0.8, initialSpringVelocity: 0.8, options: [], animations: {
                fromView.transform = screenOffDown
                fromView.alpha = 0.5
                toView.transform = CGAffineTransform.identity
                toView.alpha = 1
            }) { (success) in
                transitionContext.completeTransition(success)
        }

(i have added all buttons, etc. on the main.storyboard)


I´m thankful for any ideas!

Replies

When you press first time, does animation work correctly ?


Do you transition with performSegue or by instantiating and presenting the destination ?

Could you show how you call animation on the destination ?

And how do you come back ?

Yes the animation works fine

i transition with two button which i just dragged into the VCs without programming and i connected each button the concerning VC using right click and then Present Modally

So you connected the button in the destination controller back to the initial controller ?


Doing so, you stack a second instance of the initial controller.


You should:

- create an unwind segue in the initial controller ; you don tot have to connect the IBAction, that will be done automatically


    @IBAction func unwindToInitialViewController(_ sender: UIStoryboardSegue) {
       // No code needed ; can print a log to check it works
    }


- In the destination controller, connect (control-drag) the button to the exit button at the top right of the viewController ; in the popup, select unwindToInitialViewController (that does establish the connection to the IBAction).

This will dismiss the destination controller, and let you return to the original initail Controller, not creating a new instance.


That's it.

OK so nooow this happened:

i implemented what you said and opened a new ViewController and connected the bot VCs with the VCs from the main.storyboard. Now the button on my VC2 didnt react anymore so i went back and undid everything and suddenly everything worked fine. Pretty weird.

Now i used this and transfered it into a bigger project and suddenly this happened: The VC2 (which should come up when clicking the fist button) came down instead and the "back"-button on the VC2 to go back to VC1 didnt work at all (just like when implemented the second VC programmatically in the project of my initial question). I realised that i had connected the main.storyboard-VC1 to the programmatical-VC1 using the side/ toolbar in the main.storyboard. So i disconnected that (just like in my initial project) and it gives me a signalSigabrt-error in the AppDelegate.


I might need to rethink the whole VC-opening and -closing, unless you have an easier solution?!

For the first part, may be undoing caused to rebuild the connections.

-> Did you try a clean build folder ?

-> Are you using a navigation controller ?


For the second part :

The VC2 (which should come up when clicking the fist button) came down instead

What type of segue did you define ?

and the "back"-button on the VC2 to go back to VC1 didnt work at all (just like when implemented the second VC programmatically in the project of my initial question).

How do you program the return ? via a perform segue ?


I realised that i had connected the main.storyboard-VC1 to the programmatical-VC1 using the side/ toolbar in the main.storyboard. So i disconnected that (just like in my initial project) and it gives me a signalSigabrt-error in the AppDelegate.

- how did you disconnect ?

Check in IB that the connection is not still defined and thus dangling