显示 UIAlertView 时处理摇动手势

Posted

技术标签:

【中文标题】显示 UIAlertView 时处理摇动手势【英文标题】:Handle Shake Gestures when UIAlertView is displaying 【发布时间】:2016-07-21 07:34:51 【问题描述】:

我想在摇动设备时截取屏幕截图,并且还希望在 UIAlertView 可见时它能够工作。 问题是没有调用 MotionBegan 和 MotionEnded 方法。我已经尝试继承 UIWindow 和 UIAlertView 并覆盖其中的方法,但仍然没有调用任何内容。

我错过了什么吗?

我通过调用启用摇晃手势

    UIApplication.SharedApplication.ApplicationSupportsShakeToEdit = true;

在 AppDelegate.cs 中。

当没有 UIAlertView 可见时,这一切都可以完美运行。

当显示 UIAlertView 时,哪个视图会响应摇动手势?

【问题讨论】:

【参考方案1】:

我强烈建议不要使用UIAlertView

首先它在 ios9 中被弃用

第二个真的是搞砸了UIView。 Apple 不支持对它进行子类化,并且在尝试 ResignFirstResponder 时事情会变得非常糟糕,因此您可以接收事件。除了其他一些奇怪的东西外,难怪Apple 弃用了它。

改为使用UIAlertController,它在iOS8/9/10 中可用,并且在与UIAlertControllerStyle.Alert 样式一起使用时类似于正确的UIViewController,并且看起来像旧警报,MotionBegan/MotionEnded 不会有任何问题使用时。

所以您可以在每个 UIViewController 上覆盖 MotionBegan/MotionEnded

public override void MotionBegan(UIEventSubtype motion, UIEvent evt)

    Console.WriteLine("MotionBegin");
    base.MotionBegan(motion, evt);


public override void MotionEnded(UIEventSubtype motion, UIEvent evt)

    Console.WriteLine("MotionEnded");
    base.MotionEnded(motion, evt);

创建您自己的 UIWindow 子类,因此如果您的应用程序的其他区域需要响应运动,您将获得全局运动事件(您可以通过通知中心发布 (PostNotificationName)事件。

public class ShakeWindow : UIWindow

    public ShakeWindow() : base()  

    public ShakeWindow(IntPtr handle) : base(handle)  

    public override void MotionBegan(UIEventSubtype motion, UIEvent evt)
    
        Console.WriteLine("Window MotionBegin");
        NSNotificationCenter.DefaultCenter.PostNotificationName("ShakeMe", this);
        base.MotionBegan(motion, evt);
    

    public override void MotionEnded(UIEventSubtype motion, UIEvent evt)
    
        Console.WriteLine("Window MotionEnded");
        base.MotionEnded(motion, evt);
    
 

UIAlertController 使用NSNotificationCenter 的示例:

var button2 = new UIButton(UIButtonType.RoundedRect);
button2.SetTitle("Alert 2", UIControlState.Normal);
button2.Frame = new CGRect(20, 60, 100, 40);
button2.TouchUpInside += (object sender, EventArgs e) =>

    var alert2 = UIAlertController.Create("***", "Shake me now", UIAlertControllerStyle.Alert);
    NSNotificationCenter.DefaultCenter.AddObserver(new NSString("ShakeMe"), (obj) => 
    
        alert2?.DismissViewController(true, null);
    );
    alert2.AddAction(UIAlertAction.Create("Ok", UIAlertActionStyle.Default, (UIAlertAction obj) =>
    
        alert2.DismissViewController(true, null);
    ));
    PresentViewControllerAsync(alert2, true);
;
Add(button2);

【讨论】:

太棒了!感谢您的快速回复。我将改用 UIAlertController。使用 UIAlertViews 的原因是一些用户仍然有 iOS 7,因此将无法显示 UIAlerViewControllers。但由于此屏幕截图功能仅用于内部测试目的,我将在显示警报时检查操作系统版本。无论如何都应该实现 UIAlertViewControllers :-) @Hypo :如果您最终不得不在 iOS7(+) 上支持警报,我将创建一个自定义 UIViewController 并重现警报外观,但对它来说并不是很重要......祝你好运,快乐的 Xammie 编码...

以上是关于显示 UIAlertView 时处理摇动手势的主要内容,如果未能解决你的问题,请参考以下文章

处理 iPad 摇动手势

使用情节提要时如何使用摇动手势?

在 UIAlertview 之后摇动不再起作用

更改 SpriteKit 中摇动手势的灵敏度:目标是创建更快的摇动?

如何在 Cocos2d CCLayer 中添加摇动手势?

相机图像选择器和摇动手势?