.alert внутри .fullScreenCover немедленно закрывается при использовании внутри определенной иерархии представлений.IOS

Программируем под IOS
Ответить
Anonymous
 .alert внутри .fullScreenCover немедленно закрывается при использовании внутри определенной иерархии представлений.

Сообщение Anonymous »

Я создал повторно используемое представление ModalDialog, которое представляет модальное содержимое через .fullScreenCover. Внутри этого диалогового окна кнопка запускает SwiftUI .alert.
Это отлично работает во многих ситуациях. Однако в определенной иерархии представлений .alert появляется на долю секунды и тут же снова закрывается.
В приведенном ниже коде .alert завершается сбоем только при использовании внутри точной иерархии, используемой в демонстрационном коде. Удаление любого из следующих элементов заставляет оповещение снова работать:
  • Удалить окружающий TabView
  • Удалить окружающий VStack
  • Удалить NavigationStack
  • Удалить .navigationDestination
  • Представить диалоговое окно непосредственно со страницы вкладки, а не внутри листа
Однако в моем реальном приложении все эти слои представления необходимы и служат определенной цели, поэтому я не могу их удалить. Например, SettingsContentView не только отображает диалоговые окна, но также может переходить к другим представлениям, помещая содержимое в NavigationPath.
Что именно вызывает немедленное отклонение этого оповещения? Это ошибка SwiftUI или что-то в корне не так с моим кодом?
// App Entry
@main
struct SwiftAppApp: App {
var body: some Scene {
WindowGroup {
ContentView()
}
}
}

// Base Content View
struct ContentView: View {
var body: some View {
// Alert failes when TabView is used.
// Without the TabView the .alert works fine
TabView() {
TabPageView()
}
}
}

// Page View
struct TabPageView: View {
@State private var isPresented: Bool = false
@State private var showDlg: Bool = false

var body: some View {
// Removing this sourrounding VStack also 'solves' the problem
VStack {
Button("Show Settings Sheet") {
isPresented = true
}

.sheet(isPresented: $isPresented) {
SettingsSheetView()
.background(.red)
}

// When presented here, the dialog and the alert works fine.
Button ("Show Dialog") {
showDlg = true
}

ModalDialogView(isPresented: $showDlg)
}
}
}

// Sheet and Content
struct SettingsSheetView: View {
@State private var path = NavigationPath()

var body: some View {
// Alert failes when NavigationStack is used.
// Without the NavigationStack the .alert works fine
NavigationStack(path: $path) {
SettingsContentView(path: $path)
}
}
}

struct SettingsContentView: View {
let path: Binding
@State var showDlg: Bool = false

var body: some View {
Button("Show Dlg") {
showDlg = true
}

//Button("Navigate to other view") {
// path.append(...)
//}

ModalDialogView(isPresented: $showDlg)

// Alert failes when navigationDestination is used.
// Without the navigationDestination the .alert works fine
.navigationDestination(for: MySettingsRoute.self) { route in
EmptyView()
}
}
}

public struct MySettingsRoute: Hashable { }

// Dialog with Alert
struct ModalDialogView: View {
@Binding var isPresented: Bool
@State private var showAlert: Bool = false

var body: some View {
ModalDialog(isPresented: $isPresented) {
Button("Show Alert") {
showAlert = true
}
.buttonStyle(.borderedProminent)

.alert("Title", isPresented: $showAlert) {
EmptyView()
} message: {
Text("Message")
}
}
}
}

struct ModalDialog: View {
@Binding var isPresented: Bool
let content: Content

init(
isPresented: Binding,
@ViewBuilder content: () -> Content
) {
self._isPresented = isPresented
self.content = content()
}

var body: some View {
ZStack{}
.fullScreenCover(isPresented: $isPresented) {
content
.padding()
.background(.yellow)
.presentationBackground(.clear)
}
}
}


Подробнее здесь: https://stackoverflow.com/questions/798 ... de-specifi
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «IOS»