触觉反馈在Xamarin.Forms iOS依赖服务中崩溃

问题描述 投票:0回答:1

我试图在Xamarin.Forms应用程序中使用触觉反馈来通知用户选择变化。我发现了对iOS的引用,并为iOS做了一个依赖服务;但是,它总是在没有任何C#错误的情况下崩溃。我试过在主线程和我使用的线程上调用它。它甚至在trycatch块中崩溃。这是我的代码。

using System;
namespace App.Services
{
    public enum HapticFeedbackType
    {
        ImpactHeavy, // Heavy impact
        ImpactMedium, // Medium impact
        ImpactLight, // Light impact
        Selection, // To tick while scrolling through a scrollview or carousel
        NotificationError, // When an in-app error notification occurs
        NotificationWarning, // When an in-app warning notification occurs
        NotificationSuccess // When an in-app success notification occurs
    }
    public interface IHapticFeedback
    {
        void PrepareHapticFeedback(HapticFeedbackType type);
        void ExecuteHapticFeedback(HapticFeedbackType type);
    }
}

using System;
using UIKit;

using Xamarin.Forms;

using App.Services;

[assembly: Dependency(typeof(App.iOS.Services.HapticFeedbackService))]
namespace App.iOS.Services
{
    public class HapticFeedbackService : IHapticFeedback
    {
        HapticFeedbackHelper helper;
        public HapticFeedbackService()
        {
            helper = new HapticFeedbackHelper();
        }
        public void PrepareHapticFeedback(HapticFeedbackType type)
        {
            helper.PrepareHapticFeedback(type);
        }

        public void ExecuteHapticFeedback(HapticFeedbackType type)
        {
            helper.ExecuteHapticFeedback(type);
        }
    }
    //https://blog.francois.raminosona.com/add-vibrations-in-a-xamarin-ios-app/
    public class HapticFeedbackHelper: IDisposable
    {
        private UIImpactFeedbackGenerator _impactHeavyFeedbackGenerator;
        private UIImpactFeedbackGenerator _impactMediumFeedbackGenerator;
        private UIImpactFeedbackGenerator _impactLightFeedbackGenerator;
        private UISelectionFeedbackGenerator _selectionFeedbackGenerator;
        private UINotificationFeedbackGenerator _notificationFeedbackGenerator;

        public HapticFeedbackHelper()
        {
            _impactHeavyFeedbackGenerator = new UIImpactFeedbackGenerator(UIImpactFeedbackStyle.Heavy);
            _impactMediumFeedbackGenerator = new UIImpactFeedbackGenerator(UIImpactFeedbackStyle.Medium);
            _impactLightFeedbackGenerator = new UIImpactFeedbackGenerator(UIImpactFeedbackStyle.Light);
            _selectionFeedbackGenerator = new UISelectionFeedbackGenerator();
            _notificationFeedbackGenerator = new UINotificationFeedbackGenerator();
        }


        public void PrepareHapticFeedback(HapticFeedbackType type)
        {
            switch (type)
            {
                case HapticFeedbackType.ImpactHeavy:
                    _impactHeavyFeedbackGenerator.Prepare();
                    break;
                case HapticFeedbackType.ImpactMedium:
                    _impactMediumFeedbackGenerator.Prepare();
                    break;
                case HapticFeedbackType.ImpactLight:
                    _impactLightFeedbackGenerator.Prepare();
                    break;
                case HapticFeedbackType.Selection:
                    _selectionFeedbackGenerator.Prepare();
                    break;
                case HapticFeedbackType.NotificationError:
                case HapticFeedbackType.NotificationWarning:
                case HapticFeedbackType.NotificationSuccess:
                    _notificationFeedbackGenerator.Prepare();
                    break;
            }
        }

        public void ExecuteHapticFeedback(HapticFeedbackType type)
        {
            switch (type)
            {
                case HapticFeedbackType.ImpactHeavy:
                    _impactHeavyFeedbackGenerator.ImpactOccurred();
                    break;
                case HapticFeedbackType.ImpactMedium:
                    _impactMediumFeedbackGenerator.ImpactOccurred();
                    break;
                case HapticFeedbackType.ImpactLight:
                    _impactLightFeedbackGenerator.ImpactOccurred();
                    break;
                case HapticFeedbackType.Selection:
                    _selectionFeedbackGenerator.SelectionChanged();
                    break;
                case HapticFeedbackType.NotificationError:
                    _notificationFeedbackGenerator.NotificationOccurred(UINotificationFeedbackType.Error);
                    break;
                case HapticFeedbackType.NotificationWarning:
                    _notificationFeedbackGenerator.NotificationOccurred(UINotificationFeedbackType.Warning);
                    break;
                case HapticFeedbackType.NotificationSuccess:
                    _notificationFeedbackGenerator.NotificationOccurred(UINotificationFeedbackType.Success);
                    break;
            }
        }

        #region IDisposable
        public void Dispose()
        {
            _impactHeavyFeedbackGenerator = null;
            _impactMediumFeedbackGenerator = null;
            _impactLightFeedbackGenerator = null;
            _selectionFeedbackGenerator = null;
            _notificationFeedbackGenerator = null;
        }
        #endregion


    }
}

 async void LikeDown(object sender, MR.Gestures.DownUpEventArgs e)
        {
            LoggingController.Info("LikeDown event started...");
            if (cancelReactionShowToken?.Token != null && cancelReactionShowToken.Token.CanBeCanceled)
                cancelReactionShowToken.Cancel();

            cancelReactionShowToken = new CancellationTokenSource();
            Task task = new Task(async delegate {
                await Task.Delay(800);
                if (cancelReactionShowToken.Token.IsCancellationRequested)
                {
                    cancelReactionShowToken = null;
                    return;
                }
                MainThread.BeginInvokeOnMainThread(() =>
                {
                    reactionPopup = new SfPopupLayout();
                    reactionPopup.PopupView.ShowHeader = false;
                    reactionPopup.PopupView.ShowFooter = false;
                    reactionPopup.PopupView.AutoSizeMode = AutoSizeMode.Both;
                    reactionPopup.PopupView.ContentTemplate = new DataTemplate(() =>
                    {
                        ReactionsView view = new ReactionsView();
                        this.Emojis = view.Emojis;
                        this.ReactionTypes = view.ReactionTypes;
                        return view;
                    });
                    reactionPopup.ShowRelativeToView(actionsRow, RelativePosition.AlignBottom, 0, 0);


                    try
                    {
                        hapticFeedback.ExecuteHapticFeedback(Services.HapticFeedbackType.Selection);

                    } catch (Exception ex) { Console.WriteLine(ex.Message); }

                //needs to be canceled so other guestures know
                cancelReactionShowToken.Cancel();
            }, cancelReactionShowToken.Token);
            task.Start();
            await task;
        }

如果有人有在Xamarin.Forms中使用触觉反馈的经验,那会有很大的帮助。

c# ios xamarin xamarin.forms xamarin.ios
1个回答
1
投票

你需要放置一个异常捕获点,看看到底是哪里发生了崩溃。你已经放置了所有的代码,但很难弄清楚你在哪里出了问题。它可能只是在一些不相关的地方。你还应该分享你的应用程序的放,将显示异常是什么。

下面是一个例子 触觉 由ElysiumLab.com实现,他们也有一个Nuget包,可能已经实现了它的使用"Naylah":

在你的Coreforms项目中

public class HapticFeedback
{
    public static IHapticFeedback Instance { get; set; }

    static HapticFeedback()
    {
        Instance = new DefaultHapticFeedback();
    }
}

internal class DefaultHapticFeedback : IHapticFeedback
{
    public void Run(HapticFeedbackType hapticFeedbackType)
    {
        //This is a default thing should not be used;
        //throw new System.Exception("Not initialized in device platforms isbrubles");
    }
}

public interface IHapticFeedback
{
    void Run(HapticFeedbackType hapticFeedbackType);
}

public enum HapticFeedbackType
{
    Softy,
    Medium,
    Heavy
}

iOS实施

public class HapticFeedbackService
{
    public static void Init()
    {
        HapticFeedback.Instance = new iOSHapticFeedback();
    }
}

public class iOSHapticFeedback : IHapticFeedback
{
    public void Run(HapticFeedbackType hapticFeedbackType)
    {
        UIImpactFeedbackGenerator impact = null;

        switch (hapticFeedbackType)
        {
            case HapticFeedbackType.Softy:
                impact = new UIImpactFeedbackGenerator(UIImpactFeedbackStyle.Light);
                break;

            case HapticFeedbackType.Medium:
                impact = new UIImpactFeedbackGenerator(UIImpactFeedbackStyle.Medium);
                break;

            case HapticFeedbackType.Heavy:
                impact = new UIImpactFeedbackGenerator(UIImpactFeedbackStyle.Heavy);
                break;
        }

        impact.Prepare();
        impact.ImpactOccurred();
    }
}

另外,你也可以像这样为触觉反馈创建一个Android实现。

public class HapticFeedbackService
{
    public static void Init(Activity activity)
    {
        HapticFeedback.Instance = new AndroidHapticFeedback(activity);
    }
}

internal class AndroidHapticFeedback : IHapticFeedback
{
    private readonly Activity activity;

    public AndroidHapticFeedback(Activity activity)
    {
        this.activity = activity;
    }

    public void Run(HapticFeedbackType hapticFeedbackType)
    {
        switch (hapticFeedbackType)
        {
            case HapticFeedbackType.Softy:
                activity.Window.DecorView.RootView.PerformHapticFeedback(FeedbackConstants.ContextClick);
                break;

            case HapticFeedbackType.Medium:
                activity.Window.DecorView.RootView.PerformHapticFeedback(FeedbackConstants.KeyboardPress);
                break;

            case HapticFeedbackType.Heavy:
                activity.Window.DecorView.RootView.PerformHapticFeedback(FeedbackConstants.KeyboardPress);
                break;
        }
    }
}

你可以查看详细的代码 此处但如果你只是在寻找一个iOS的实现,你可以看到 此处.

© www.soinside.com 2019 - 2024. All rights reserved.