uerceg
uerceg

Reputation: 4807

Scroll to specific view in UIScrollView without animating

I have UIScrollView and about 20 items (UIViewControllers) in it. I have also buttons on each page which help me to jump between these 20 items. So, if I am at first view, and press button which takes me to 18th item, entire scroll view is scrolling to that view and animating scroll operation, so I am able to see all views between 1st and 18th item.

Is it possible to jump from 1st to 18th item in scroll view without this long animation (I would like to see animation like I am scrolling between two neighbor items)?

I thought this line of code will help me prevent this long scrolling animation:

[scrollView scrollRectToVisible:rect animated:NO];

but no luck.

Any suggestions?

[edit #1] Method where am I scrolling to specific view looks something like this:

// I found view controller to which I want to scroll

CGRect rect = selectedViewController.view.frame;

float duration; // I calculate animation duration in some way now

[UIView beginAnimations:@"ScrollRectToVisible" context:nil];
[UIView setAnimationCurve:UIViewAnimationTransitionNone];

[scrollView scrollRectToVisible:rect animated:NO];
[UIView commitAnimations];

With this code, when I scroll from first to last view in UIScrollView, application scrolls to last view and that animation lasts for duration value I calculated. And I see EVERY view which exists between first and last one. My wish is to scroll from first to last view right away without seeing all views between them.

When I change crollRectToVisible line to:

[scrollView scrollRectToVisible:rect animated:YES];

same thing happens, just this time scrolling animation happens like 5 times faster, but still all views between are shown.

When I remove animation from method, transition occurs immediately. My question is how to achieve this animation to last view which looks the same when sliding to neighbor view in UIScrollView?

Upvotes: 1

Views: 1975

Answers (2)

Nikita Pestrov
Nikita Pestrov

Reputation: 5966

The only possible way not to show all the views between those two is.. Not to have them at all, or make them invisible.

The easy solution, that may not satisfy you, though, is to set the alpha of all the view between those to to zero, and then scroll. The problem is that it will scroll really fast, i guess.

Another, more complex solution, is to remove those views at all, or set their alphas to zero again, but move that destination view right next to the first one—this will give you the desired effect. After this scrolling, you should move that view back to it's origin and scroll to it's origin at the same time(by changing the contentOffset)—so the user wouldn't notice it, and then bring all the view back to screen.

So it looks just like some kind of shrinking your scroll view.

Upvotes: 1

David Hoerl
David Hoerl

Reputation: 41682

So what you need to so is as follows:

  • assume you have 5 views, a,b,c,d,e
  • you are at 'b' and want to animate to 'e' as if 'e' was next to 'b', not showing 'c' or 'd'
  • when the user hits a button indicating they want to see 'e', you will first swap 'c' and 'e'
  • you animate as you wish from 'b' to 'e' (which is now its neighbor)
  • when the animation stops (you should use a block animation with a completion block), you do all of this:
    • swap 'c' and 'e'
    • set the contentOffset of the scrollView so the horizontal value is where 'e' is

Now your array is back the way it was, and the user is none the wiser for it.

Upvotes: 1

Related Questions