2009-02-01 25 views
71

जब उपयोगकर्ता मेरे आवेदन पर मानक चुटकी कार्रवाई करता है तो मैं UIImage ऑब्जेक्ट को ज़ूम इन/आउट करना चाहता हूं। मैं वर्तमान में अपनी छवि को प्रदर्शित करने के लिए UIImageView का उपयोग कर रहा हूं, अगर वह विवरण किसी भी तरह से मदद करता है।जब उपयोगकर्ता स्क्रीन को पिन करता है तो UIImage ऑब्जेक्ट को ज़ूम इन/आउट कैसे करें?

मैं यह पता लगाने की कोशिश कर रहा हूं कि यह कैसे करें, लेकिन अब तक ऐसी कोई किस्मत नहीं है।

कोई सुराग?

उत्तर

77

यह करने के लिए एक और आसान तरीका है अपने UIImageView एक UIScrollView भीतर जगह है। As I describe here, आपको स्क्रॉल व्यू की सामग्री सेट को अपने UIImageView's आकार के समान होने की आवश्यकता है। स्क्रॉल व्यू के प्रतिनिधि होने के लिए अपने नियंत्रक उदाहरण को सेट करें और viewForZoomingInScrollView: और scrollViewDidEndZooming:withView:atScale: विधियों को चुटकी-ज़ूमिंग और छवि पैनिंग की अनुमति देने के लिए लागू करें। यह प्रभावी रूप से बेन का समाधान करता है, केवल थोड़ी अधिक हल्के ढंग से, क्योंकि आपके पास पूर्ण वेब दृश्य का ओवरहेड नहीं है।

एक समस्या जो आप चला सकते हैं वह यह है कि स्क्रॉल व्यू के भीतर स्केलिंग छवि पर लागू ट्रांसफॉर्म के रूप में आता है। इससे उच्च ज़ूम कारकों पर धुंधला हो सकता है। कुछ ऐसा करने के लिए जिसे पुन: खींचा जा सकता है, चुटकी इशारा खत्म होने के बाद एक क्रिस्पर डिस्प्ले प्रदान करने के लिए आप मेरे सुझावों का पालन कर सकते हैं here। आपकी छवि को पुन: सहेजने के लिए उस बिंदु पर hniels 'समाधान का उपयोग किया जा सकता है।

+2

सुनिश्चित करें कि आप maxZoomScale और/या minimalZoomScale बदलते हैं :)। –

2

ऐसा करने का सबसे आसान तरीका है, यदि आप चाहते हैं कि यह चुटकी ज़ूमिंग है, तो अपनी छवि को UIWebView (HTML रैपर कोड की छोटी मात्रा लिखें, अपनी छवि का संदर्भ लें, और मूल रूप से किया गया है) के अंदर रखें। ऐसा करने के लिए अधिक जटिल तरीका उपयोगकर्ता की उंगलियों का ट्रैक रखने के लिए touchesBegan, touchesMoved, और touchesEnded का उपयोग करना है, और अपनी दृश्य की रूपांतरित संपत्ति को उचित रूप से समायोजित करना है।

+0

क्या आप मुझे अपने उत्तर से संबंधित कोई उदाहरण सुझा सकते हैं। मैं स्पर्शों का उपयोग कर छवि को ज़ूम और घुमा कैसे सकता हूं, स्पर्श करता है। मेरा प्रश्न लिंक => http://stackoverflow.com/questions/36833841/how-to-handle-multiple-touch-gesture-at-a-time?noredirect=1#comment61239098_36833841 –

18

ध्यान रखें कि आप कभी भी UIImage पर ज़ूम इन नहीं कर रहे हैं। कभी।

इसके बजाय, आप view पर ज़ूम इन और आउट कर रहे हैं जो UIImage प्रदर्शित करता है।

इस विशेष मामले में, आप एक UIImageView जो आप के लिए छवि प्रदर्शित करता है, या एक UIWebView जो यह बैकअप लेने के लिए कुछ अतिरिक्त एचटीएमएल आवश्यकता होगी छवि प्रदर्शित करने के लिए कस्टम ड्राइंग के साथ एक कस्टम UIView बनाने का निर्णय ले chould।

सभी मामलों में, आपको touchesBegan, touchesMoved, और यह निर्धारित करने की आवश्यकता होगी कि उपयोगकर्ता क्या करने का प्रयास कर रहा है (ज़ूम, पैन इत्यादि)।

+0

+1 स्पष्टीकरण के लिए, यह कभी नहीं के बारे में सोचा इस तरह, चीयर्स दोस्त – Elmo

+0

@ अगस्त, क्या आप मुझे कोई उदाहरण दे सकते हैं जो छूने पर छवि को ज़ूम और घुमाएंगेगन, स्पर्श करता है? एक jsp होस्टेड समर्थन पृष्ठ के लिए –

8

यहां एक समाधान है जिसका मैंने पहले उपयोग किया है, आपको UIWebView का उपयोग करने की आवश्यकता नहीं है।

- (UIImage *)scaleAndRotateImage(UIImage *)image 
{ 
    int kMaxResolution = 320; // Or whatever 

    CGImageRef imgRef = image.CGImage; 

    CGFloat width = CGImageGetWidth(imgRef); 
    CGFloat height = CGImageGetHeight(imgRef); 


    CGAffineTransform transform = CGAffineTransformIdentity; 
    CGRect bounds = CGRectMake(0, 0, width, height); 
    if (width > kMaxResolution || height > kMaxResolution) { 
     CGFloat ratio = width/height; 
     if (ratio > 1) { 
      bounds.size.width = kMaxResolution; 
      bounds.size.height = bounds.size.width/ratio; 
     } 
     else { 
      bounds.size.height = kMaxResolution; 
      bounds.size.width = bounds.size.height * ratio; 
     } 
    } 

    CGFloat scaleRatio = bounds.size.width/width; 
    CGSize imageSize = CGSizeMake(CGImageGetWidth(imgRef), CGImageGetHeight(imgRef)); 
    CGFloat boundHeight; 
    UIImageOrientation orient = image.imageOrientation; 
    switch(orient) { 

     case UIImageOrientationUp: //EXIF = 1 
      transform = CGAffineTransformIdentity; 
      break; 

     case UIImageOrientationUpMirrored: //EXIF = 2 
      transform = CGAffineTransformMakeTranslation(imageSize.width, 0.0); 
      transform = CGAffineTransformScale(transform, -1.0, 1.0); 
      break; 

     case UIImageOrientationDown: //EXIF = 3 
      transform = CGAffineTransformMakeTranslation(imageSize.width, imageSize.height); 
      transform = CGAffineTransformRotate(transform, M_PI); 
      break; 

     case UIImageOrientationDownMirrored: //EXIF = 4 
      transform = CGAffineTransformMakeTranslation(0.0, imageSize.height); 
      transform = CGAffineTransformScale(transform, 1.0, -1.0); 
      break; 

     case UIImageOrientationLeftMirrored: //EXIF = 5 
      boundHeight = bounds.size.height; 
      bounds.size.height = bounds.size.width; 
      bounds.size.width = boundHeight; 
      transform = CGAffineTransformMakeTranslation(imageSize.height, imageSize.width); 
      transform = CGAffineTransformScale(transform, -1.0, 1.0); 
      transform = CGAffineTransformRotate(transform, 3.0 * M_PI/2.0); 
      break; 

     case UIImageOrientationLeft: //EXIF = 6 
      boundHeight = bounds.size.height; 
      bounds.size.height = bounds.size.width; 
      bounds.size.width = boundHeight; 
      transform = CGAffineTransformMakeTranslation(0.0, imageSize.width); 
      transform = CGAffineTransformRotate(transform, 3.0 * M_PI/2.0); 
      break; 

     case UIImageOrientationRightMirrored: //EXIF = 7 
      boundHeight = bounds.size.height; 
      bounds.size.height = bounds.size.width; 
      bounds.size.width = boundHeight; 
      transform = CGAffineTransformMakeScale(-1.0, 1.0); 
      transform = CGAffineTransformRotate(transform, M_PI/2.0); 
      break; 

     case UIImageOrientationRight: //EXIF = 8 
      boundHeight = bounds.size.height; 
      bounds.size.height = bounds.size.width; 
      bounds.size.width = boundHeight; 
      transform = CGAffineTransformMakeTranslation(imageSize.height, 0.0); 
      transform = CGAffineTransformRotate(transform, M_PI/2.0); 
      break; 

     default: 
      [NSException raise:NSInternalInconsistencyException format:@"Invalid image orientation"]; 

    } 

    UIGraphicsBeginImageContext(bounds.size); 

    CGContextRef context = UIGraphicsGetCurrentContext(); 

    if (orient == UIImageOrientationRight || orient == UIImageOrientationLeft) { 
     CGContextScaleCTM(context, -scaleRatio, scaleRatio); 
     CGContextTranslateCTM(context, -height, 0); 
    } 
    else { 
     CGContextScaleCTM(context, scaleRatio, -scaleRatio); 
     CGContextTranslateCTM(context, 0, -height); 
    } 

    CGContextConcatCTM(context, transform); 

    CGContextDrawImage(UIGraphicsGetCurrentContext(), CGRectMake(0, 0, width, height), imgRef); 
    UIImage *imageCopy = UIGraphicsGetImageFromCurrentImageContext(); 
    UIGraphicsEndImageContext(); 

    return imageCopy; 
} 

लेख पर एप्पल समर्थन पाया जा सकता है: http://discussions.apple.com/message.jspa?messageID=7276709#7276709

+0

-1। * डॉट सिंटैक्स पर मुट्ठी हिलाता है * – esharp

+0

क्या आप कृपया मुझे इस विधि को कॉल करने के लिए प्रदान कर सकते हैं (माउस चाल या स्पर्श पर)? –

22

कोड नीचे UIScrollView का उपयोग किए बिना UIImageView ज़ूम करने के लिए मदद करता है:

-(void)HandlePinch:(UIPinchGestureRecognizer*)recognizer{ 
    if ([recognizer state] == UIGestureRecognizerStateEnded) { 
     NSLog(@"======== Scale Applied ==========="); 
     if ([recognizer scale]<1.0f) { 
      [recognizer setScale:1.0f]; 
     } 
     CGAffineTransform transform = CGAffineTransformMakeScale([recognizer scale], [recognizer scale]); 
     imgView.transform = transform; 
    } 
} 
+0

यह सर्वोच्च समाधान है :)। धन्यवाद। – sabiland

48

UIImageView के लिए शेफाली के समाधान अच्छा काम करता है, लेकिन यह एक छोटे संशोधन की जरूरत है:

- (void)pinch:(UIPinchGestureRecognizer *)gesture { 
    if (gesture.state == UIGestureRecognizerStateEnded 
     || gesture.state == UIGestureRecognizerStateChanged) { 
     NSLog(@"gesture.scale = %f", gesture.scale); 

     CGFloat currentScale = self.frame.size.width/self.bounds.size.width; 
     CGFloat newScale = currentScale * gesture.scale; 

     if (newScale < MINIMUM_SCALE) { 
      newScale = MINIMUM_SCALE; 
     } 
     if (newScale > MAXIMUM_SCALE) { 
      newScale = MAXIMUM_SCALE; 
     } 

     CGAffineTransform transform = CGAffineTransformMakeScale(newScale, newScale); 
     self.transform = transform; 
     gesture.scale = 1; 
    } 
} 

(शेफाली के समाधान नकारात्मक पक्ष यह था यह है कि पिंचिंग करते समय निरंतर स्केल नहीं किया।इसके अलावा, जब एक नया चुटकी शुरू करने, वर्तमान छवि पैमाने रीसेट किया गया था।)

+0

मुझे चुटकी इशारा शुरू होने के बाद पैन इशारा करना चाहिए। ऐसा कैसे करें? –

+0

@Gajendra: उस मामले में, मुझे लगता है कि आप एक स्क्रॉल देखने के लिए, जो दोनों बॉक्स – JRV

+0

से बाहर का समर्थन करता है में अपने घटकों को एम्बेड उपयोग किसे करना चाहिए लेकिन मैं दोनों टैप जेस्चर और पिंच जेस्चर के लिए कार्यक्षमता चाहते हैं। मैंने Imageview पर ग्रिड (परतें) का भी उपयोग किया है। क्या मुझे पता है, क्या स्क्रॉल दृश्य में चुटकी इशारा करना और इशारा टैप करना संभव है? –

75

के रूप में दूसरों का वर्णन किया, सबसे आसान समाधान एक UIScrollView में अपने UIImageView डाल करने के लिए है। मैंने इंटरफ़ेस बिल्डर .xib फ़ाइल में ऐसा किया था।

viewDidLoad में, निम्न चर निर्धारित किया है। अपने नियंत्रक को UIScrollViewDelegate होने के लिए सेट करें।

- (void)viewDidLoad { 
    [super viewDidLoad]; 
    self.scrollView.minimumZoomScale = 0.5; 
    self.scrollView.maximumZoomScale = 6.0; 
    self.scrollView.contentSize = self.imageView.frame.size; 
    self.scrollView.delegate = self; 
} 

आपको छवि को वापस करने के लिए निम्न विधि को लागू करने की आवश्यकता है जिसे आप ज़ूम करना चाहते हैं।

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

संस्करणों में पूर्व iOS9 लिए, आप भी इस खाली प्रतिनिधि विधि जोड़ने की जरूरत हो सकता है:

- (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(CGFloat)scale 
{ 
} 

Apple Documentation करता है यह करने के लिए कैसे का वर्णन करने का एक अच्छा काम:

+2

में काम नहीं कर यह scrollViewDidEndZooming हटाया जाना ठीक है: withView: अब, मैं iOS9 Xcode7 – ElonChan

+0

यह मेरे लिए काम करता है के साथ परीक्षण किया गया है! 'ScrollViewDidEndZooming:' विधि को लागू किए बिना। –

4

Shafali और जेआरवी के उत्तरों में पैनिंग और ज़ूम करने के लिए चुटकी शामिल है:

#define MINIMUM_SCALE 0.5 
#define MAXIMUM_SCALE 6.0 
@property CGPoint translation; 


- (void)pan:(UIPanGestureRecognizer *)gesture { 
    static CGPoint currentTranslation; 
    static CGFloat currentScale = 0; 
    if (gesture.state == UIGestureRecognizerStateBegan) { 
     currentTranslation = _translation; 
     currentScale = self.view.frame.size.width/self.view.bounds.size.width; 
    } 
    if (gesture.state == UIGestureRecognizerStateEnded || gesture.state == UIGestureRecognizerStateChanged) { 

     CGPoint translation = [gesture translationInView:self.view]; 

     _translation.x = translation.x + currentTranslation.x; 
     _translation.y = translation.y + currentTranslation.y; 
     CGAffineTransform transform1 = CGAffineTransformMakeTranslation(_translation.x , _translation.y); 
     CGAffineTransform transform2 = CGAffineTransformMakeScale(currentScale, currentScale); 
     CGAffineTransform transform = CGAffineTransformConcat(transform1, transform2); 
     self.view.transform = transform; 
    } 
} 


- (void)pinch:(UIPinchGestureRecognizer *)gesture { 
    if (gesture.state == UIGestureRecognizerStateEnded || gesture.state == UIGestureRecognizerStateChanged) { 
//  NSLog(@"gesture.scale = %f", gesture.scale); 

     CGFloat currentScale = self.view.frame.size.width/self.view.bounds.size.width; 
     CGFloat newScale = currentScale * gesture.scale; 

     if (newScale < MINIMUM_SCALE) { 
      newScale = MINIMUM_SCALE; 
     } 
     if (newScale > MAXIMUM_SCALE) { 
      newScale = MAXIMUM_SCALE; 
     } 

     CGAffineTransform transform1 = CGAffineTransformMakeTranslation(_translation.x, _translation.y); 
     CGAffineTransform transform2 = CGAffineTransformMakeScale(newScale, newScale); 
     CGAffineTransform transform = CGAffineTransformConcat(transform1, transform2); 
     self.view.transform = transform; 
     gesture.scale = 1; 
    } 
} 
+0

कृपया दूसरे के उत्तर का उल्लेख करने से बचें क्योंकि वे कभी भी अपना जवाब निकाल सकते हैं। – manetsus

+0

धन्यवाद यह एक आकर्षण की तरह काम किया – aznelite89

0

रखें ध्यान रखें कि आप UIImage को ज़ूम इन/आउट नहीं करना चाहते हैं। इसके बजाय उस दृश्य को ज़ूम इन/आउट करने का प्रयास करें जिसमें UIImage व्यू कंट्रोलर है।

मैं इस समस्या के लिए एक समाधान बना दिया है। मेरे कोड पर एक नज़र डालें:

@IBAction func scaleImage(sender: UIPinchGestureRecognizer) { 
     self.view.transform = CGAffineTransformScale(self.view.transform, sender.scale, sender.scale) 
     sender.scale = 1 
    } 
    override func viewDidLoad() { 
     super.viewDidLoad() 
     // Do any additional setup after loading the view, typically from a nib. 
     view.backgroundColor = UIColor.blackColor() 
    } 

N.B .: भूल PinchGestureRecognizer ऊपर हुक करने न करें।

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

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