Question

I have a UIScrollView, and its only misstion is to display a single photo token from camera or choosed from the photo library.

But there's one problem - the orientation of the photos,

I mean, the "vertical" photos (the photos whose height > width), versus the "horizontal" photos (width > height).

And what I want is just like displaying a single photo in the system Photo app,

in which I can comfortablely zooming both vertical and horizon photo

Firstly, here's my code of my custom PhotoView (which mainly controls a UIScrolView and a UIImageView)

// .h
@interface PhotoView : UIView
<UIScrollViewDelegate>{
    UIScrollView *myScrollView;
    UIImageView *photoView;
}
...
@end
// .m
- (void)refreshPhoto:(UIImage *)aPhoto {
    if (aPhoto) {
        CGSize photoSize = aPhoto.size;
        CGSize scrollSize = self.myScrollView.frame.size;
        if (photoSize.height > photoSize.width) { // vertical photo
            self.photoView.frame = CGRectMake(0, 0, scrollSize.width, scrollSize.height);
        }
        else { // horizontal photo, initially it should be zoomed out to fit the width of myScrollView
            CGFloat factor = photoSize.width / scrollSize.width;
            self.photoView.frame = CGRectMake(0, 0, scrollSize.width, photoSize.height / factor);
            self.photoView.center = CGPointMake(scrollSize.width / 2, scrollSize.height / 2);
        }
    }
    else  // no photo
        self.photoView.frame = self.myScrollView.frame;
    self.photoView.image = aPhoto;
    //self.myScrollView.zoomScale = 1.0;
    //self.myScrollView.contentSize = self.photoView.frame.size;
}
- (id)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        self.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"photoViewBg.png"]];
        self.myScrollView = [[[UIScrollView alloc] initWithFrame:CGRectMake(30, 35, 260, 360)] autorelease];
        self.myScrollView.delegate = self;
        self.myScrollView.maximumZoomScale = 2.5;
        self.myScrollView.minimumZoomScale = 1.0;
        self.myScrollView.backgroundColor = [UIColor clearColor];
        self.photoView = [[[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 0, 0)] autorelease];
        self.myScrollView.contentSize = self.imageView.frame.size;
        [self.myScrollView addSubview:self.photoView];
        [self addSubview:self.imageView];
    }
    return self;
}
#pragma mark - Scroll View Delegate
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView {
    return self.photoView;
}

And my problem is, My code initially worked fine with vertical photos - no matter how big or small the photo has beening zoomed to, that is,

when I zoom and then drag the photo to out of the frame of myScrollView ((30, 35, 260, 360) in device screen),

it always bounces back to the edge of myScrollView.

But when I started dealing with the horizontal photos, things get confused.

From my code you can see that what I want initially for a horizontal photo is that, since horizontal ones' width is > their height but myScrollView's width is < height,

so initially, the horizontal ones should be in the middle of myScrollView, with the same width but smaller height, leaving two equal blanks on both the upper and lower side,

then when being zoomed and scrolled, its "bounce edge" should also be the same as myScrollView's edges, just like the vertical ones.

I'm afraid my poor English cannot express myself very clearly, if you don't get me, just take a vertical and a horizontal photo with your IOS device, then try to zoom and drag them in the Photo app, see how they are displayed initially and how they bounce back.

So now, I don't know how to get that effect I want, I'm in fact not so clear with UIScrollView - although I've read the document sevral times already.

I tried to change myScrollView's contentSize to adjust both vertical and horizontal photos, but I didn't make it yet,

and now I always set the contentSize the same as myScrollView's size, because I think myScrollView's edges are always the correct "bounce edge" for any zoomed photo.

But now this photoView has both problems for vertical and horizontal photos, such as the photo is scrolled completely out of myScrollView and became unvisible but not bounce back at all,

or the upper "bounce edge" is under the real upper edge of myScrollView in some distance and photos always bounce back there, which always leave a blank above.

I'm not sure if I correctly understand how UIScrollView works.

Should the contentSize always be equal to the photo that I'm displaying or fixed to myScrollView,

and when the photo is zoomed in or out, does the contentSize also changed or never?

I guess I should carefully take care of contenOffset and contentInset, but how?

Wish some one could offer me a help!

Thanks a lot!

Was it helpful?

Solution

I've solved this out, just take care of the contentSize and its position (the contentInset and contentOffset)

I managed to solve this issue with the below code:

- (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(float)scale {
    CGSize nowSize = view.frame.size;
    if (nowSize.height >= self.myScrollView.frame.size.height)
        self.myScrollView.contentInset = UIEdgeInsetsZero;
    else {
        CGFloat delta = self.myScrollView.frame.size.height/2 - view.frame.size.height/2;
        self.myScrollView.contentInset = UIEdgeInsetsMake(delta, 0, delta, 0);
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top