Textfield tap is dismissing navigation link in SwiftUI
Asked Answered
S

5

7

I'm facing a weird issue with textfields and navigation view/link using SwiftUI

All I do is navigate through views using navigation links and inside the destination view there are some textfields. When I tap on any of them the navigation automatically dismisses.

How can I fix navigation link from dismissing when textfield is tapped on and the keyboard shows up?

var emailLoginButton: some View {
    NavigationLink(destination: LoginView(viewModel: .init(mode: .login, isPushed: $viewModel.authViewPushed)), isActive: $viewModel.authViewPushed) {
        Button(action: { viewModel.authViewPushed = true }) {
            HStack {
                Image(systemName: "envelope")
                    .resizable()
                    .aspectRatio(contentMode: .fit)
                    .frame(width: 20, height: 20)
                    .foregroundColor(.white)
                
                Text("continue_with_email".localized())
                    .padding(.horizontal, 20)
            }
        }
        .padding()
        .frame(maxWidth: .infinity)
        .foregroundColor(.white)
        .background(Capsule().fill(Color.primaryPurple))
        .shadow(color: Color.black.opacity(0.15), radius: 5, x: 5, y: 5)
        .padding(.horizontal)
        .padding(.bottom, 20)
    }
    .isDetailLink(false)
}

// Destination's view textfield which "dismisses" navigationLink
var emailTextField: some View {
    HStack {
        Image(systemName: "envelope")
            .font(.title2)
            .foregroundColor(.primary)
            .frame(width: 35)

        TextField(viewModel.emailPlaceholderText.uppercased(), text: $viewModel.email)
            .autocapitalization(.none)
    }
    .padding()
    .background(Color.white.opacity(viewModel.email == stringEmpty ? 0 : 0.12))
    .cornerRadius(12)
    .padding(.horizontal)
}
Suppose answered 16/3, 2021 at 14:0 Comment(5)
Hi, Have you find any solution for this?Bally
Not yet, it might be a bug or something. I changed the onboarding flow to work around the problem.Czech
I'm facing the same bug and I don't have any viewModel in my SceneWafd
Hi, do you still have this problem? I suddenly started having the same issue only on iPhone 15.4.1.Orland
@Orland Yeah, still. But after researching and testing just found out the problem and this comment explain what happens https://mcmap.net/q/1518305/-textfield-tap-is-dismissing-navigation-link-in-swiftuiCzech
S
2

After some time of research I've found that NavigationLink closes because authViewPushed parameter in the viewModel becomes false. That happens because viewModel is being recreated because of firstView update. I've faced the same issue and here is the solution:

struct MyView: View {
    @StateObject var viewModel = MyViewModel()

    var body : some View {
        
    }
}

In this case MyView is being updated but MyViewModel remains the same.

Schram answered 8/5, 2021 at 18:15 Comment(0)
S
3

There seems to be an issue with iOS 14.5 and up where the tapping of any TextField inside a NavigationLink destination makes the view to pop out to the previous one.

There is a workaround thanks to @SeitenWerk and documented on the Apple Developer Forums

https://developer.apple.com/forums/thread/677333

The solution is simple. Just add an empty NavigationLink next to the one that fails. Interestingly, it logs "Unable to present. Please file a bug." on the debug console but makes things right with the usability of the app

NavigationLink(destination: LoginView()){
    Text("LOGIN")
}
NavigationLink(destination: EmptyView()) {
     EmptyView()
}

Remember to thank SeitenWerk on the Developer Forums.

Shuman answered 27/7, 2021 at 11:28 Comment(3)
iOS 15 doesn't work anymoreUnseemly
@SimonePistecchia I just tested it in iOS 15.1 and works fine. What is happening in your case?Shuman
Hi @JulioBailon, I'm accessing the child views in a scroll view. So this solution doesn't seem to work for me. Do you have any advice?Orland
S
2

After some time of research I've found that NavigationLink closes because authViewPushed parameter in the viewModel becomes false. That happens because viewModel is being recreated because of firstView update. I've faced the same issue and here is the solution:

struct MyView: View {
    @StateObject var viewModel = MyViewModel()

    var body : some View {
        
    }
}

In this case MyView is being updated but MyViewModel remains the same.

Schram answered 8/5, 2021 at 18:15 Comment(0)
U
1

on iOS 15

NavigationView {
    //your staff          
}
.navigationViewStyle(StackNavigationViewStyle())
Unseemly answered 13/11, 2021 at 14:18 Comment(0)
I
0

This might be one of the most frustrating and egregious examples of "this works everywhere else on every other version of whatever" I've seen of late in SwiftUI. (sigh) I'm reworking the whole workflow on two Views just to support previous versions of iOS which I didn't initially set out to do. Grrrr... Are there any known workarounds that are consistently proven to work?

Idiot answered 28/3, 2022 at 12:26 Comment(1)
This is exactly the situation. I am calling the same view from two different views, in the same exact way. One works and the other not. Did you find a solution?Orland
C
0

For me the solution is to force out focus of the text field by focus state:

   @FocusState private var nameIsFocused: Bool

   TextField("text", text: $text)
   .textInputAutocapitalization(.never)
   .textContentType(.username).keyboardType(.asciiCapable)
   .focused($nameIsFocused)

And then in the button callback

  var timer:Timer?
  timer?.invalidate()
  timer = Timer.scheduledTimer(withTimeInterval: 0.25, repeats: false) { _ in
     moveToScreen.toggle(); // here change the state}
Citrin answered 30/10, 2022 at 17:7 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.