我正在使用与主应用共享的代码实现iOS动作扩展。其中一些使用[[UIApplication sharedApplication] sendAction:to:from:event]
向第一响应者发送动作。
由于sharedApplication
在扩展中不可用,因此此代码将无法编译。
我尝试了一种解决方法,即实现UIControl
,并使用-[UIControl sendAction:to:forEvent:]
从中发送操作。这有效,但有一个很大的缺点(除了感觉非常hacky):它不可能控制发送者(这将是UIControl
实例),在我的情况下是必要的。
我正在考虑的另一个解决方法是通过观察UIApplication通知并从中获取UIApplication
属性来检索包装扩展的object
对象(我已经确认其中一些通知仍在发送中)延期。)但即使这确实有效,它是否有机会被Apple批准,因为它会欺骗sharedApplication
限制?有没有人在现场应用中体验过这种技术?
谢谢!
答案 0 :(得分:2)
看起来没有直接的方法来做到这一点。看一下反汇编的UIKit,很少有方法调用-[UIApplication sendAction:to:from:forEvent:]
,所有这些方法都明确地提供了发送者。
好消息是-[UIControl sendAction:to:forEvent:]
只是-[UIApplication sendAction:to:from:forEvent:]
的一个薄包装:
void -[UIControl sendAction:to:forEvent:](void * self, void * _cmd, void * arg2, void * arg3, void * arg4) {
rbx = [arg3 retain];
[*_UIApp sendAction:arg2 toTarget:rbx fromSender:self forEvent:arg4];
rdi = rbx;
[rdi release];
return;
}
如果您愿意承担风险,Apple可能会更改控件互动的基本行为,以完全取消UIApplication
扩展程序,那么在sendAction:to:from:forEvent:
上调用view.window.nextResponder
可能相对安全找到应用实例。我检索它的方式是UIApplication
,因为如果窗口不是nil,它总是[(id)view.window.nextResponder sendAction:@selector(foo:) to:nil from:nil event:nil]
:
UIControl
Apple不应该拒绝这一点,因为你没有使用不允许使用的API,而且你还没有做任何PlotOrientation
已经做过的事情。
如果您不想承担风险,那么您所做的可能是最好的方法,创建虚拟控件(如果需要)并使用它来发送操作。