Mouse Interaction with UIPointerInteraction
Apple released iPadOS 13.4 on March 24th which introduced mouse and trackpad support for the iPad. This means if you connect a bluetooth or USB pointer device to your iPad you have a completly new way to interact with it.
Apple decided not to show a classic cursor. Instead, they reinvented the cursor for the iPad. Instead you will see a circle that, if it gets near a UIBarButtons
,UISegementedControl
or UITabBarItem
, snaps automatically to this element and focuses it. In addition to this, you will get a nice highlight effect. This means a lot of elements of app are working out of the box without an app update.
UIButton
Apple added new APIs to add this effect to more UI elements than are supported out of the box. For an UIButton you only have to set a property and you will get the same effect.
aButton.isPointerInteractionEnabled = true
UIView and Custom Implementation
It is also possible to add an effect to a UIView
or a custom pointer style for an UIButton
. The implementation requires only need a few lines of code:
Add the Delegate protocol to your class
class MyViewController, UIPointerInteractionDelegate
Attach the UIPointerInteraction
to the view, which should get you a mouseover effect. This should be done in viewDidLoad
of your view controller or in the init
method of the view.
if #available(iOS 13.4, *) { customPointerInteraction(on: myButton, pointerInteractionDelegate: self) }
Last but not least add this block to your class. It includes the function for adding the pointer interaction to the view and the delegate method for the UIPointerInteraction
which sets the preferred pointer style. There are different pointer effects available, highlight
, hover
, lift
and automatic
.
// MARK: - UIPointerInteractionDelegate @available(iOS 13.4, *) func customPointerInteraction(on view: UIView, pointerInteractionDelegate: UIPointerInteractionDelegate){ let pointerInteraction = UIPointerInteraction(delegate: pointerInteractionDelegate) view.addInteraction(pointerInteraction) } @available(iOS 13.4, *) func pointerInteraction(_ interaction: UIPointerInteraction, styleFor region: UIPointerRegion) -> UIPointerStyle { var pointerStyle: UIPointerStyle? if let interactionView = interaction.view { let targetedPreview = UITargetedPreview(view: interactionView) pointerStyle = UIPointerStyle(effect: UIPointerEffect.highlight(targetedPreview)) } return pointerStyle }
That’s all!
Hover Effect
If you want to give your table views, rows and collection view cells a hover effect, you can use the same implementation as above, but set the interaction to your UITableViewCell
or UICollectionViewCell
and use UIPointerStyle
with hover effect.
UIPointerStyle(effect: UIPointerEffect.hover(targetedPreview, preferredTintMode: .overlay, prefersShadow: true, prefersScaledContent: true))
The pointer style will be set as mentioned above in the delegate method func pointerInteraction(_ interaction: UIPointerInteraction, styleFor region: UIPointerRegion) -> UIPointerStyle?
.
Custom Pointer Shape
You can also change the shape of the pointer and implement a custom pointer style for when hovering on a UI element by setting an bezier path:
@available(iOS 13.4, *) func pointerInteraction(_ interaction: UIPointerInteraction, styleFor region: UIPointerRegion) -> UIPointerStyle? { let shape = UIBezierPath() shape.move(to: CGPoint(x: 10, y: 6)) shape.addLine(to: CGPoint(x: 10, y: 0)) shape.addLine(to: CGPoint(x: 6, y: 0)) shape.addLine(to: CGPoint(x: 6, y: 6)) shape.addLine(to: CGPoint(x: 0, y: 6)) shape.addLine(to: CGPoint(x: 0, y: 10)) shape.addLine(to: CGPoint(x: 6, y: 10)) shape.addLine(to: CGPoint(x: 6, y: 16)) shape.addLine(to: CGPoint(x: 10, y: 16)) shape.addLine(to: CGPoint(x: 10, y: 10)) shape.addLine(to: CGPoint(x: 16, y: 10)) shape.addLine(to: CGPoint(x: 16, y: 6)) shape.addLine(to: CGPoint(x: 10, y: 6)) shape.close() let pointerShape = UIPointerShape.path(shape) return UIPointerStyle(shape: pointerShape) }
This code sample gives you a crosshair pointer shape:
Conclusion
As of iPadOS 13.4, developers can upgrade their apps to support pointing devices on the iPad and create a user experience that rivals that of desktop apps.
We at ownCloud already implemented UIPointerInteraction
in our iOS app. The new version will be availabe soon on the AppStore. Do you want to test it right now? Join our TestFlight beta!
The ownCloud iOS app is open source and the code for UIPointerInteraction
implementation can be found in this branch of our repository on GitHub: feature/ipad-pointerinteraction
The complete documentation by Apple is available here: Apple Developer Documentation > UIKit > Pointer Interactions