2017-08-09 18 views
1

該博客介紹瞭如何執行shake to undo,但是我想創建某種基類(在Xamarin形式)的,我可以重複使用此代碼:如何在Xamarin Forms中實現iOS「搖動以撤消」,僅在蘋果設備上?

#region respond to shaking (OS3+) 
public override bool CanBecomeFirstResponder { 
    get { 
     return true; 
    } 
} 
public override void ViewDidAppear (bool animated) 
{ 
    base.ViewDidAppear (animated); 
    this.BecomeFirstResponder(); 
} 
public override void ViewWillDisappear (bool animated) 
{ 
    this.ResignFirstResponder(); 
    base.ViewWillDisappear (animated); 
} 
public override void MotionEnded (UIEventSubtype motion, UIEvent evt) 
{ 
    Console.WriteLine("Motion detected"); 
    if (motion == UIEventSubtype.MotionShake) 
    { 
     Console.WriteLine("and was a shake"); 
     // Do your application-specific shake response here... 
     Update(); 
    } 
} 
#endregion 

我不知道在哪裏開始......創建一個僅適用於iOS的基類。

是否有任何種類的依賴注入我可以使用XamarinForms爲所有視圖的基類的運行時實現?

+0

你可以創建一個通用的BasePage類,所有的頁面都繼承自它們,並且它們使用自定義渲染器在iOS上添加晃動行爲 – Jason

+0

你在哪裏實現Shake To Undo?它默認爲iOS的'Xamarin.Forms.Entry'控件實現。 –

+0

@BrandonMinnick期望的效果是爲所有其他情況創建此彈出窗口:''你想提交一個錯誤報告嗎?'' – LamonteCristo

回答

3

好消息是,我們可以利用Device Motion NuGet Package的代替自定義渲染的!

我們可以在基類NavgiationPage類中實現搖動功能,並將其用作我們的MainPage

我還在App構造函數中包含了邏輯,該構造函數只爲iOS實現了ShakeListenerNavigationPage

代碼

using System; 
using System.Diagnostics; 

using Xamarin.Forms; 

using DeviceMotion.Plugin; 
using DeviceMotion.Plugin.Abstractions; 

namespace YourNamespace 
{ 

    public class App : Application 
    { 
     public App() 
     { 
      NavigationPage navigationPage; 
      switch(Device.RuntimePlatform) 
      { 
       case Device.iOS: 
        navigationPage = new ShakeListenerNavigationPage(new MyPage()); 
        break; 
       default: 
        navigationPage = new NavigationPage(new MyPage()); 
        break; 
      } 

      MainPage = navigationPage; 
     } 
    } 

    public class ShakeListenerNavigationPage : NavigationPage 
    { 
     #region Constant Fields 
     const int _shakeDetectionTimeLapse = 250; 
     readonly double _shakeThreshold; 
     #endregion 

     #region Fields 
     bool _hasUpdated; 
     DateTime _lastUpdate; 
     double _lastX, _lastY, _lastZ; 
     #endregion 

     #region Constructors 
     public ShakeListenerNavigationPage(Page root) : base(root) 
     { 
      switch (Device.RuntimePlatform) 
      { 
       case Device.iOS: 
        _shakeThreshold = 20; 
        break; 
       default: 
        _shakeThreshold = 800; 
        break; 
      } 


      CrossDeviceMotion.Current.Start(MotionSensorType.Accelerometer, MotionSensorDelay.Default); 
      CrossDeviceMotion.Current.SensorValueChanged += HandleSensorValueChanged; 
     } 
     #endregion 

     #region Methods 
     void HandleSensorValueChanged(object sender, SensorValueChangedEventArgs e) 
     { 
      if (e.SensorType == MotionSensorType.Accelerometer) 
      { 
       double x = ((MotionVector)e.Value).X; 
       double y = ((MotionVector)e.Value).Y; 
       double z = ((MotionVector)e.Value).Z; 

       var currentTime = DateTime.Now; 

       if (_hasUpdated == false) 
       { 
        _hasUpdated = true; 
        _lastUpdate = currentTime; 
       } 
       else 
       { 
        var hasMinimumTimeElapsed = (currentTime - _lastUpdate).TotalMilliseconds > _shakeDetectionTimeLapse; 

        if (!hasMinimumTimeElapsed) 
         return; 

        _lastUpdate = currentTime; 

        var timeSinceLastShakeInMilliseconds = (currentTime - _lastUpdate).TotalMilliseconds; 
        var totalMovementDistance = x + y + z - _lastX - _lastY - _lastZ; 
        var shakeSpeed = Math.Abs(totalMovementDistance)/timeSinceLastShakeInMilliseconds * 10000; 

        Debug.WriteLine($"Shake Speed: {shakeSpeed}"); 

        if (shakeSpeed > _shakeThreshold) 
         HandleShake(); 
       } 

       _lastX = x; 
       _lastY = y; 
       _lastZ = z; 
      } 
     } 

     void HandleShake() 
     { 
      Device.BeginInvokeOnMainThread(async() => await DisplayAlert("Shake Detected", "You shook your device!", "Ok")); 
     } 
     #endregion 
    } 
} 

示例應用程序

下面是一個示例應用程序Xamarin.Forms,我實現了這個功能! https://github.com/brminnick/InvestmentDataSampleApp

+0

謝謝!我明天會看看! – LamonteCristo

相關問題