Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SwiftUI TextField max length

Tags:

ios

swift

swiftui

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 user begins/finishes editing and not called while user is typing. I've also read the docs but haven't found anything yet. Is there any workaround?

TextField($text, placeholder: Text("Username"), onEditingChanged: { _ in   print(self.$text) }) {   print("Finished editing") } 
like image 583
M Reza Avatar asked Jun 06 '19 10:06

M Reza


People also ask

What is the maximum length of text field character?

The maximum length of a text field can be 255. Explanation: Text is a readable pattern of characters and the words can be encoded into computer-readable formats.

How do I disable TextField in SwiftUI?

In SwiftUI iOS apps, you can disable the list item's text field until someone taps the Edit button. In edit mode you can tap the list item to rename it. When the person taps the Done button, disable the text field.


2 Answers

You can do it with Combine in a simple way.

Like so:

import SwiftUI import Combine  struct ContentView: View {      @State var username = ""      let textLimit = 10 //Your limit          var body: some View {         //Your TextField         TextField("Username", text: $username)         .onReceive(Just(username)) { _ in limitText(textLimit) }     }      //Function to keep text length in limits     func limitText(_ upper: Int) {         if username.count > upper {             username = String(username.prefix(upper))         }     } } 
like image 21
Roman Shelkford Avatar answered Sep 25 '22 05:09

Roman Shelkford


A slightly shorter version of Paulw11's answer would be:

class TextBindingManager: ObservableObject {     @Published var text = "" {         didSet {             if text.count > characterLimit && oldValue.count <= characterLimit {                 text = oldValue             }         }     }     let characterLimit: Int      init(limit: Int = 5){         characterLimit = limit     } }  struct ContentView: View {     @ObservedObject var textBindingManager = TextBindingManager(limit: 5)          var body: some View {         TextField("Placeholder", text: $textBindingManager.text)     } } 

All you need is an ObservableObject wrapper for the TextField string. Think of it as an interpreter that gets notified every time there's a change and is able to send modifications back to the TextField. However, there's no need to create the PassthroughSubject, using the @Published modifier will have the same result, in less code.

One mention, you need to use didSet, and not willSet or you can end up in a recursive loop.

like image 67
Alex Ioja-Yang Avatar answered Sep 23 '22 05:09

Alex Ioja-Yang