2012-06-15 10 views
6

में स्वाइप इशारा के साथ स्क्रॉल प्रभाव मेरे पास एक दृश्य है जिसमें दो लेबल हैं। जब मैं बाएं स्वाइप करता हूं तो मैं लेबल को लेबल करने के लिए अगली सामग्री भरता हूं। इसी तरह पिछले सामग्री को सही लोड स्वाइप करना। मैं लेबल को प्रभाव देना चाहता हूं जैसे कि वे बाएं या दाएं से स्क्रॉल कर रहे हैं। मैंने पहले स्क्रॉलव्यू का उपयोग किया लेकिन इसमें स्मृति समस्या थी। तो मैं एक दृश्य का उपयोग कर रहा हूं, और अगली या पिछली सामग्री को इशारा लोड स्वाइप करें। मैं लेबल में स्क्रॉलव्यू के स्लाइडिंग प्रभाव को जोड़ना चाहता हूं। मैं उसे कैसे कर सकता हूँ?आईओएस

+0

वैसे, जबकि मैं नीचे दिए गए लेबल को एनिमेट करने का एक तरीका दिखाता हूं, मुझे समझ में नहीं आता कि आपको स्क्रॉल व्यू के साथ "स्मृति समस्या" क्यों है। यदि आप उस कोड को पोस्ट करते हैं, तो यदि आप चाहें तो हम आपकी स्मृति समस्या को ढूंढने में आपकी सहायता कर सकते हैं। – Rob

+0

कवर प्रवाह का सबसे अच्छा उपयोग करें और अच्छी तरह से देखो – parag

उत्तर

15

मुझे बिल्कुल यकीन नहीं है कि आप किस प्रभाव को देख रहे हैं, लेकिन आप ऐसा कुछ कर सकते हैं, जो एक नया, अस्थायी लेबल बनाता है, इसे स्क्रीन से बाहर रखता है, इसे आपके लेबल पर ले जाने के लिए एनिमेट करता है स्क्रीन, और फिर पूर्ण होने पर, पुराने को रीसेट करता है और अस्थायी लेबल हटा देता है।

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    // Do any additional setup after loading the view. 

    UISwipeGestureRecognizer *left = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(leftSwipe:)]; 
    [left setDirection:UISwipeGestureRecognizerDirectionLeft]; 
    [self.view addGestureRecognizer:left]; 
    // if non-ARC, release it 
    // [release left]; 

    self.label1.text = @"Mo"; 
} 

- (void)leftSwipe:(UISwipeGestureRecognizer *)gesture 
{ 
    NSString *newText; 
    UILabel *existingLabel = self.label1; 

    // in my example, I'm just going to toggle the value between Mo and Curly 

    if ([existingLabel.text isEqualToString:@"Curly"]) 
     newText = @"Mo"; 
    else 
     newText = @"Curly"; 

    // create new label 

    UILabel *tempLabel = [[UILabel alloc] initWithFrame:existingLabel.frame]; 
    [existingLabel.superview addSubview:tempLabel]; 
    tempLabel.text = newText; 

    // move the new label off-frame to the right 

    tempLabel.transform = CGAffineTransformMakeTranslation(tempLabel.superview.bounds.size.width, 0); 

    // animate the sliding of them into place 

    [UIView animateWithDuration:0.5 
        animations:^{ 
         tempLabel.transform = CGAffineTransformIdentity; 
         existingLabel.transform = CGAffineTransformMakeTranslation(-existingLabel.superview.bounds.size.width, 0); 
        } 
        completion:^(BOOL finished) { 
         existingLabel.text = newText; 
         existingLabel.transform = CGAffineTransformIdentity; 
         [tempLabel removeFromSuperview]; 
        }]; 

    // if non-ARC, release it 
    // [release tempLabel]; 
} 

इस एनीमेशन अपने superview के संबंध में लेबल एनिमेट: इसी का एक गैर autolayout कार्यान्वयन लग सकता है की तरह है। आप यह सुनिश्चित करना चाहते हैं कि superview "क्लिप सबव्यू" पर सेट है। इस तरह, एनीमेशन superview की सीमाओं तक सीमित हो जाएगा, जो थोड़ा अधिक पॉलिश दिखता है।

नोट, यदि ऑटो लेआउट का उपयोग करते हैं, तो विचार समान है (हालांकि निष्पादन अधिक जटिल है)। मूल रूप से अपनी बाधाओं को कॉन्फ़िगर करें ताकि नया दृश्य दाईं ओर बंद हो, फिर, एनीमेशन ब्लॉक अपडेट/बाधाओं को प्रतिस्थापित करें ताकि मूल लेबल बाईं ओर बंद हो और नया मूल मूल लेबल के स्थान पर हो और अंत में, समापन ब्लॉक मूल लेबल की बाधाओं को रीसेट करता है और अस्थायी लेबल को हटा देता है।


वैसे, यह सब असीम आसान है अगर आप बदलाव में बनाया में से एक के साथ आराम कर रहे हैं: आप एनीमेशन है कि और अधिक एक स्क्रॉल दृश्य की तरह बर्ताव (यानी पसंद करते हैं

- (void)leftSwipe:(UISwipeGestureRecognizer *)gesture 
{ 
    NSString *newText; 
    UILabel *existingLabel = self.label1; 

    // in my example, I'm just going to toggle the value between Mo and Curly 

    if ([existingLabel.text isEqualToString:@"Curly"]) 
     newText = @"Mo"; 
    else 
     newText = @"Curly"; 

    [UIView transitionWithView:existingLabel // or try `existingLabel.superview` 
         duration:0.5 
         options:UIViewAnimationOptionTransitionFlipFromRight 
        animations:^{ 
         existingLabel.text = newText; 
        } 
        completion:nil]; 
} 
+0

आपके विस्तृत उत्तर के लिए बहुत बहुत धन्यवाद। एनीमेशन अभी ठीक है। लेकिन स्क्रॉलव्यू की एनीमेशन बेहतर है। स्क्रॉल व्यू के साथ समस्या: स्क्रॉलव्यू के अंदर एक और दृश्य है। जब भी उपयोगकर्ता स्क्रॉलव्यू के अंदर एक नया दृश्य स्क्रॉल करता है। लेकिन 50 विचारों के बाद ऐप स्मृति चेतावनी के साथ दुर्घटनाग्रस्त हो जाता है। मैंने कुछ कोशिश की लेकिन मुझे कोई समाधान नहीं मिला। तो स्क्रॉल व्यू को हटाने का फैसला किया। – Oktay

+0

@Oktay ऐसा लगता है कि आपके स्क्रॉलव्यू कोड में आपके पास एक साधारण बग/रिसाव है। बहुत से लोग बिना किसी समस्या के स्क्रॉलव्यू का उपयोग करते हैं। दोबारा, यदि आप अपना कोड पोस्ट करते हैं, तो मुझे संदेह है कि इसे आसानी से उपचार किया जाता है। – Rob

+0

@Oktay आप कहते हैं कि आपको स्क्रॉल व्यू एनीमेशन बेहतर पसंद है, लेकिन मुझे यकीन नहीं है कि आप इसके बारे में क्या बेहतर पसंद करते हैं। चूंकि यह पैन इशारा करता है (यानी यह एक सतत संकेत है जो जैसे ही आप अपनी उंगली को स्क्रीन पर ले जाना शुरू करते हैं)? मैंने एक पैन इशारा के बजाए एक स्वाइप इशारा किया क्योंकि आपके शीर्षक ने सुझाव दिया था कि आप चाहते थे, लेकिन एक सतत पैन इशारा बहुत आसान है। या क्या आप स्क्रॉलव्यू के बारे में कुछ और पसंद करते हैं? – Rob

6

, एक कंटेनर UIVie में

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 

    UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panHandler:)]; 
    [self.view addGestureRecognizer:pan]; 

    self.label1.text = @"Mo"; 
} 

- (void)panHandler:(UIPanGestureRecognizer *)sender 
{ 
    if (sender.state == UIGestureRecognizerStateBegan) 
    { 
     _panLabel = [[UILabel alloc] init]; 

     // in my example, I'm just going to toggle the value between Mo and Curly 
     // you'll presumably set the label contents based upon the direction of the 
     // pan (if positive, swiping to the right, grab the "previous" label, if negative 
     // pan, grab the "next" label) 

     if ([self.label1.text isEqualToString:@"Curly"]) 
      _newText = @"Mo"; 
     else 
      _newText = @"Curly"; 

     // set the text 

     _panLabel.text = _newText; 

     // set the frame to just be off screen 

     _panLabel.frame = CGRectMake(self.label1.frame.origin.x + self.containerView.frame.size.width, 
            self.label1.frame.origin.y, 
            self.label1.frame.size.width, 
            self.label1.frame.size.height); 

     [self.containerView addSubview:_panLabel]; 

     _originalCenter = self.label1.center; // save where the original label originally was 
    } 
    else if (sender.state == UIGestureRecognizerStateChanged) 
    { 
     CGPoint translate = [sender translationInView:self.containerView]; 

     if (translate.x > 0) 
     { 
      _panLabel.center = CGPointMake(_originalCenter.x - self.containerView.frame.size.width + translate.x, _originalCenter.y); 
      self.label1.center = CGPointMake(_originalCenter.x + translate.x, _originalCenter.y); 
     } 
     else 
     { 
      _panLabel.center = CGPointMake(_originalCenter.x + self.containerView.frame.size.width + translate.x, _originalCenter.y); 
      self.label1.center = CGPointMake(_originalCenter.x + translate.x, _originalCenter.y); 
     } 
    } 
    else if (sender.state == UIGestureRecognizerStateEnded || sender.state == UIGestureRecognizerStateFailed || sender.state == UIGestureRecognizerStateCancelled) 
    { 
     CGPoint translate = [sender translationInView:self.containerView]; 
     CGPoint finalNewFieldLocation; 
     CGPoint finalOriginalFieldLocation; 
     BOOL panSucceeded; 

     if (sender.state == UIGestureRecognizerStateFailed || 
      sender.state == UIGestureRecognizerStateCancelled) 
     { 
      panSucceeded = NO; 
     } 
     else 
     { 
      // by factoring in the velocity, we can capture a flick more accurately 
      // 
      // (by the way, I don't like iOS's velocity, because if you stop moving, it records the velocity 
      // prior to stopping the move rather than noting that you actually stopped, so I usually calculate my own, 
      // but I'll leave this as is for purposes of this example) 

      CGPoint velocity = [sender velocityInView:self.containerView]; 

      if (translate.x < 0) 
       panSucceeded = ((translate.x + velocity.x * 0.5) < -(self.containerView.frame.size.width/2)); 
      else 
       panSucceeded = ((translate.x + velocity.x * 0.5) > (self.containerView.frame.size.width/2)); 
     } 

     if (panSucceeded) 
     { 
      // if we succeeded, finish moving the stuff 

      finalNewFieldLocation = _originalCenter; 
      if (translate.x < 0) 
       finalOriginalFieldLocation = CGPointMake(_originalCenter.x - self.containerView.frame.size.width, _originalCenter.y); 
      else 
       finalOriginalFieldLocation = CGPointMake(_originalCenter.x + self.containerView.frame.size.width, _originalCenter.y); 
     } 
     else 
     { 
      // if we didn't, then just return everything to where it was 

      finalOriginalFieldLocation = _originalCenter; 

      if (translate.x < 0) 
       finalNewFieldLocation = CGPointMake(_originalCenter.x + self.containerView.frame.size.width, _originalCenter.y); 
      else 
       finalNewFieldLocation = CGPointMake(_originalCenter.x - self.containerView.frame.size.width, _originalCenter.y); 
     } 

     // animate the moving of stuff to their final locations, and on completion, clean everything up 

     [UIView animateWithDuration:0.3 
           delay:0.0 
          options:UIViewAnimationOptionCurveEaseOut 
         animations:^{ 
          _panLabel.center = finalNewFieldLocation; 
          self.label1.center = finalOriginalFieldLocation; 
         } 
         completion:^(BOOL finished) { 
          if (panSucceeded) 
           self.label1.text = _newText; 
          self.label1.center = _originalCenter; 
          [_panLabel removeFromSuperview]; 
          _panLabel = nil; // in non-ARC, release instead 
         } 
     ]; 
    } 
} 

ध्यान दें, मैं डाल दिया है दोनों मूल लेबल, और साथ ही नए लेबल पर आलोचना की जा रही,: इशारे पर निरंतर प्रतिक्रिया) के साथ, ऐसा निम्नलिखित कुछ लग सकता है डब्ल्यू (कंटेनर व्यू कहा जाता है, आश्चर्यजनक रूप से पर्याप्त), ताकि मैं उस कंटेनर को एनीमेशन क्लिप कर सकूं।