Lch
Lch

Reputation: 41

swiftui ios15 keyboard avoidance issue on custom textfield

Repost question from this Adjust View up with Keyboard show in SwiftUI 3.0 iOS15.

SwiftUI keyboard avoidance won't show the whole textfield including the overlay.

I already tried a lot different ways from googling.
Does anyone have any solution for this?

struct ContentView: View {
    @State var text: String = ""
    var body: some View {
        ScrollView {
            VStack {
                Spacer(minLength: 600)
                TextField("Placeholder", text: $text)
                    .textFieldStyle(CustomTextFieldStyle())
            }
        }
    }
}

struct CustomTextFieldStyle: TextFieldStyle {
    func _body(configuration: TextField<Self._Label>) -> some View {
        configuration
            .padding(10)
            .overlay(
                RoundedRectangle(cornerRadius: 20)
                    .stroke(Color.red, lineWidth: 5)
            )
    }
}

Image Preview

Upvotes: 4

Views: 650

Answers (1)

NiceIceEyes
NiceIceEyes

Reputation: 11

You can write the custom UITextFeild, in which the intrinsicContentSize will be overridden.

Example:

final class _UITextField: UITextField {
    override var intrinsicContentSize: CGSize {
        CGSize(width: UIView.noIntrinsicMetric, height: 56)
    }
}

Then, you can write your own implementation of TextField, using UIViewRepresentable protocol and UITextFieldDelegate:

struct _TextField: UIViewRepresentable {
    private let title: String?
    @Binding var text: String

    let textField = _UITextField()

    init(
        _ title: String?,
        text: Binding<String>
    ) {
        self.title = title
        self._text = text
    }

    func makeCoordinator() -> _TextFieldCoordinator {
        _TextFieldCoordinator(self)
    }

    func makeUIView(context: Context) -> _UITextField {
        textField.placeholder = title
        textField.delegate = context.coordinator
        return textField
    }

    func updateUIView(_ uiView: _UITextField, context: Context) {}
}

final class _TextFieldCoordinator: NSObject, UITextFieldDelegate {
    private let control: _TextField

    init(_ control: _TextField) {
        self.control = control
        super.init()
        control.textField.addTarget(self, action: #selector(textFieldEditingChanged), for: .editingChanged)
    }

    @objc private func textFieldEditingChanged(_ textField: UITextField) {
        control.text = textField.text ?? ""
    }
}

Upvotes: 1

Related Questions