0

When using .navigationDestination(isPresented:), the navigation hangs when in the following situation:

@State private var navigateToChatView = false
    
var body: some View {
        MyView()
            .navigationTitle("Users")
            .searchable(text: $viewModel.searchText)
            .navigationDestination(isPresented: $navigateToChatView) {
                if let selectedUser = selectedUsers.first, let name = selectedUser.name {
                    NewComposeView(sendMessage: { message in
                        viewModel.sendMessage(message: message) // removing this works
                    })
                    .navigationTitle(name)
                }
            }
        }

Just commenting out the viewModel function allows it to navigate to the view as expected. Not sure why this is an issue.

Also note that even making sendMessage a simple function that prints a statement is an issue so I don't think it has anything to do with sendMessage being an asynchronous call

Here is the NewComposeView code:

import SwiftUI

struct NewComposeView: View {
    @State private var message: String = ""
    var sendMessage: (String) -> Void

    var body: some View {
        HStack {
            ZStack {
                RoundedRectangle(cornerRadius: 18)
                    .stroke()
                HStack {
                    TextField("Write a message", text: $message)
                    Spacer()
                    Button {
                        sendMessage(message)
                        message = ""  // Clear the text field
                    } label: {
                        Image(systemName: "paperplane.fill")
                            .resizable()
                            .frame(width: 20, height: 20)
                            .font(.title)
                    }
                }
                .padding(EdgeInsets(top: 3, leading: 20, bottom: 3, trailing: 20))
            }
            .frame(height: 40)
        }
        .foregroundColor(Color(.white))
    }
}
Christian
  • 336
  • 1
  • 4
  • 16

1 Answers1

0

Your code works for me in my tests, on MacOS 14, Xcode 15, tested on real ios 17 devices (not Previews), and macCatalyst. It could be different on older systems.

Since you don't provide all relevant code in your post, I assume that, it is the code you don't show that is reponsible for your issue.

Here is the working code I used in my tests, this may help your track down your issue:

struct ContentView: View {
    var body: some View {
        NavigationStack {
            TestView()
        }
    }
}

class TheViewModel: ObservableObject {
    @Published var searchText: String = ""
    
    func sendMessage(message: String) {
        print("----> sendMessage message: \(message)")
    }
}

struct User: Identifiable {
    let id = UUID()
    var name: String?
}

struct TestView: View {
    @StateObject var viewModel = TheViewModel()
    @State private var navigateToChatView = false
    @State private var selectedUsers = [User(name: "user-1"),User(name: "user-2")]
     
    var body: some View {
        Button("click me") {
            navigateToChatView = true  // <--- for testing
        }
        MyView()
            .navigationTitle("Users")
            .searchable(text: $viewModel.searchText)
            .navigationDestination(isPresented: $navigateToChatView) {
                if let selectedUser = selectedUsers.first, let name = selectedUser.name {
                    NewComposeView(sendMessage: { message in
                        viewModel.sendMessage(message: message)
                    })
                    .navigationTitle(name)
                }
            }
    }
}

struct NewComposeView: View {
    @State private var message: String = ""
    var sendMessage: (String) -> Void
    
    var body: some View {
        HStack {
            ZStack {
                RoundedRectangle(cornerRadius: 18).stroke()
                HStack {
                    TextField("Write a message", text: $message)
                    Spacer()
                    Button {
                        sendMessage(message)
                        message = ""  // Clear the text field
                    } label: {
                        Image(systemName: "paperplane.fill")
                            .resizable()
                            .frame(width: 20, height: 20)
                            .font(.title)
                    }
                }
                .padding(EdgeInsets(top: 3, leading: 20, bottom: 3, trailing: 20))
            }
            .frame(height: 40)
        }
        .foregroundColor(Color.red) // <--- for testing
    }
}

struct MyView: View {
    var body: some View {
        Text("MyView")  // <--- for testing
    }
}