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

2022 SwiftUI & UI Frameworks

WWDC22 · 21 min · SwiftUI & UI Frameworks

Adopt desktop-class editing interactions

Discover advanced desktop-class editing features that can help people accelerate their productivity in your app. Learn how you can provide more interactions inline with your UI to help people quickly access editing features and make your iPadOS app feel right at home on macOS with Mac Catalyst. We’ll also explore the highly-customizable find interaction and learn how the system UI can help people consistently find content in your app.

Watch at developer.apple.com ↗

Transcript all transcripts

Code shown on screen · 7 snippets

Adding items into text edit menus swift · at 2:42 ↗
func textView(
    _ textView: UITextView, 
    editMenuForTextIn range: NSRange, 
    suggestedActions: [UIMenuElement]) -> UIMenu?
Adding actions into a text view's menu swift · at 4:03 ↗
func textView(
    _ textView: UITextView,
    editMenuForTextIn range: NSRange,
    suggestedActions: [UIMenuElement]
) -> UIMenu? {
    var additionalActions: [UIMenuElement] = []
    if range.length > 0 {
        let highlightAction = UIAction(title: "Highlight", ...)
        additionalActions.append(highlightAction)
    }
    let insertPhotoAction = UIAction(title: "Insert Photo", ...)
    additionalActions.append(insertPhotoAction)
    return UIMenu(children: suggestedActions + additionalActions)
}
Presenting an edit menu with a custom gesture swift · at 5:24 ↗
let editMenuInteraction = UIEditMenuInteraction(delegate: self)
view.addInteraction(editMenuInteraction)

let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector(didTap(_:)))
tapRecognizer.allowedTouchTypes = [UITouch.TouchType.direct.rawValue as NSNumber]
view.addGestureRecognizer(tapRecognizer)

@objc func didTap(_ recognizer: UITapGestureRecognizer) {
    let location = recognizer.location(in: self.view)
    if self.hasSelectedObjectView(at: location) {
        let configuration = UIEditMenuConfiguration(identifier: nil, sourcePoint: location)
        editMenuInteraction.presentEditMenu(with: configuration)
    }
}
Implementing UIEditMenuInteractionDelegate swift · at 7:13 ↗
func editMenuInteraction(
    _ interaction: UIEditMenuInteraction,
    targetRectFor configuration: UIEditMenuConfiguration
) -> CGRect {
    guard let selectedView = objectView(at: configuration.sourcePoint) else { return .null }
    return selectedView.frame
}

func editMenuInteraction(
    _ interaction: UIEditMenuInteraction,
    menuFor configuration: UIEditMenuConfiguration,
    suggestedActions: [UIMenuElement]
) -> UIMenu? {
    let duplicateAction = UIAction(title: "Duplicate") { ... }
    return UIMenu(children: suggestedActions + [duplicateAction])
}
Using the "keeps menu presented" attribute swift · at 10:34 ↗
UIAction(title: "Increase",
         image: UIImage(systemName: "increase.indent"),
         attributes: .keepsMenuPresented) { ... }

UIAction(title: "Decrease",
         image: UIImage(systemName: "decrease.indent"),
         attributes: .keepsMenuPresented) { ... }
Find with system views swift · at 12:46 ↗
open var findInteraction: UIFindInteraction? { get }
textView.isFindInteractionEnabled = true
Installing a UIFindInteraction on a custom view swift · at 17:22 ↗
let customDocument = MyDocument(string: "")
lazy var customView = MyTextView(document: customDocument)

lazy var findInteraction = UIFindInteraction(sessionDelegate: self)

override var canBecomeFirstResponder: Bool { true }

override func viewDidLoad() {
    customView.addInteraction(findInteraction)
}

func findInteraction(_ interaction: UIFindInteraction, sessionFor view: UIView) -> UIFindSession? {
    return UITextSearchingFindSession(searchableObject: customDocument)
}

Resources