SwiftUI transition from modal sheet to regular view with Navigation Link
You can do this by creating an environmentObject
and bind the navigationLink
destination value to the environmentObject
's value then change the value of the environmentObject
in the modal view.
Here is a code explaining what I mean
import SwiftUI
class NavigationManager: ObservableObject{
@Published private(set) var dest: AnyView? = nil
@Published var isActive: Bool = false
func move(to: AnyView) {
self.dest = to
self.isActive = true
}
}
struct StackOverflow6: View {
@State var showModal: Bool = false
@EnvironmentObject var navigationManager: NavigationManager
var body: some View {
NavigationView {
ZStack {
NavigationLink(destination: self.navigationManager.dest, isActive: self.$navigationManager.isActive) {
EmptyView()
}
Button(action: {
self.showModal.toggle()
}) {
Text("Show Modal")
}
}
}
.sheet(isPresented: self.$showModal) {
secondView(isPresented: self.$showModal).environmentObject(self.navigationManager)
}
}
}
struct StackOverflow6_Previews: PreviewProvider {
static var previews: some View {
StackOverflow6().environmentObject(NavigationManager())
}
}
struct secondView: View {
@EnvironmentObject var navigationManager: NavigationManager
@Binding var isPresented: Bool
@State var dest: AnyView? = nil
var body: some View {
VStack {
Text("Modal view")
Button(action: {
self.isPresented = false
self.dest = AnyView(thirdView())
}) {
Text("Press me to navigate")
}
}
.onDisappear {
// This code can run any where but I placed it in `.onDisappear` so you can see the animation
if let dest = self.dest {
self.navigationManager.move(to: dest)
}
}
}
}
struct thirdView: View {
var body: some View {
Text("3rd")
.navigationBarTitle(Text("3rd View"))
}
}
Hope this helps, if you have any questions regarding this code, please let me know.
SwiftUI: Go to a new view from inside a modal
I understood your question in 2 different ways, and luckily I have both solutions.
If you want the following flow: ViewA -> Opens ViewB As modal -> opens ViewC as NavigatedView in ViewB
Then all you need to change is your ModalView
to this
struct ModalView: View {
@Binding var showModal: Bool
var body: some View {
NavigationView {
VStack (spacing: 30){
NavigationLink(destination: NewView()) {
Text("Take me to NewView")
}
Text("My Modal View")
.font(.title)
.padding()
Button("Close modal") {
self.showModal.toggle()
}
Button("Close modal and go to a new view") {
}
}
}
}
}
IF however what you mean is ViewA -> opens ViewsB as Moda -> ViewB then tells ViewA to navigate to ViewC
then please refer to this link, someone asked this question earlier and I provided the solution
SwiftUI transition from modal sheet to regular view with Navigation Link
SwiftUI: How to dismiss a modal sheet and then execute a navigationlink together
You can use the method to show a modal and execute an action on dismiss. It should look similar to this:
import SwiftUI
struct Signup: View {
// Property to keep track of your modal state
@State var isPresented = false
var body: some View {
NavigationView {
VStack {
Button(action: {
// Show / hide the modal view with toggle()
self.isPresented.toggle()
}, label: {
// Your button label
})
.sheet(isPresented: $isPresented,
onDismiss: {
// What happen when your modal dismiss
}) {
// Modal view that opens to be declared here
}
}
}
}
}
SwiftUI NavigationView detail view binding to sheet modal not working
By following @jnpdx suggestion, I was able to solve it with using a different approach to rendering sheets
struct UserDetailView: View {
@Binding var user: User
@State private var sheetEnum: SheetEnum<SheetType>?
enum SheetType {
case EditUser
}
var body: some View {
VStack {
// content
}
.toolbar {
ToolbarItem(placement: .navigationBarTrailing) {
Button(action: {
sheetEnum = SheetEnum(type: .EditUser)
}) {
Text("Edit")
}
}
}
.sheet(item: $sheetEnum) { sheet in
if sheet.type == .EditUser {
EditUserView(user: $user)
{
}
}
}
struct SheetEnum<T>: Identifiable {
var id = UUID()
var type: T
}
How to pass data from a modal view list to parent view in SwiftUI?
At its most basic, you need the selected exercise in your parent view (SelectExerciseView
) as a state variable. You then pass that in to the child view (the modal) via a binding. Assuming exercise
as a string holds the variable you want to change:
.sheet(isPresented: $showingSheet) {
ExerciseList(exercise: $exercise)
}
Your modal then needs to have a @Binding
reference.
struct ExerciseList: View {
@Binding var exercise: Exercise
var body: some View {
List {
ForEach(1..<30) { _ in
Button("yoga") {
exercise = "yoga"
}
}
}
}
}
Related Topics
How to Get Date from String in Swift 3
How to Download a PDF File in Swift and Find in File Manager
Swift 2 Unused Constant Warning
Periodically Call an API with Rxswift
Settitletextattributes Doesn't Work for Uitabbaritem When It Is Unselected in Swift
Swift 3 Imessage Extension Doesn't Open Url
How to Draw Text in Center to Uiimage
Determine If Mkmapview Was Dragged/Moved in Swift 2.0
Do I Need to Wrap My Alamofire Calls Inside Dispatch_Async
@Ibdesignable - View Not Rendering as Expected
Didbegincontact Passed Pkphyicsobject
Why am I Getting an Error Regarding Bolts Framework and Facebooksdk When I'm Not Even Using Bolts