Add vibrations in a Xamarin.iOS app
Long time ago I've worked on adding Haptic Feedback, aka. vibrations on a Xamarin.Native app. Here is how it works for iOS :
I've isolated these 7 different types of Haptic Feedback available in the iOS SDK :
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
}
In iOS SDK, to use a Feedback Generator you need to :
- Instantiate the Generator
- Prepare the Generator (optional)
- Trigger Feedback
- Release the Generator (optional).
Instantiate the Generator
private UIImpactFeedbackGenerator _impactHeavyFeedbackGenerator;
private UIImpactFeedbackGenerator _impactMediumFeedbackGenerator;
private UIImpactFeedbackGenerator _impactLightFeedbackGenerator;
private UISelectionFeedbackGenerator _selectionFeedbackGenerator;
private UINotificationFeedbackGenerator _notificationFeedbackGenerator;
public HapticFeedbackHelperIOS()
{
_impactHeavyFeedbackGenerator = new UIImpactFeedbackGenerator(UIImpactFeedbackStyle.Heavy);
_impactMediumFeedbackGenerator = new UIImpactFeedbackGenerator(UIImpactFeedbackStyle.Medium);
_impactLightFeedbackGenerator = new UIImpactFeedbackGenerator(UIImpactFeedbackStyle.Light);
_selectionFeedbackGenerator = new UISelectionFeedbackGenerator();
_notificationFeedbackGenerator = new UINotificationFeedbackGenerator();
}
Prepare the Generator (optional)
This step is optional. This step exists because the phone may need half a second to prepare the Haptic effect before triggering it. Without this step it might delay (a little) the triggering of a vibration.
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;
}
}
Trigger the feedback
public static 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;
}
}
Release the Generator (optional)
This is also optional. It will free the memory of the unused Generators.
public void Dispose()
{
_impactHeavyFeedbackGenerator = null;
_impactMediumFeedbackGenerator = null;
_impactLightFeedbackGenerator = null;
_selectionFeedbackGenerator = null;
_notificationFeedbackGenerator = null;
}
All this packed in a nice Gist
Find the Gist here : https://gist.github.com/framinosona/489ea6e0bc04689b5d251eda30f6c220
To use HapticFeedbackHelperIOS
ImpactHeavyButton.TouchDown += (sender, e) => _hapticFeedbackHelperIOS.PrepareHapticFeedback(HapticFeedbackType.ImpactHeavy);
ImpactHeavyButton.TouchUpInside += (sender, e) => _hapticFeedbackHelperIOS.ExecuteHapticFeedback(HapticFeedbackType.ImpactHeavy);
ImpactMediumButton.TouchDown += (sender, e) => _hapticFeedbackHelperIOS.PrepareHapticFeedback(HapticFeedbackType.ImpactMedium);
ImpactMediumButton.TouchUpInside += (sender, e) => _hapticFeedbackHelperIOS.ExecuteHapticFeedback(HapticFeedbackType.ImpactMedium);
ImpactLightButton.TouchDown += (sender, e) => _hapticFeedbackHelperIOS.PrepareHapticFeedback(HapticFeedbackType.ImpactLight);
ImpactLightButton.TouchUpInside += (sender, e) => _hapticFeedbackHelperIOS.ExecuteHapticFeedback(HapticFeedbackType.ImpactLight);
SelectionButton.TouchDown += (sender, e) => _hapticFeedbackHelperIOS.PrepareHapticFeedback(HapticFeedbackType.Selection);
SelectionButton.TouchUpInside += (sender, e) => _hapticFeedbackHelperIOS.ExecuteHapticFeedback(HapticFeedbackType.Selection);
NotificationErrorButton.TouchDown += (sender, e) => _hapticFeedbackHelperIOS.PrepareHapticFeedback(HapticFeedbackType.NotificationError);
NotificationErrorButton.TouchUpInside += (sender, e) => _hapticFeedbackHelperIOS.ExecuteHapticFeedback(HapticFeedbackType.NotificationError);
NotificationWarningButton.TouchDown += (sender, e) => _hapticFeedbackHelperIOS.PrepareHapticFeedback(HapticFeedbackType.NotificationWarning);
NotificationWarningButton.TouchUpInside += (sender, e) => _hapticFeedbackHelperIOS.ExecuteHapticFeedback(HapticFeedbackType.NotificationWarning);
NotificationSuccessButton.TouchDown += (sender, e) => _hapticFeedbackHelperIOS.PrepareHapticFeedback(HapticFeedbackType.NotificationSuccess);
NotificationSuccessButton.TouchUpInside += (sender, e) => _hapticFeedbackHelperIOS.ExecuteHapticFeedback(HapticFeedbackType.NotificationSuccess);