如何在iOS中以编程方式触发震动事件?
我已经尝试过以下但是它一直在崩溃......
+ (void)shake {
NSLog(@"TEST");
UIMotionEventProxy *m = [[NSClassFromString(@"UIMotionEvent") alloc] _init];
m->_subtype = UIEventSubtypeMotionShake;
m->_shakeState = 1;
[[[UIApplication sharedApplication] keyWindow] motionBegan:UIEventSubtypeMotionShake withEvent:m];
[[[UIApplication sharedApplication] keyWindow] motionEnded:UIEventSubtypeMotionShake withEvent:m];
}
苹果在Hardware > Shake Gesture
下的模拟器中做了什么?
答案 0 :(得分:4)
尝试替换
UIMotionEventProxy *m = [[NSClassFromString(@"UIMotionEvent") alloc] _init];
带
UIMotionEventProxy *m = [[UIMotionEventProxy alloc] _init];
我想当NSClassFromString(@"UIMotionEvent")
返回nil时,它正在崩溃。
答案 1 :(得分:2)
您想在越狱应用程序或Apple兼容用途中使用吗?
对于有关模拟器的问题,Apple使用私有功能。
这是一个小解释:
当你使用“Shake Gesture”时,模拟器调用sendButtonEvent:0x3fc
sendButtonEvent是Simulator中的一个函数,谁:
在越狱应用程序中,您可以执行类似的操作(未经测试但应该有效):
struct UIEvent {
int subtype;
double timestamp;
int type;
} * event;
bzero(event, sizeof(event));
event->type = UIEventTypeMotion;
event->subtype = UIEventSubtypeMotionShake;
event->timestamp = GSCurrentEventTimestamp();
NSString* bundle = [[NSBundle mainBundle] bundleIdentifier];
mach_port_t port = GSCopyPurpleNamedPort([bundle UTF8String]);
GSEventRecord* record = (GSEventRecord*)event;
GSSendEvent(record, port);
答案 2 :(得分:2)
更改UIMotionEventProxy类(添加两个setter方法)似乎可以解决问题。我只添加了两个方法setShakeState
和_setSubtype
,如下所示。
-(void)setShakeState:(int)fp8 {
_shakeState = fp8;
}
-(void)_setSubtype:(int)fp8 {
_subtype = fp8;
}
然后我将代码更改为以下内容......
UIMotionEventProxy *m = [[NSClassFromString(@"UIMotionEvent") alloc] _init];
[m setShakeState:1];
[m _setSubtype:UIEventSubtypeMotionShake];
[[UIApplication sharedApplication] sendEvent:m];
[[[UIApplication sharedApplication] keyWindow] motionBegan:UIEventSubtypeMotionShake withEvent:m];
[[[UIApplication sharedApplication] keyWindow] motionEnded:UIEventSubtypeMotionShake withEvent:m];
对于模拟器和物理设备似乎都能完美运行。如果有人想要查看完整的UIMotionEventProxy文件,Here是可供下载的主文件和头文件。