Zooming UIImageView inside UIScrollView with autolayout

前端 未结 3 855
迷失自我
迷失自我 2020-12-14 08:50

I have a UIImageView embedded inside a UIScrollView, prior to iOS 6 and autolayout I used the following snippet inside the controller\'s viedDidLoad method to display a scro

相关标签:
3条回答
  • 2020-12-14 09:21

    The best solution was proposed by Zsolt in the comments:

    http://github.com/evgenyneu/ios-imagescroll check this out. Works perfectly for me.

    The solution proposed in this repository is to adjust the minimum and current zoom level before displaying the image:

    @interface MyViewController () <UIScrollViewDelegate>
    @property (weak, nonatomic) IBOutlet UIScrollView *scrollView;
    @property (weak, nonatomic) IBOutlet UIImageView *imageView;
    @end
    
    
    @implementation MyViewController
    
    - (void)viewDidLoad
    {
      [super viewDidLoad];
      self.scrollView.delegate = self;
    
      [self initZoom];
    }
    - (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
    {
      [self initZoom];
    }
    
    // Zoom to show as much image as possible
    - (void) initZoom {
      float minZoom = MIN(self.view.bounds.size.width / self.imageView.image.size.width,
                          self.view.bounds.size.height / self.imageView.image.size.height);
      if (minZoom > 1) return;
    
      self.scrollView.minimumZoomScale = minZoom;
    
      self.scrollView.zoomScale = minZoom;
    }
    
    - (UIView*)viewForZoomingInScrollView:(UIScrollView *)scrollView
    {
      return self.imageView;
    }
    

    However sample conatins issue with zooming out. Image is not getting centered. This can be easily fixed by using the custom scroll view class with the following code in it:

    @interface MyScrollView : UIScrollView
    @end
    
    @implementation MyScrollView
    
    -(void)layoutSubviews
    {
      [super layoutSubviews];
      UIView* v = [self.delegate viewForZoomingInScrollView:self];
      CGFloat svw = self.bounds.size.width;
      CGFloat svh = self.bounds.size.height;
      CGFloat vw = v.frame.size.width;
      CGFloat vh = v.frame.size.height;
      CGRect f = v.frame;
      if (vw < svw)
        f.origin.x = (svw - vw) / 2.0;
      else
        f.origin.x = 0;
      if (vh < svh)
        f.origin.y = (svh - vh) / 2.0;
      else
        f.origin.y = 0;
      v.frame = f;
    }
    
    @end
    
    0 讨论(0)
  • 2020-12-14 09:32

    I also agree with Zsolt's suggestion and link.

    But I update the width/height constraints to allow it to handle any size image:

    - (void) initZoom
    {
      for (NSLayoutConstraint *constraint in self.photoImageView.constraints)
      {
        if (constraint.firstAttribute == NSLayoutAttributeWidth)
          constraint.constant = self.photoImageView.image.size.width;
        else if (constraint.firstAttribute == NSLayoutAttributeHeight)
          constraint.constant = self.photoImageView.image.size.height;
      }
    
      float minZoom = MIN(self.scrollView.bounds.size.width / self.photoImageView.image.size.width,
                          self.scrollView.bounds.size.height / self.photoImageView.image.size.height);
      if (minZoom > 1) return;
    
      self.scrollView.minimumZoomScale = minZoom;
    
      self.scrollView.zoomScale = minZoom;
    }
    
    0 讨论(0)
  • 2020-12-14 09:35

    Solved my problem using the following code sample. The github repository corresponds to the book Programming iOS by Matt Neuburg.

    https://github.com/mattneub/Programming-iOS-Book-Examples/blob/11c6c57743b04e6e722b635b87be69fa41a5abaf/ch20p573scrollViewAutoLayout/ch20p573scrollViewAutoLayout/ViewController.m

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