Swiftui Textfield Max Length

SwiftUI TextField max length

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.

How to set textfield character limit SwiftUI?

No need to use didSet on your published property. You can add a modifier to TextField and limit the string value to its prefix limited to the character limit:

import SwiftUI

struct ContentView: View {
@ObservedObject var textBindingManager = TextBindingManager(limit: 5)
var body: some View {
TextField("Placeholder", text: $textBindingManager.phoneNumber)
.padding()
.onChange(of: textBindingManager.phoneNumber, perform: editingChanged)
}
func editingChanged(_ value: String) {
textBindingManager.phoneNumber = String(value.prefix(textBindingManager.characterLimit))
}
}


struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}


class TextBindingManager: ObservableObject {
let characterLimit: Int
@Published var phoneNumber = ""
init(limit: Int = 10){
characterLimit = limit
}
}

Is it possible to set a character limit on a TextField using SwiftUI?

Here is one way, not sure if it was mentioned in the other examples you gave:

@State var text = ""

var body: some View {
TextField("text", text: $text)
.onReceive(text.publisher.collect()) {
self.text = String($0.prefix(5))
}
}

The text.publisher will publish each character as it is typed. Collect them into an array and then just take the prefix.

Limit TextField to x amount of characters using SwiftUI

U can use this:

.onReceive(variable.publisher.collect()) {
variable = String($0.prefix(4))
}

Code for textfield character limit isn't working(SwiftUI)

Your solution is lies in SwiftUI's subscriber .onReceive,

Make sure that your property hasReachedLimit must not marked with @Published else it will trigger infinite loop of view body rendering.

Below shown code works as your expectation.

class TextLimiter: ObservableObject {
let limit: Int
@Published var value = ""
var hasReachedLimit = false

init(limit: Int) {
self.limit = limit
}
}

struct Strix: View {
@ObservedObject var input = TextLimiter(limit: 5)
var body: some View {
TextField("Text Input",
text: $input.value)
.border(Color.red,
width: $input.hasReachedLimit.wrappedValue ? 1 : 0 )
.onReceive(Just(self.input.value)) { inputValue in

self.input.hasReachedLimit = inputValue.count > self.input.limit

if inputValue.count > self.input.limit {
self.input.value.removeLast()
}
}
}
}

BTW this is not an efficient solution.

How to limit the number of characters while also allowing only a subset of characters in a TextField?

You can simply filter all characters that is whole number and get the first 10 characters of the resulting string. You would need also to check if the string is empty and set the value back to zero:



import SwiftUI
import Combine

struct ContentView: View {
@State private var text = "0"
let maxLength = 10
var body: some View {
TextField("", text: $text)
.keyboardType(.numberPad)
.onReceive(Just(text)) {
guard !$0.isEmpty else {
self.text = "0"
return
}
if let value = Int($0.filter(\.isWholeNumber).prefix(maxLength)) {
self.text = String(value)
}
}
}
}

Exceeding max Text() concatenation length - SwiftUI -

Hmm... unexpected limitation... anyway - learn something new.

Ok, here is improved algorithm, which should move that limitation far away.

Tested with Xcode 12 / iOS 14. (also updated code in referenced topic Highlight a specific part of the text in SwiftUI)

func hilightedText(str: String, searched: String) -> Text {
guard !str.isEmpty && !searched.isEmpty else { return Text(str) }

var result = Text("")

var range = str.startIndex..<str.endIndex
repeat {
guard let found = str.range(of: searched, options: .caseInsensitive, range: range, locale: nil) else {
result = result + Text(str[range])
break
}

let prefix = str[range.lowerBound..<found.lowerBound]
result = result + Text(prefix) + Text(str[found]).bold().foregroundColor(.yellow)

range = found.upperBound..<str.endIndex
} while (true)

return result
}

demo



Related Topics



Leave a reply



Submit