在UIAlertView显示时处理摇动手势

时间:2016-07-21 07:34:51

标签: ios xamarin xamarin.ios screenshot shake

我想在摇动设备时拍摄屏幕截图,并希望在UIAlertView可见时使用此功能。 问题是没有调用MotionBegan和MotionEnded方法。我已经尝试了子类化UIWindow和UIAlertView并重写了那里的方法,但仍然没有被调用。

我在这里错过了什么吗?

我通过调用

启用摇动手势
    UIApplication.SharedApplication.ApplicationSupportsShakeToEdit = true;

在AppDelegate.cs。

当没有UIAlertView可见时,这一切都很完美。

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

1 个答案:

答案 0 :(得分:2)

我强烈建议不要使用UIAlertView

  • 首先在iOS9中弃用

  • 其次,它真的是混乱 UIView。 Apple不支持对它进行子类化,并且在尝试ResignFirstResponder时事情会变得非常侧向,因此您可以接收事件。除了一些奇怪的其他事情外,难怪Apple不赞成它。

使用UIAlertController代替,它可以在iOS8 / 9/10中使用,就像一个正确的UIViewController一样,当与UIAlertControllerStyle.Alert样式一起使用时看起来像旧警报,你不会有使用MotionBegan/MotionEnded时遇到任何问题。

那么您可以覆盖MotionBegan/MotionEnded的每一个UIViewController

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);