如何在UIScrollView中缩放视图,锚点位于中心?

时间:2011-11-16 15:12:58

标签: iphone objective-c ios uiscrollview

我在UIScrollView中有一个用户可以放大的视图。

视图与UIScrollView框架的大小相同。但是,该视图的子视图更大,更集中。它是一个与UIScrollView具有相同大小的容器,具有居中的内容。

当缩小时,UIScrollView会将内容的缩放更改为左上方的笨拙锚点,而不是居中的。

有没有办法改变这种行为,以便在放大或缩小时相对于中心而不是左上角发生变焦?

2 个答案:

答案 0 :(得分:14)

可以将行为更改为围绕中心进行缩放,但该技术很棘手。

假设您有一个大小(300,300)的滚动视图,其中包含一个可缩放的子视图self.imageView,最初位于(0,0,300,300)。现在你要缩小。发生的事情是,contentOffset在缩小时始终保持(0,0)。这会导致您使用左上角的锚点进行缩放。

但是,在任何视图上更改锚点都无济于事;这是因为滚动视图的缩放行为不仅仅是应用于某些子视图的缩放变换。滚动视图中内容的外观由contentInsetcontentOffset控制,它们是由滚动视图维护的单独变量。您需要在缩放期间修改内容偏移的行为和内容插入。

一种解决方案是在滚动视图滚动时动态调整contentInset。目的是使图像始终居中在滚动视图的可见区域中。

初始化滚动视图时,请按以下方式准备其框架:

 - (void) viewDidLoad {
      //// .......
      self.scrollView.zoomScale = 1;
      self.scrollView.minimumZoomScale = fminf(1, fminf(self.scrollView.frame.size.width/(self.imageView.image.size.width+1), self.scrollView.frame.size.height/(self.imageView.image.size.height+1)));
      CGFloat leftMargin = (self.scrollView.frame.size.width - self.imageView.image.size.width)*0.5;
      CGFloat topMargin = (self.scrollView.frame.size.height - self.imageView.image.size.height)*0.5;
      self.imageView.frame = CGRectMake(0, 0, self.imageView.image.size.width, self.imageView.image.size.height);
      [self assignInsetsOnScroller]; // this has to be done before settings contentOffset!
      self.scrollView.contentOffset = CGPointMake(fmaxf(0,-leftMargin), fmaxf(0,-topMargin));
      self.scrollView.contentSize = CGSizeMake(fmaxf(self.imageView.image.size.width, self.scrollView.frame.size.width+1), fmaxf(self.imageView.image.size.height, self.scrollView.frame.size.height+1));
   }

为滚动视图设置委托,覆盖scrollViewDidScroll:,并执行以下操作:

 - (void)scrollViewDidScroll:(UIScrollView *)scrollView {
    [self assignInsetsOnScroller];
 }
 - (void) assignInsetsOnScroller {
    CGFloat leftMargin = (scrollView.frame.size.width - self.imageView.frame.size.width)*0.5;
    CGFloat topMargin = (scrollView.frame.size.height - self.imageView.frame.size.height)*0.5;
    scrollView.contentInset = UIEdgeInsetsMake(fmaxf(0, topMargin), fmaxf(0, leftMargin), 0, 0);
 }

每个捏合手势都会产生滚动动作。结果是动态调整插图,以便imageView始终显示在滚动视图的中心。

答案 1 :(得分:1)

是的,我相信您可以更改视图图层的anchorPoint。像这样 -

[self.yourView.layer setAnchorPoint:CGPointMake(0.5, 0)];

此图中适当定义了锚点的坐标 -

enter image description here

如果您希望动画从左中心锚定,则将anchorPoint设置为(0.0, 0.5),即图中的B点。