在滚动视图中使用自动布局缩放图像如何居中?

Posted

技术标签:

【中文标题】在滚动视图中使用自动布局缩放图像如何居中?【英文标题】:Zoom image using auto layout in scroll view How to center? 【发布时间】:2015-09-30 16:11:58 【问题描述】:

我几乎完全从情节提要使用自动布局完成了缩放,唯一的问题是我的图像在缩放后没有居中。目标是使图片缩放与图片边界完全一致,没有黑色条纹。

这是我的约束(它基本上是带有 imageView 的标准 ScrollView):

这是我按顺序做的。首先我设置UIScrollViewDelegate方法:

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

然后在图像下载完成后,我更新我的UIImageViewheight 约束:

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

对于一个图像的约束就像

所以它是这样工作的(抱歉 3MB GIF):

所以它几乎几乎可以工作,但奇怪的是它落到了底部,而不是居中,如何居中?

我知道我必须用方法-(void)scrollViewDidZoom:(UIScrollView *)scrollView 做某事但我真的不确定我应该在那里设置什么。

【问题讨论】:

【参考方案1】:

尤里卡!我设法用AutoLayout 完全做到了这一点

要实现这一点,需要为中心 Y 约束创建出口,然后在缩放时对其进行修改:

-(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];

就是这样。

【讨论】:

【参考方案2】:

我可以通过子类化 UIScrollView 以编程方式做到这一点(子类不是必需的,但我想要一些可重用的东西)。

我使用了以下约束:

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]];

注意这里self 是一个UIScrollView。使用您的滚动视图参考代替它。

scrollViewDidZoom委托方法中:

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];

设置适当的内容插入。

【讨论】:

谢谢你,这给了我想法,如何在故事板中做到这一点(+1)

以上是关于在滚动视图中使用自动布局缩放图像如何居中?的主要内容,如果未能解决你的问题,请参考以下文章

页面应用程序 + 自动布局 + 子视图在滚动时缩放

如何使用固定宽度和自动布局正确缩放图像?

如何将图像居中和自动缩放?

在水平堆栈视图(自动布局)中将文本与图像垂直居中 - iOS

有没有办法在结合页面控制的滚动视图中自动布局图像?

表格视图中单元格内的自动布局图像。正确的布局,但只有一次向下滚动和备份?