Use multiple keys for shortcuts
On Android, you can use the dispatchKeyEvent) and onKeyUp) methods to activate shortcuts. Both methods give you a reference to a KeyEvent object. Use the isShiftPressed) or isCtrlPressed) method to make sure that shortcuts are not activated by accident.
kotlin
override fun onKeyUp(keyCode: Int, event: KeyEvent): Boolean {
return when (keyCode) {
KeyEvent.KEYCODE_F -> {
if (event.isCtrlPressed) {
find()
true
}
}
else -> super.onKeyUp(keyCode, event)
}
}
private fun find() {
// Logic
} In Jetpack Compose, you can use the onKeyEvent.onKeyEvent(kotlin.Function1)) modifier to activate shortcuts. This modifier gives you a reference to KeyEvent, which can be used to determine key presses.
Use the isShiftPressed.isShiftPressed()) or isCtrlPressed.isCtrlPressed()) properties to ensure that shortcuts are not activated by accident.
kotlin
Box(
modifier = Modifier
.onKeyEvent { event ->
when (event.type) {
KeyEventType.KeyUp -> {
if (event.key == Key.F && event.isCtrlPressed) {
// open find window
true
} else {
false
}
}
else -> false
}
}
) {
// Box content...
} On iOS, the pressesBegan and pressesEnded can be used to activate shortcuts. But, you should use UIKeyCommand to add keyboard shortcuts. By adding modifierFlags you can be sure that shortcuts are not activated by accident. An additional advantage is that UIKeyCommand-shortcuts are shown when long pressing the command key.
swift
let find = UIKeyCommand(
input: "f",
modifierFlags: .command,
action: #selector(findContent),
discoverabilityTitle: "Find"
)
override var keyCommands: [UIKeyCommand]? {
return [find]
}
@objc private func find() {
// Logic
} In SwiftUI, you can use the keyboardShortcut view modifier to define key combinations that activate specific buttons or toggles. By specifying modifier keys, you can prevent shortcuts from being accidentally activated.
swift
@State private var isShowingSearchModal = false
var body: some View {
VStack {
Button("Search") {
self.isShowingSearchModal = true
}
.keyboardShortcut("s", modifiers: .command)
if isShowingSearchModal {
SearchModalView(isShowing: $isShowingSearchModal)
}
}
} With Flutter, you can use the RawKeyboard listener to implement shortcuts in your app. The RawKeyboard listener yields a RawKeyUpEvent of a RawKeyDownEvent. The data attribute has a isModifierPressed() method that can be used to determine whether a modifier key has been pressed.
dart
RawKeyboard.instance.addListener((keyEvent) {
if (keyEvent is RawKeyUpEvent) {
if (keyEvent.logicalKey == LogicalKeyboardKey.keyF &&
keyEvent.data.isModifierPressed(ModifierKey.controlModifier)) {
find();
}
}
});
void find() {
// Logic
} React Native does not support binding custom key events for shortcuts. The package react-native-keyevent allows you to capture external keyboard keys. However, it only works on Android.
jsx
componentDidMount() {
KeyEvent.onKeyMultipleListener((keyEvent) => {
console.log(`onKeyMultiple keyCode: ${keyEvent.keyCode}`);
console.log(`Action: ${keyEvent.action}`);
console.log(`Characters: ${keyEvent.characters}`);
});
}
componentWillUnmount() {
KeyEvent.removeKeyMultipleListener();
} In MAUI, there is no cross platform way to achieve setting a keyboard shortcut. But, you can listen for keypresses by overriding the default MainActivity.KeyUp method for Android, and for iOS by setting up a UIKeyCommand inside the default AppDelegate.
Android implementation:
csharp
[Activity(
Theme = "@style/Maui.SplashTheme",
MainLauncher = true,
LaunchMode = LaunchMode.SingleTop,
ConfigurationChanges = ConfigChanges.ScreenSize |
ConfigChanges.Orientation |
ConfigChanges.UiMode |
ConfigChanges.ScreenLayout |
ConfigChanges.SmallestScreenSize |
ConfigChanges.Density
)]
public class MainActivity : MauiAppCompatActivity
{
public override bool OnKeyUp([GeneratedEnum] Keycode keyCode, KeyEvent? e)
{
if (keyCode == Keycode.F && e.IsCtrlPressed)
{
//Apply any logic
return true;
}
return base.OnKeyUp(keyCode, e);
}
} csharp
[Register("AppDelegate")]
public class AppDelegate : MauiUIApplicationDelegate
{
public UIKeyCommand FKeyCommand = UIKeyCommand.Create(
new NSString("f"),
UIKeyModifierFlags.Control,
new ObjCRuntime.Selector("Action:")
);
protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
public override UIKeyCommand[] KeyCommands
=> new[] { FKeyCommand };
[Export("Action:")]
private void Excute(UIKeyCommand keyCommand)
{
//Apply any logic
}
} Xamarin does not have support for hardware keyboard events. However, you can intercept key events inside the Android and iOS application.
- Android: hook into
onKeyUpinsideMainActivity.cs - iOS: hook into
KeyCommandsusing a custom renderer.
The code example below shows a sample implementation for iOS.
csharp
[assembly: ExportRenderer(typeof(ContentPage), typeof(KeyboardPageRenderer))]
namespace KeyCommandsInXamarinForms.iOS
{
public class KeyboardPageRenderer : PageRenderer
{
protected override void OnElementChanged(VisualElementChangedEventArgs e)
{
base.OnElementChanged(e);
if (e.OldElement != null || Element == null)
{
return;
}
// Create key command for Command + F
UIKeyCommand command1 = UIKeyCommand.Create(
new NSString("F"),
UIKeyModifierFlags.Command,
new ObjCRuntime.Selector("OnKeyPressed:")
);
this.AddKeyCommand(command1);
}
[Export("OnKeyPressed:")]
private void Excute(UIKeyCommand keyCommand)
{
// Find
}
public override bool CanBecomeFirstResponder
{
get
{
return true; // Key commands require first responder
}
}
}
} csharp
public override bool OnKeyUp([GeneratedEnum] Keycode keyCode, KeyEvent e)
{
if (keyCode == Keycode.KEYCODE_F && e.isCtrlPressed)
{
// Search
return true
}
return base.OnKeyUp(keyCode, e);
}