更新时间:2023-02-26 21:44:14
在搜索联系人应用程序之后,我已经弄清楚它是如何工作的。
After serval hours' digging in the Contact App, I have figured out how it works.
ABNewPersonViewControlle调用ToneLibrary框架中的一些类来执行此操作。
ABNewPersonViewControlle invoke some class in ToneLibrary framework to do this.
调用堆栈如下所示:
0 CoreFoundation 0x3359a1d4 CFGetTypeID + 0
1 CoreFoundation 0x33596396 __CFPropertyListIsValidAux + 46
2 CoreFoundation 0x33517090 CFPropertyListCreateData + 124
3 AudioToolbox 0x38ac255a AudioServicesPlaySystemSoundWithVibration + 158
5 ToneLibrary 0x35a7811a -[TLVibrationRecorderView vibrationComponentDidStartForVibrationRecorderTouchSurface:] + 38
6 ToneLibrary 0x35a772b2 -[TLVibrationRecorderTouchSurface touchesBegan:withEvent:] + 342
7 UIKit 0x3610f526 -[UIWindow _sendTouchesForEvent:] + 314
8 UIKit 0x360fc804 -[UIApplication sendEvent:] + 376
在网上搜索AudioServicesPlaySystemSoundWithVibration之后,我一无所获。
After search "AudioServicesPlaySystemSoundWithVibration" on the web , I found nothing.
所以我决定亲自调查一下。它是AudioToolbox框架中的私有函数。
So I decide to look into it myself. It's a private function in AudioToolbox framework.
该函数的声明类似于
void AudioServicesPlaySystemSoundWithVibration(SystemSoundID inSystemSoundID,id arg,NSDictionary* vibratePattern)
inSystemSoundIDis SystemSoundID。就像AudioServicesPlaySystemSound一样,传递kSystemSoundID_Vibrate。
"inSystemSoundID" is SystemSoundID .just like "AudioServicesPlaySystemSound", pass "kSystemSoundID_Vibrate".
arg并不重要,传递给它,一切都会正常工作。
"arg" is not important, pass nil to it , everything will still work fine.
vibratePattern是NSDictionary的指针,Contact App传入
{
Intensity = 1;
OffDuration = 1;
OnDuration = 10;
}用于记录用户输入。
"vibratePattern" is a pointer of "NSDictionary", the Contact App pass into { Intensity = 1; OffDuration = 1; OnDuration = 10; } for recording user input.
但只有调用此函数才能使振动永不停止。所以我必须找到一些函数来阻止它。
But only call this function will make a vibration never stop. So I have to found some function to stop it.
答案是AudioServicesStopSystemSound。它也是AudioToolbox框架中的私有函数。
The answer is "AudioServicesStopSystemSound". It's also a private function in AudioToolbox framework.
函数的声明就像
void AudioServicesStopSystemSound(SystemSoundID inSystemSoundID)
我猜联系人应用程序在touchesBegan方法中使用AudioServicesPlaySystemSoundWithVibration和touchSernd方法中的AudioServicesStopSystemSound达到此效果。
I guess the Contact App use AudioServicesPlaySystemSoundWithVibration in touchesBegan method, and AudioServicesStopSystemSound in touchEnd method to reach this effect.
TLVibrationController将管理一个振动模式对象来记录您输入的过程。
TLVibrationController will manager a vibrate pattern object to record the process you input.
最后生成一个字典,传入AudioServicesPlaySystemSoundWithVibration以重放整个过程,如下所示:
At last it generate a dictionary to pass into AudioServicesPlaySystemSoundWithVibration to replay the whole process like below:
NSMutableDictionary* dict = [NSMutableDictionary dictionary];
NSMutableArray* arr = [NSMutableArray array ];
[arr addObject:[NSNumber numberWithBool:YES]]; //vibrate for 2000ms
[arr addObject:[NSNumber numberWithInt:2000]];
[arr addObject:[NSNumber numberWithBool:NO]]; //stop for 1000ms
[arr addObject:[NSNumber numberWithInt:1000]];
[arr addObject:[NSNumber numberWithBool:YES]]; //vibrate for 1000ms
[arr addObject:[NSNumber numberWithInt:1000]];
[arr addObject:[NSNumber numberWithBool:NO]]; //stop for 500ms
[arr addObject:[NSNumber numberWithInt:500]];
[dict setObject:arr forKey:@"VibePattern"];
[dict setObject:[NSNumber numberWithInt:1] forKey:@"Intensity"];
AudioServicesPlaySystemSoundWithVibration(4095,nil,dict);
因此,如果您想在iOS中进行自定义振动。使用AudioServicesPlaySystemSoundWithVibration和AudioServicesStopSystemSound。
So if you want a custom vibrations in iOS. Use AudioServicesPlaySystemSoundWithVibration and AudioServicesStopSystemSound.