【问题标题】:SwiftUI: Switch .sheet on enum, does not workSwiftUI:在枚举上切换.sheet,不起作用
【发布时间】:2021-02-11 20:21:13
【问题描述】:

我有两个 Modal/Popover .sheet,我想根据用户按下的按钮来显示。我用不同的选项设置了一个enum 并设置了一个默认选项。

预期行为:

当用户选择任何选项时,将显示右侧工作表。当用户 THEN 选择另一个选项时,它也会显示正确的工作表。

观察到的行为:

在下面的示例中,当用户首先选择第二个选项时,会显示第一个工作表并将继续显示,直到用户选择第一个工作表,然后它会开始切换。

调试打印显示@State 变量正在发生变化,但是,工作表表示没有观察到这种变化,并按上述方式显示工作表。有什么想法吗?

import SwiftUI


//MARK: main view:
struct ContentView: View {
    
    //construct enum to decide which sheet to present:
    enum ActiveSheet {
        case sheetA, sheetB
    }
    
    //setup needed vars and set default sheet to show:
    @State var activeSheet = ActiveSheet.sheetA //sets default sheet to Sheet A
    @State var showSheet = false
    
    
    var body: some View {
        
        
        VStack{
            
            Button(action: {
                self.activeSheet = .sheetA //set choice to Sheet A on button press
                print(self.activeSheet) //debug print current activeSheet value
                self.showSheet.toggle() //trigger sheet
            }) {
                Text("Show Sheet A")
            }
            
            
            Button(action: {
                self.activeSheet = .sheetB //set choice to Sheet B on button press
                print(self.activeSheet) //debug print current activeSheet value
                self.showSheet.toggle() //trigger sheet
            }) {
                Text("Show Sheet B")
            }
        }
        
        //sheet choosing view to display based on selected enum value:
        .sheet(isPresented: $showSheet) {
            switch self.activeSheet {
            case .sheetA:
                SheetA() //present sheet A
            case .sheetB:
                SheetB() //present sheet B
            }
        }
    }
}





//MARK: ancillary sheets:
struct SheetA: View {
    var body: some View {
        Text("I am sheet A")
            .padding()
    }
}

struct SheetB: View {
    var body: some View {
        Text("I am sheet B")
            .padding()
    }
}

【问题讨论】:

    标签: swiftui


    【解决方案1】:

    对您的代码进行一些非常小的改动,您可以使用sheet(item:) 来解决这个问题:

    
    //MARK: main view:
    struct ContentView: View {
        
        //construct enum to decide which sheet to present:
        enum ActiveSheet : String, Identifiable { // <--- note that it's now Identifiable
            case sheetA, sheetB
            var id: String {
                return self.rawValue
            }
        }
        
        @State var activeSheet : ActiveSheet? = nil // <--- now an optional property
        
        var body: some View {
            
            
            VStack{
                
                Button(action: {
                    self.activeSheet = .sheetA
                }) {
                    Text("Show Sheet A")
                }
                
                
                Button(action: {
                    self.activeSheet = .sheetB 
                }) {
                    Text("Show Sheet B")
                }
            }
            //sheet choosing view to display based on selected enum value:
            .sheet(item: $activeSheet) { sheet in // <--- sheet is of type ActiveSheet and lets you present the appropriate sheet based on which is active
                switch sheet {
                case .sheetA:
                    SheetA() 
                case .sheetB:
                    SheetB()
                }
            }
        }
    }
    

    问题在于,在不使用item: 的情况下,当前版本的 SwiftUI 会使用第一个状态值(即本例中的工作表 A)呈现初始工作表,并且不会在第一次演示时正确更新。使用这种item: 方法可以解决问题。

    【讨论】:

    • 另外,您可以捕获状态变量activeSheet ,例如`.sheet(isPresented: $showSheet) { [activeSheet] in ...}
    • 好技巧——以前没有遇到过。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-10-28
    • 2016-02-27
    • 2016-10-12
    • 1970-01-01
    • 2020-08-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多