उपयोगकर्ता चुटकी स्क्रीन जब UIImage ऑब्जेक्ट को ज़ूम इन / आउट कैसे करें?


84

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

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

कोई सुराग?

जवाबों:


85

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

आपके द्वारा चलाया जा सकने वाला एक मुद्दा यह है कि स्क्रॉल दृश्य के भीतर स्केलिंग छवि पर लागू परिवर्तनों के रूप में आती है। इससे उच्च ज़ूम कारकों पर धुंधलापन आ सकता है। कुछ चीज़ों के लिए, जिन्हें फिर से तैयार किया जा सकता है, चुटकी का इशारा खत्म होने के बाद आप अपने सुझावों का पालन ​​कर सकते हैं । आपकी छवि को पुनः व्यवस्थित करने के लिए उस बिंदु पर हनील्स के समाधान का उपयोग किया जा सकता है।


2
सुनिश्चित करें कि आप अधिकतमZZSSale और / या न्यूनतमZ :) बदलाव करें।
क्रिस प्रिंस

94

जैसा कि अन्य लोगों ने बताया, सबसे आसान उपाय यह है कि आप अपने UIImageView को UIScrollView में डालें। मैंने इंटरफ़ेस बिल्डर .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
{
}

एप्पल प्रलेखन ऐसा करने के तरीके का वर्णन करने का एक अच्छा काम करता है:


3
अब, मैं iOS9 Xcode7 साथ परीक्षण किया है: यह scrollViewDidEndZooming हटाया जाना ठीक है: withView
ElonChan

1
इससे मेरा काम बनता है! बिना क्रियान्वयन scrollViewDidEndZooming :विधि के।
जॉनी जांग

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

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


मैं चाहता हूं कि चुटकी का इशारा शुरू होने के बाद पैन जेस्चर सक्षम हो। ऐसा कैसे करें?
गजेंद्र के चौहान

@ गजेंद्र: उस स्थिति में, मुझे लगता है कि आपको अपने घटकों को स्क्रॉल दृश्य में एम्बेड करना चाहिए, जो बॉक्स से बाहर दोनों का समर्थन करता है
JRV

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

@ गजेन्द्रकचौहान: एक स्क्रॉल दृश्य ज़ूम करने और बॉक्स के बाहर पैनिंग करने के लिए चुटकी का समर्थन करता है - बस न्यूनतम / अधिकतम ज़ूम स्केल सेट करना याद रखें, लेकिन ब्रैड लार्सन उत्तर भी देखें। और यदि आप टैप जेस्चर भी चाहते हैं, तो आप इसे जेस्चर के रूप में जोड़ सकते हैं।
JRV

@JRV, मुझे पहचानने के लिए स्वयं को प्राप्त करने के लिए किन प्रतिनिधियों को जोड़ने की आवश्यकता है?

23

नीचे दिए गए कोड UIIcageView का उपयोग किए बिना 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;
    }
}

यह सर्वोच्च समाधान है :)। धन्यवाद।
सबीलैंड

19

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

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

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

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


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

@ ऑगस्ट, क्या आप मुझे कोई उदाहरण प्रदान कर सकते हैं जो टच और इमेज पर ज़ूम और रोटेट करता है, टच करता है?
मितेश डोबरीया

7

यहाँ एक समाधान है जिसका मैंने पहले इस्तेमाल किया है जिसके लिए आपको 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;
}

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


-1 jsp होस्टेड सपोर्ट पेज के लिए। डॉट सिंटैक्स पर मुट्ठी हिलाता है
esharp

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

5

झूमने और चुटकी को शामिल करने के लिए शैफाली और जेआरवी के उत्तरों में विस्तार किया गया:

#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;
    }
}

कृपया अन्य के उत्तर का उल्लेख करने से बचें क्योंकि वे अपना उत्तर कभी भी निकाल सकते हैं।
इनामुल हसन

3

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


क्या आप मुझे आपके उत्तर से संबंधित कोई उदाहरण दे सकते हैं। मैं टचबाइन, टचस्मैट तरीकों का उपयोग करके छवि को कैसे ज़ूम और रोटेट कर सकता हूं। मेरा प्रश्न लिंक => stackoverflow.com/questions/36833841/…
मितेश दोबरीया

0

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

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

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

NB: PinchGestureRecognizer को हुक करने के लिए मत भूलना।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.