前言
TapticEngine是什么总的来说,TapticEngine是苹果产品上推出的全新震动模块名称,最早出现在AppleWatch中,苹果iPhone6s和iPhone6sPlus也内置了TapticEngine,设计上有所升级。TapticEngine的全新震动模块,这颗震动模块经过特殊设计,能在短时间内达到震动的最佳状态,是普通振动马达所做不到的。Taptic这个单词本身没有什么含义,比较接近的词是Haptic(触觉)。
TapticEngine工作原理传统的手机震动器是马达带着偏振片一起转动,从而产生震动。
大概是这个样子滴。

而TapticEngine是直线电机驱动带着震块做直线往返运动。看看下面这两张蜜汁动感的示意图,你就一下子就明白它是怎么产生震动的了。

iPhone6s的内置的TapticEngine

AppleWatch的内置的TapticEngine,左边集成了扬声器
Taptic Engine 振动模块为 Apple Watch 以及 iPhone 6s、iPhone 7 提供了 Force Touch 以及 3D Touch,不同的屏幕操作,可以感受到不同的振动触觉效果,带来更好的用户体验。
What has Happened?
上周,leader 拿着 iPhone 7 打开了网易新闻,问我:『你看,你这里的下拉刷新是短震动,我们的手机数周遥控电视的时候只有长震动,产品那边问能不能用短震动』。
然后博主就去查看了一下关于短震动的方式,整个过程可以描述为——『资料真少!』。
不过最后通过一下午的搜集,最终还是总结整理出来了这份文档,也补充了自己对 iPhone 6s 之后对 Taptic Engine 的了解。
短震方法一 AudioServicesPlaySystemSound
常用调用:
AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
以上代码在各个型号手机中反应为长震
API 系统版本支持:
__OSX_AVAILABLE_STARTING(__MAC_10_5,__IPHONE_2_0);
APPLE 公开的 SystemSoundID 有:
CF_ENUM(SystemSoundID)
{
 kSystemSoundID_UserPreferredAlert = 0x00001000,
 kSystemSoundID_FlashScreen   = 0x00000FFE,
  // this has been renamed to be consistent
 kUserPreferredAlert  = kSystemSoundID_UserPreferredAlert
};
CF_ENUM(SystemSoundID)
{
 kSystemSoundID_Vibrate    = 0x00000FFF
};
以上类型 没有短震动 。
但通过以下代码,可以得到更多类型的震动:
// 普通短震,3D Touch 中 Peek 震动反馈 AudioServicesPlaySystemSound(1519);
// 普通短震,3D Touch 中 Pop 震动反馈 AudioServicesPlaySystemSound(1520);
// 连续三次短震 AudioServicesPlaySystemSound(1521);
但以上 ID 均未在 Apple 的 Documents 中描述。显然,这是调用了一些私有一些属性 。
关于是否调用了私有 API,也有一些讨论,可以查看这里。
短震方法二 获取 _tapticEngine
这种方法是从这里搜集到的。
id tapticEngine = [[UIDevice currentDevice] performSelector: NSSelectorFromString(@"_tapticEngine")
              withObject:nil];
[tapticEngine performSelector: NSSelectorFromString(@"actuateFeedback:")
      withObject:@(0)];
或者:
id tapticEngine = [[UIDevice currentDevice] performSelector: NSSelectorFromString(@"_tapticEngine")
              withObject:nil];
SEL selector = NSSelectorFromString(@"actuateFeedback:");
int32_t arg = 1001;
 
NSInvocation *inv = [NSInvocation invocationWithMethodSignature:[tapticEngine methodSignatureForSelector:selector]];
[inv setTarget:tapticEngine];
[inv setSelector:selector];
[inv setArgument:&arg atIndex:2];
[inv invoke];
显然, 这是调用了私有 API 。
这些方法,在实际测试的时候发现,在 iPhone 7 上调用没有震动反馈,在 iPhone 6S Plus 上调用有震动反馈,在 iPhone 6 上调用 无反馈。
短震方法三 UIImpactFeedbackGenerator
iOS10 引入了一种新的、产生触觉反馈的方式, 帮助用户认识到不同的震动反馈有不同的含义 。这个功能的核心就是由 UIFeedbackGenerator 提供。Apple 对于 UIImpactFeedbackGenerator 有一篇介绍文档。
UIFeedbackGenerator 可以帮助你实现 haptic feedback。它的要求是:
- 支持 Taptic Engine 机型 (iPhone 7 以及 iPhone 7 Plus).
- app 需要在前台运行
- 系统 Haptics setting 需要开启
Apple 曾表示公开了 Taptic Engine 的 API,但是鲜有文档。在搜罗了各种资料后,可以认为 UIImpactFeedbackGenerator 即 Taptic Engine 的 公开 API。
它的调用方式是:
UIImpactFeedbackGenerator *generator = [[UIImpactFeedbackGenerator alloc] initWithStyle: UIImpactFeedbackStyleLight]; [generator prepare]; [generator impactOccurred];
Others
观察 UIImpactFeedbackGenerator 你会发现它继承于 UIFeedbackGenerator。除了 UIImpactFeedbackGenerator 还有三种 FeedbackGenerator:
- UIImpactFeedbackGenerator
- UISelectionFeedbackGenerator
- UINotificationFeedbackGenerator
详情可参考 Apple 的 这篇 Reference 。
对于震动反馈的应用,Apple 也给出了示例场景:
- (IBAction)gestureHandler:(UIPanGestureRecognizer *)sender {
 
 switch (sender.state) {
  case UIGestureRecognizerStateBegan:
   
   // Instantiate a new generator.
   self.feedbackGenerator = [[UISelectionFeedbackGenerator alloc] init];
   
   // Prepare the generator when the gesture begins.
   [self.feedbackGenerator prepare];
   
   break;
   
  case UIGestureRecognizerStateChanged:
   
   // Check to see if the selection has changed...
   if ([self myCustomHasSelectionChangedMethodWithTranslation:[sender translationInView: self.view]]) {
    
    // Trigger selection feedback.
    [self.feedbackGenerator selectionChanged];
    
    // Keep the generator in a prepared state.
    [self.feedbackGenerator prepare];
 
   }
   
   break;
   
  case UIGestureRecognizerStateCancelled:
  case UIGestureRecognizerStateEnded:
  case UIGestureRecognizerStateFailed:
   
   // Release the current generator.
   self.feedbackGenerator = nil;
   
   break;
   
  default:
   
   // Do nothing.
   break;
 }
}
三种方法在测试机上不同的反馈结果
  
    
       
  
  AudioServicesPlaySystemSound 
      1519 
      1520 
      1521 
    
获取 _tapticEngine 
  
    
       
  
  UIImpactFeedbackGenerator 
      .Light 
      .Medium 
      .Heavy 
    
总结一下,希望同样的代码能在更多的机型上实现短振,建议使用 AudioServicesPlaySystemSound(1519)。不过可能会涉及到调用私有 API。安全起见,可以使用 UIImpactFeedbackGenerator。
代码
测试代码在这里。
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对自由互联的支持。
