0

I have a view with an image shows some text in it. I need to perform animation which reveals the character by character in the end the complete text has to be displayed.

I have a logo view in my interface, over that I have animate view. for animate view the Leading, trailing, top and bottom constraints are set based on the superView (logo view).

I have tried following code but the duration which I have specified is not working properly.

   - (void) animateLogo {
    [UIView animateWithDuration:10.0 animations:^{
        NSLog(@"animation started");
        if (self.animateViewLeadingConstraint.constant < 94) { //94 is the total width of the logo view
            self.animateViewLeadingConstraint.constant = self.animateViewLeadingConstraint.constant + 1;
        } else {
            self.animateViewLeadingConstraint.constant = 0;
        }
    } completion:^(BOOL finished) {
        NSLog(@"animation ended");
        [self.animateView layoutIfNeeded];
        [self animateLogo];
    }];
}

I have attached the log for time duration

2016-08-01 17:55:27.317 sample[20361:481531] animation started
2016-08-01 17:55:27.318 sample[20361:481531] animation ended
2016-08-01 17:55:27.318 sample[20361:481531] animation started
2016-08-01 17:55:27.318 sample[20361:481531] animation ended
2016-08-01 17:55:27.318 sample[20361:481531] animation started
2016-08-01 17:55:27.319 sample[20361:481531] animation ended
2016-08-01 17:55:27.319 sample[20361:481531] animation started
2016-08-01 17:55:27.319 sample[20361:481531] animation ended

I am not sure what mistake I have made in above code or am I misunderstood the UIView Animation concept

Any help or hint would greatly appreciated.

Peer Mohamed Thabib
  • 636
  • 2
  • 9
  • 29

2 Answers2

1

See this answer: How do I animate constraint changes?

You should be calling layoutIfNeeded on the animated view's superview before your animation block, and in the animations: block itself. The first call makes sure any layout changes are applied. Assuming logoView is the superview of animateView:

- (void) animateLogo {
    self.animateViewLeadingConstraint.constant = 0.0;
    [self.logoView layoutIfNeeded];
    [UIView animateWithDuration:10.0 animations:^{
        NSLog(@"animation started");
        self.animateViewLeadingConstraint.constant = 94.0;
        [self.logoView layoutIfNeeded];
    } completion:^(BOOL finished) {
        NSLog(@"animation ended");
    }];
}
Community
  • 1
  • 1
stevekohls
  • 2,214
  • 23
  • 29
  • thanks for the thread. I wonder why the duration seconds is not working as expected do you know the reason? or could you elaborate me on that? – Peer Mohamed Thabib Aug 01 '16 at 13:13
  • As you have seen, if you don't call `layoutIfNeeded`, the animation happens immediately. Have you changed your code and it's still not correct? – stevekohls Aug 01 '16 at 13:26
  • Also, if you are not animating this correctly. Your `animations` block should just set the constant to 94 instead of incrementing. Don't call `animateLogo` in your `completion` block. The animation takes care of doing the entire animation for you. You don't have to move it each step of the way. – stevekohls Aug 01 '16 at 13:29
  • I've edited my answer to show what I think you want to do. It moves your view's leading constraint from a 0 offset, to 94 in 10 seconds. Try that. – stevekohls Aug 01 '16 at 13:32
  • 1
    If you want to move it back when the animation is done, in your `completion` block, set the constant to 0 and call `layoutIfNeeded` again. – stevekohls Aug 01 '16 at 13:33
  • its not animating. log 2016-08-01 19:05:16.184 sample[20924:524987] animation started 2016-08-01 19:05:16.185 sample[20924:524987] animation ended – Peer Mohamed Thabib Aug 01 '16 at 13:36
  • Did you try my updated code sample? The NSlog might not correspond to the actual animations – stevekohls Aug 01 '16 at 13:43
  • 1
    Just made another edit. You need to call layoutIfNeeded on the superview of the view being animated. Also, have you taken a look at your other constraints? Your `animateView` compression resistance should be low enough to allow the view to reduce it's width. – stevekohls Aug 01 '16 at 17:32
  • I have posted the working code based on your code. Thank you so much for your help! – Peer Mohamed Thabib Aug 02 '16 at 12:07
  • @PeerMohamedThabib I'm glad I was able to help! If you agree could you mark this as the accepted answer? – stevekohls Aug 02 '16 at 13:14
0

Finally, I have got the solution based on @stevekohls comments

- (void) animateLogo {
    self.animateViewLeadingConstraint.constant = 0;
    [UIView animateWithDuration:5.0f animations:^{
        self.animateViewLeadingConstraint.constant = 94.0;
        [self.view layoutIfNeeded];
    } completion:^(BOOL finished) {
        [UIView animateWithDuration:0.5f animations:^{
            self.animateView.alpha = 0;
        } completion:^(BOOL finished) {
                self.animateViewLeadingConstraint.constant = 0;
                [self.view layoutIfNeeded];
                self.animateView.alpha = 1.0f;
                [self animateLogo];
        }];
    }];
}
Peer Mohamed Thabib
  • 636
  • 2
  • 9
  • 29