SwiftUI: лист не отображается, если запускается из подпредставления, когда супервизор также может представлять лист

Скажем, у меня есть представление в NavigationView с ведущими и конечными кнопками. Поскольку я могу представить два разных листа из этого представления, я использую подобное перечисление:

enum AccountActiveSheet {
   case about, settings
}

В этом главном представлении есть два свойства @State для запуска представления листа.

@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")
    })
}

В конце окна навигации я выбираю правильный лист, чтобы он выглядел так

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

Он работает нормально и представляет правильный вид в модальном окне.

Но у меня также есть несколько подпредставлений в этом главном представлении, которые могут отображать листы при нажатии кнопки. В этом случае лист, управляемый подпредставлением (т. Е. Переменная @State для отслеживания содержимого $isSheetPresent + для листа, предоставленного подпредставлением), не отображается. Ничего не произошло. Кажется, что модификатор листа суперпредставления не позволяет подпредставлению представлять лист.

Можно ли иметь как супервизор, так и подпредставление для управления представлением листа?

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

1 ответ

Решение

Переместить лист корневого вида из NavigationView (протестировано с 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
    }
}
Другие вопросы по тегам