Auto Layout Constraint Conflict in SwiftUI When Tapping TextField

I am developing an iOS app using SwiftUI and have encountered an Auto Layout constraint conflict issue that appears when tapping on a TextField within a LoginView. I've tried several troubleshooting steps but haven't been able to resolve it.

Error Message:

	Probably at least one of the constraints in the following list is one you don't want. 
	Try this: 
		(1) look at each constraint and try to figure out which you don't expect; 
		(2) find the code that added the unwanted constraint or constraints and fix it. 
(
    "<NSLayoutConstraint:0x6000021298b0 'accessoryView.bottom' _UIRemoteKeyboardPlaceholderView:0x10460dd10.bottom == _UIKBCompatInputView:0x1059220e0.top   (active)>",
    "<NSLayoutConstraint:0x60000217a620 'assistantHeight' SystemInputAssistantView.height == 45   (active, names: SystemInputAssistantView:0x10591ce60 )>",
    "<NSLayoutConstraint:0x60000217d090 'assistantView.bottom' SystemInputAssistantView.bottom == _UIKBCompatInputView:0x1059220e0.top   (active, names: SystemInputAssistantView:0x10591ce60 )>",
    "<NSLayoutConstraint:0x60000217d040 'assistantView.top' V:[_UIRemoteKeyboardPlaceholderView:0x10460dd10]-(0)-[SystemInputAssistantView]   (active, names: SystemInputAssistantView:0x10591ce60 )>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x60000217d040 'assistantView.top' V:[_UIRemoteKeyboardPlaceholderView:0x10460dd10]-(0)-[SystemInputAssistantView]   (active, names: SystemInputAssistantView:0x10591ce60 )>

This error appears in the console when I click on the TextField in my LoginView while running the code on a simulation. The app doesn't crash, but the console indicates there is a constraint conflict related to the keyboard. Here's my LoginView:


struct LoginView: View {
    @StateObject var viewModel = LoginViewModel()
    
    var body: some View {
        NavigationStack {
            VStack {
                
                Spacer()
                
                Image("logo")
                    .resizable()
                    .scaledToFit()
                    .frame(width: 150, height: 100)
                
                VStack {
                    TextField("Enter your email", text: $viewModel.email)
                        .autocapitalization(/*@START_MENU_TOKEN@*/.none/*@END_MENU_TOKEN@*/)
                        .modifier(TextFieldModifier())
                    
                    SecureField("Enter your password", text: $viewModel.password)
                        .modifier(TextFieldModifier())
                }
                
                Button {
                    print("Show forgot password")
                } label: {
                    Text("Forgot Password")
                        .font(.footnote)
                        .fontWeight(.semibold)
                        .padding(.top)
                        .padding(.trailing, 20)
                }
                .frame(maxWidth: .infinity, alignment: .trailing)
                
                Button {
                    Task { try await viewModel.signIn() }
                } label: {
                    Text("Login")
                        .font(.subheadline)
                        .fontWeight(.semibold)
                        .foregroundColor(.white)
                        .frame(width: 360, height: 44)
                        .background(Color(.black))
                        .cornerRadius(8)
                }
                .padding(.vertical)
                
                HStack {
                    Rectangle()
                        .frame(width: (UIScreen.main.bounds.width / 2) - 40, height: 0.5)
                        
                    Text("OR")
                        .font(.footnote)
                        .fontWeight(.semibold)
                        .foregroundColor(.gray)
                    
                    Rectangle()
                        .frame(width: (UIScreen.main.bounds.width / 2) - 40, height: 0.5)
                }
                .foregroundColor(.gray)
                
                HStack {
                    Image("facebook_logo")
                        .resizable()
                        .frame(width: 20, height: 20)
                    
                    Text("Continue with Facebook")
                        .font(.footnote)
                        .fontWeight(.semibold)
                        .foregroundColor(Color(.systemBlue))
                }
                .padding(.top, 8)
                
                Spacer()
                
                Divider()
                
                NavigationLink {
                    AddEmailView()
                        .navigationBarBackButtonHidden(true)
                } label: {
                    HStack (spacing: 3) {
                        Text("Don't have an account?")
                        
                        Text("Sign Up")
                            .fontWeight(.semibold)
                    }
                    .font(.footnote)
                }
                .padding(.vertical, 16)
            }
        }
    }
}

#Preview {
    LoginView()
}

And my TextFieldModifier:


struct TextFieldModifier: ViewModifier {
    func body(content: Content) ->some View {
        content
            .font(.subheadline)
            .padding(12)
            .background(Color(.systemGray6))
            .cornerRadius(10)
            .padding(.horizontal, 24)
            .padding(.top)
    }
}

Attempts to Resolve:

  1. I've checked the TextFieldModifier for any potential issues but it seems standard.
    
  2. I've tried simplifying the view by removing other elements, but the issue persists.
    
  3. The issue seems to occur regardless of the simulator device or iOS version I use.
    

Questions:

  1. What could be causing this Auto Layout constraint conflict in a SwiftUI app?
    
  2. Are there any known issues with SwiftUI's TextField and keyboard interactions that might lead to such constraints issues?
    
  3. Any suggestions on how to debug or resolve this constraint conflict?
    
Post not yet marked as solved Up vote post of best_pc Down vote post of best_pc
692 views

Replies

Have you solved this issue?

I've also had the same issue with a login view with a warning that denote the exact same constraints your warning did. I completely stripped my view, and after doing so was able to pinpoint what was causing the issue.

I have a view called InputView that had a text field, and depending on a Boolean parameter, it'd give me either a SecureField or a TextField:

        if isSecureField {
            SecureField(placeholder, text: $text)//.textInputAutocapitalization(.never)
                //.font(.system(size: 15)).frame(height: 30)
        } else {
            TextField(placeholder, text: $text).textInputAutocapitalization(.never)
                .font(.system(size: 15)).frame(height: 30)
        }

Upon getting rid of the if statement and making the view only for a TextField and eliminating the isSecureField parameter, the error did not occur anymore:

            TextField(placeholder, text: $text).textInputAutocapitalization(.never)
                .font(.system(size: 15)).frame(height: 30)

I wish I could tell you why this happens, but I don't really know and it doesn't seem like your code puts you in the same situation as me. Despite figuring out that error, I still get these:

<0x10710add0> Gesture: System gesture gate timed out. CAReportingClient.mm:532 Attempted to remove a reporter not created by this client { careporter_id=17,540,646,436,865 } -[RTIInputSystemClient remoteTextInputSessionWithID:performInputOperation:] perform input operation requires a valid sessionID

, so my code isn't perfect either. I hope I could help!