用 .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,發現眾多技術與框架,讓開發者獲得更多能力。