用 .environment scene modifier 可設定特定 key path 的環境變數。
environment Scene Modifier 概覽
用 .environment scene modifier 可設定系統內建或我們自己客製的 EnvironmentValues 值。
@main
struct Example: App {
var body: some Scene {
WindowGroup {
ContentView()
}
.environment(
keyPath: WritableKeyPath<EnvironmentValues, V>,
value: V
)
}
}
舉個例子,如果我們要將一個 Scene 設成夜間模式,可以這樣寫:
@main
struct Example: App {
var body: some Scene {
WindowGroup {
ContentView()
}
.environment(\.colorScheme, .dark)
}
}
key path 會用「\.」來取得某個 EnvironmentValues,而第二個參數就是我們要設定的值。
設定好環境變數之後,我們就能在這個 Scene 底下的任何子 View 裡透過 @Environment 來拿到這個值:
struct ContentView: View {
@Environment(\.colorScheme) var colorScheme: ColorScheme
var body: some View { ... }
}
注意
不過也不是所有的 EnvironmentValues 都能被設定,有些只能讀,所以不是所有的環境變數都能用 .environment 設定值。
SwiftUI 的 EnvironmentValues 環境變數
SwiftUI 內建的環境變數有非常多,主要可以分成十二大類:無障礙 Accessibility、行為 Actions、驗證 Authentication、控制與輸入 Controls and Input、顯示特性 Display Characteristics、全域物件 Global Objects、滾動 Scrolling、狀態 State、StoreKit 設定 StoreKit Configuration、文字樣式 Text Styles、畫面屬性 View Attributes、桌面小工具 Widgets。
| Accessibility 無障礙 | 型別 | 說明 |
|---|---|---|
| accessibilityDimFlashingLights | Bool | 是否開啟「設定」→「輔助使用」→「動態效果」→「調暗閃爍燈光」 |
| accessibilityDifferentiateWithoutColor | Bool | 是否開啟「設定」→「輔助使用」→「顯示與文字大小」→「不以顏色來區分」 |
| accessibilityEnabled | Bool | 是否開啟任一輔助功能:旁白、切換控制、語音控制 |
| accessibilityInvertColors | Bool | 是否開啟任一「顏色反向」:智慧型、經典 |
| accessibilityLargeContentViewerEnabled | Bool | 是否使用更大的輔助字體大小 |
| accessibilityPlayAnimatedImages | Bool | 是否開啟「自動播放的動畫式影像」 |
| accessibilityPrefersHeadAnchorAlternative | Bool | 在 visionOS 中,是否傾向以頭部為錨點 |
| accessibilityQuickActionsEnabled | Bool | 是否開啟「快速動作」,如 watchOS 的手指捏兩下 |
| accessibilityReduceMotion | Bool | 是否開啟「減少動態效果」 |
| accessibilityReduceTransparency | Bool | 是否開啟「減少透明度」 |
| accessibilityShowButtonShapes | Bool | 是否開啟「設定」→「輔助使用」→「顯示與文字大小」→「按鈕形狀」 |
| accessibilitySwitchControlEnabled | Bool | 是否開啟「切換控制」 |
| accessibilityVoiceOverEnabled | Bool | 是否開啟「旁白」 |
| legibilityWeight | LegibilityWeight? | 是否開啟「設定」→「輔助使用」→「顯示與文字大小」→「粗體文字」 |
| Actions 行為 | 型別 | 說明 |
|---|---|---|
| dismiss | DismissAction | 可執行:關掉目前的 sheet 或 popover、Navigate 到上一頁、關閉視窗 |
| dismissSearch | DismissSearchAction | 結束搜尋。SwiftUI 會:把 isSearching 設成 false、清空搜尋框、移除搜尋框的 focus |
| dismissWindow | DismissWindowAction | 關閉視窗 |
| openImmersiveSpace | OpenImmersiveSpaceAction | 開啟一個 visionOS 的 ImmersiveSpace |
| dismissImmersiveSpace | DismissImmersiveSpaceAction | 關閉 visionOS 的 ImmersiveSpace |
| newDocument | NewDocumentAction | 新增檔案 |
| openDocument | OpenDocumentAction | 打開檔案 |
| openURL | OpenURLAction | 打開 URL(可以是 App DeepLink 或以瀏覽器開網頁) |
| openWindow | OpenWindowAction | 開啟指定視窗 |
| purchase | PurchaseAction | 執行 App 內購 |
| refresh | RefreshAction? | 重新整理畫面 |
| rename | RenameAction? | 開始重新命名 |
| resetFocus | ResetFocusAction | 還原成預設的 focus |
| Authentication 驗證 | 型別 | 說明 |
|---|---|---|
| authorizationController | AuthorizationController | 可用來執行驗證,如:登入 |
| webAuthenticationSession | WebAuthenticationSession | 可用來執行透過網頁服務的驗證 |
| Controls and Input 控制與輸入 | 型別 | 說明 |
|---|---|---|
| buttonRepeatBehavior | ButtonRepeatBehavior | 按鈕長壓時是否重複觸發 |
| controlSize | ControlSize | 畫面控件的大小:mini、small、regular、large、extraLarge |
| controlActiveState | ControlActiveState | macOS 畫面中控件的活躍狀態,可用來判斷此視窗是否正被 focus |
| defaultWheelPickerItemHeight | CGFloat | watchOS 中 wheel-style picker 各選項的預設高度 |
| keyboardShortcut | KeyboardShortcut? | Button 的 KeyboardShortcut |
| menuIndicatorVisibility | Visibility | 是否顯示 Menu 右方的「」 |
| menuOrder | MenuOrder | Menu 中選項的排列邏輯 |
| searchSuggestionsPlacement | SearchSuggestionsPlacement | 搜尋建議的擺放位置 |
| Display Characteristics 顯示特性 | 型別 | 說明 |
|---|---|---|
| colorScheme | ColorScheme | 當前傾向的日夜間模式 |
| colorSchemeContrast | ColorSchemeContrast | 是否開啟增加對比 |
| displayScale | CGFloat | 顯示縮放大小,可以理解為 Assets 中的 1x、2x、3x |
| horizontalSizeClass | UserInterfaceSizeClass? | 螢幕水平大小:regular 或 compact,影響的因素有:裝置類型、螢幕轉向、iPad 分割螢幕 |
| imageScale | Image.Scale | 圖片縮放大小:small、medium、large |
| pixelLength | CGFloat | 螢幕 Pixel 大小 = 1/displayScale |
| sidebarRowSize | SidebarRowSize | 側欄圖像大小,適用所有平台,但只有 macOS 可以設定,其他平台都是 medium |
| verticalSizeClass | UserInterfaceSizeClass? | 螢幕垂直大小:regular 或 compact,影響的因素有:裝置類型、螢幕轉向 |
| Global Objects 全域物件 | 型別 | 說明 |
|---|---|---|
| calendar | Calendar | 取得 View 可用於處理日期的 Calendar |
| documentConfiguration | DocumentConfiguration? | 取得 DocumentGroup 中的 document 設定,如:檔案路徑 |
| locale | Locale | 取得 View 可用於處理地區的 Locale |
| managedObjectContext | NSManagedObjectContext | 取得 Core Data 用於處理資料的 managedObjectContext |
| modelContext | ModelContext | 取得 SwiftData 用於處理資料的 modelContext |
| timeZone | TimeZone | 取得 View 可用於處理日期的 TimeZone |
| undoManager | UndoManager? | 用來註冊 View 的 undo 操作 |
| Scrolling 滾動 | 型別 | 說明 |
|---|---|---|
| isScrollEnabled | Bool | ScrollView 能不能滾動 |
| horizontalScrollIndicatorVisibility | ScrollIndicatorVisibility | 水平 ScrollView 是否顯示下方的橫條 |
| verticalScrollIndicatorVisibility | ScrollIndicatorVisibility | 垂直 ScrollView 是否顯示右方的直條 |
| scrollDismissesKeyboardMode | ScrollDismissesKeyboardMode | 滑動時的收鍵盤行為 |
| horizontalScrollBounceBehavior | ScrollBounceBehavior | 水平滑到底時的彈跳行為 |
| verticalScrollBounceBehavior | ScrollBounceBehavior | 垂直滑到底時的彈跳行為 |
| State 狀態 | 型別 | 說明 |
|---|---|---|
| editMode | Binding<EditMode>? | View 的編輯狀態 |
| isActivityFullscreen | Bool | Live Activity 是否以 full-screen 的方式呈現,在 iOS 16 這個值永遠是 false |
| isEnabled | Bool | View 可否與使用者互動,預設為 true |
| isFocused | Bool | 最接近的父 View 是否被 focus |
| isHoverEffectEnabled | Bool | View 能否反應 hover effects,預設為 true |
| isLuminanceReduced | Bool | 螢幕是否調暗亮度。如:當使用者放下手腕時,watchOS 便會調暗亮度 |
| isPresented | Bool | View 是否被顯示 |
| isSceneCaptured | Bool | View 被抓取的狀態,可判斷如:AirPlay、鏡像輸出、螢幕錄影 |
| isSearching | Bool | View 是否正在搜尋 |
| scenePhase | ScenePhase | Scene 的狀態:active、inactive、background |
| supportsMultipleWindows | Bool | 當前平台是否支援多視窗 |
| StoreKit Configuration 設定 | 型別 | 說明 |
|---|---|---|
| displayStoreKitMessage | DisplayMessageAction | 顯示 StoreKit 的訊息 Sheet,如:訂閱價格調整、使用條款更新⋯⋯ |
| requestReview | RequestReviewAction | 跳出鼓勵使用者至 App Store 評分與評論 |
| Text Styles 文字樣式 | 型別 | 說明 |
|---|---|---|
| allowsTightening | Bool | 字與字的間距是否更緊密,預設為 false |
| autocorrectionDisabled | Bool | 是否關閉自動更正,預設為 false |
| dynamicTypeSize | DynamicTypeSize | 當前的動態字級大小,預設會根據裝置而有不同 |
| font | Font? | 預設的字型 |
| layoutDirection | LayoutDirection | 排版方向:左至右、右至左 |
| lineLimit | Int? | 文字最多能顯示幾行。預設為 nil,會把字全部顯示出來 |
| lineSpacing | CGFloat | 行距,此值永遠不為負 |
| minimumScaleFactor | CGFloat | 在有限的空間裡,字最小能縮小幾倍,預設為 1 |
| multilineTextAlignment | TextAlignment | 多行時,字要靠左、中、右 |
| textCase | Text.Case? | 大小或小寫,預設為 nil |
| truncationMode | Text.TruncationMode | 空間不夠顯示所有字時,要變「⋯」在哪,預設為句尾 |
| View Attributes 畫面屬性 | 型別 | 說明 |
|---|---|---|
| allowedDynamicRange | Image.DynamicRange? | View 使用的 Dynamic Range:standard、high、constrainedHigh |
| backgroundMaterial | Material? | 當前背景使用的 Material,如果不是 Material 此值為 nil |
| backgroundProminence | BackgroundProminence | 取得背景狀態:increased 或 standard,可用於 View 被選取時調整顏色 |
| backgroundStyle | AnyShapeStyle? | 背景樣式 |
| badgeProminence | BadgeProminence | Badge 的強調程度:standard:、increased、decreased |
| contentTransition | ContentTransition | 當前執行動畫的 method |
| contentTransitionAddsDrawingGroup | Bool | render 畫面時,是否使用 GPU 加速 |
| defaultMinListHeaderHeight | CGFloat? | 預設的最小 List Header 高 |
| defaultMinListRowHeight | CGFloat | 預設的最小 List Row 高 |
| isFocusEffectEnabled | Bool | View 能否反應 Focus Effect |
| headerProminence | Prominence | Section Header 的強調程度 |
| physicalMetrics | PhysicalMetricsConverter | visionOS 中取得 point 與實際長度的轉換器 |
| realityKitScene | Scene? | 取得 RealityKit Scene |
| redactionReasons | RedactionReasons | 畫面還沒顯示完的原因:invalidated、placeholder、privacy |
| springLoadingBehavior | SpringLoadingBehavior | 畫面 Spring Loading 的行為:automatic、enabled、disabled |
| symbolRenderingMode | SymbolRenderingMode? | 圖像渲染的模式:hierarchical、monochrome、multicolor、palette |
| symbolVariants | SymbolVariants | 圖像樣式:none、circle、square、rectangle、fill、slash |
| Widgets 桌面小工具 | 型別 | 說明 |
|---|---|---|
| showsWidgetContainerBackground | Bool | 是否顯示 Widget 背景,預設為 true |
| showsWidgetLabel | Bool | Widget 能否使用 .widgetLabel(label:) 顯示文字 |
| widgetFamily | WidgetFamily | 可用的 Widget 大小類型 |
| widgetRenderingMode | WidgetRenderingMode | Widget 渲染的模式:fullColor、accented、vibrant |
| widgetContentMargins | EdgeInsets | Widget 的間距 |
關於 XcodeProject
XcodeProject 創立於 2023,致力於協助開發者探索 Apple 的創新世界,學習在 iOS、iPadOS、macOS、tvOS、visionOS 與 watchOS 上開發 App,發現眾多技術與框架,讓開發者獲得更多能力。