Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>If you prefer animation that behaves more like a scroll view (i.e., with continuous feedback on the gesture), it might look something like the following:</p> <pre><code>- (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 &gt; 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 &lt; 0) panSucceeded = ((translate.x + velocity.x * 0.5) &lt; -(self.containerView.frame.size.width / 2)); else panSucceeded = ((translate.x + velocity.x * 0.5) &gt; (self.containerView.frame.size.width / 2)); } if (panSucceeded) { // if we succeeded, finish moving the stuff finalNewFieldLocation = _originalCenter; if (translate.x &lt; 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 &lt; 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 } ]; } } </code></pre> <p>Note, I have put both the original label, as well as the new label being panned on, in a container UIView (called containerView, surprisingly enough), so that I can clip the animation to that container.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload