Can't find responder for tag ..., make sure to set a tag using `.responderTag(_:)`
ninnios opened this issue · 4 comments
Hello,
I tried to integrate ResponderChain in order to fix the issue with TextField's tappable area as described here https://stackoverflow.com/questions/56795712/swiftui-textfield-touchable-area & here https://gist.github.com/Amzd/d7d0c7de8eae8a771cb0ae3b99eab73d.
I have my own custom text field which I use everywhere and there I added the extension and the .textFieldFocusableArea() view modifier to the TextField.
However, whenever I click on the text field I get "Can't find responder for tag 9C01...64, make sure to set a tag using .responderTag(_:)
" in the logs and it's not working.
How can I fix this, please?
Okay so what .responderTag(_:)
does is look for a view that returns canBecomeFirstResponder as true.
It can't find that for your custom textfield I think? Kind of hard to speculate without knowing your exact implementation.
Hello,
Here's a part of what the DefaultTextFieldView.swift looks like.
import SwiftUI
import ResponderChain
struct DefaultTextFieldView: View {
@ObservedObject var viewModel: DefaultTextFieldViewModel
var body: some View {
VStack(spacing: 5) {
if viewModel.isSecureField {
SecureField(viewModel.placeholder, text: $viewModel.text)
.font(viewModel.font)
.foregroundColor(viewModel.fontColor)
.disabled(viewModel.isTappable)
.frame(height: viewModel.height)
.disableAutocorrection(true)
.autocapitalization(.none)
} else {
TextField(viewModel.placeholder, text: $viewModel.text)
.frame(height: viewModel.height)
.textFieldFocusableArea()
.font(viewModel.font)
.foregroundColor(viewModel.fontColor)
.disabled(viewModel.isTappable)
.disableAutocorrection(true)
.autocapitalization(.none)
}
}.frame(height: viewModel.height)
.background(viewModel.backgroundColor)
.cornerRadius(viewModel.cornerRadius)
.overlay(
RoundedRectangle(cornerRadius: viewModel.cornerRadius)
.stroke(viewModel.borderColor,
lineWidth: viewModel.borderWidth))
.padding([.leading, .trailing], viewModel.leadingAndTrailingPadding)
}
}
extension View {
public func textFieldFocusableArea() -> some View {
self.modifier(TextFieldFocusableAreaModifier())
}
}
fileprivate struct TextFieldFocusableAreaModifier: ViewModifier {
@EnvironmentObject private var chain: ResponderChain
@State private var id = UUID()
func body(content: Content) -> some View {
content
.contentShape(Rectangle())
.responderTag(id)
.onTapGesture {
chain.firstResponder = id
}
}
}
I am using this text field in the sign-in screen and I show the sign-in screen like this:
SignInView().environmentObject(ResponderChain(forWindow: UIApplication.shared.window))
Uhh, yeah first of all, you're swapping out textfields. So ResponderChain wont know which one you're trying to make firstResponder.
Second, I think the problem with canBecomeFirstResponder returning false is maybe because you disable the textfield? Not sure.
I added the .textFieldFocusableArea()
at the end, right after the padding and that works great :) Thanks