Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UIScrollView frame is a different size on iOS 8 vs iOS 7

I implemented a view controller that simply displays a single image and allows the user to pinch to zoom in/pan around the image. It works great on iOS 7, but on iOS 8 the scroll view's frame is a different size, and the end result is the image is zoomed in too far on iPhone and zoomed out too far on iPad when running on iOS 8. This is because the scroll view frame's width is 600pt, which is its size in the storyboard (Universal Storyboard using size classes). But I have autolayout constraints that are supposed to ensure the scroll view stretches to fill the available space - it should be 768pt on iPad. That is the case on iOS 7 but not iOS 8.

This is the setup: In Interface Builder, I have a UIViewController that contains a UIView which contains a UIScrollView with autolayout contraints trailing, leading, bottom, and top space to the superview. Then in viewDidLoad:

    UIImage *image = [UIImage imageNamed:@"image"];
    self.imageView = [[UIImageView alloc] initWithImage:image];
    self.imageView.contentMode = UIViewContentModeScaleAspectFit;
    self.imageView.frame = CGRectMake(0, 0, self.imageView.image.size.width, self.imageView.image.size.height);

    [self.scrollView addSubview:self.imageView];
    self.scrollView.contentSize = image.size;

    #warning Bug here - scroll view frame is 600pt on iOS 8 - should be 768 for iPad
    NSLog(@"scroll view frame wid: %f", self.scrollView.frame.size.width);

I discovered if I put that same NSLog in viewDidAppear the frame's width is correctly 768pt. I tried moving that code into viewWillAppear instead of viewDidLoad, but I get the same outcome - it's 600 in viewWillAppear as well. So the scroll view is properly stretching to fill the display but not until after it appears on screen. I need the correct frame size before the image appears on screen so that I may calculate the proper min and max zoom values.

What can I do to fix that and ensure it works for iOS 7 and 8?

like image 208
Jordan H Avatar asked Oct 23 '14 16:10

Jordan H


2 Answers

I've solved it. For some reason, viewDidLoad is too early in the life cycle to obtain the scroll view's adjusted frame on iOS 8, but again it works on iOS 7. viewWillAppear is also too early, as well as viewWillLayoutSubviews.

To solve the problem, I just moved the code where I need to use the scroll view's frame size to viewDidLayoutSubviews which does finally obtain the correct size it will be when it appears.

like image 105
Jordan H Avatar answered Oct 29 '22 11:10

Jordan H


I was also struggling a lot with a similar problem. I solved it by changing the width of the contentView inside the scrollview programatically. In ViewDidLoad i call this method

func setupWidthOfContentView(){

    let screen = UIScreen.mainScreen().bounds
//        println("Width: \(screen.size.width) Height: \(screen.size.height)")

    var constW = NSLayoutConstraint(item: vwContentView, attribute: NSLayoutAttribute.Width, relatedBy: NSLayoutRelation.Equal, toItem: nil, attribute: NSLayoutAttribute.NotAnAttribute, multiplier: 1, constant: screen.size.width)
    vwContentView.addConstraint(constW)
}
like image 23
Ibrahim Yildirim Avatar answered Oct 29 '22 12:10

Ibrahim Yildirim