Animation inside a UIScrollView

11,285

Solution 1

very interesting ... I've checked this out, and yes, i have the same effect ... Well, it seems that the animateWithDuration somehow blocks the main thread ... which is not logical, and the documentation doesn't say anything about it either .. However there is an easy workaround, something similar to this: (i've set the animation duration to 3 so i can see that it's working while i'm moving my scroll view :) ...)

[UIView beginAnimations:@"FadeAnimations" context:nil];
[UIView setAnimationDuration:3]; 

self.subview.alpha = 0.0f;

[UIView commitAnimations];

Solution 2

A little late, but if you want to keep using blocks, you can use:

animateWithDuration:delay:options:animation:complete:

add "UIViewAnimationOptionAllowUserInteraction" to options to allow interaction while scrolling.

I'm sure that you will still have the lag problem. Here's the best way I can explain it. Please forgive me in advance since I'm probably using the wrong terms. All animations must run on the main thread. When you call an animation, iOS first *P*rocesses then it *R*enders before it generates *F*rames. It looks like this.

PPPPRRRRFFFFFFFFFFFFFFFFFF

But since ScrollViews don't know how long your animation is going to be or when it will end, it has to perform the animation like this.

PRFPRFPRFPRFPRFPRFPRFPRF

My theory is that the lag you are experiencing has to do with these two calls colliding on the main thread at the same time. I'm not sure how you would solve this problem other than with a faster chip. I've that you could push one animation to the CPU and one to the GPU, but I'm not that advanced at programming yet.

Solution 3

I would suggest, since the opacity is based on the user's finger's movements in the UIScrollView, using the delegate method scrollViewDidScroll:. The scrollView passed as a parameter can be used to check the contentOffset which is simply a CGPoint indicating how far into the content view of the UIScrollView the user has scrolled. Something like this can be used to relate the scroll position to the opacity of a given view in a paginated UIScrollView:

- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
  // The case where I used this, the x-coordinate was relevant. You may be concerned with the y-coordinate--I'm not sure
  CGFloat percent = ((int)(scrollView.contentOffset.x) % (int)(scrollView.frame.size.width)) / scrollView.frame.size.width;
  if (percent > 0.0 && percent < 1.0) { // Of course, you can specify your own range of alpha values
    relevantView.alpha = percent; // You could also create a mathematical function that maps contentOffset to opacity in a different way than this
  }
}
Share:
11,285

Related videos on Youtube

OpenUserX03
Author by

OpenUserX03

Updated on June 04, 2022

Comments

  • OpenUserX03
    OpenUserX03 almost 2 years

    I want to fade-out a view as it is scrolling inside a parent UIScrollview. When the fade-out animation begins, the scroll view stops scrolling. It jumps to the correct position when the fade is complete.

    My fade-out is achieved with animateWithDuration and block objects, triggered upon a page-change I detect in scrollViewWillBeginDragging.

    Does anyone know how to make them both happen simultaneously? Just to be clear, I am not 'animating' the UIScrollView scrolling - rather it is happening via user interaction of swiping.

    EDIT:

    Here is the code I'm using to fade the UIView. This code is in a UIViewController derived class, which is the delegate for a UIScrollView. When the user starts dragging his finger, I want to fade out the subView. But when the user starts draggin a finger, the subview fades and the scrolling stops. After the subView has completely faded out, the the scroll view will then snap to the location where the user's finger is.

    -(void)scrollViewWillBeginDragging:(UIScrollView*)scrollView
    {
        [UIView animateWithDuration:0.5
            animations:^
            {
                self.subView.alpha = 0.0f;
            }
            completion:^(BOOL finished) { }];
    }
    
  • sudo rm -rf
    sudo rm -rf about 13 years
    So you're saying the normal UIView methods don't affect the table, while the block methods do? Quite strange.
  • Moszi
    Moszi about 13 years
    well .. i don't know why (yet), but i have tested this, and i can confirm that it works like this ...
  • casademora
    casademora over 12 years
    perhaps try the more thorough block animation method animate:delay:options:completion: and send in the option UIViewAnimationAllowUserInteraction
  • levigroker
    levigroker about 11 years
    Using the non-block based UIView animations also solved the reverse issue for me (the scroll view was causing block based UIView animations to fire at strange times/not at all). (iOS 6.1)
  • Luda
    Luda almost 10 years
    Jacob, you are the king!
  • maddy
    maddy almost 7 years
    perfect logicak solution, i converted for verticall score thanks mate

Related