Dunfey · Hotel WWDC as data, est. 1983
Front desk everything
Years
Topics

2021 SwiftUI & UI Frameworks

WWDC21 · 20 min · SwiftUI & UI Frameworks

Focus on iPad keyboard navigation

Improve the keyboard experience in your iPad and Mac Catalyst app. Discover how you can accelerate access to key features with the hardware keyboard, and navigate through your views and view controllers. Learn how to customize which elements are keyboard navigable, as well as how to customize the tab loop.

Watch at developer.apple.com ↗

Transcript all transcripts

Code shown on screen · 15 snippets

canBecomeFocused swift · at 3:01 ↗
override var canBecomeFocused: Bool { true }
allowsFocus swift · at 4:00 ↗
class MyViewController: UICollectionViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        self.collectionView.allowsFocus = true
    }
}
canFocusItemAtIndexPath swift · at 4:23 ↗
class MyCollectionViewDelegate: NSObject, UICollectionViewDelegate {
    func collectionView(_ collectionView: UICollectionView,
                canFocusItemAt indexPath: IndexPath) -> Bool {
        return true
    }
}
UIFocusDebugger checkFocusability(for:) bash · at 4:40 ↗
po UIFocusDebugger.checkFocusability(for:)
UIFocusHaloEffect swift · at 5:48 ↗
let focusEffect = UIFocusHaloEffect(roundedRect: self.bounds, cornerRadius: self.layer.cornerRadius, curve: .continuous)
self.focusEffect = focusEffect
ReferenceView and ContainerView swift · at 6:03 ↗
let focusEffect = UIFocusHaloEffect(roundedRect: self.bounds, cornerRadius: self.layer.cornerRadius, curve: .continuous)

// make sure the effect is added right above the image view
focusEffect.referenceView = self.imageView

// make sure the effect is added to our scroll view
focusEffect.containerView = self.scrollView

self.focusEffect = focusEffect
Custom focus effects swift · at 7:43 ↗
init(frame: CGRect) {
   super.init(frame: frame)
   self.focusEffect = nil
}

func didUpdateFocus(in context: UIFocusUpdateContext, withAnimationCoordinator coordinator: UIFocusAnimationCoordinator) {
    if context.nextFocusedItem == self {
        // This view is focused. Customize its appearance.
    }
    else if context.previouslyFocusedItem == self {
        // This view was focused.
    }
}
Selection Follows Focus swift · at 9:08 ↗
var selectionFollowsFocus: Bool
Selection Follows Focus for Item at Index Path swift · at 9:16 ↗
func collectionView(_ collectionView: UICollectionView, selectionFollowsFocusForItemAt indexPath: IndexPath) -> Bool {
    return self.action(for: indexPath).type != .showAlert
}
Focus Group Identifier swift · at 12:12 ↗
self.focusGroupIdentifier = "com.myapp.groups.sidebar"
UIFocusGroupPriority swift · at 12:52 ↗
extension UIFocusGroupPriority {
    public static let ignored: UIFocusGroupPriority // 0
    public static let previouslyFocused: UIFocusGroupPriority // 1000
    public static let prioritized: UIFocusGroupPriority // 2000
    public static let currentlyFocused: UIFocusGroupPriority // NSIntegerMax
}
Focus Group Priority on a cell swift · at 13:40 ↗
// Customizing an item’s focus group priority

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = ...
    if self.isCallToActionCell(at: indexPath) {
        // This cell is not as important as a selected cell but should
        // be chosen over the last focused cell in this group.
        cell.focusGroupPriority = .previouslyFocused + 10
    }
    return cell
}
UIFocusDebugger checkFocusGroupTree(for:) bash · at 15:46 ↗
po UIFocusDebugger.checkFocusGroupTree(for:)
wantsPriorityOverSystemBehavior swift · at 19:16 ↗
keyCommand.wantsPriorityOverSystemBehavior = true
pressesBegan swift · at 19:36 ↗
override func pressesBegan(_ presses: Set<UIPress>, with event: UIPressesEvent?) {
    if (/* check presses of interest */) {
        // handle the press
    }
    else {
        super.pressesBegan(presses, with: event)
    }
}

Resources