UIImageView and UIScrollView zooming

后端 未结 6 1635
抹茶落季
抹茶落季 2020-12-04 19:45

Do I actually need a UIPinchGestureRecognizer inside a UIScrollView to have the pinch working? If yes how do I do it? I am trying to implement what flipboard has, where it b

相关标签:
6条回答
  • 2020-12-04 20:09

    I did a custom image viewer not a long ago without the pinch recognizers. Just UIImageView on top of UIScrollView. There you pass a string with a link to the image and it also has a progress bar. Once that image is finished loading the image is shown. Here's the code:

    -(UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
    {
      return self.theImageView;
    }
    
    - (CGRect)centeredFrameForScrollView:(UIScrollView *)scroll andUIView:(UIView *)rView {
      CGSize boundsSize = scroll.bounds.size;
      CGRect frameToCenter = rView.frame;
      // center horizontally
      if (frameToCenter.size.width < boundsSize.width) {
        frameToCenter.origin.x = (boundsSize.width - frameToCenter.size.width) / 2;
      }
      else {
        frameToCenter.origin.x = 0;
      }
      // center vertically
      if (frameToCenter.size.height < boundsSize.height) {
        frameToCenter.origin.y = (boundsSize.height - frameToCenter.size.height) / 2;
      }
      else {
        frameToCenter.origin.y = 0;
      }
      return frameToCenter;
    }
    
    -(void)scrollViewDidZoom:(UIScrollView *)scrollView
    {
      self.theImageView.frame = [self centeredFrameForScrollView:self.theScrollView andUIView:self.theImageView];                               
    }
    
    - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
      [self.resourceData setLength:0];
      self.filesize = [NSNumber numberWithLongLong:[response expectedContentLength]];
    }
    
    -(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
    {
      [self.resourceData appendData:data];
      NSNumber *resourceLength = [NSNumber numberWithUnsignedInteger:[self.resourceData length]];
      self.progressBar.progress = [resourceLength floatValue] / [self.filesize floatValue];
    }
    
    -(void)connectionDidFinishLoading:(NSURLConnection *)connection
    {
      self.theImage = [[UIImage alloc]initWithData:resourceData];
      self.theImageView.frame = CGRectMake(0, 0, self.theImage.size.width, self.theImage.size.height);
      self.theImageView.image = self.theImage;
      self.theScrollView.minimumZoomScale = self.theScrollView.frame.size.width / self.theImageView.frame.size.width;
      self.theScrollView.maximumZoomScale = 2.0;
      [self.theScrollView setZoomScale:self.theScrollView.minimumZoomScale];
      self.theScrollView.contentSize = self.theImageView.frame.size;
      self.theLabel.hidden = YES;
      self.progressBar.hidden = YES;
    }
    
    -(void)setImageInImageView
    {
      NSURLRequest *req = [[NSURLRequest alloc]initWithURL:[NSURL URLWithString:self.imageLink]];
      NSURLConnection *conn = [[NSURLConnection alloc]initWithRequest:req delegate:self];
      if (conn)
      {
        self.resourceData = [NSMutableData data];
      }
      else
      {
        NSLog(@"Connection failed: IMageViewerViewController");
      }
    }
    
    -(void)loadView
    {
      self.filesize = [[NSNumber alloc]init];
      self.progressBar = [[UIProgressView alloc]initWithProgressViewStyle:UIProgressViewStyleBar];
      self.progressBar.frame = CGRectMake(20, 240, 280, 40);
      [self.progressBar setProgress:0.0];
      self.theImageView = [[[UIImageView alloc]initWithFrame:[[UIScreen mainScreen]applicationFrame]]autorelease];
      self.theScrollView = [[[UIScrollView alloc]initWithFrame:[[UIScreen mainScreen]applicationFrame]]autorelease];
      self.theScrollView.delegate = self;
      [self.theScrollView addSubview:self.theImageView];
      self.view = self.theScrollView;
      self.theLabel = [[UILabel alloc]initWithFrame:CGRectMake(0, 200, 320, 40)];
      self.theLabel.font = [UIFont boldSystemFontOfSize:15.0f];
      self.theLabel.text = @"Please wait, file is being downloaded";
      self.theLabel.textAlignment = UITextAlignmentCenter;
      self.theLabel.hidden = NO;
      [self.view addSubview:self.progressBar];
      [self.view bringSubviewToFront:self.progressBar];
      [self.view addSubview:self.theLabel];
      [self.view bringSubviewToFront:self.    theLabel];
      [self performSelectorOnMainThread:@selector(setImageInImageView) withObject:nil waitUntilDone:NO];
    }
    

    And the header file:

    @interface ImageViewerViewController : UIViewController<UIScrollViewDelegate, NSURLConnectionDelegate, NSURLConnectionDataDelegate>
    
    @property (nonatomic, retain) IBOutlet UIImageView *theImageView;
    @property (nonatomic, retain) IBOutlet UIScrollView *theScrollView;
    @property (nonatomic, retain) NSString *imageLink;
    @property (nonatomic, retain) UIImage *theImage;
    @property (nonatomic, retain) UILabel *theLabel;
    @property (nonatomic, retain) UIProgressView *progressBar;
    @property (nonatomic, retain) NSMutableData *resourceData;
    @property (nonatomic, retain) NSNumber *filesize;
    @end
    

    Hope it helps

    0 讨论(0)
  • 2020-12-04 20:12

    Objective C

    Pinch-zoom Image in Scrollview Steps (Objective C)

    1. Scroll View Constraints

    2. Add ImageView In ScrollView and set Constraints

    3. Take IBOutlets

    IBOutlet UIScrollView * bgScrollView;
    IBOutlet UIImageView * imageViewOutlet;
    

    4. viewDidLoad Method

    - (void)viewDidLoad
     {
        [super viewDidLoad];
    
        float minScale=bgScrollView.frame.size.width / imageViewOutlet.frame.size.width;
        bgScrollView.minimumZoomScale = minScale;
        bgScrollView.maximumZoomScale = 3.0;
        bgScrollView.contentSize = imageViewOutlet.frame.size;
        bgScrollView.delegate = self;
    }
    

    5. Scroll View Delegate Method

    - (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
    {
        return imageViewOutlet;
    }
    

    Swift

    Pinch-zoom Image in Scrollview Steps (Swift)

    1. Scroll View Constraints

    2. Add ImageView In ScrollView and set Constraints

    3. Take IBOutlets

    @IBOutlet weak var bgScrollView : UIScrollView!
    @IBOutlet weak var imageView : UIImageView!
    

    4. viewDidLoad Method

     override func viewDidLoad() {
        super.viewDidLoad()
    
        let minScale = bgScrollView.frame.size.width / imageView.frame.size.width;
        bgScrollView.minimumZoomScale = minScale
        bgScrollView.maximumZoomScale = 3.0
        bgScrollView.contentSize = imageView.frame.size
        bgScrollView.delegate = self
    }
    

    5. Scroll View Delegate Method

    func viewForZooming(in scrollView: UIScrollView) -> UIView? {
        return imageView
    }
    
    0 讨论(0)
  • 2020-12-04 20:16

    All you need to do is add your UIImageView (or any view you want to zoom) inside your UIScrollView.

    Set your maximumZoomScale on your UIScrollView to any value higher than 1.0f.

    Set yourself as the delegate of your UIScrollView and return the UIImageView in the viewForZooming delegate method.

    That's it. No pinch gesture needed, no nothing. UIScrollView handles pinch zooming for you.

    0 讨论(0)
  • 2020-12-04 20:28

    I guess this answer may be unnecessary but I have had similar problems as @adit and solved it in a very simple way (I think) and maybe someone with similar challenges can use it:

    - (void)viewDidLoad {
        [super viewDidLoad];
    
        self.view.backgroundColor = [UIColor yellowColor];
    
        UIImage *imageToLoad = [UIImage imageNamed:@"background_green"];
    
        self.myImageView = [[UIImageView alloc]initWithImage:imageToLoad];
        self.myScrollView = [[UIScrollView alloc]initWithFrame:self.view.bounds];
        [self.myScrollView addSubview:self.myImageView];
        self.myScrollView.contentSize = self.myImageView.bounds.size;
        self.myScrollView.indicatorStyle = UIScrollViewIndicatorStyleWhite;
        self.myScrollView.minimumZoomScale = 0.3f;
        self.myScrollView.maximumZoomScale = 3.0f;
        self.myScrollView.delegate = self;
        [self.view addSubview:self.myScrollView];
    }
    
    - (UIView *) viewForZoomingInScrollView:(UIScrollView *)scrollView {
        NSLog(@"viewForZoomingInScrollView");
        return self.myImageView;
    } 
    

    My problem was a very simple I had forgot to add self.myScrollView.delegate = self;, which was the reason why i had problems. It took me forever to figure that simple problem out, i guess I did not see the forrest for all the trees :-)

    0 讨论(0)
  • 2020-12-04 20:28

    For 'snap-image-to-screen-edges' solution @Shrikant Tanwade's worked well, but I wanted some insets. I tried settings constraints' constants, but that does not worked.

    I ended with following solution:

    1. same as for Shrikant's - set scrollView, imageView's constraints, set their constants to 0.

    2. set insets with scrollView.contentInset = UIEdgeInsetsMake(....

    0 讨论(0)
  • 2020-12-04 20:35

    When I was developing my Zooming PDF viewer in a UIScrollView I found out that when running it on the Phone it actually already has the zooming implemented as part of the phone. But you could have a look at this, http://developer.apple.com/library/ios/#samplecode/ZoomingPDFViewer/Introduction/Intro.html it is a piece of sample code that tries to implement the functionality for zooming, this is want got me started.

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