删除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]; } }