swilliams
swilliams

Reputation: 48920

UIView animation not working with addSubview

I have an iPad app that is displaying a "note" (subclassed UILabel) with text on it. In order to navigate to the next note, I'd like it to slide it off the screen to the left while having the next one slide in from the right. I can get either animation to work, but not both at the same time.

Here's the code in my controller:

- (void)slideOutLeft {
    // create the new note
    flSlidingNote *newNote = [[flSlidingNote alloc] init];
    newNote.text = @"blah blah";
    CGRect newFrame = CGRectMake(1000, 70, 637, 297); // off the right
    newNote.frame = newFrame;
    [self.view addSubview:newNote];

    // slide off the current one
    CGRect currentFrameEnd = noteLabel.frame; // noteLabel is the existing note
    currentFrameEnd.origin.x = 0 - noteLabel.frame.size.width; // off the left

    [UIView animateWithDuration:1.0 animations:^{
        noteLabel.frame = currentFrameEnd;
    } completion:nil];
}

noteLabel does not animate at all. If I comment out the addSubview:newNote part it does. I'm still relatively new at this, so it's probably just something simple.

The problem happens whether newNote is animated or not (not animated in the code snippet).

Upvotes: 2

Views: 3618

Answers (3)

tuliomir
tuliomir

Reputation: 416

Adding to what Gabriele Petronella commented, here is a good resource on KeyFrames and AnimationGroup, with a sample GitHub project linked:

http://blog.corywiles.com/using-caanimationgroup-for-view-animations

This really helped me understand animations better.

Upvotes: 1

algal
algal

Reputation: 28094

You want to put the animation for both your views and the addSubview call for your new view in one animation block, like so:

  // layout the new label like the old, but 300px offscreen right 
  UILabel * newNote = [[UILabel alloc] initWithFrame:CGRectOffset(self.noteLabelView.frame, 300, 0)];
  newNote.text = @"NEW NOTE";

 [UIView animateWithDuration:2.0f
                       delay:0
                     options:UIViewAnimationCurveEaseInOut
                  animations:^{
                     // animate the old label left 300px to offscreen left
                     self.noteLabelView.center = CGPointMake(self.noteLabelView.center.x-300, self.noteLabelView.center.y);
                     // add the new label to the view hierarchy
                     [self.view addSubview:newNote];
                     // animate the new label left 300px into the old one's spot
                    newNote.center = CGPointMake(newNote.center.x-300, newNote.center.y);
                  }
                  completion:^(BOOL finished) {
                    // remove the old label from the view hierarchy
                    [self.noteLabelView removeFromSuperview];
                    // set the property to point to the new label
                    self.noteLabelView = newNote;
               }];

In this snippet above, I'm assuming the old label is addressable via the property self.noteLabelView.

(Also have a look at https://github.com/algal/SlidingNotes , though I can't promise that will stay there long so maybe SO isn't the right format for such a link? )

Upvotes: 1

Bejmax
Bejmax

Reputation: 945

not sure but i've seen other code that loops through subviews and performs animations, you may want to try the following:

for(UIView *view in self.subviews)
{
    // perform animations 
}

Upvotes: -1

Related Questions