UIScrollView采用纯AutoLayout方法,缩放和居中ImageView

时间:2014-01-26 17:24:40

标签: ios uiscrollview uiimageview autolayout zooming

我想实现一个UIScrollview,其中包含一个居中的缩放UIImageView,并且只使用Layout-Constraints进行缩放,而且只使用了Layout-Constraints。

我创建了一个UIScrollView,UIImageView将其作为子视图添加到普通的UIView中。

self.scrollView = [[UIScrollView alloc] initWithFrame:CGRectZero];
self.scrollView.translatesAutoresizingMaskIntoConstraints = NO;
self.scrollView.maximumZoomScale = 10.0f;
self.scrollView.delegate = self;

self.imageView = [[UIImageView alloc] initWithFrame:CGRectZero];
self.imageView.translatesAutoresizingMaskIntoConstraints = NO;

[self.scrollView addSubview:self.imageView];
[self.view addSubview:self.scrollView];

比我添加这些视图的约束:

    NSDictionary *viewsDictionary = @{@"scrollView" : self.scrollView,
                                  @"imageView" : self.imageView};

CGRect imageFrame = CGRectMake(0, 0, 184, 111);
NSDictionary *metrics = @{@"width" : @(self.view.frame.size.width),
                          @"height" : @(self.view.frame.size.height),
                          @"imageWidth" : @(widgetFrame.size.width),
                          @"imageHeight" : @(widgetFrame.size.height)};

NSArray *scrollViewVerticalConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|[scrollView(height)]" options:0 metrics:metrics views:viewsDictionary];
NSArray *scrollViewHorizontalConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|[scrollView(width)]" options:0 metrics:metrics views:viewsDictionary];

NSArray *imageViewVerticalConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"V:[imageView(imageHeight)]" options:0 metrics:metrics views:viewsDictionary];
NSArray *imageViewHorizontalConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"H:[imageView(imageWidth)]" options:0 metrics:metrics views:viewsDictionary];

NSLayoutConstraint *imageCenterXConstraint = [NSLayoutConstraint constraintWithItem:self.imageView attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeCenterX multiplier:1.0 constant:0.0];
NSLayoutConstraint *imageCenterYConstraint = [NSLayoutConstraint constraintWithItem:self.imageView attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeCenterY multiplier:1.0 constant:0.0];

[self.view addConstraints:scrollViewVerticalConstraints];
[self.view addConstraints:scrollViewHorizontalConstraints];

[self.view addConstraints:imageViewVerticalConstraints];
[self.view addConstraints:imageViewHorizontalConstraints];

[self.view addConstraints:@[imageCenterXConstraint, imageCenterYConstraint]];

现在它看起来应该...... UIScrollView中的一个居中的UIImageView可以缩放(通过UIScrollViewDelegate方法)。

但是当我完成Zoom-Gesture后我遇到了一个问题,UIImageView很快移动到另一个位置并立即返回到中心。通过放大,它向左上角方向移动,通过向右下角方向缩小。

为什么这么做呢?

有人可以给我一个提示吗?我查看了SO,但没有找到与中心UIImageView相关的答案。

1 个答案:

答案 0 :(得分:0)

我从事过类似的工作。我建议的最好方法是使用滚动视图的子类。您可以在此类中定义属性imageView。我做了同样的事情,并在PhotoScrollView类中使用了以下代码片段,它扩展了UIScrollView:

//In viewDidLoad

    self.minimumZoomScale = 1.0f;
    self.maximumZoomScale = 15.0f;
    self.zoomScale = 1.0f;

    self.delegate   =   self;

//In your doubleTapped method
 //for zooming after double tapping
 - (void)scrollViewDoubleTapped:(UITapGestureRecognizer*)recognizer
  {
   // get the point of image which is double tapped

   CGPoint pointInView = [recognizer locationInView:self.imageView];

    // Get a zoom scale that's zoomed in slightly, capped at the maximum zoom scale specified by the scroll view
    CGFloat newZoomScale = self.zoomScale * 4.0f;
    newZoomScale = MIN(newZoomScale, self.maximumZoomScale);

    // Figure out the rect we want to zoom to, then zoom to it

    CGSize scrollViewSize = self.imageView.frame.size;


    CGFloat w = scrollViewSize.width / newZoomScale;
    CGFloat h = scrollViewSize.height / newZoomScale;
    CGFloat x = pointInView.x - (w / 2.0f);
    CGFloat y = pointInView.y - (h / 2.0f);

    CGRect rectToZoomTo = CGRectMake(x, y, w, h);

    [self zoomToRect:rectToZoomTo animated:YES];
  }
// To re-center the image after zooming in and zooming out
- (void)centerScrollViewContents
{
    CGSize boundsSize = self.bounds.size;
    CGRect contentsFrame = self.imageView.frame;

    if (contentsFrame.size.width < boundsSize.width)
    {
      contentsFrame.origin.x = (boundsSize.width - contentsFrame.size.width) / 2.0f;
    }
    else
    {
      contentsFrame.origin.x = 0.0f;
    }

    if (contentsFrame.size.height < boundsSize.height)
    {
      contentsFrame.origin.y = (boundsSize.height - contentsFrame.size.height) / 2.0f;
    }
    else
    {
      contentsFrame.origin.y = 0.0f;
    }

  self.imageView.frame = contentsFrame;
}

此外,您还必须使用以下方法返回imageView:

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

但如果您不想按照我的建议使用自定义ScollView,则可以在此代码段中使用属性scrollView而不是self。

如果有效,请告诉我。谢谢:))