簡體   English   中英

SwiftUI 清理 ContentView

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM