是否可以在 UIButton 上实现 3d touch?

Is it possible to implement 3d touch on UIButton?

我是 iOS 开发的新手,但我需要在 UIButton 上实现 3d touch,当用户在按钮快捷菜单上施加力时会弹出,即使有人可以向我提供示例代码用于 3d touch 的 ObjectiveC 将不胜感激。提前致谢。

您可以重载 UIButton 并检查

UITouch 上的 force 属性

- (BOOL)beginTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event;

- (BOOL)continueTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event;

根据此处发生的情况,您可以发送自己的强制触摸自定义操作,其中:

- (void)sendActionsForControlEvents:(UIControlEvents)controlEvents;

是的,我在下面 github 上的示例应用程序中演示了如何检测 UIButton 上的 3d 触摸。对于菜单弹出部分,我将留给您实现,但这将为您提供 force/3d 触控块。

https://github.com/foggzilla/DFContinuousForceTouchGestureRecognizer

我这样做的方法是使用我在示例项目中提供的 DFContinuousForceTouchGestureRecognizer

DFContinuousForceTouchGestureRecognizer 提供有关压力变化的持续更新,因此您可以做一些不错的事情,例如随着用户改变对按钮施加的压力而改变按钮,而不是单个事件。如果您只想要一个事件,您可以忽略 DFContinuousForceTouchDelegate 中的所有内容,但 - (void) forceTouchRecognized 回调除外。

您可以在支持强制按下的设备上下载此应用和 运行 示例应用,看看它的感觉。

在你的 UIViewController 实现中:

- (void)viewDidLoad {
    [super viewDidLoad];
    _forceTouchRecognizer = [[DFContinuousForceTouchGestureRecognizer alloc] init];
    _forceTouchRecognizer.forceTouchDelegate = self;

    [self.button addGestureRecognizer:_forceTouchRecognizer];
}

实现强制触摸委托协议:

#pragma DFContinuousForceTouchDelegate

- (void)forceTouchRecognized:(DFContinuousForceTouchGestureRecognizer *)recognizer {
    self.button.transform = CGAffineTransformIdentity;
    [self.button setNeedsDisplay];
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1f * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        [[[UIAlertView alloc] initWithTitle:@"Force Touch Button" message:@"YEAH!!" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil] show];
    });
}
- (void)forceTouchRecognizer:(DFContinuousForceTouchGestureRecognizer *)recognizer didStartWithForce:(CGFloat)force maxForce:(CGFloat)maxForce {
    CGFloat transformDelta = 1.0f + ((force/maxForce) / 3.0f);
    self.button.transform = CGAffineTransformMakeScale(transformDelta, transformDelta);
    [self.button setNeedsDisplay];
}

- (void)forceTouchRecognizer:(DFContinuousForceTouchGestureRecognizer *)recognizer didMoveWithForce:(CGFloat)force maxForce:(CGFloat)maxForce {
    CGFloat transformDelta = 1.0f + ((force/maxForce) / 3.0f);
    self.button.transform = CGAffineTransformMakeScale(transformDelta, transformDelta);
    [self.button setNeedsDisplay];
}

- (void)forceTouchRecognizer:(DFContinuousForceTouchGestureRecognizer *)recognizer didCancelWithForce:(CGFloat)force maxForce:(CGFloat)maxForce  {
    self.button.transform = CGAffineTransformIdentity;
    [self.button setNeedsDisplay];
}

- (void)forceTouchRecognizer:(DFContinuousForceTouchGestureRecognizer *)recognizer didEndWithForce:(CGFloat)force maxForce:(CGFloat)maxForce {
    self.button.transform = CGAffineTransformIdentity;
    [self.button setNeedsDisplay];
}

- (void)forceTouchDidTimeout:(DFContinuousForceTouchGestureRecognizer *)recognizer {
    self.button.transform = CGAffineTransformIdentity;
    [self.button setNeedsDisplay];
}

请注意,这仅在支持强制触摸的设备上有用。

此外,如果您 运行 在 iOS8 或以下,则不应将 DFContinuousForceTouchGestureRecognizer 添加到视图中,因为它使用新的 force 属性 UITouch 仅适用于 iOS9。

如果你在 iOS8 上添加它会崩溃,所以如果你支持的版本比 iOS 9.