2011-11-13 20 views
25

यहाँ पर दो फिंगर घुमाएँ मेरे कोड है:आईओएस पिंच स्केल और एक ही समय

viewDidLoad:

UIPinchGestureRecognizer *pinch = [[UIPinchGestureRecognizer alloc]initWithTarget:self action:@selector(pinch:)]; 
[self.canvas addGestureRecognizer:pinch]; 
pinch.delegate = self; 

UIRotationGestureRecognizer *twoFingersRotate = [[UIRotationGestureRecognizer alloc] initWithTarget:self action:@selector(pinchRotate:)]; 
[[self canvas] addGestureRecognizer:twoFingersRotate]; 

twoFingersRotate.delegate = self; 

कोड चुटकी और Rotates के लिए:

-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer 
{ 
    return YES; 
} 

-(void)pinchRotate:(UIRotationGestureRecognizer*)rotate 
{ 
    SMImage *selectedImage = [DataCenter sharedDataCenter].selectedImage; 

    switch (rotate.state) 
    { 
     case UIGestureRecognizerStateBegan: 
     { 
      selectedImage.referenceTransform = selectedImage.transform; 
      break; 
     } 
     case UIGestureRecognizerStateChanged: 
     { 
      selectedImage.transform = CGAffineTransformRotate(selectedImage.referenceTransform, ([rotate rotation] * 55) * M_PI/180); 
      break; 
     } 

     default: 
      break; 
    } 
} 

-(void)pinch:(UIPinchGestureRecognizer*)pinch 
{ 
    SMImage *selectedImage = [DataCenter sharedDataCenter].selectedImage; 
    [self itemSelected]; 

    switch (pinch.state) 
    { 
     case UIGestureRecognizerStateBegan: 
     { 
      selectedImage.referenceTransform = selectedImage.transform; 
      break; 
     } 
     case UIGestureRecognizerStateChanged: 
     { 
      CGAffineTransform transform = CGAffineTransformScale(selectedImage.referenceTransform, pinch.scale, pinch.scale); 
      selectedImage.transform = transform; 
      break; 
     } 

     default: 
      break; 
    } 
} 

मेरे रोटेशन पर अच्छा काम करता है इसके स्वयं और मेरा पैमाने अपने आप पर बहुत अच्छा काम करता है, लेकिन वे एक साथ काम नहीं करेंगे। एक हमेशा काम करता है या दूसरा नहीं करता है। जब मैं कार्यान्वित करता हूं तो पहचानना चाहिए साथ-साथ विथगेशर रिकॉग्नाइज़र दो इशारे एक-दूसरे के खिलाफ लड़ने लगते हैं और खराब परिणाम देते हैं। मैं क्या खो रहा हूँ? (हां मैंने <UIGestureRecognizerDelegate> लागू किया है)

उत्तर

33

हर बार pinch: कहा जाता है, आप केवल चुटकी पहचानकर्ता के पैमाने पर आधारित परिवर्तन की गणना करते हैं। प्रत्येक बार pinchRotate: कहा जाता है, आप बस रोटेशन पहचानकर्ता के घूर्णन के आधार पर परिवर्तन की गणना करते हैं। आप स्केल और रोटेशन को एक ट्रांसफॉर्म में कभी गठबंधन नहीं करते हैं।

यहां एक दृष्टिकोण है।

NSMutableSet *_activeRecognizers; 

viewDidLoad में यह प्रारंभ:

के लिए कार्रवाई के रूप में
_activeRecognizers = [NSMutableSet set]; 

उपयोग एक विधि दोनों recognizers:

- (IBAction)handleGesture:(UIGestureRecognizer *)recognizer 
{ 
    SMImage *selectedImage = [DataCenter sharedDataCenter].selectedImage; 

    switch (recognizer.state) { 
     case UIGestureRecognizerStateBegan: 
      if (_activeRecognizers.count == 0) 
       selectedImage.referenceTransform = selectedImage.transform; 
      [_activeRecognizers addObject:recognizer]; 
      break; 

     case UIGestureRecognizerStateEnded: 
      selectedImage.referenceTransform = [self applyRecognizer:recognizer toTransform:selectedImage.referenceTransform]; 
      [_activeRecognizers removeObject:recognizer]; 
      break; 

     case UIGestureRecognizerStateChanged: { 
      CGAffineTransform transform = selectedImage.referenceTransform; 
      for (UIGestureRecognizer *recognizer in _activeRecognizers) 
       transform = [self applyRecognizer:recognizer toTransform:transform]; 
      selectedImage.transform = transform; 
      break; 
     } 

     default: 
      break; 
    } 
} 

आप हूँ अपने आप को एक नया उदाहरण चर, _activeRecognizers दें इस सहायक विधि की आवश्यकता है:

- (CGAffineTransform)applyRecognizer:(UIGestureRecognizer *)recognizer toTransform:(CGAffineTransform)transform 
{ 
    if ([recognizer respondsToSelector:@selector(rotation)]) 
     return CGAffineTransformRotate(transform, [(UIRotationGestureRecognizer *)recognizer rotation]); 
    else if ([recognizer respondsToSelector:@selector(scale)]) { 
     CGFloat scale = [(UIPinchGestureRecognizer *)recognizer scale]; 
     return CGAffineTransformScale(transform, scale, scale); 
    } 
    else 
     return transform; 
} 

यह काम करता है अगर आप घूर्णन और स्केलिंग की अनुमति दे रहे हैं। (मैंने इसका परीक्षण भी किया है!)

यदि आप पैनिंग जोड़ना चाहते हैं, तो एक अलग क्रिया विधि का उपयोग करें और बस selectedImage.center समायोजित करें। selectedImage.transform का उपयोग करके घूर्णन और स्केलिंग के साथ पैनिंग करने का प्रयास करना अधिक जटिल है।

+0

तुम मुझे मैं कैसे एक ही समय में दोनों लागू हो सकते हैं की एक कोड उदाहरण दे सकते हैं? मेरे UIRotationGestureRecognizer में "स्केल" संपत्ति नहीं है और मेरे UIPinchGestureRecognizer में "रोटेशन" संपत्ति नहीं है। और मुझे यकीन नहीं है कि मैं एक ही समय में दोनों एफ़िन का उपयोग करने के लिए उपयोग करूंगा। – spentak

+0

खूबसूरती से काम करता है। मैं इस ज्ञान को धन्यवाद देने से बहुत बेहतर हूं! – spentak

+0

खुशी है कि मैं मदद कर सकता हूं। बीटीडब्लू मैंने पैनिंग करने के बारे में आखिरी बिट बदल दिया। साथ ही, आप अपने XIB में इशारा पहचानकर्ता डाल सकते हैं और फिर आपको उन्हें 'viewDidLoad' में कोड के साथ बनाना नहीं है। बस एक पहचानकर्ता को एक दृश्य पर खींचें, फिर पहचानकर्ता के प्रतिनिधि और कार्रवाई आउटलेट को पहचानकर्ता से फ़ाइल के स्वामी से नियंत्रण-ड्रैग के साथ हुक करें। –

8

ऐसा होने के लिए आपको इशारा प्रतिनिधि shouldRecognizeSimultaneouslyWithGestureRecognizer लागू करने की आवश्यकता है और आप एक साथ पहचानने के लिए क्या संकेत देना चाहते हैं।

// ensure that the pinch and rotate gesture recognizers on a particular view can all recognize simultaneously 
// prevent other gesture recognizers from recognizing simultaneously 
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer 
{ 
    // if the gesture recognizers's view isn't one of our views, don't allow simultaneous recognition 
    if (gestureRecognizer.view != firstView && gestureRecognizer.view != secondView) 
     return NO; 

    // if the gesture recognizers are on different views, don't allow simultaneous recognition 
    if (gestureRecognizer.view != otherGestureRecognizer.view) 
     return NO; 

    // if either of the gesture recognizers is the long press, don't allow simultaneous recognition 
    if ([gestureRecognizer isKindOfClass:[UILongPressGestureRecognizer class]] || [otherGestureRecognizer isKindOfClass:[UILongPressGestureRecognizer class]]) 
     return NO; 

    return YES; 
} 

इस कोड को उस दृश्य में संशोधित करने की आवश्यकता है जिसके लिए आप एक साथ इशारा पहचानकर्ता चाहते हैं। उपरोक्त कोड वह है जो आपको चाहिए।

+0

उसे पहले से ही 'पहचानना चाहिए' इसके साथ-साथ WithGestureRecognizer: 'जो हमेशा हाँ देता है। –

6

पान, घुमाएँ के साथ स्विफ्ट 3 और चुटकी

// MARK: - Gesturies 

    func transformUsingRecognizer(_ recognizer: UIGestureRecognizer, transform: CGAffineTransform) -> CGAffineTransform { 

     if let rotateRecognizer = recognizer as? UIRotationGestureRecognizer { 
      return transform.rotated(by: rotateRecognizer.rotation) 
     } 

     if let pinchRecognizer = recognizer as? UIPinchGestureRecognizer { 
      let scale = pinchRecognizer.scale 
      return transform.scaledBy(x: scale, y: scale) 
     } 

     if let panRecognizer = recognizer as? UIPanGestureRecognizer { 
      let deltaX = panRecognizer.translation(in: imageView).x 
      let deltaY = panRecognizer.translation(in: imageView).y 
      return transform.translatedBy(x: deltaX, y: deltaY) 
     } 

     return transform 
    } 

    var initialTransform: CGAffineTransform? 

    var gestures = Set<UIGestureRecognizer>(minimumCapacity: 3) 

    @IBAction func processTransform(_ sender: Any) { 

     let gesture = sender as! UIGestureRecognizer 

     switch gesture.state { 

     case .began: 
      if gestures.count == 0 { 
       initialTransform = imageView.transform 
      } 
      gestures.insert(gesture) 

     case .changed: 
      if var initial = initialTransform { 
       gestures.forEach({ (gesture) in 
        initial = transformUsingRecognizer(gesture, transform: initial) 
       }) 
       imageView.transform = initial 
      } 

     case .ended: 
      gestures.remove(gesture) 

     default: 
      break 
     } 
    } 

    func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool { 

     return true 
    } 
+0

क्या आपने इसका परीक्षण किया था? –

+0

@RoiMulia सुनिश्चित करें। असली ऐप में इसका उपयोग करना (प्रोड में अभी तक नहीं)। क्या गलत है? –

+0

हे माइक, तनाव के लिए खेद है। कुछ भी नहीं गलत है। सिर्फ यह पूछना चाहता था कि यह पहले से ही यह सुनिश्चित करने के लिए परीक्षण किया गया है कि यह उपयोग सुरक्षित है (बस अगर मैं कुछ अंत परिदृश्यों को याद करता हूं) –

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