2012-07-03 18 views
21

रखने के लिए स्क्रॉलव्यू में छविदृश्य जोड़ें, मैं UIImage के साथ UIImageView सेट करना चाहता हूं और इस छवि को ज़ूम प्राप्त करने के लिए UIScrollView के अंदर इस छविदृश्य को रखना चाहता हूं; और मुझे यह UIImageView और UIScrollView दृश्य के केंद्र में रेक्ट में फिट करने के लिए चाहिए ... क्या यह संभव है?आईओएस: ज़ूम

+0

तो आप छवि एक चुटकी के साथ ज़ूम करने के लिए चाहते हैं, लेकिन पुस्तक दृश्य में सब कुछ एक ही रहने के लिए? – woz

+0

हाँ ............. – CrazyDev

+0

हां यह निश्चित रूप से संभव है। क्या आपने कुछ भी करने की कोशिश की है? आप जो कुछ भी वर्णन कर रहे हैं वह इंटरफ़ेस बिल्डर/स्टोरीबोर्ड –

उत्तर

76
  1. एक <UIScrollViewDelegate>
  2. के रूप में अपने दृश्य नियंत्रक सेट अपने UIScrollView आकार आप दृश्य के केंद्र में आयत के लिए चाहते हैं खींचें। इंस्पेक्टर में अधिकतम ज़ूम को 1 से बड़ा कुछ सेट करें। 4 या 10.
  3. स्क्रॉल व्यू पर राइट क्लिक करें और प्रतिनिधि को अपने व्यू कंट्रोलर से कनेक्ट करें।
  4. को UIScrollView में खींचें और अपनी इच्छित छवि के साथ इसे सेट करें। इसे UIScrollView के समान आकार बनाएं।
  5. Ctrl + खींचें प्रपत्र आप अपने दृश्य नियंत्रक UIImageView के लिए एक IBOutlet बनाने के लिए की .h को UIImageView, यह कुछ imageView की तरह चतुर कहते हैं। एप्लिकेशन और चुटकी और अपने दिल की सामग्री के टिल पैन

    -(UIView *) viewForZoomingInScrollView:(UIScrollView *)scrollView 
    { 
        return self.imageView; 
    } 
    
  6. रन:

  7. यह कोड जोड़ें।

+0

में किया जा सकता है क्या आप इसका उदाहरण बना सकते हैं लेकिन प्रोग्रामेटिक रूप से? – fawrkes

+1

अब तक का सबसे सरल और सबसे स्पष्ट समाधान मैंने पाया है – anthonypliu

+0

@ जस्टिन पॉलसन क्या हम ज़ूमआउट को छवि आकार में प्रतिबंधित कर सकते हैं। मैं नहीं चाहता कि उपयोगकर्ता छवि आकार से ज़ूम आउट करें। क्या आप मेरी मदद कर सकते हैं? –

29

डाउनलोड this और this फ़ाइलें। छूने को संभालने के लिए आपको उनकी आवश्यकता होगी। स्क्रीन के अंदर

@property (nonatomic, retain) IBOutlet UIScrollView *imageScrollView; 
@property (nonatomic, retain) UIImageView *imageView; 

आयात डाउनलोड की गई फ़ाइल और कार्य करें::

आपके विचार scrollview प्रतिनिधि <UIScrollViewDelegate> में जोड़े और दुकानों की घोषणा

#import "TapDetectingImageView.h" 

#define ZOOM_STEP 2.0 
@interface myView (UtilityMethods) 
- (CGRect)zoomRectForScale:(float)scale withCenter:(CGPoint)center; 
@end 


@implementation myView 
@synthesize imageScrollView, imageView; 


- (void)viewDidLoad 
{ 

    [super viewDidLoad]; 

    //Setting up the scrollView  
    imageScrollView.bouncesZoom = YES; 
    imageScrollView.delegate = self; 
    imageScrollView.clipsToBounds = YES; 

    //Setting up the imageView 
    imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"myImage.png"]]; 
    imageView.userInteractionEnabled = YES; 
    imageView.autoresizingMask = (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin); 

    //Adding the imageView to the scrollView as subView 
    [imageScrollView addSubview:imageView]; 
    imageScrollView.contentSize = CGSizeMake(imageView.bounds.size.width, imageView.bounds.size.height); 
    imageScrollView.decelerationRate = UIScrollViewDecelerationRateFast; 

    //UITapGestureRecognizer set up 
    UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleSingleTap:)]; 
    UITapGestureRecognizer *doubleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleDoubleTap:)]; 
    UITapGestureRecognizer *twoFingerTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTwoFingerTap:)]; 

    [doubleTap setNumberOfTapsRequired:2]; 
    [twoFingerTap setNumberOfTouchesRequired:2]; 

    //Adding gesture recognizer 
    [imageView addGestureRecognizer:doubleTap]; 
    [imageView addGestureRecognizer:twoFingerTap]; 

    [singleTap release]; 
    [doubleTap release]; 
    [twoFingerTap release]; 

    // calculate minimum scale to perfectly fit image width, and begin at that scale 
    float minimumScale = 1.0;//This is the minimum scale, set it to whatever you want. 1.0 = default 
    imageScrollView.maximumZoomScale = 4.0; 
    imageScrollView.minimumZoomScale = minimumScale; 
    imageScrollView.zoomScale = minimumScale; 
    [imageScrollView setContentMode:UIViewContentModeScaleAspectFit]; 
    [imageView sizeToFit]; 
    [imageScrollView setContentSize:CGSizeMake(imageView.frame.size.width, imageView.frame.size.height)]; 



} 

- (void)scrollViewDidZoom:(UIScrollView *)aScrollView { 
    CGFloat offsetX = (imageScrollView.bounds.size.width > imageScrollView.contentSize.width)? 
    (imageScrollView.bounds.size.width - imageScrollView.contentSize.width) * 0.5 : 0.0; 
    CGFloat offsetY = (imageScrollView.bounds.size.height > imageScrollView.contentSize.height)? 
    (imageScrollView.bounds.size.height - imageScrollView.contentSize.height) * 0.5 : 0.0; 
    imageView.center = CGPointMake(imageScrollView.contentSize.width * 0.5 + offsetX, 
            imageScrollView.contentSize.height * 0.5 + offsetY); 
} 

- (void)viewDidUnload { 
    self.imageScrollView = nil; 
    self.imageView = nil; 
} 



#pragma mark UIScrollViewDelegate methods 

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

#pragma mark TapDetectingImageViewDelegate methods 

- (void)handleDoubleTap:(UIGestureRecognizer *)gestureRecognizer { 
    // zoom in 
    float newScale = [imageScrollView zoomScale] * ZOOM_STEP; 

    if (newScale > self.imageScrollView.maximumZoomScale){ 
     newScale = self.imageScrollView.minimumZoomScale; 
     CGRect zoomRect = [self zoomRectForScale:newScale withCenter:[gestureRecognizer locationInView:gestureRecognizer.view]]; 

     [imageScrollView zoomToRect:zoomRect animated:YES]; 

    } 
    else{ 

     newScale = self.imageScrollView.maximumZoomScale; 
     CGRect zoomRect = [self zoomRectForScale:newScale withCenter:[gestureRecognizer locationInView:gestureRecognizer.view]]; 

     [imageScrollView zoomToRect:zoomRect animated:YES]; 
    } 
} 


- (void)handleTwoFingerTap:(UIGestureRecognizer *)gestureRecognizer { 
    // two-finger tap zooms out 
    float newScale = [imageScrollView zoomScale]/ZOOM_STEP; 
    CGRect zoomRect = [self zoomRectForScale:newScale withCenter:[gestureRecognizer locationInView:gestureRecognizer.view]]; 
    [imageScrollView zoomToRect:zoomRect animated:YES]; 
} 

#pragma mark Utility methods 

- (CGRect)zoomRectForScale:(float)scale withCenter:(CGPoint)center { 

    CGRect zoomRect; 

    // the zoom rect is in the content view's coordinates. 
    // At a zoom scale of 1.0, it would be the size of the imageScrollView's bounds. 
    // As the zoom scale decreases, so more content is visible, the size of the rect grows. 
    zoomRect.size.height = [imageScrollView frame].size.height/scale; 
    zoomRect.size.width = [imageScrollView frame].size.width/scale; 

    // choose an origin so as to get the right center. 
    zoomRect.origin.x = center.x - (zoomRect.size.width/2.0); 
    zoomRect.origin.y = center.y - (zoomRect.size.height/2.0); 

    return zoomRect; 
} 

हो गया!

मूल रूप से के सबव्यूव के रूप में imageView जोड़ने के लिए यह कोड क्या है।

फिर, यह नल की संख्या को पहचानने के लिए, 0Vकक्षा विधियों को स्क्रॉल व्यू में जोड़ता है - उपयोगकर्ता चुटकी और ज़ूम कार्यक्षमताओं को जोड़ता है।

आप छवि के minimumScale सेट कर सकते हैं यदि आप 1.0 छोड़ छवि के रूप में यह है (आप इसे सेट करता है, तो एक छोटा सा कम यह छोटा किया जा रहा है), और maximumZoomScale, मैं सुझाव है कि आप छोड़ने के लिए प्रदर्शित किया जाना चाहिए यह 4 है, यह ठीक है!

अब, आप वहां से प्रोग्रामेटिक रूप से छवियां लोड कर सकते हैं।

आखिरी चीज़ जो आपको करना है वह है UIScrollView अपनी xib फ़ाइल के अंदर डालें और इसे imageScrollView पर लिंक करें। आपके पास सही केंद्र पर छवि होगी, आप ज़ूम करने के लिए उस पर टैप कर सकते हैं, कोड में सेट अप के रूप में ज़ूम करने के लिए चुप रहें।

+1

यह एक खाना पकाने की विधि की तरह है। कदम सही हैं लेकिन आप यह नहीं समझाते कि उन्हें ऐसा क्यों करना चाहिए। यह अंत में उसे और दूसरों की मदद करेगा। – Pfitz

+0

यह मूल रूप से कोड है जो मैं अपने ऐप्स में उपयोग कर रहा हूं। मैं – Phillip

+0

समझाऊंगा मुझे गलत मत समझो - कोड अच्छा है, लेकिन यह भी महत्वपूर्ण क्यों है। अन्यथा वह एक समान समस्या को हल करने के बारे में नहीं जानता। – Pfitz

2

मैंने एक उदाहरण एप्लिकेशन लिखा है जो इस व्यवहार को प्रदर्शित करने के लिए ऑटोलाउट और स्टोरीबोर्ड का भी समर्थन करता है।मुझे उम्मीद है कि यह हर बार इसे समझने की कोशिश कर रहा है: http://rexstjohn.com/facebook-like-ios-photo-modal-gallery-swipe-gestures/

0

स्विफ्ट 4 और आईओएस 11 के साथ, आप अपनी समस्या को हल करने के लिए निम्न में से किसी एक समाधान का उपयोग कर सकते हैं।


# 1। का उपयोग करते हुए सन्निवेश वाली

ViewController.swift

final class ViewController: UIViewController { 

    private let scrollView = ImageScrollView(image: UIImage(named: "image")!) 

    override func viewDidLoad() { 
     view.backgroundColor = .black 
     view.addSubview(scrollView) 

     scrollView.frame = view.frame 
     scrollView.autoresizingMask = [.flexibleWidth, .flexibleHeight] 
    } 

} 

ImageScrollView.swift

import UIKit 

final class ImageScrollView: UIScrollView { 

    private let imageView = UIImageView() 
    override var frame: CGRect { 
     didSet { 
      if frame.size != oldValue.size { setZoomScale() } 
     } 
    } 

    required init(image: UIImage) { 
     super.init(frame: .zero) 

     imageView.image = image 
     imageView.sizeToFit() 
     addSubview(imageView) 
     contentSize = imageView.bounds.size 

     contentInsetAdjustmentBehavior = .never // Adjust content according to safe area if necessary 
     showsVerticalScrollIndicator = false 
     showsHorizontalScrollIndicator = false 
     alwaysBounceHorizontal = true 
     alwaysBounceVertical = true 
     delegate = self 
    } 

    required init?(coder aDecoder: NSCoder) { 
     fatalError("init(coder:) has not been implemented") 
    } 

    // MARK: - Helper methods 

    func setZoomScale() { 
     let widthScale = frame.size.width/imageView.bounds.width 
     let heightScale = frame.size.height/imageView.bounds.height 
     let minScale = min(widthScale, heightScale) 
     minimumZoomScale = minScale 
     zoomScale = minScale 
    } 

} 
extension ImageScrollView: UIScrollViewDelegate { 

    func viewForZooming(in scrollView: UIScrollView) -> UIView? { 
     return imageView 
    } 

    func scrollViewDidZoom(_ scrollView: UIScrollView) { 
     let imageViewSize = imageView.frame.size 
     let scrollViewSize = scrollView.bounds.size 
     let verticalInset = imageViewSize.height < scrollViewSize.height ? (scrollViewSize.height - imageViewSize.height)/2 : 0 
     let horizontalInset = imageViewSize.width < scrollViewSize.width ? (scrollViewSize.width - imageViewSize.width)/2 : 0 
     scrollView.contentInset = UIEdgeInsets(top: verticalInset, left: horizontalInset, bottom: verticalInset, right: horizontalInset) 
    } 

} 

# 2। का उपयोग करते हुए ऑटो लेआउट

ViewController.swift

import UIKit 

final class ViewController: UIViewController { 

    private let scrollView = ImageScrollView(image: UIImage(named: "image")!) 

    override func viewDidLoad() { 
     view.backgroundColor = .black 
     view.addSubview(scrollView) 

     scrollView.translatesAutoresizingMaskIntoConstraints = false 
     scrollView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true 
     scrollView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true 
     scrollView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true 
     scrollView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true 
    } 

    override func viewDidLayoutSubviews() {   
     scrollView.setZoomScale() 
    } 

} 

ImageScrollView.swift

import UIKit 

final class ImageScrollView: UIScrollView { 

    private let imageView = UIImageView() 
    private var imageViewBottomConstraint = NSLayoutConstraint() 
    private var imageViewLeadingConstraint = NSLayoutConstraint() 
    private var imageViewTopConstraint = NSLayoutConstraint() 
    private var imageViewTrailingConstraint = NSLayoutConstraint() 

    required init(image: UIImage) { 
     super.init(frame: .zero) 

     imageView.image = image 
     imageView.sizeToFit() 
     addSubview(imageView) 

     imageView.translatesAutoresizingMaskIntoConstraints = false 
     imageViewLeadingConstraint = imageView.leadingAnchor.constraint(equalTo: leadingAnchor) 
     imageViewTrailingConstraint = imageView.trailingAnchor.constraint(equalTo: trailingAnchor) 
     imageViewTopConstraint = imageView.topAnchor.constraint(equalTo: topAnchor) 
     imageViewBottomConstraint = imageView.bottomAnchor.constraint(equalTo: bottomAnchor) 
     NSLayoutConstraint.activate([imageViewLeadingConstraint, imageViewTrailingConstraint, imageViewTopConstraint, imageViewBottomConstraint]) 

     contentInsetAdjustmentBehavior = .never // Adjust content according to safe area if necessary 
     showsVerticalScrollIndicator = false 
     showsHorizontalScrollIndicator = false 
     alwaysBounceHorizontal = true 
     alwaysBounceVertical = true 
     delegate = self 
    } 

    required init?(coder aDecoder: NSCoder) { 
     fatalError("init(coder:) has not been implemented") 
    } 

    // MARK: - Helper methods 

    func setZoomScale() { 
     let widthScale = frame.size.width/imageView.bounds.width 
     let heightScale = frame.size.height/imageView.bounds.height 
     let minScale = min(widthScale, heightScale) 
     minimumZoomScale = minScale 
     zoomScale = minScale 
    } 

} 
extension ImageScrollView: UIScrollViewDelegate { 

    func viewForZooming(in scrollView: UIScrollView) -> UIView? { 
     return imageView 
    } 

    func scrollViewDidZoom(_ scrollView: UIScrollView) { 
     let yOffset = max(0, (bounds.size.height - imageView.frame.height)/2) 
     imageViewTopConstraint.constant = yOffset 
     imageViewBottomConstraint.constant = yOffset 

     let xOffset = max(0, (bounds.size.width - imageView.frame.width)/2) 
     imageViewLeadingConstraint.constant = xOffset 
     imageViewTrailingConstraint.constant = xOffset 

     layoutIfNeeded() 
    } 

} 

सूत्रों का कहना है:

संबंधित मुद्दे