我有一个UIAlertView
弹出一条消息和一个按钮“继续”。我想要的是Shake Gesture也会调用相同的代码来点击continue按钮。但是,我不确定iOS7中的UIAlertView是否可以实现这一点,或者我是否必须创建自己的自定义警报视图。
我尝试过实施:
(void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event { ... }
和
canBecomeFirstResponder { return YES; }
但是当它们正常工作且主视图设置为becomeFirstResponder
时,一旦UIAlertView
弹出,它们就不会响应。那么,我尝试在UIAlertView+MotionResponder.h
的类别中实现这些,以尝试扩展UIAlertView
,但即使canBecomeFirstResponder正确返回motionEnded
,也不会调用YES
。< / p>
这应该有效吗?或者我是否必须实施自己的警报视图?
答案 0 :(得分:2)
UIAlertView
类旨在按原样使用,不支持子类化。此类的视图层次结构是私有的,不得修改。
UIAlertView
的内部视图层次结构比它看起来要复杂得多,从iOS 7开始它甚至没有添加到任何UIWindow
,因此它不参与任何UIAlertView
也就不足为奇了。响应者链如你所料。
但是,您可以考虑在控制器中实现动作识别逻辑,并让它触发UIAlertView
解雇。
您只需要保留对–dismissWithClickedButtonIndex:animated:
实例的引用,检测控制器中的摇晃手势,并向警报发送UIAlertView
消息,以便将其解除。
当UIWindow
出现在当前控制器之上时,上述技术将不起作用,因为它将拦截摇动手势,并且永远不会调用控制器方法。
要使其正常工作,您必须在窗口级别检测手势。以下是您可以做的一个简短示例。
首先我们在@implementation
上定义一个类别,拦截摇动手势并广播通知(我只发布@interface
,因为@implementation UIWindow (Shake)
- (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event {
if (event.type == UIEventTypeMotion && event.subtype == UIEventSubtypeMotionShake) {
[[NSNotificationCenter defaultCenter] postNotificationName:@"UIWindowDidShake" object:nil userInfo:nil];
}
}}
@end
为空)
@property (nonatomic, strong) UIAlertView *alert;
...
- (IBAction)showAlert:(id)sender {
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(dismissAlert) name:@"UIWindowDidShake" object:nil];
self.alert = [[UIAlertView alloc] initWithTitle:nil message:@"An alert" delegate:self cancelButtonTitle:@"Ok" otherButtonTitles:nil];
[self.alert show];
}
- (void)dismissAlert {
[self.alert dismissWithClickedButtonIndex:0 animated:YES];
}
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex {
[[NSNotificationCenter defaultCenter] removeObserver:self name:@"UIWindowDidShake" object:nil];
}
然后在控制器中我们在显示警报时注册通知,并在通知到达时关闭警报。最后,我们可以在警报解除后立即从观察者中删除控制器。
{{1}}