1

I'm trying to animate a transition for one specific subView among many. Originally, when I tried to perform the transitionFromView:toView: it animated the entire superView, which is not what I want. I only want the specific subViews to animate. So I searched and found this: Transition behavior using transitionFromView and transitionWithView, which suggests creating a container view to perform the animations in. Ok, easy enough, so I came up with this code:

UIView *container = [[UIView alloc] init];
container.frame = selected.frame;
selected.frame = container.bounds;
[selected.superview addSubview:container];
[container addSubview:selected];
[UIView transitionFromView:selected toView:normal duration:.2f options:UIViewAnimationOptionTransitionFlipFromLeft completion:^(BOOL fin){
    normal.frame = container.frame;
    [container.superview addSubview:normal];
    [container removeFromSuperview];
}];

But now I get no animation at all. I'm probably missing something simple but I can't find it. Any ideas?

UPDATE

All of the values are initialized. If I break just before this code block runs I pull this up through the debugger console:

(gdb) po normal
<SLabel: 0x9c43150; frame = (0 0; 40 40); text = '28'; tag = 28; layer = <CALayer: 0x9c43190>>
(gdb) po selected
<SLabel: 0x9ca5f00; frame = (137 148; 45 37); text = '28'; tag = 28; layer = <CALayer: 0x9c596b0>>
(gdb) po [normal superview]
Can't print the description of a NIL object.
(gdb) po [selected superview]
<UIView: 0x9c4c890; frame = (0 0; 320 190); layer = <CALayer: 0x9c4c8c0>>

After the code has run through line 5 (just before the transition method) I get:

(gdb) po container
<UIView: 0x848bfc0; frame = (47 74; 45 37); layer = <CALayer: 0x9c32b10>>
(gdb) po [container superview]
<UIView: 0x9c4c890; frame = (0 0; 320 190); layer = <CALayer: 0x9c4c8c0>>
(gdb) po [selected superview]
<UIView: 0x848bfc0; frame = (47 74; 45 37); layer = <CALayer: 0x9c32b10>>

So everything seems correct. The container is placed at the location of the selected view (which is the view I want to flip from). The container added to the selected view's superview. The selected view is placed inside the container. And finally the transition is run (with cleanup afterward). But I still get no animation...the transition occurs immediately.

Please note that the transition between the view is occurring correctly. I'm just getting no animation at all.

Another question: Do the transitioning views HAVE to be a subview, no matter how distant, of a UINavigationController view in order to perform the animation? I've never seen any requirement like this that I can remember, but it's the one non-standard aspect of my code. If you follow the superview's of each view, not one will be part of a nav controller before it hits the window. Sometimes Apple's frameworks depend on each other in unexpected ways...I was wondering if this was one of them.

The final answer was that all my code was correct. What was happening is layoutSubviews was being called after I started the animation, which was re-laying out all my subviews before the animation even had a chance to start. I'm not quite sure why it was called. I didn't call it from my code, so for some reason my moving views around was triggering UIView to call it I guess. At any rate, I moved my code out of layoutSubviews into a private method and only call it when the size of the view changes. Everything works now. :)

Community
  • 1
  • 1
Aaron Hayman
  • 8,492
  • 2
  • 36
  • 63

1 Answers1

0

The code you put there does not have error, the only thing I can think is that you have some problem in other place. You are sure that your container view is going to your view that is showed?

In what method you are calling it?

Because to do the animation what you need to do is showed bellow (and from your code you post here you are doing it):

UIView* normalView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
[normalView setBackgroundColor:[UIColor redColor]];
UIView* selectedView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
[selectedView setBackgroundColor:[UIColor blueColor]];

UIView* container = [[UIView alloc] initWithFrame:CGRectMake(100, 100, 100, 100)];
[container setBackgroundColor:[UIColor grayColor]];

[container addSubview:selectedView];
[self.view addSubview:container];

And then call the method to do the flip.

[UIView transitionFromView:selectedView toView:normalView duration:2.0 options:UIViewAnimationOptionTransitionFlipFromRight completion:^(BOOL fin){}];
ggrana
  • 2,335
  • 2
  • 21
  • 31
  • Well, all the objects are initialized correctly (I'll add that to my question). You mention `self.view`, but this code is in a UIView subclass so instead it would just be `self`. Does the container need to be a direct subview of `self`, cause as it stands the normal superview (`selectedView.superview`) is a direct subview of `self` but the container is not (it's a subview of a subview of `self`). – Aaron Hayman Mar 28 '12 at 11:54
  • Naw...nevermind. I tried setting the container as a subview of `self` and I get the same behavior. – Aaron Hayman Mar 28 '12 at 12:04
  • Sorry @AaronHayman, but need more info to can help you. Like where you are calling it. you are seeing the transition? Because in the viewDidLoad for example you can see the animation. In the end of the process, you are seeing the normal or the selected view? They change with no animation or they do not change? – ggrana Mar 28 '12 at 12:20
  • Ah yeah, sorry I wasn't clear. Yes, the transition occurs, but with no animation. So at the end, I see the normal view like I should. This code is run in response to a UITapGestureRecognizer. But none of these views are part of a UINavigationController. This particular animation transition is essentially "de-selecting" a previous selection, while another standard animation (not a transition animation) animates the selection of the view tapped. Pretty simple and everything works except for the transition animation. – Aaron Hayman Mar 28 '12 at 12:37
  • My previous comment is wrong the right is: Because in the viewDidLoad for example you CAN'T see the animation. Something you are doing is blocking your animation, like putting it in a viewDidLoad of a viewController, but I do not know how to help you more, sorry. =/ – ggrana Mar 28 '12 at 12:49
  • That's fine....I may just create my own transition animation anyway rather than rely on Apple's. I don't think anything is blocking my animation because a few lines down from this transition, I have another non-transition animation that runs perfectly fine. Plus, I have managed to get the transition animation to perform, but it animated the entire superview, which is not what I wanted and why I created the container view in the first place. – Aaron Hayman Mar 28 '12 at 13:48
  • Did you ever get this to work? I have exactly the same problem. I create a temporary container view which gets added into the view hierarchy, with the fromView as a subview. I then do an animated transition to the toView and clean up afterward. Result: The fromView-to-toView transition works, but it's just not animated. Frustrating ... – hkatz Jul 18 '12 at 15:30
  • Got it! ggrana's comment that "something you are doing is blocking your animation" got me thinking, so I separated the container-and-subview setup code from the actual animation code, and called the latter with a [self performSelector:withObject:afterDelay:0] on conclusion of the former. Worked like a charm! – hkatz Jul 18 '12 at 16:20
  • @hkatz Glad it worked, if you have any questions, ask it and I'll try to help you – ggrana Jul 18 '12 at 21:09