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

ope*_*rog 4 iphone objective-c uiscrollview ios

我在UIScrollView中有一个视图,用户可以在其中放大.

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

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

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

win*_*zki 15

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

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

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

一种解决方案是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));
   }
Run Code Online (Sandbox Code Playgroud)

设置滚动视图的委托,覆盖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);
 }
Run Code Online (Sandbox Code Playgroud)

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


Sri*_*aju 0

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

[self.yourView.layer setAnchorPoint:CGPointMake(0.5, 0)];
Run Code Online (Sandbox Code Playgroud)

在此图中恰当地定义了锚点的坐标 -

在此输入图像描述

如果你想让动画从左中心锚定,那么将anchorPoint设置为(0.0, 0.5)图中的B点。

  • 当您在普通视图上设置变换时,anchorPoint 将起作用。但它不会影响滚动视图内容的行为。请参阅下面我的回答。 (3认同)