[英]SwiftUI clean up ContentView
我正在嘗試簡化項目中的 ContentView,並且我正在努力了解如何將基於@State
的邏輯移動到它自己的文件中並讓 ContentView 適應任何更改。 目前我有基於@Binding
操作顯示自己的動態視圖,我將 $binding 向下傳遞到視圖層次結構以使按鈕切換 bool 值。
這是我目前的嘗試。 我不確定在 SwiftUI 中如何從嵌套視圖更改 SheetPresenter 的視圖SheetPresenter
而無需將 $binding 一直傳遞到視圖堆棧。 理想情況下,我希望它看起來像ContentView.overlay(sheetPresenter($isOpen, $present)
。
另外,我正在學習 SwiftUI,所以如果這不是最好的方法,請提供指導。
class SheetPresenter: ObservableObject {
@Published var present: Present = .none
@State var isOpen: Bool = false
enum Present {
case none, login, register
}
@ViewBuilder
func makeView(with presenter: Present) -> some View {
switch presenter {
case .none:
EmptyView()
case .login:
BottomSheetView(isOpen: $isOpen, maxHeight: UIConfig.Utils.screenHeight * 0.75) {
LoginScreen()
}
case .register:
BottomSheetView(isOpen: $isOpen, maxHeight: UIConfig.Utils.screenHeight * 0.75) {
RegisterScreen()
}
}
}
}
如果您不想在視圖中一直傳遞 $binding,您可以在頂部視圖中創建一個 StateObject 變量並使用 .environmentObject() 傳遞它。 並使用 EnvironmentObject 從任何視圖訪問它
struct testApp: App {
@StateObject var s1: sViewModel = sViewModel()
var body: some Scene {
WindowGroup {
ContentView()
.environmentObject(s1)
}
}
}
你是對的,這不是最好的方法,但這是一個常見的錯誤。 在 SwiftUI 中,我們實際上將@State
用於視圖擁有的瞬態數據。 這意味着使用像結構這樣的值類型,而不是類。 這在 WWDC 2020 的 SwiftUI 中的 Data Essentials 中的 4:18 進行了解釋。
EditorConfig 可以在其屬性上保持不變量並獨立測試。 並且因為 EditorConfig 是一種值類型,所以對 EditorConfig 屬性的任何更改(如其進度)都將作為對 EditorConfig 本身的更改而可見。
struct EditorConfig {
var isEditorPresented = false
var note = ""
var progress: Double = 0
mutating func present(initialProgress: Double) {
progress = initialProgress
note = ""
isEditorPresented = true
}
}
struct BookView: View {
@State private var editorConfig = EditorConfig()
func presentEditor() { editorConfig.present(…) }
var body: some View {
…
Button(action: presentEditor) { … }
…
}
}
然后你只需使用$editorConfig.isEditorPresented
作為.sheet
或.overlay
中的 boolean 綁定。
還值得一看sheet(item:onDismiss:content:)這使得顯示項目變得更加簡單,因為不需要 boolean 它使用可選的@State
,您可以將其設置為 nil 以關閉。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.