Preparing your app for VoiceOver: MagicTap
Discover MagicTap and how to easily support it in both SwiftUI and UIKit.
In Preparing your App for VoiceOver: Accessibility Actions, we discussed how to execute actions within our app for users relying on assistive technology.
There are different kinds of accessibility actions available, one of them called MagicTap.
MagicTap is a useful feature for VoiceOver users that allows you to perform the primary action of a view by double-tapping with two fingers anywhere on the app screen. This feature is widely available in Apple apps. For example, while using the Phone app, you can answer and end calls, in the Clock app, you can start and stop timers, in the Music app, you can start and stop playback, and in the Camera app, you can take a picture without having to go through the app's interface.
Despite its utility, MagicTap is rarely implemented in third-party apps. We are going to demonstrate how to easily add MagicTap support in both SwiftUI and UIKit.
SwiftUI
In SwiftUI, implementing MagicTap is straightforward. Use the accessibilityAction(_:_:)
modifier passing the .magicTap
as action kind and providing a closure to handle the action.
import SwiftUI
struct ContentView: View {
var body: some View {
VStack {
Text("Hello Accessibility")
.accessibilityAction(.magicTap){
print("MagicTap action performed")
}
}
.padding()
}
}
UIKit
To integrate MagicTap into your UIKit
app, override the accessibilityPerformMagicTap()
method within your controller class and define the desired action.
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var label: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
label.text = "Hello Accessibility"
}
override func accessibilityPerformMagicTap() -> Bool {
print("MagicTap action performed")
return true
}
}
To handle Magic Tap gestures from anywhere in your app, implement the accessibilityPerformMagicTap()
method in the AppDelegate.
import UIKit
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
return true
}
// MARK: UISceneSession Lifecycle
func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
}
func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) {
// ...
}
override func accessibilityPerformMagicTap() -> Bool {
print("MagicTap action performed")
return true
}
}
Conclusion
MagicTap should be used to perform the primary function of your app. This feature allows users to execute actions independently of the selected accessibility element. It is easy to implement and provides an additional accessibility option for your users.