6

I have a horizontal UIScrollview set up (meaning its not one that scrolls up and down but one that only scrolls left-right) and upon the app launching, I want this scrollview to scroll itself left, then right - kind of "demonstrating" its ability to scroll - and finally then stop, letting the user then take over and control the scroll manually with their finger. Everything works - except for this on-load left-right demo-scrolling.

I'm not using Interface Builder for any of this, I'm doing everything with code:

//(this is in viewDidLoad:)
// Create the scrollView:
UIScrollView *photosScroll = [[UIScrollView alloc] initWithFrame: CGRectMake(0, 0, 320, 200)];
[photosScroll setContentSize: CGSizeMake(1240, 200)]; 
// Add it as a subview to the mainView
[mainView addSubview:photosScroll];


// Set the photoScroll's delegate: 
photosScroll.delegate = self;

// Create a frame to which to scroll:   
CGRect frame = CGRectMake(10, 10, 80, 150);
// Scroll to that frame:
[photosScroll scrollRectToVisible: frame animated:YES];

So the scrollView loads successfully and I'm able to scroll it left and right with my finger - but it doesn't do this "auto-scroll" like I was hoping it would.

  • I tried calling the scrollRectToVisible before and after adding the scrollView as a subview - didn't work.
  • Thinking maybe this should happen in loadView and not in viewDidLoad? But if so, how?

Any ideas?

logancautrell
  • 8,762
  • 3
  • 39
  • 50
sirab333
  • 3,662
  • 8
  • 41
  • 54

1 Answers1

5

A couple of ways to do this:

  1. Use scrollRectToVisible:animated: for a zero X value and then a largeish positive one, then set it back to your middle point. You can call the method after the scroll view is added as a subview (probably before too, but best be safe). You'll need to calculate what value of X is off-screen to the left using your contentSize and knowledge about how wide your various elements inside the scroll view are.
  2. Since you're just doing a quick animation and will give the user control, this can really be a quick-and-dirty animation, so you could use setContentOffset:animated: to force the content of the scrollview to move relative to your current view position. Move the elements right for a left scroll (positive X value), then left twice as far for a right scroll (negative X value), then set the offset back to zero.

You shouldn't put either of these in viewDidLoad or loadView; put them in viewDidAppear, which is after your scrollview is actually drawn on screen. You only care about animations when the user can see them!

  • do you mean something like this? CGRect frame = CGRectMake(800, 0, 800, 150); [photosScroll scrollRectToVisible: frame animated:YES]; frame = CGRectMake(0, 0, 800, 150); [photosScroll scrollRectToVisible: frame animated:YES]; cause that did not work... – sirab333 Oct 24 '11 at 03:36
  • For #1, yes, but you don't need to make the `frame` you scroll to the size of the entire view. You can do `CGRectMake(800, 0, 1, 1)` if you like, and then `CGRectMake(0, 0, 1, 1)`. To scroll the area from 800 pixels to 1600 pixels into view, you can scroll to `(1599, 0, 1, 1)`, and then to scroll the area from 0 to 800 back into view, you can scroll to `(0, 0, 1, 1)`. –  Oct 24 '11 at 03:39
  • well it works - but not 100% :-) Since the scrollView is alloc'd and init'd in the viewDidLoad, its only available to that method, and not to viewDidAppear. So it does scroll to where I told it to scroll when the app first loads, but it ignores all the other subsequent scrollRectToVisible commands which are in viewDidLoad. How can I access this scrollView outside of viewDidLoad though? Meaning, from viewDidAppear? – sirab333 Oct 24 '11 at 03:53
  • Create an `@property (nonatomic) UIScrollView *scrollView;` in your controller class (remember to `@synthesize scrollView;` in your .m file), and in `viewDidLoad` set `self.scrollView` to the init'd view. Then you can reference `scrollView` from `viewDidAppear` :) –  Oct 24 '11 at 03:58
  • sounds good - but will have to wait for 2morrow morning - its lights out right now! :-) thanks for help in the meantime, will post results tomorrow! much obliged. – sirab333 Oct 24 '11 at 04:15
  • ok - not working. I set everything up like we discussed - see the code below - and I get only one scroll upon the App's launch - which comes from viewDidLoad - but I don't get the second one that should come from viewDidAppear 'code'@interface scrollTestViewController : UIViewController { UIScrollView *photoScroll; } @property (nonatomic, retain) UIScrollView *photoScroll; – sirab333 Oct 24 '11 at 11:47
  • If you've `@synthesize`'d `photoScroll`, and called `scrollRectToVisible:animated:` in `viewDidAppear`, it **should** work. You may have entered a rect which is already visible on-screen from your initial scroll position. Try extreme values - the very other end of the view - and see what happens there. –  Oct 24 '11 at 23:03
  • What about if you don't want animations?! – fatuhoku Apr 08 '15 at 12:42