删除UILabel时拖动到图像
我有一个UILabel,我添加了一个平移手势识别器,我也有我的视图使用UIImage视图的垃圾桶图像。 每次我将UILabel拖到垃圾桶图像时,我想从程序视图中删除UILabel。
我假设你想要做这样的事情:
我会告诉你如何实现。
我们将需要一个标签出口和垃圾桶视图出口:
@interface ViewController () @property (strong, nonatomic) IBOutlet UIImageView *trashView; @property (strong, nonatomic) IBOutlet UILabel *label; @end
将这些连接到您的标签和垃圾箱视图。 我们还需要两个实例variables:
@implementation ViewController { CGPoint labelOriginalCenter; BOOL trashIsShowingPendingDropAppearance; }
我们需要保存标签的原始位置,所以如果拖动被取消,我们可以将其重新制作回去:
- (void)viewDidLoad { [super viewDidLoad]; labelOriginalCenter = self.label.center; }
现在让我们为平移手势识别器做出动作。 我们需要根据手势移动标签。 那么我们需要根据手势的状态采取行动。
- (IBAction)labelWasDragged:(UIPanGestureRecognizer *)recognizer { [self moveLabelForDrag:recognizer]; switch (recognizer.state) { case UIGestureRecognizerStateChanged: [self labelDragDidChange:recognizer]; break; case UIGestureRecognizerStateEnded: [self labelDragDidEnd:recognizer]; break; case UIGestureRecognizerStateCancelled: [self labelDragDidAbort:recognizer]; break; default: break; } }
为了移动标签,我们通过手势的翻译来改变它的中心。 我们还会在每次更改时将手势的翻译重置为零。
- (void)moveLabelForDrag:(UIPanGestureRecognizer *)sender { CGPoint translation = [sender translationInView:self.label]; [sender setTranslation:CGPointZero inView:self.label]; CGPoint center = self.label.center; center.x += translation.x; center.y += translation.y; self.label.center = center; }
如果手势改变,我们要根据触摸是否在垃圾桶上方来更新垃圾桶的外观:
- (void)labelDragDidChange:(UIPanGestureRecognizer *)recognizer { if ([self dragIsOverTrash:recognizer]) { [self updateTrashAppearanceForPendingDrop]; } else { [self updateTrashAppearanceForNoPendingDrop]; } }
如果手势结束了,我们希望根据手势结束时是否触摸垃圾桶来丢弃标签或中止拖动:
- (void)labelDragDidEnd:(UIPanGestureRecognizer *)recognizer { if ([self dragIsOverTrash:recognizer]) { [self dropLabelInTrash]; } else { [self abortLabelDrag]; } }
如果手势被取消,我们要中止拖动:
- (void)labelDragDidAbort:(UIPanGestureRecognizer *)recognizer { [self abortLabelDrag]; }
为了检测手势的触摸是否在垃圾桶上,我们要求手势识别器在垃圾视图的坐标系中定位。 然后我们询问垃圾箱的位置是否在垃圾箱的边界内。
- (BOOL)dragIsOverTrash:(UIPanGestureRecognizer *)recognizer { CGPoint pointInTrash = [recognizer locationInView:self.trashView]; return [self.trashView pointInside:pointInTrash withEvent:nil]; }
我们可以用很多不同的方式更新垃圾桶的外观。 在这里,我们将使垃圾桶在摆放垃圾箱时摆动:
- (void)updateTrashAppearanceForPendingDrop { if (trashIsShowingPendingDropAppearance) return; trashIsShowingPendingDropAppearance = YES; self.trashView.transform = CGAffineTransformMakeRotation(-.1); [UIView animateWithDuration:0.15 delay:0 options:UIViewAnimationOptionAutoreverse | UIViewAnimationOptionRepeat animations:^{ self.trashView.transform = CGAffineTransformMakeRotation(.1); } completion:nil]; }
当拖动垃圾桶,我们需要让垃圾停止摆动:
- (void)updateTrashAppearanceForNoPendingDrop { if (!trashIsShowingPendingDropAppearance) return; trashIsShowingPendingDropAppearance = NO; [UIView animateWithDuration:0.15 animations:^{ self.trashView.transform = CGAffineTransformIdentity; }]; }
当我们想把标签放在垃圾箱里时,我们需要做几件事情。 我们需要停止垃圾桶摆动,我们需要将标签制作成垃圾桶animation,当animation结束时,我们需要完全删除标签。
- (void)dropLabelInTrash { [self updateTrashAppearanceForNoPendingDrop]; [UIView animateWithDuration:0.5 delay:0 options:UIViewAnimationOptionCurveEaseIn animations:^{ self.label.center = self.trashView.center; self.label.transform = CGAffineTransformMakeScale(0.1, 0.1); } completion:^(BOOL finished) { [self.label removeFromSuperview]; self.label = nil; }]; }
如果拖动被中止,我们需要停止垃圾桶摆动,并将标签制作回原来的位置:
- (void)abortLabelDrag { [self updateTrashAppearanceForNoPendingDrop]; [UIView animateWithDuration:0.5 delay:0 options:UIViewAnimationOptionCurveEaseOut animations:^{ self.label.center = labelOriginalCenter; } completion:nil]; }
就这样!
标签可以从手势识别器的视图属性中获得。 就垃圾桶而言,您可以使用CGRectIntersectsRect来确定拖动的标签的矩形是否与垃圾桶的矩形重叠。 在手势识别器的动作方法中,类似这样的东西:
- (IBAction)handlePan:(UIPanGestureRecognizer *)sender { // your other panning code here if (sender.state == UIGestureRecognizerStateEnded){ if (CGRectIntersectsRect(sender.view.frame, trashcanImageView.frame)) [ sender.view removeFromSuperview]; } }