发生了什么事?上周,领导用iPhone7打开网易新闻,问我:“你看,你这里的下拉刷新是短震动,我们手机控制电视几个星期的时候,只有长震动,而那个产品方询问是否可以使用短振动。然后博主就去查了一下短振的方法,整个过程可以用——“资料太少了!”来形容。不过最后经过一个下午的收集,终于总结整理出了这篇文档,这也补充了我在iPhone6s之后对TapticEngine的理解,TapticEngine首先了解一个概念——TapticEngineTapticEngine是苹果产品上推出的一种新的振动模块,这个组件最早出现在AppleWatch上,iPhone6s和iPhone6sPlus也内置TapticEngine,在设计上进行了升级,TapticEngine振动模块为AppleWatch、iPhone6s、iPhone7提供ForceTouch和3DTouch,不同的屏幕操作可以感受到不同的振动触觉效果,带来更好的体验用户体验。短震动方式一:AudioServicesPlaySystemSound普通调用:AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);以上代码在各机型手机中体现为长振API系统版本支持:__OSX_AVAILABLE_STARTING(__MAC_10_5,__IPHONE_2_0);Apple的公共SystemSoundID为:CF_ENUM(SystemSoundID){kSystemSoundID_UserPreferred000Alert=10x0,kSystemSoundID_FlashScreen=0x00000FFE,//已重命名以保持一致kUserPreferredAlert=kSystemSoundID_UserPreferredAlert};CF_ENUM(SystemSoundID){kSystemSoundID_Vibrate=0x00000FFF};以上类型均无短震。但是通过下面的代码,可以获得更多类型的震动://普通短震动,Pop震动反馈在3DTouchAudioServicesPlaySystemSound(1520);//普通短震动,Peek震动反馈在3DTouchAudioServicesPlaySystemSound(1519);//三个连续短振动ShockAudioServicesPlaySystemSound(1521);但上述ID均未在Apple的文档中进行描述。很明显,这是在调用一些私有属性。还有一些关于是否调用私有API的讨论,你可以在这里查看(https://forums.developer.apple.com/thread/45628)。Short-shock方法二获取_tapticEngine这个方法是从这里收集的(https://unifiedsense.com/development/using-taptic-engine-on-ios.html)。idtapticEngine=[[UIDevicecurrentDevice]performSelector:NSSelectorFromString(@"_tapticEngine")withObject:nil];[tapticEngineperformSelector:NSSelectorFromString(@"actuateFeedback:")withObject:@(0)];(@"_tapticEngine")withObject:nil];SELselector=NSSelectorFromString(@"actuateFeedback:");int32_targ=1001;NSInvocation*inv=[NSInvocationinvocationWithMethodSignature:[tapticEnginemethodSignatureForSelector:选择器]];];[invsetArgument:&argatIndex:2];[invinvoke];很明显,这是在调用私有API。这些方法,在实际测试中,发现在iPhone7上调用没有震动反馈,在iPhone6SPlus上调用有震动反馈,在iPhone6上调用没有反馈。简略震动方法三UIImpactFeedbackGeneratoriOS10介绍了一个产生触觉反馈的新方式,帮助用户意识到不同的振动反馈有不同的含义。此功能的核心由UIFeedbackGenerator提供。Apple有UIImpactFeedbackGenerator的介绍文档。UIFeedbackGenerator可以帮助您实现触觉反馈。其要求是:支持TapticEngine机型(iPhone7和iPhone7Plus)。该应用程序需要在前台运行。需要启用系统触觉设置。Apple表示已经公开了TapticEngineAPI,但文档很少。搜集了各种资料,可以认为UIImpactFeedbackGenerator是TapticEngine的公共API。它的调用方法是:UIImpactFeedbackGenerator*generator=[[UIImpactFeedbackGeneratoralloc]initWithStyle:UIImpactFeedbackStyleLight];[generatorprepare];[generatorimpactOccurred];其他观察UIImpactFeedbackGenerator会发现它继承自UIFeedbackGenerator。除了UIImpactFeedbackGenerator,还有三种FeedbackGenerator:UIImpactFeedbackGeneratorUISelectionFeedbackGeneratorUINotificationFeedbackGenerator具体可以参考Apple的Reference(https://developer.apple.com/reference/uikit/uifeedbackgenerator?language=objc)。对于震动反馈的应用,苹果也给出了一个示例场景://Preparethegeneratorwhenthegesturebegins.[self.feedbackGeneratorprepare];break;caseUIGestureRecognizerStateChanged://Checktoseeiftheselectionhaschanged...if([selfmyCustomHasSelectionChangedMethodWithTranslation:[sendertranslationInView:self.view]]){//触发选择反馈。[self.feedbackGeneratorselectionChanged];//保持生成器[inapreparedstateself.feedbackGeneratorPrepare];}break;caseuigesturerecognizerstatecancelled:caseuigeSturerEcognizEntateDEDED:caseuigesturerEcognizerStatefailed://releasethecurrentgenerator..feed..feedbackgenerator=nilter=nil=nil;iPhone7(iOS10)peektouchpop三连短震动iPhone6sPuls(iOS9)peektouchpop三连短短震动iPhone6(iOS10)无震动无震动无震动采集_TAPTICENGINEiPhone7(iOS10)无震动iPhone6sPuls(iOS9)长振iPhone6(iOS10)无振UIIMPACTFEEDBACKGENERATOR.LIGHT.MEDIUM.HEAVYiPhone7(iOS10)弱短振中等短振明显短振iPhone6sPuls(iOS9)长振长振长振iPhone6(iOS10)无震动无震动无震动综上所述,希望同样的代码能在更多机型上实现短震动,推荐使用AudioServicesPlaySystemSound(1519),但可能涉及调用私有API。为了安全起见,请使用UIImpactFeedbackGenerator。在此处编写测试代码(https://github.com/summertian4/iOS-ObjectiveC/tree/master/iPhoneShakeDemo)。
