В настоящее время я пытаюсь понять, как закрыть лист в SwiftUI. Я создал представление для Dismiss-Button, потому что хочу использовать эту кнопку несколько раз в разных местах приложения. Когда лист всплывает, нажатие кнопки ничего не делает, я могу только закрыть лист, проведя пальцем вниз по экрану.
Сначала я попытался следовать учебному пособию YouTube, но он использует устаревший .presentationMode. Поэтому в настоящее время я пытаюсь заставить переменную .dismiss работать, но не могу понять, что я делаю неправильно. Я уже пытался объявить .dismiss в Button-View и Portfolio-View. Я также использовал функцию отклонения() и функцию отклонения.callAsFunction().
Вот мой Button-View (XMarkButton), представленный Sheet-View (PortfolioView) и мой Home-View, где будет отображаться лист:
XMarkButton
struct XMarkButton: View {
@Environment(\.dismiss) private var dismiss
var body: some View {
Button(action: {
dismiss.callAsFunction()
}, label: {
Image(systemName: "xmark")
.font(.headline)
})
}
}
ПортфолиоПросмотр
struct PortfolioView: View {
var body: some View {
NavigationView {
ScrollView {
VStack(alignment: .leading, spacing: 0) {
Text("Portfolio")
}
}
.navigationTitle("Edit Portfolio")
.toolbar(content: {
ToolbarItem(placement: .navigationBarLeading) {
XMarkButton()
}
})
}
}
}
ГлавнаяВид
struct HomeView: View {
@EnvironmentObject private var vm: HomeViewModel
@State private var showPortfolio: Bool = false
@State private var showPortfolioView: Bool = false
var body: some View {
ZStack {
// Background layer
Color.theme.background
.ignoresSafeArea()
.sheet(isPresented: $showPortfolioView) {
PortfolioView()
.environmentObject(vm)
}
VStack {
homeHeader
HomeStatsView(showPortfolio: $showPortfolio)
SearchBarView(searchText: $vm.searchText)
columnTitles
if !showPortfolio {
allCoinsList
.transition(.move(edge: .leading))
}
if showPortfolio {
portfolioCoinsList
.transition(.move(edge: .trailing))
}
Spacer(minLength: 0)
}
}
}
}
Возможный дубликат см. stackoverflow.com/questions/76111198/…
Самый простой способ запустить это — переместить функциональность dismiss
в представление, которое нужно закрыть.
Проблема с текущим подходом заключается в том, что вы пытаетесь закрыть кнопку X, а не фактический вид.
struct XMarkButton: View {
var body: some View {
Image(systemName: "xmark") //changed to image, can change color here if needed
.font(.headline)
}
}
struct PortfolioView: View {
@Environment(\.dismiss) private var dismiss // moved dismiss functionality here
var body: some View {
NavigationView {
ScrollView {
VStack(alignment: .leading, spacing: 0) {
Text("Portfolio")
}
}
.navigationTitle("Edit Portfolio")
.toolbar(content: {
ToolbarItem(placement: .navigationBarLeading) {
XMarkButton().onTapGesture { // on tap gesture calls dismissal
dismiss()
}
}
})
}
}
}
Альтернативный подход, сохраняющий ту же структуру, заключается в использовании обработчика завершения - см. ниже:
struct XMarkButton: View {
var action: () -> Void
var body: some View {
Button(action: {
action()
}, label: {
Image(systemName: "xmark")
.font(.headline)
})
}
}
struct PortfolioView: View {
@Environment(\.dismiss) private var dismiss
var body: some View {
NavigationView {
ScrollView {
VStack(alignment: .leading, spacing: 0) {
Text("Portfolio")
}
}
.navigationTitle("Edit Portfolio")
.toolbar(content: {
ToolbarItem(placement: .navigationBarLeading) {
XMarkButton {
dismiss()
}
}
})
}
}
}
Одна вещь, которую я рекомендую продвигаться вперед, — это создать минимально воспроизводимый пример. Копирование этого кода приводит к целому ряду ошибок, так как в нем отсутствует несколько компонентов.