拖动到图像时删除UILabel

时间:2013-07-20 19:13:41

标签: ios objective-c uilabel

我有一个UILabel,我添加了一个平移手势识别器,我的视图中还有一个垃圾桶图像,使用UIImage视图。每次我将UILabel拖到垃圾桶图像时,我想从程序视图中删除UILabel。

2 个答案:

答案 0 :(得分:9)

我假设你想做这样的事情:

drag demo

我将告诉你如何实现它。

我们需要一个标签插座和垃圾桶视图的插座:

@interface ViewController ()

@property (strong, nonatomic) IBOutlet UIImageView *trashView;
@property (strong, nonatomic) IBOutlet UILabel *label;

@end

将它们连接到您的标签和垃圾桶视图。我们还需要两个实例变量:

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

当我们想要将标签丢弃在垃圾箱中时,我们需要做几件事。我们需要阻止垃圾桶摆动,我们需要将标签设置为垃圾桶动画,当动画结束时,我们需要完全删除标签。

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

这就是全部!

答案 1 :(得分:0)

标签可以从手势识别器的视图属性中获取。就垃圾桶而言,您可以使用CGRectIntersectsRect来确定拖动标签的rect是否与垃圾桶的rect重叠。在手势识别器的动作方法中有类似的东西:

- (IBAction)handlePan:(UIPanGestureRecognizer *)sender {
    // your other panning code here
    if (sender.state == UIGestureRecognizerStateEnded){
        if (CGRectIntersectsRect(sender.view.frame, trashcanImageView.frame))
           [ sender.view removeFromSuperview];
    }
}