How to zoom a view in UIScrollView with anchor point in center?

后端 未结 2 1719
暗喜
暗喜 2021-02-10 14:51

I have a view in UIScrollView in which the user can zoom into.

The view has the same size as the UIScrollView frame. However, the subviews of that view are bigger and ce

相关标签:
2条回答
  • 2021-02-10 15:21

    Yes I believe you can change the anchorPoint for a view's layer. like so -

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

    The coordinates of the anchor point are aptly defined in this diagram -

    enter image description here

    If you want the animation to anchor from left-center then set the anchorPoint to (0.0, 0.5) i.e. point B in the figure.

    0 讨论(0)
  • 2021-02-10 15:25

    The behavior can be changed to zooming around the center, but the technique is tricky.

    Suppose you have a scroll view of size (300,300) with a single zoomable subview, self.imageView, located initially at (0,0,300,300). Now you want to zoom out. What is happening is that the contentOffset always remains (0,0) as you zoom out. This leads to the appearance that you are zooming with the anchor point at top-left corner.

    However, changing the anchor point on any views will not help here; this is because the zooming behavior of the scroll view is not just a zoom transformation applied to some subview. The appearance of content in scroll view is controlled by contentInset and contentOffset, which are separate variables maintained by the scroll view. You need to modify the behavior of the content offset and the content inset during zoom.

    One solution is to adjust the contentInset dynamically as the scrollview scrolls. The purpose is to keep the image always centered in the visible area of the scroll view.

    When initializing the scroll view, prepare its frame like this:

     - (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));
       }
    

    Set up a delegate for the scroll view, override scrollViewDidScroll:, and do something like this:

     - (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);
     }
    

    Each pinch gesture will give rise to a scrolling action. The result is that the insets are adjusted dynamically, so that the imageView always appears to be in the center of the scroll view.

    0 讨论(0)
提交回复
热议问题