IOS swipe gesture swipe effect

I have a view that has two labels. When I scroll left, I fill in the following text for the text. Similarly, scrolling right loads the previous content. I want to give shortcuts as they scroll left or right. I used to use scrolling, but I had a memory problem. Therefore, I use one view and click the gestures of the next or previous content. I want to add a scroll effect to shortcuts. How can i do this?

+6
source share
2 answers

I don’t quite understand exactly what effect you are looking for, but you can do something like this by creating a new timestamp, putting it on the screen, animating moving it around the shortcut that you have on the screen, and then when it will be done, resets the old one and removes the timestamp. This might look like a non-auto audit:

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

This animation animates the label in relation to its supervisor. You can verify that the superview parameter superview set to "clip subviews". Thus, the animation will be limited to the borders of this superview , which will give a slightly more polished look.

Note that when using automatic layout, the idea is the same (although the execution is more complicated). Basically configure your restrictions so that the new view is on the right, then in the animation block, update / replace the restrictions so that the original label is on the left, and the new one in the place of the original label and, finally, in the completion block reset the restrictions of the original label and delete the time stamp.


By the way, this is all infinitely simpler if you are comfortable with one of the built-in transitions:

 - (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]; } 
+15
source

If you prefer an animation that looks more like scrolling (i.e. with continuous feedback on a gesture), it might look something like this:

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

Notice that I put both the original shortcut and the new shortcut that was launched in the UIView container (called containerView, surprisingly enough) so that I can crop the animation in this container.

+6
source

Source: https://habr.com/ru/post/918217/


All Articles