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

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

我错过了什么吗?

我通过调用启用摇晃手势

    UIApplication.SharedApplication.ApplicationSupportsShakeToEdit = true;

在 AppDelegate.cs 中。

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

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

【问题讨论】:

    标签: ios xamarin xamarin.ios screenshot shake


    【解决方案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("StackOverflow", "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 编码...
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-19
    • 1970-01-01
    • 1970-01-01
    • 2011-07-11
    • 1970-01-01
    相关资源
    最近更新 更多