WWDC Quick Look 💓 By SwiftGGTeam
What's new in Mac Catalyst

What's new in Mac Catalyst

Watch original video

Highlight

macOS Monterey brings four types of native Mac experiences to Mac Catalyst: four button modes (Push/Toggle/Pull-down/Pop-up), ToolTip hover prompts, print menu integration, and window subtitles, making iPad applications more like native applications on the Mac.

Core Content

Macization of button system

Mac users are accustomed to specific button interaction methods: Push Button to execute when pressed, Toggle Button to switch states, Pull-down Menu to expand the menu, and Pop-up Button to change the title after selection.iPad applications are moved directly to Mac, and the button behavior is often “wrong”.

macOS Monterey solves this problem through two properties:showsMenuAsPrimaryActionandchangesSelectionAsPrimaryAction.Four Boolean combinations correspond to four button types and only require a few lines of code.

Hover prompts fill information gaps

When Mac users see interface elements, they instinctively hover their mouse and wait for prompts.The iPad app doesn’t have this feature, leaving many of the controls to have to be guessed at.

UIToolTipInteractionEnable any UIView to display hover tips.UILabel also supportsshowsExpansionTextWhenTruncated, showing the full text on hover when truncated.

Printing is a fundamental feature of Mac apps.NewUIApplicationSupportsPrintCommandplist key automatically adds File > Print menu,printContentResponder methods handle printing logic.

Window subtitlescene.subtitleAdd contextual information to the window title bar, which is more in line with Mac habits than the navigation bar title.

Detailed Content

Four button configurations (02:26)

// Push Button — standard push button
let pushButton = UIButton(type: .system)

// Toggle Button — tap to toggle the selected state
let toggleButton = UIButton(type: .system)
toggleButton.changesSelectionAsPrimaryAction = true

// Pull-down Menu — click to expand the menu
let pullDownButton = UIButton(type: .system)
pullDownButton.menu = UIMenu()
pullDownButton.showsMenuAsPrimaryAction = true

// Pop-up Button — the button title changes after selection
let popupButton = UIButton(type: .system)
popupButton.menu = UIMenu()
popupButton.showsMenuAsPrimaryAction = true
popupButton.changesSelectionAsPrimaryAction = true

Key points:

  • showsMenuAsPrimaryAction = true: Left-click to directly expand the menu (Mac habit), no longer relying on long press or right-click
  • changesSelectionAsPrimaryAction = true:Button title automatically tracks the selected item in the menu
  • Four combinations cover all standard button types on Mac
  • When using Mac idiom, the button without menu configuration can be triggered by long pressing; for iPad idiom, the menu can be triggered by right-clicking.

Add ToolTip to the control (03:50)

// Approach 1: Add a ToolTip to any UIView
let toolTipInteraction = UIToolTipInteraction(defaultToolTip: "Iguaçu Falls in Brazil")
imageView.addInteraction(toolTipInteraction)

// Approach 2: Quickly set a ToolTip on a UIControl
let switchControl = UISwitch()
switchControl.toolTip = "Enable automatic updates"

// Approach 3: Show the full text when hovering over a truncated label
let label = UILabel()
label.text = "Very long title that will be truncated"
label.showsExpansionTextWhenTruncated = true

Key points:

  • UIToolTipInteractionApplicable to any UIView, need to create interaction object
  • UIControltoolTipProperties are shortcuts, just one line of code
  • showsExpansionTextWhenTruncatedOnly display ToolTip when text is truncated, keeping the interface clean

Window subtitle (06:01)

// Set the subtitle when the scene connects
func scene(_ scene: UIScene, willConnectTo session: UISceneSession,
           options connectionOptions: UIScene.ConnectionOptions) {
    scene.subtitle = "Countries"
}

// Or update it dynamically based on navigation
func updateSubtitle(for selection: String) {
    guard let scene = view.window?.windowScene else { return }
    scene.subtitle = selection
}

Key points:

  • The subtitle is displayed in the window title bar, which is more in line with Mac design specifications than the navigation bar title
  • differenttoolbarStyleThe display position of the lower subtitle is different and needs experimental adjustment.
  • Suitable for displaying the currently selected item or application status context

Printing support (04:52)

First add in Info.plist:

<key>UIApplicationSupportsPrintCommand</key>
<true/>

The printing is then handled via the responder chain:

// DetailViewController.swift
override func printContent(_ sender: Any?) {
    let printInteractionController = UIPrintInteractionController.shared
    // Configure the print content
    printInteractionController.present(animated: true)
}

override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
    if action == #selector(self.printContent(_:)) {
        // Allow printing only when content is currently selected
        return selectedItem != nil
    }
    return super.canPerformAction(action, withSender: sender)
}

// Centralized dispatch in the root SplitViewController
override func target(forAction action: Selector, withSender sender: Any?) -> Any? {
    switch action {
    case #selector(UIResponder.printContent(_:)):
        // Decide which child controller handles printing based on business logic
        return currentPrintTarget
    default:
        return super.target(forAction: action, withSender: sender)
    }
}

Key points:

  • UIApplicationSupportsPrintCommandAutomatically add File > Print and Export as PDF menu items
  • printContentIs a new action of UIResponder, implemented through responder chain lookup
  • canPerformActionControl whether printing is allowed in the current state
  • target(forAction:withSender:)Unified scheduling in the root controller to avoid forcingbecomeFirstResponder

Keep iPad button style (07:34)

Mac idiom uses native Mac controls by default, but sometimes you need to maintain iPad-style buttons (such as large-area fill buttons):

let button = UIButton(configuration: .filled(), primaryAction: nil)
button.configuration?.image = UIImage(systemName: "leaf")
button.preferredBehavioralStyle = .pad
button.configuration?.preferredSymbolConfigurationForImage =
    UIImage.SymbolConfiguration(pointSize: 60)
button.changesSelectionAsPrimaryAction = true
button.configurationUpdateHandler = colorUpdateHandler

Key points:

  • preferredBehavioralStyle = .padForce iPad layout behavior so button background stretches to fill
  • Only used on specific controls, not recommended for global use
  • Unlike Mac idiom’s 77% scaling rule, iPad styles maintain original size

Core Takeaways

  1. What to do: Add Mac Catalyst support to the existing iPad note-taking app and use ToolTip to demonstrate toolbar button functionality
  • Why it’s worth it: Mac users rely on hover tips to understand the interface, and adding ToolTip makes the app instantly more like a native Mac app.
  • How ​​to get started: Settings for each toolbar buttontoolTipProperty, enabled for truncated document titlesshowsExpansionTextWhenTruncated
  1. What to do: Add a printing function to the Mac version of the file management application to support printing the currently selected file list
  • Why it’s worth it: Printing is a basic expectation for Mac users,UIApplicationSupportsPrintCommandOne line of plist configuration can add a standard menu
  • How ​​to start: Add plist key and implement it in file list controllerprintContentandcanPerformAction
  1. What to do: Use a Pop-up Button for the Mac version of the Settings app instead of the original Segmented Control
  • Why it’s worth doing: Pop-up Button is a standard Mac control, which is more space-saving and user-friendly than Segmented Control.
  • How ​​to start: UseUIButton + changesSelectionAsPrimaryAction = true + showsMenuAsPrimaryAction = trueCreate Pop-up Button
  1. What to do: Show current path using window subtitle in Mac browser/file manager
  • Why it’s worth doing: The subtitle is more in line with Mac design specifications than the navigation bar title and does not take up space in the content area.
  • How ​​to start: InUISceneDelegateMedium settingsscene.subtitle, updated when navigation changes

Comments

GitHub Issues · utterances