Jakub
Jakub

Reputation: 13860

Zoom image using auto layout in scroll view How to center?

I'm almost done zooming using auto layout completely from storyboard, the only problem is that my image does not center after zoom. The goal is to make picture zoom exactly with picture boundaries without black stripes.

Here is my constraints (it's basically standard ScrollView with imageView): enter image description here

And here is what I done in order. Firstable I set UIScrollViewDelegate methods:

-(UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView{
    return self.fullScreenImageView;
}

And then after image download is complete i update the height constraint of my UIImageView:

-(void)setupConstraintsToImageSize:(CGSize)imageSize {
    [self.imageHConstraint setConstant:imageSize.height];
    [self layoutIfNeeded];
}

For an image constraints is like

enter image description here

So it's work like this (sorry 3MB GIF) :

enter image description here

So it's almost ALMOST works, but it's strangely goes to bottom, not center, how to center it?

I figure out i have to do sth with method -(void)scrollViewDidZoom:(UIScrollView *)scrollView But I'm really not sure what should I set there.

Upvotes: 4

Views: 2811

Answers (2)

Jakub
Jakub

Reputation: 13860

Eureka! I managed to do this completely with AutoLayout

To achieve this what needs to be done is create outlet to your Center Y Constraints and then modify it when zoomed:

-(void)scrollViewDidZoom:(UIScrollView *)scrollView {
    CGFloat diff = self.fullScreenImageView.frame.size.height-self.fullScreenImageView.image.size.height;
    if(self.fullScreenImageView.frame.size.height >= self.frame.size.height) {return;}
    [self.centerYConstraint setConstant:-diff/2];
}

That's it.

Upvotes: 2

Ishan Handa
Ishan Handa

Reputation: 2281

I was able to do this programmatically by subclassing UIScrollView (subclass not necessary, but I wanted something reusable).

I used the following constraints:

CGRect visibleRect = CGRectMake(0, self.contentInset.top, self.bounds.size.width, self.bounds.size.height -  self.contentInset.top - self.contentInset.bottom);

        CGRect scaleFrame = AVMakeRectWithAspectRatioInsideRect(_image.size, visibleRect);

        _imageViewLeadingConstraint = [NSLayoutConstraint constraintWithItem:_imageView
                                                                   attribute:NSLayoutAttributeLeading
                                                                   relatedBy:NSLayoutRelationEqual
                                                                      toItem:self attribute:NSLayoutAttributeLeading
                                                                  multiplier:1.0 constant:scaleFrame.origin.x];

        _imageViewTopConstraint = [NSLayoutConstraint constraintWithItem:_imageView
                                                               attribute:NSLayoutAttributeTop
                                                               relatedBy:NSLayoutRelationEqual
                                                                  toItem:self attribute:NSLayoutAttributeTop
                                                              multiplier:1.0 constant:scaleFrame.origin.y];

        _imageViewWidthConstraint = [NSLayoutConstraint constraintWithItem:_imageView
                                                                 attribute:NSLayoutAttributeWidth
                                                                 relatedBy:NSLayoutRelationEqual
                                                                    toItem:self attribute:NSLayoutAttributeWidth
                                                                multiplier:scaleFrame.size.width / self.bounds.size.width constant:0];

        _imageViewHeightConstraint = [NSLayoutConstraint constraintWithItem:_imageView
                                                                  attribute:NSLayoutAttributeHeight
                                                                  relatedBy:NSLayoutRelationEqual
                                                                     toItem:self attribute:NSLayoutAttributeHeight
                                                                 multiplier:scaleFrame.size.height / self.bounds.size.height constant:0];

        [self addConstraints:@[_imageViewLeadingConstraint, _imageViewTopConstraint, _imageViewWidthConstraint, _imageViewHeightConstraint]];

Note that here self is a UIScrollView. use your scrollview reference in place of it.

In scrollViewDidZoom delegate method:

CGFloat Ws = self.frame.size.width - self.contentInset.left - self.contentInset.right;
    CGFloat Hs = self.frame.size.height - self.contentInset.top - self.contentInset.bottom;
    CGFloat W = _imageView.frame.size.width;
    CGFloat H = _imageView.frame.size.height;

    _imageViewLeadingConstraint.constant = MAX((Ws-W)/2, 0);
    _imageViewTopConstraint.constant = MAX((Hs-H)/2, 0);
    [self layoutIfNeeded];

Set appropriate content insets.

Upvotes: 1

Related Questions