1

I want to use a UIScrollView as my main container in the app, enabling me to swipe back and forth between subviews. To achieve this, I created a UIViewController subclass with a UIScrollView IBOutlet:

In the viewDidLoad method I construct the sub-pages:

for (int i= 0; i< pageCount; i++)
{
   CGRect frame = self.scrollView.frame;
   frame.origin.x = frame.size.width * i;
   frame.origin.y = 0;

   UIWebView* aWebView= [[UIWebView alloc] initWithFrame:frame];

   [self.scrollView addSubview:aWebView];
}

When launching the app (portrait mode), everything works. That is, the UIWebViews are layed out side by side with the correct dimensions, and I can swipe back and forth between them.

When I rotate to landscape, it seems that neither the scrollview size nor the subviews are resized.

I don't know what I should do in order to resize the subviews and the scrollview itself, or at what point in code I should do anything, and I cant seem to find any examples for this.

Anyone know what to do?

[edit] Attempt to adjust sizes as suggested by mahboudz:

- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation 
{
   self.scrollView.contentSize = CGSizeMake(self.scrollView.frame.size.width * pageCount, self.scrollView.frame.size.height);

   for (int i= 0; i< pageCount; i++)
   {
      CGRect frame = self.scrollView.frame;
      frame.origin.x = frame.size.width * i;
      frame.origin.y = 0;

      UIWebView* view= [[self.scrollView subviews] objectAtIndex:i];

      view.frame= frame;
   }
}

This kind of does what I want, but has the following issues:

1) one can see the subviews grow to correct screen size upon changing orientation

2) when the current page is, for example, page 2 of 5 pages, the page is not fully visible after orientation was changed, but is off-screen by like 40 pixels

3) I get strange effects depending on whether the app is launched in portrait or landscape mode (simulator), ill try to explain:

When the app is launched in portrait mode:

  • The shape/border of the subviews looks messed up/offscreen, see screenshots:

http://i53.tinypic.com/21jr76x.png

  • when I rotate to landscape, everything looks okay, scrolling works superb. even when I rotate back to portrait, everything is great now:

http://i55.tinypic.com/if3iiw.png

When the app is launchend in landscape mode:

  • I get the same messed up/offscreen glitches as in portrait mode

  • Switching back and forth between portrait and landscape fixes this for landscape mode

  • BUT: Portrait mode will have the subviews with the width of the landscape mode, thus subviews are too wide

I tried to fix 1) doing the code above in willRotateToInterfaceOrientation however it completely messed up the layout.

I fixed 2) by adding the following code to didRotateFromInterfaceOrientation:

// update the scroll view to the appropriate page

CGRect frame = self.scrollView.frame;
frame.origin.x = frame.size.width * self.currentPage;
frame.origin.y = 0;

[self.scrollView scrollRectToVisible:frame animated:NO];

Note: current page is determined in scrollViewDidScroll

I dont have any idea how to fix 3)

user944943
  • 113
  • 1
  • 2
  • 9

2 Answers2

3

You would need to reset the frame size, content size and the content offset in order to get the subviews in a proper position.

CGFloat screenHeight =[UIScreen mainScreen].bounds.size.height;
CGFloat screenWidth =[UIScreen mainScreen].bounds.size.width;
self.scrollView.frame = CGRectMake(0, 0, screenWidth, screenHeight);
self.scrollView.contentSize = CGSizeMake(scrollView.frame.size.width * numberOfPages, self.scrollView.frame.size.height);
self.scrollView.contentOffset = CGPointMake(visiblePageBeforeRotation * self.scrollView.bounds.size.width, 0);

This code should be placed in the method

-(void)willRotateToInterfaceOrientation: (UIInterfaceOrientation)orientation duration:(NSTimeInterval)duration

Check as well the answer on this question: Clean autorotation transitions in a paging UIScrollView It has good example named Rotolling for rotating UIScrollView with paging enabled.

Hope this helps.

P.S: I am facing a problem on repositioning the center of the UIWebView on the rotation.

Community
  • 1
  • 1
Lily
  • 387
  • 4
  • 18
0

You need to implement viewWillRotate/viewDidRotate and make adjustments to our content size and orientation as needed.

mahboudz
  • 39,196
  • 16
  • 97
  • 124
  • So basically I need to first set the contentSize (new geometry * count of subviews), then loop the subviews and set the frame property to the new geometry? Do I also have to trigger a redraw of the views (setNeedsDisplay) or similar, or will it work by just setting frame and contentSize? – user944943 Sep 29 '11 at 09:18
  • I don't think you need to setNeedsDisplay. I am pretty sure you need to resize your frames/bounds and contentSize, etc. See if you can get some automatic shifting/resizing help by setting up the auto-resizing flags using InterfaceBuilder (or via code). – mahboudz Sep 29 '11 at 10:11