SwiftUI:当父视图也可以显示工作表时,如果从子视图触发,则不会显示工作表 [英] SwiftUI: sheet not presented if triggered from subview when superview can also present sheet

查看:30
本文介绍了SwiftUI:当父视图也可以显示工作表时,如果从子视图触发,则不会显示工作表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我在 NavigationView 中有一个视图,带有前导和尾随按钮.因为我可以从这个视图中呈现两个不同的工作表,所以我使用了这样的枚举:

Let's say I have a view in a NavigationView, with leading and trailing buttons. Because I can present two different sheets from this view, I use an enum like that:

enum AccountActiveSheet {
   case about, settings
}

这个主视图在视图中有两个 @State 属性来触发工作表展示.

This main view has two @State properties in the view to trigger the sheet presentation.

@State private var isSheetPresented: Bool = false
@State private var activeSheet: AccountActiveSheet = .about

每个按钮都可以触发一个工作表.

Each button can trigger a sheet.

var aboutButton: some View {
    Button(action: {
        self.activeSheet = .about
        self.isSheetPresented.toggle()
    }, label: {
        Image(systemName: "info.circle.fill")
    })
}

在导航视图的末尾,我选择了正确的工作表来呈现

At the end of the navigation view, I select the correct sheet to present like that

.sheet(isPresented: $isSheetPresented) {
   self.activeSheet.sheet
}

它工作正常并在模态中显示正确的视图.

It's working fine and presenting the correct view in a modal.

但我在这个主视图中也有多个子视图,可以在点击按钮时显示工作表.在这种情况下,子视图管理的工作表(即用于跟踪子视图提供的工作表的 $isSheetPresented + 内容的@State 变量)不会显示.没发生什么事.似乎超视图工作表修饰符阻止子视图显示工作表.

But I also have multiple subviews in this main view that can present sheets when tapping on a button. In this case, the sheet managed by the subview (i.e. a @State variable to track the $isSheetPresented + content for the sheet provided by the subview) is not presented. Nothing happens. It seems the superview sheet modifier is preventing the subview to present the sheet.

是否可以同时使用父视图和子视图来管理工作表演示?

Is it possible to have both a superview and a subview manage sheet presentation?

enum AccountActiveSheet {
    case about, settings

    @ViewBuilder
    var sheet: some View {
        switch self {
        case .about: Text("About")
        case .settings: Text("Settings")
        }
    }
}

struct AccountView: View {
    @State private var isSheetPresented: Bool = false
    @State private var activeSheet: AccountActiveSheet = .about
    
    var aboutButton: some View {
        Button(action: {
            self.activeSheet = .about
            self.isSheetPresented.toggle()
        }, label: {
            Image(systemName: "info.circle.fill")
        })
    }
    
    var settingsButton: some View {
        Button(action: {
            self.activeSheet = .settings
            self.isSheetPresented.toggle()
        }, label: {
            Image(systemName: "gearshape.fill")
        })
    }

    var body: some View {
        NavigationView {
            VStack {
                Subview()
            }
            .navigationBarTitle("Account", displayMode: .inline)
            .navigationBarItems(leading: aboutButton, trailing: settingsButton)
            .sheet(isPresented: $isSheetPresented) {
                self.activeSheet.sheet
            }
        }
    }
}

struct Subview: View {
    @State var isSheetPresented: Bool = false

    var body: some View {
        Button("Present sheet") {
            self.isSheetPresented.toggle()
        }
        .sheet(isPresented: $isSheetPresented) {
            Text("Subview")
        }
    }
}

推荐答案

Move root view sheet out of NavigationView(使用 Xcode 12.1/iOS 14.1 测试)

Move root view sheet out of NavigationView (tested with Xcode 12.1 / iOS 14.1)

var body: some View {
    NavigationView {
        VStack {
            Subview()
        }
        .navigationBarTitle("Account", displayMode: .inline)
        .navigationBarItems(leading: aboutButton, trailing: settingsButton)
    }
    .sheet(isPresented: $isSheetPresented) {   // << here !!
        self.activeSheet.sheet
    }
}

这篇关于SwiftUI:当父视图也可以显示工作表时,如果从子视图触发,则不会显示工作表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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