I am currently trying to figure out how to dismiss a sheet in SwiftUI. I created a view for the Dismiss-Button because I want to use that button multiple times at different locations in the app. When the sheet pops up, pressing the button is not doing anything, I can only dismiss the sheet via swiping down on the screen.
I first tried to follow a YouTube tutorial, but it uses the deprecated .presentationMode Therefore I am currently trying to make the .dismiss variable working, but I can't figure out what I am doing wrong. I already tried declaring .dismiss in the Button-View and Portfolio-View. I also used dismiss() and dismiss.callAsFunction().
Here is my Button-View (XMarkButton), the presented Sheet-View (PortfolioView) and my Home-View, where the sheet will be displayed:
XMarkButton
struct XMarkButton: View {
@Environment(\.dismiss) private var dismiss
var body: some View {
Button(action: {
dismiss.callAsFunction()
}, label: {
Image(systemName: "xmark")
.font(.headline)
})
}
}
PortfolioView
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()
}
})
}
}
}
HomeView
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)
}
}
}
}
The easiest way to get this up and running would be to move the
dismissfunctionality into the view that needs to be dismissed.The problem with the current approach is you are attempting to dismiss the X button, not the actual view.
An alternate approach that keeps your same structure would be to use a completion handler - see below: