SwiftUI: Switch .sheet on enum, does not work

做~自己de王妃 提交于 2021-02-20 02:51:10

问题


I have two Modal/Popover .sheet's I would like to show based on which button is pressed by a user. I have setup an enum with the different choices and set a default choice.

Expected behaviour:

When the user selects any choice, the right sheet is displayed. When the user THEN selects the other choice, it also shows the correct sheet.

Observed behaviour:

In the example below, when the user first picks the second choice, the first sheet is shown and will continue to show until the user selects the first sheet, then it will start to switch.

Debug printing shows that the @State variable is changing, however, the sheet presentation does not observe this change and shows the sheets as described above. Any thoughts?

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()
    }
}

回答1:


With some very small alterations to your code, you can use sheet(item:) for this, which prevents this problem:


//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()
            }
        }
    }
}

The problem is that without using item:, current versions of SwiftUI render the initial sheet with the first state value (ie sheet A in this case) and don't update properly on the first presentation. Using this item: approach solves the issue.



来源:https://stackoverflow.com/questions/66162219/swiftui-switch-sheet-on-enum-does-not-work

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!