【发布时间】:2020-08-08 07:21:04
【问题描述】:
我正在尝试在 Xamarin.Forms 应用程序中使用触觉反馈来通知用户选择更改。我找到了对 iOS 的引用,并为 iOS 做了一个依赖服务;但是,它总是在没有任何 C# 错误的情况下崩溃。我试过在主线程和我正在使用的线程上调用它。它甚至在 try/catch 块中崩溃。这是我的代码:
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 中使用触觉反馈有任何经验,那将会很有帮助。
【问题讨论】:
-
Xamarin Essentials 有一个振动库,可以满足您的需求。如果没有,您需要首先确定导致崩溃的行。
-
振动不起作用,因为它太强大了。触觉反馈是在选择器中使用的。它非常温和,并且有不同类型的振动。每当用户在图表上滑动手指或需要对某种次要事件的反馈时,都会调用它。振动适用于主要的事情,例如电话等
标签: c# ios xamarin xamarin.forms xamarin.ios