SwiftUI:在枚举上切换 .sheet,不起作用 [英] SwiftUI: Switch .sheet on enum, does not work

查看:27
本文介绍了SwiftUI:在枚举上切换 .sheet,不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

预期行为:

当用户选择任何选项时,会显示正确的工作表.当用户 THEN 选择其他选项时,它也会显示正确的工作表.

观察到的行为:

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

调试打印显示 @State 变量正在更改,但是,工作表演示文稿未观察到此更改并按上述方式显示工作表.有什么想法吗?

导入 SwiftUI//MARK: 主视图:结构内容视图:查看{//构造枚举以决定要呈现的工作表:枚举 ActiveSheet {案例表A,表B}//设置需要的变量并设置默认工作表以显示:@State var activeSheet = ActiveSheet.sheetA//设置默认工作表为工作表A@State var showSheet = falsevar主体:一些视图{虚拟堆栈{按钮(动作:{self.activeSheet = .sheetA//在按下按钮时将选择设置为工作表 Aprint(self.activeSheet)//调试打印当前activeSheet值self.showSheet.toggle()//触发表}) {文本(显示工作表 A")}按钮(动作:{self.activeSheet = .sheetB//在按下按钮时将选择设置为 Sheet Bprint(self.activeSheet)//调试打印当前activeSheet值self.showSheet.toggle()//触发表}) {文本(显示工作表 B")}}//工作表根据选定的枚举值选择要显示的视图:.sheet(isPresented: $showSheet) {切换 self.activeSheet {案例.sheetA:SheetA()//当前工作表A案例.sheetB:SheetB()//当前工作表B}}}}//MARK:辅助表:结构表A:查看{var主体:一些视图{Text(我是A表").填充()}}结构表B:查看{var主体:一些视图{Text(我是B表").填充()}}

解决方案

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

<预><代码>//MARK: 主视图:结构内容视图:查看{//构造枚举以决定要呈现的工作表:enum ActiveSheet : String, Identifiable {//<--- 注意它现在是 Identifiable案例表A,表B变量 ID:字符串 {返回 self.rawValue}}@State var activeSheet :ActiveSheet?= nil//<--- 现在是一个可选属性var主体:一些视图{虚拟堆栈{按钮(动作:{self.activeSheet = .sheetA}) {文本(显示工作表 A")}按钮(动作:{self.activeSheet = .sheetB}) {文本(显示工作表 B")}}//工作表根据选定的枚举值选择要显示的视图:.sheet(item: $activeSheet) { sheet in//<--- sheet 是 ActiveSheet 类型,并允许您根据哪个是活动的来显示适当的工作表切换表{案例.sheetA:表A()案例.sheetB:表B()}}}}

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

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

解决方案

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.

这篇关于SwiftUI:在枚举上切换 .sheet,不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆