View in English

  • Apple Developer
    • 今すぐ始める

    「今すぐ始める」を詳しく見る

    • 概要
    • 学ぶ
    • Apple Developer Program

    最新情報

    • 最新ニュース
    • Hello Developer
    • プラットフォーム

    プラットフォームを詳しく見る

    • Appleプラットフォーム
    • iOS
    • iPadOS
    • macOS
    • tvOS
    • visionOS
    • watchOS
    • App Store

    特集

    • デザイン
    • 配信
    • ゲーム
    • アクセサリ
    • Web
    • Home
    • CarPlay
    • テクノロジー

    テクノロジーを詳しく見る

    • 概要
    • Xcode
    • Swift
    • SwiftUI

    特集

    • アクセシビリティ
    • App Intent
    • Apple Intelligence
    • ゲーム
    • 機械学習とAI
    • セキュリティ
    • Xcode Cloud
    • コミュニティ

    コミュニティを詳しく見る

    • 概要
    • 「Appleに相談」イベント
    • コミュニティによるイベント
    • デベロッパフォーラム
    • オープンソース

    特集

    • WWDC
    • Swift Student Challenge
    • デベロッパストーリー
    • App Store Awards
    • Apple Design Awards
    • Apple Developer Center
    • ドキュメント

    ドキュメントを詳しく見る

    • ドキュメントライブラリ
    • テクノロジー概要
    • サンプルコード
    • ヒューマンインターフェイスガイドライン
    • ビデオ

    リリースノート

    • 注目のアップデート
    • iOS
    • iPadOS
    • macOS
    • watchOS
    • visionOS
    • tvOS
    • Xcode
    • ダウンロード

    ダウンロードを詳しく見る

    • すべてのダウンロード
    • オペレーティングシステム
    • アプリ
    • デザインリソース

    特集

    • Xcode
    • TestFlight
    • フォント
    • SF Symbols
    • Icon Composer
    • サポート

    サポートを詳しく見る

    • 概要
    • ヘルプガイド
    • デベロッパフォーラム
    • フィードバックアシスタント
    • お問い合わせ

    特集

    • アカウントヘルプ
    • App Reviewガイドライン
    • App Store Connectヘルプ
    • 近日導入予定の要件
    • 契約およびガイドライン
    • システムステータス
  • クイックリンク

    • イベント
    • ニュース
    • Forum
    • サンプルコード
    • ビデオ
 

ビデオ

メニューを開く メニューを閉じる
  • コレクション
  • すべてのビデオ
  • 利用方法

その他のビデオ

  • 概要
  • Summary
  • コード
  • AppKitアプリのモダナイズ

    AppKitアプリを、macOSにおける最新のプラクティスに合わせてモダナイズしましょう。コントロールイベントやジェスチャリコグナイザによる入力の処理を、従来のトラッキングループより進化した方法で実行する方法を解説します。アプリのキーボードナビゲーションの強化、再起動後のグレースフルな状態復元の実装や、インターフェイスをmacOSのデザインとシームレスに調和させる、コーナー同心性に関する新しいAPIの活用方法も紹介します。

    関連する章

    • 0:00 - Introduction
    • 1:06 - Modern input
    • 1:27 - Modern event handling with gesture recognizers
    • 2:25 - Selection, context menus, and drag and drop
    • 3:52 - Text selection in custom views
    • 4:26 - Control events and gesture recognizers
    • 5:51 - Keyboard navigation and status items
    • 8:57 - Continuity across launches
    • 9:08 - Graceful app termination
    • 9:55 - State restoration
    • 14:09 - Design updates
    • 14:24 - Liquid Glass updates in macOS 27
    • 15:41 - Concentricity
    • 16:59 - Next steps

    リソース

    • Use SwiftUI with AppKit
    • Restoring your app’s state with AppKit
    • Gestures
    • TN3212: Adopting gesture recognizers for Sidecar touch support
    • NSControl.Events
      • HDビデオ
      • SDビデオ

    関連ビデオ

    WWDC26

    • SwiftUIとUIKitおよびAppKitの併用
  • このビデオを検索
    • 3:35 - Modern dragging delegate

      // Modern dragging delegate methods
      func tableView(_ tableView: NSTableView,
              pasteboardWriterForRow row: Int) -> (any NSPasteboardWriting)? {
          let pasteboardItem = NSPasteboardItem()
          pasteboardItem.setString(..., forType: .string)
          return pasteboardItem
      }
    • 4:55 - Control events

      // Use control events
      let button = NSButton()
      button.addTarget(
          self,
          action: #selector(trackingEndedOutsideHandler),
          for: .trackingEndedOutside
      )
    • 5:44 - hitTest override

      override func hitTest(_ point: NSPoint) -> NSView? {
          return nil
      }
    • 6:24 - autorecalculatesKeyViewLoop

      window.autorecalculatesKeyViewLoop = true
    • 7:37 - Expanded interface delegate — setup

      // Set the expanded interface delegate
      @main class LightAppDelegate: NSObject, NSApplicationDelegate {
          lazy var lightStatusItem: NSStatusItem = { ... }()
      
          func applicationDidFinishLaunching(_ notification: Notification) {
              // ...
              lightStatusItem.expandedInterfaceDelegate = self
          }
      }
    • 7:52 - Expanded interface delegate — methods

      // Implement the delegate methods
      extension LightAppDelegate: NSStatusItemExpandedInterfaceDelegate {
          // ...
          func statusItem(_ statusItem: NSStatusItem, didBegin session:
                          NSStatusItemExpandedInterfaceSession) {
              // Show window
          }
          func statusItemDidEndExpandedInterfaceSession(
              _ statusItem: NSStatusItem, animated: Bool) {
              // Hide window
          }
          func selectedAction() {
              // Take the action
              // Cancel session to request window dismissal
              lightStatusItem.expandedInterfaceSession?.cancel()
          }
      }
    • 8:16 - Expanded interface delegate — cancel

      // Cancel the session when dismissing
      extension LightAppDelegate: NSStatusItemExpandedInterfaceDelegate {
          // ...
          func statusItem(_ statusItem: NSStatusItem, didBegin session:
                          NSStatusItemExpandedInterfaceSession) {
              // Show window
          }
          func statusItemDidEndExpandedInterfaceSession(
              _ statusItem: NSStatusItem, animated: Bool) {
              // Hide window
          }
          func selectedAction() {
              // Take the action
              // Cancel session to request window dismissal
              lightStatusItem.expandedInterfaceSession?.cancel()
          }
      }
    • 9:45 - preventsApplicationTerminationWhenModal

      window.preventsApplicationTerminationWhenModal = false
    • 10:18 - Set window identifiers for state restoration

      // Set window identifiers for state restoration
      @MainActor class MainWindowController: NSWindowController, NSWindowDelegate {
          // ...
          convenience init() {
              let window = NSWindow( ... )
              // ...
              window.identifier = NSUserInterfaceItemIdentifier(WindowIdentifiers.mainWindow)
              window.setFrameAutosaveName(WindowIdentifiers.mainWindow)
              window.isRestorable = true
              window.restorationClass = WindowRestorationHandler.self
              // ...
          }
      }
    • 11:04 - encodeRestorableState

      // Preserve state to recreate the UI
      @MainActor class MainWindowController: NSWindowController, NSWindowDelegate {
          // ...
          override func encodeRestorableState(with coder: NSCoder) {
              super.encodeRestorableState(with: coder)
              // ...
              coder.encode(selectedProduct?.identifier.uuid,
                          forKey: RestorationKeys.productIdentifier)
              // ...
          }
          // ...
      }
    • 11:50 - invalidateRestorableState

      // Invalidate restorable state when the view hierarchy changes
      @MainActor class MainWindowController: NSWindowController, NSWindowDelegate {
          // ...
          convenience init() {
              // ...
              splitViewController.onProductSelected = { [weak self] product in
                  self?.invalidateRestorableState()
              }
          }
      }
    • 12:26 - restoreWindow(withIdentifier:)

      // Restore windows
      class WindowRestorationHandler: NSObject, NSWindowRestoration {
          static func restoreWindow(
              withIdentifier identifier: NSUserInterfaceItemIdentifier,
              state: NSCoder,
              completionHandler: @escaping (NSWindow?, Error?) -> Void
          ) {
              //...
              if identifier == .mainWindow, let window = appDelegate.mainWindowController?.window {
                  completionHandler(window, nil)
              } else if identifier == .imageWindow {
                  let controller = ImageWindowController()
                  appDelegate.imageWindowControllers.append(controller)
                  completionHandler(controller.window, nil)
              } else {
                  completionHandler(nil, error)
              }
          }
      }
    • 13:29 - restoreState

      // Restore window UI
      @MainActor class MainWindowController: NSWindowController, NSWindowDelegate {
          //...
          override func restoreState(with coder: NSCoder) {
              super.restoreState(with: coder)
              if let productId = coder.decodeObject(
                  of: [NSString.self],
                  forKey: RestorationKeys.productIdentifier) as? String {
                  splitViewController?.selectedProductId = productId
              }
              //...
          }
      }
    • 16:11 - cornerConfiguration

      // Subclass NSView to override cornerConfiguration
      class LocalWeatherView: NSView {
          // ...
          override var cornerConfiguration: NSViewCornerConfiguration? {
              let radius: NSViewCornerRadius = .containerConcentric(minimumCornerRadius)
              return .uniformCorners(radius: radius)
          }
          // ...
      }
    • 0:00 - Introduction
    • A modern app takes advantage of how AppKit interfaces with Mac so that its form and function feel in harmony with the rest of the system. That harmony shows up in precision input, continuity across launches, and look and feel.

    • 1:06 - Modern input
    • Precision input devices have been at the heart of the Mac since the very beginning. Learn modern APIs for handling mouse events, keyboard navigation, and status items.

    • 1:27 - Modern event handling with gesture recognizers
    • Gesture recognizers are the modern way to handle mouse events in AppKit. mouseDown: overrides and tracking loops must be replaced with modern APIs.

    • 2:25 - Selection, context menus, and drag and drop
    • AppKit has dedicated view-based APIs for the most common mouseDown: use cases: observe selected on collection and table types for selection, use menuForEvent: or .menu for context menus, and use modern pasteboard delegate methods for drag and drop.

    • 3:52 - Text selection in custom views
    • NSTextSelectionManager brings classic macOS text selection behaviors to any view outside of NSTextView. Attach it to a view to get bidirectional selection, drag and drop, and toggling.

    • 4:26 - Control events and gesture recognizers
    • Control events let you react to user-driven tracking state changes on standard controls. For custom interactions, use NSGestureRecognizer.

    • 5:51 - Keyboard navigation and status items
    • Enable autorecalculatesKeyViewLoop on your window to keep Tab navigation correct as views change. For status items with custom UI, use the expanded interface session API so AppKit can manage keyboard focus correctly.

    • 8:57 - Continuity across launches
    • A great Mac app seamlessly quits and quickly restores. Learn how to handle graceful app termination and state restoration using NSWindowRestoration.

    • 9:08 - Graceful app termination
    • Apps should quit without blocking, especially during system reboots. Set preventsApplicationTerminationWhenModal to false on any sheet or modal that does not strictly require user intervention.

    • 9:55 - State restoration
    • Use NSWindowRestoration to save and recover your app's UI across launches, so it picks up exactly where people left off.

    • 14:09 - Design updates
    • There's one more area where your app and the Mac meet: the UI. Learn about Liquid Glass updates in macOS 27 and the new concentricity API.

    • 14:24 - Liquid Glass updates in macOS 27
    • Liquid Glass continues to evolve in macOS 27, and many updates apply automatically. Sidebars, scroll edge effects, and toolbar items all receive refinements, and a new interactive glass effect gives controls a physical sense of response when clicked.

    • 15:41 - Concentricity
    • The NSViewCornerConfiguration API lets views near a container's corners automatically match the container's corner radius using .containerConcentric, so views adapt to the shape of their container instead of feeling at odds with the rest of the window.

    • 16:59 - Next steps
    • Prioritize gesture recognizers and view-based APIs over mouseDown:, ensure your app is fully keyboard-navigable, make quit and relaunch feel seamless, and adopt concentricity in your view hierarchies.

Developer Footer

  • ビデオ
  • WWDC26
  • AppKitアプリのモダナイズ
  • メニューを開く メニューを閉じる
    • iOS
    • iPadOS
    • macOS
    • tvOS
    • visionOS
    • watchOS
    Open Menu Close Menu
    • Swift
    • SwiftUI
    • Swift Playground
    • TestFlight
    • Xcode
    • Xcode Cloud
    • SF Symbols
    メニューを開く メニューを閉じる
    • アクセシビリティ
    • アクセサリ
    • Apple Intelligence
    • App Extension
    • App Store
    • オーディオとビデオ(英語)
    • 拡張現実
    • デザイン
    • 配信
    • 教育
    • フォント(英語)
    • ゲーム
    • ヘルスケアとフィットネス
    • アプリ内課金
    • ローカリゼーション
    • マップと位置情報
    • 機械学習とAI
    • オープンソース(英語)
    • セキュリティ
    • SafariとWeb(英語)
    メニューを開く メニューを閉じる
    • 英語ドキュメント(完全版)
    • 日本語ドキュメント(一部トピック)
    • チュートリアル
    • ダウンロード
    • フォーラム(英語)
    • ビデオ
    Open Menu Close Menu
    • サポートドキュメント
    • お問い合わせ
    • バグ報告
    • システム状況(英語)
    メニューを開く メニューを閉じる
    • Apple Developer
    • App Store Connect
    • Certificates, IDs, & Profiles(英語)
    • フィードバックアシスタント
    メニューを開く メニューを閉じる
    • Apple Developer Program
    • Apple Developer Enterprise Program
    • App Store Small Business Program
    • MFi Program(英語)
    • Mini Apps Partner Program
    • News Partner Program(英語)
    • Video Partner Program(英語)
    • セキュリティ報奨金プログラム(英語)
    • Security Research Device Program(英語)
    Open Menu Close Menu
    • Appleに相談
    • Apple Developer Center
    • App Store Awards(英語)
    • Apple Design Awards
    • Apple Developer Academy(英語)
    • WWDC
    最新ニュースを読む。
    Apple Developerアプリを入手する。
    Copyright © 2026 Apple Inc. All rights reserved.
    利用規約 プライバシーポリシー 契約とガイドライン