iOS/macOS 2026 adds NSGestureRecognizerRepresentable, NSHostingMenu, and NSHostingSceneRepresentation, making it easier than ever to incrementally adopt SwiftUI inside existing AppKit apps without a full rewrite. Observable tracking in NSView draw methods is also enabled by default.
• New NSGestureRecognizerRepresentable protocol allows embedding custom NSGestureRecognizer subclasses in SwiftUI views
• New NSHostingMenu subclass of NSMenu wraps any SwiftUI view as a native menu
• New NSHostingSceneRepresentation enables adding SwiftUI scenes (e.g. MenuBarExtra) programmatically from an NSApplicationDelegate
• @Observable-driven automatic NSView redraw is now enabled by default (previously required Info.plist opt-in on macOS 15/iOS 18)
• NSGestureRecognizerRepresentable lets you attach existing NSGestureRecognizer subclasses directly to SwiftUI views using the familiar .gesture() modifier
• NSHostingMenu wraps a SwiftUI view as a native NSMenu so you can add SwiftUI-powered menu items (with keyboard shortcuts, pickers, animations) into your existing main menu
• NSHostingSceneRepresentation lets you dynamically add SwiftUI scenes (like MenuBarExtra) from your NSApplicationDelegate, enabling powerful new entry points without converting your app
Demonstrates NSGestureRecognizerRepresentable to attach a custom force-click recognizer to a SwiftUI view, and NSHostingMenu to add a SwiftUI-powered submenu with a keyboard shortcut to an existing AppKit main menu.
+import SwiftUIimport AppKit−// Pre-2026: No NSGestureRecognizerRepresentable — you had to subclass−// NSHostingView and add the gesture recognizer at the AppKit layer+// MARK: - Observable Model+@Observable+final class ColorModel {+ var hue: Double = 0.5+ var saturation: Double = 1.0+ var brightness: Double = 1.0−class ColorModel: NSObject {− @objc dynamic var hue: CGFloat = 0.5− @objc dynamic var saturation: CGFloat = 1.0− @objc dynamic var brightness: CGFloat = 1.0−func resetSaturationAndBrightness() {saturation = 1.0brightness = 1.0}}−// Wrapping SwiftUI in AppKit and bolting on the gesture externally−class ColorPickerHostingView: NSHostingView<AnyView> {− let model: ColorModel− private var pressRecognizer: NSPressGestureRecognizer!+// MARK: - NSGestureRecognizerRepresentable+struct ForceClickReset: NSGestureRecognizerRepresentable {+ var model: ColorModel− init(model: ColorModel) {− self.model = model− // Had to pass model via environment or binding workarounds− super.init(rootView: AnyView(Circle()− .fill(Color(hue: Double(model.hue),− saturation: Double(model.saturation),− brightness: Double(model.brightness)))− .frame(width: 200, height: 200)))− pressRecognizer = NSPressGestureRecognizer(− target: self, action: #selector(handleForceClick))− addGestureRecognizer(pressRecognizer)+ func makeNSGestureRecognizer(context: Context) -> NSPressGestureRecognizer {+ let recognizer = NSPressGestureRecognizer()+ recognizer.minimumPressDuration = 0+ recognizer.allowedTouchTypes = .direct+ // In a real app you'd use a custom ForceClickGestureRecognizer subclass here+ return recognizer}− required init(rootView: AnyView) { fatalError() }− required init?(coder: NSCoder) { fatalError() }+ func handleNSGestureRecognizerAction(+ _ recognizer: NSPressGestureRecognizer,+ context: Context+ ) {+ if recognizer.state == .began {+ withAnimation {+ model.resetSaturationAndBrightness()+ }+ }+ }+}− @objc private func handleForceClick(_ r: NSPressGestureRecognizer) {− if r.state == .began { model.resetSaturationAndBrightness() }+// MARK: - SwiftUI Color Menu View (used in NSHostingMenu)+struct ColorMenuView: View {+ var model: ColorModel++ var body: some View {+ Button("Reset Brightness & Saturation") {+ withAnimation {+ model.resetSaturationAndBrightness()+ }+ }+ .keyboardShortcut("r", modifiers: [.command, .shift])++ Picker("Preset Colors", selection: $model.hue) {+ Text("Red").tag(0.0)+ Text("Green").tag(0.33)+ Text("Blue").tag(0.66)+ }+ .pickerStyle(.palette)}}−// Pre-2026: No NSHostingMenu — had to build NSMenu items imperatively−func buildColorMenu(model: ColorModel) -> NSMenu {− let menu = NSMenu(title: "Color")− let item = NSMenuItem(title: "Reset Brightness & Saturation",− action: #selector(AppDelegate.resetColors),− keyEquivalent: "r")− item.keyEquivalentModifierMask = [.command, .shift]− menu.addItem(item)− return menu+// MARK: - AppDelegate wiring+class AppDelegate: NSObject, NSApplicationDelegate {+ let colorModel = ColorModel()++ func applicationDidFinishLaunching(_ notification: Notification) {+ // Build SwiftUI-powered submenu+ let hostingMenu = NSHostingMenu(rootView: ColorMenuView(model: colorModel))+ hostingMenu.title = "Color"++ let menuItem = NSMenuItem()+ menuItem.submenu = hostingMenu+ NSApp.mainMenu?.addItem(menuItem)+ }+}++// MARK: - SwiftUI View with gesture+struct HSBColorPicker: View {+ var model: ColorModel++ var body: some View {+ Circle()+ .fill(Color(hue: model.hue,+ saturation: model.saturation,+ brightness: model.brightness))+ .frame(width: 200, height: 200)+ .gesture(ForceClickReset(model: model))+ }}
Liquid Glass is Apple's new material and visual design language introduced in iOS 27, bringing translucent, refractive glass-like surfaces to system and custom UI elements. It replaces the frosted vibrancy aesthetic with a more dynamic, depth-aware material that responds to content beneath it.
PaperKit is Apple's full-featured canvas framework — previously internal-only — now publicly available in iOS/macOS/visionOS 27. It powers the drawing and markup experience in Notes, Preview, and Freeform, giving developers access to a complete pencil, shapes, images, and text canvas with a rich data model.
iOS 27 brings significant updates to Live Activities and the Dynamic Island, including new expanded presentations, richer interactivity via App Intents directly from the island, and updated layout APIs for more expressive minimal and compact views.
In-depth guide
SwiftUI & Liquid Glass in iOS 27 →• Observation tracking in NSView draw methods requires adding NSObservationTrackingEnabled to Info.plist for macOS 15/iOS 18 back-deployment; enabled by default on 2026 SDK and later
• NSHostingMenu, NSHostingSceneRepresentation, and NSGestureRecognizerRepresentable are AppKit-only (macOS); UIKit has UIGestureRecognizerRepresentable equivalent
• Force-click gesture via NSGestureRecognizerRepresentable only fires on trackpads that support pressure stages — always provide a keyboard shortcut fallback
None — runs on all supported Mac and iPhone/iPad hardware
iOS 27 enforces stricter adaptivity requirements for UIKit apps, making iPhone apps fully resizable in iPhone Mirroring and on iPad, while introducing new navigation bar minimization controls, sidebar opt-in for iPhone tab bars, and prominent tab customization.