OpenUserX03
OpenUserX03

Reputation: 1458

Animation inside a UIScrollView

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) { }];
}

Upvotes: 8

Views: 11659

Answers (4)

Jacob
Jacob

Reputation: 926

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
  }
}

Upvotes: 8

mbm29414
mbm29414

Reputation: 11598

According to information that is still not supposed to be widely released, all iOS 4.x versions completely block user interaction while the animation is in progress.

Isn't it interesting, though, that you're UITouches are obviously still registered during the animation? Hmm... maybe that HINTS that something NEW is coming in a yet-to-be-released version!

I.e., If you can, read the iOS 5 Beta documentation on UIView class methods.

Upvotes: 0

David Chu
David Chu

Reputation: 139

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.

Upvotes: 13

Moszi
Moszi

Reputation: 3236

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];

Upvotes: 11

Related Questions