简体   繁体   English

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

[英]Haptic Feedback crashes in Xamarin.Forms iOS Dependency Service

I am trying to use haptic feedback in a Xamarin.Forms application to inform the user of selection changes.我正在尝试在 Xamarin.Forms 应用程序中使用触觉反馈来通知用户选择更改。 I found references to iOS and made a dependency service for iOS;找到iOS的引用,做了iOS的依赖服务; however, it always crashes without any C# error.但是,它总是在没有任何 C# 错误的情况下崩溃。 I've tried invoking it on the main thread and the thread I'm using.我试过在主线程和我正在使用的线程上调用它。 It even crashes in a try/catch block.它甚至在 try/catch 块中崩溃。 Here is my code:这是我的代码:

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

If anyone has any experience using haptic feedback in Xamarin.Forms it would help a lot.如果有人在 Xamarin.Forms 中有任何使用触觉反馈的经验,那将会有很大帮助。

You need to place an exception catch-point and see exactly where the crash happens.您需要放置一个异常捕获点并准确查看崩溃发生的位置。 You have placed all your code and it's difficult to figure out where you messed up.您已经放置了所有代码,很难找出哪里搞砸了。 It could just be in something unrelated.它可能只是一些不相关的东西。 You should also share your application out put that will display what the exception is.您还应该共享将显示异常情况的应用程序输出。

Here's an example of the Haptic implementation by ElysiumLab.com, they also have a Nuget package that possibly has it implemented for use " Naylah ":这是 ElysiumLab.com 的Haptic实现示例,他们还有一个 Nuget package 可能已实现以供使用“ Naylah ”:

In your core/forms project在您的核心/表单项目中

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 Implementation 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();
    }
}

Btw, you can also create an Android implementation for the Haptic Feedback like this:顺便说一句,您还可以像这样为触觉反馈创建一个 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;
        }
    }
}

You can check out the detailed code here , but if you are just looking for an iOS implementation you can see here .您可以在此处查看详细代码,但如果您只是在寻找 iOS 实现,则可以在此处查看

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Xamarin.Forms依赖服务UWP:methodNotFoundException - Xamarin.Forms Dependency Service UWP: methodNotFoundException Xamarin.Forms:Android<entry> 和依赖服务?</entry> - Xamarin.Forms: Android <Entry> and dependency service? 如果调用方未使用 Xamarin.Forms,Xamarin 依赖项服务是否可以工作? - Can the Xamarin Dependency service work if the caller is not using Xamarin.Forms? 使用依赖关系服务从Xamarin.Forms应用发送电子邮件 - Send email from Xamarin.Forms app using Dependency Service C#-Xamarin.Forms-依赖服务和事件 - C# - Xamarin.Forms - Dependency Service and event Xamarin.Forms依赖关系服务非静态字段/属性 - Xamarin.Forms Dependency Service non-static fields/properties Xamarin.Forms从iOS连接到Wcf服务 - Xamarin.Forms Connection to Wcf Service from iOS Microsoft.AppCenter.Crashes 未检测到 Xamarin.Forms iOS 项目上的崩溃 - Microsoft.AppCenter.Crashes not detecting crashes on Xamarin.Forms iOS project Xamarin.Forms Android应用程序启动时崩溃 - Xamarin.Forms Android Application crashes on startup Xamarin.Forms iOS 项目在启用链接和 Auth0.OidcClient 和 SfListViewRenderer 的情况下启动时崩溃 - Xamarin.Forms iOS Project Crashes On Startup With Linking Enabled And Auth0.OidcClient And SfListViewRenderer Enabled
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM