iOS setContentOffset not working on ipad

2019-02-26 05:32发布

问题:

This is really strange. I have a scrollview that contains a three images, and the user swipes to see the next image. However, I want the first screen to start at the middle image. Easy; I'll use setContentOffset and all will be fine.

The code works on the iPhone simulator, but not on the iPad simulator (or device!)

CGRect screen = [[UIScreen mainScreen] bounds];
CGFloat height = CGRectGetHeight(screen);
CGFloat width = CGRectGetWidth(screen);

CGPoint rightOffset = CGPointMake(width, 0);
[scrollView setContentOffset:rightOffset animated:YES];

All set just before the scrollView is added (and in fact we can do this after the scrollview is added with the same result).

width is returning 768 on ipad and 320 on the iphone.

Is this a bug? Xcode 4.4.1 and ios 6.

edit:

Looks like this is to do with creation order; moved to viewWillAppear rather than viewDidLoad and apparently working on iphone and ipad. Just the inconsistency is very surprising....

回答1:

You should not initialise UI geometry-related things in viewDidLoad, because the geometry of your view is not set at this point and the results will be unpredictable.

As you have discovered, viewWillAppear is the correct place to do these things, at this point the geometry is set so getting and setting geometry-related properties makes sense.

viewDidAppear.

update (ios6)

When using autolayout in ios6, frames are not set until subviews have been laid out. The right place to get frame data under these conditions is in the viewController method -viewDidLayoutSubviews.

This is called after -viewWillAppear. But take care - they are not always called together. For example, -viewWDidLayoutSubviews is called after a rotation, -viewWillAppear is not. -viewWillAppear is called every time a view becomes the visible view*, -viewDidLayoutSubviews not necessarily (only if us views needed relaying out).

(* unless the app was backgrounder and is becoming foreground app, then -viewWillAppear is not called)