Swift - UIView.transitionFromView -
Asked Answered
C

1

8

What happens to your “fromView” after you use UIView.transitionFromView? How do you get it back? (re-initialize it?).

Here’s a simple example I made and get “fatal error: unexpectedly found nil while unwrapping an Optional value” when I try to get back to the “fromView” or reference a label on it, etc.

Let’s say I’ve set these views in my storyboard - I added a subview to the root called “cardView” and then 2 views under cardView called “backView” and “frontView"

Linked these up to the view controller and linked the Flip button to an action that looks like this (along with the variables):

@IBOutlet weak var backView: UIView!
@IBOutlet weak var frontView: UIView!
@IBOutlet var cardView: UIView!

var front = true

@IBAction func flipIt(sender: AnyObject) {
    if front {
        UIView.transitionFromView(self.frontView, toView: self.backView, duration: 1, options: UIViewAnimationOptions.TransitionFlipFromRight, completion: nil)
    } else {
        UIView.transitionFromView(self.backView, toView: self.frontView, duration: 1, options: UIViewAnimationOptions.TransitionFlipFromLeft, completion: nil)
    }
    front = !front
}

So when I run this - the first tap of the “Flip” button does fine, it flips over to the backView, but then when I tap it again I get “fatal error: unexpectedly found nil while unwrapping an Optional value” on the 2nd transitionFromView line (the one under “else”).

Obviously there’s some effect of transitionFromView that I don’t understand. I've tried a lot of different things, including a tutorial that uses this transition and was able to get it working but it doesn’t use the storyboard so I’m not sure how to apply how that tut does it to my storyboard views, apparently...

thanks for any help.

Caz answered 17/5, 2015 at 20:37 Comment(0)
S
10

You've declared your view properties as weak, so they're getting released as soon as it appears they're no longer needed. Just change them to strong (by removing "weak") and you should be golden:

@IBOutlet var backView: UIView!
@IBOutlet var frontView: UIView!
Spirited answered 17/5, 2015 at 21:2 Comment(11)
Awesome Dave - thanks so much - that works. Can I give you bonus points for telling me why I lose my constraints on the labels on the subviews? After deleting "weak" this is flipping back and forth but the labels appear in the wrong position after tapping "Flip" from the first time. I guess I should be going to see if there's a place these constraints are set to weak...? yea I'm a newb...Caz
It doesn't seem like this flip should mess with the label constraints. Are you creating the constraints in code or Interface Builder? If in IB, they should be fine. But you could make them weak if they're created in the code, perhaps.Spirited
Also, generally weak @IBOutlets is the way to go. It's only if you remove the view from the view hierarchy (which you're doing here) that you need strong properties.Spirited
I did them in IB but I used "Reset to suggested" on all views so maybe it's a problem with that not being perfect - I only used it since this is only a test. Works fine on the initial view load though...but I'll go back and do these manually and see if for some reason it's a reason with those auto-constraints - brb.Caz
Wow, I don't understand it...after removing all constraints, putting them manually (or what I call manually - using IB but adjusting "first item" etc one at a time - going back through and double-checking them - it still comes out kinda the same way. For some reason now (maybe this is a clue) I get through 2 "Flip" taps before the UI goes whack (rather than the previous 1 tap, what? lol (love programming though, such a interesting mystery)).Caz
Also another clue, I'm pretty sure by the way it's doing it these views (backView and frontView) are coming back as subviews of my rootView rather than cardView. I write that because while cardView size/location is x=30, y=30, width=100, and height = 100. It loads up and looks good, tap "flip" and that 100x100 square flips over to the back with the other color and other label just like I want.Caz
Third click though now and the flip animations happens over to blank white 100x100 square and I can see most (but not all) of my colored view with the label on it way up at the top left of the screen. Tap Flip again and the animation happens where it supposed to but the colored label stuck up in the top-left does change to the other color....Caz
By the way, thanks for the advice about IBOutlets generally being weak - I did catch that.Caz
I'll ask in a new question - you fixed the crash for me - thanks again, Dave.Caz
I found the answer before asking a new question - I needed to use the option "UIViewAnimationOptions.ShowHideTransitionViews" which "When present, this key causes views to be hidden or shown (instead of removed or added) when performing a view transition." If anyone reads this and needs to know how to add more than one option in UIView.transitionFromView, just create variable like: var animationOptions = UIViewAnimationOptions.TransitionFlipFromLeft | UIViewAnimationOptions.ShowHideTransitionViews and then type that in for "options:" when you call .transitionFromView.Caz
Small note for Swift2, if you want to use 2 options you need this syntax: var animationOptions = [UIViewAnimationOptions.TransitionFlipFromLeft, UIViewAnimationOptions.ShowHideTransitionViews]Juror

© 2022 - 2024 — McMap. All rights reserved.