简体   繁体   中英

UIView UIScrollview - frames, bounds, center confusions

I am putting a UIImageView inside a UIScrollView, and trying to control the image so that it is centred on the scrollview after a zoom. and I am not sure the best way to do this.

The apple docs tell us NOT to use the frame property: "Warning If the transform property is not the identity transform, the value of this property is undefined and therefore should be ignored." So I am attempting using the following in a UIViewController subclass whose xib contains a scrollView and contained imageView:

scrollView.bounds =
    CGRectMake 
    (scrollView.contentSize.width/2 - scrollView.center.x,
     scrollView.contentSize.height/2 - scrollView.center.y,
     scrollView.bounds.size.width,
     scrollView.bounds.size.height);

containedView.center =    
    CGPointMake 
    (containedView.bounds.size.width*scrollView.zoomScale/2,
     containedView.bounds.size.height*scrollView.zoomScale/2);

This works accurately where the width and height of the containedView is larger than that of the scrollView and sets the views so that subsequent scrolling will take you exactly to the edges of the containedView. However when either dimension of the image is smaller than the scrollView width and height the image is magnetically attracted to the top left corner of the screen. In the iPad Simulator (only) when the images is shrunk to the size of minimumZoom it does lock on to the centre of the screen. The magnetic attraction is very smooth as if something in the UI is overriding my code after the image has been centred. It looks a bit like a CALayer contentsGravity ( kCAGravityTopLeft ) thing, maybe?

Apple contradict their own advice in their code sample, photoScroller (in a subclass of UIScrollView):

// center the image as it becomes smaller than the size of the screen

CGSize boundsSize = self.bounds.size;
CGRect frameToCenter = imageView.frame;

// center horizontally
if (frameToCenter.size.width < boundsSize.width)
    frameToCenter.origin.x = (boundsSize.width - frameToCenter.size.width) / 2;
else
    frameToCenter.origin.x = 0;

// center vertically
if (frameToCenter.size.height < boundsSize.height)
    frameToCenter.origin.y = (boundsSize.height - frameToCenter.size.height) / 2;
else
    frameToCenter.origin.y = 0;

imageView.frame = frameToCenter;

This method does a better job of centring when the image is smaller, but when I try this on my project it introduces some kind of inconsistencies. For example, with scrollView.bounces = NO, a horizontal image whose height is smaller than the height of the scrollView but whose width is larger (so it can be scrolled from left to right) will scroll further to the left than it should (when scrolling to the right it stops correctly at the edge of the image, although if scrollView.bounces = YES it then bounces in from the edge so the image is always cropped on the left) When the image is larger in both dimensions than its containing scrollview this issue accentuates and the whole result feels broken, which is unsurprising given Apple's documented advice.

I have scoured the forums and can't find much comment on this. Am I missing something really obvious?

You don't appear to be using the transform property, so you can ignore that warning about not using the frame property when using the transform property. Go ahead and use the frame property, just like Apple (and the rest of us) do.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM