SwiftUI TextField max length

后端 未结 6 943
伪装坚强ぢ
伪装坚强ぢ 2020-11-30 06:52

Is it possible to set a maximum length for TextField? I was thinking of handling it using onEditingChanged event but it is only called when the us

6条回答
  •  囚心锁ツ
    2020-11-30 07:04

    To make this flexible, you can wrap the Binding in another Binding that applies whatever rule you want. Underneath, this employs the same approach as Alex's solutions (set the value, and then if it's invalid, set it back to the old value), but it doesn't require changing the type of the @State property. I'd like to get it to a single set like Paul's, but I can't find a way to tell a Binding to update all its watchers (and TextField caches the value, so you need to do something to force an update).

    Note that all of these solutions are inferior to wrapping a UITextField. In my solution and Alex's, since we use reassignment, if you use the arrow keys to move to another part of the field and start typing, the cursor will move even though the characters aren't changing, which is really weird. In Paul's solution, since it uses prefix(), the end of the string will be silently lost, which is arguably even worse. I don't know any way to achieve UITextField's behavior of just preventing you from typing.

    extension Binding {
        func allowing(predicate: @escaping (Value) -> Bool) -> Self {
            Binding(get: { self.wrappedValue },
                    set: { newValue in
                        let oldValue = self.wrappedValue
                        // Need to force a change to trigger the binding to refresh
                        self.wrappedValue = newValue
                        if !predicate(newValue) && predicate(oldValue) {
                            // And set it back if it wasn't legal and the previous was
                            self.wrappedValue = oldValue
                        }
                    })
        }
    }
    

    With this, you can just change your TextField initialization to:

    TextField($text.allowing { $0.count <= 10 }, ...)
    

提交回复
热议问题