如何通过函数格式化 TextField 输入字符串?
Posted
技术标签:
【中文标题】如何通过函数格式化 TextField 输入字符串?【英文标题】:How to format TextField input string by function? 【发布时间】:2019-10-28 09:16:39 【问题描述】:我有一个用于电话输入的简单 TextField,并且希望在每次更改时对其进行格式化。
我正在使用 PhoneNumberKit,它工作正常,但我不明白如何在 textField 中的值更改后调用格式化函数。
电话格式化功能。
import SwiftUI
import PhoneNumberKit
import Combine
func formatTelephone(telephone : String) -> String
do
let phoneNumber = PartialFormatter().formatPartial(telephone)
print(phoneNumber)
return phoneNumber
catch
print("Generic parser error")
它做了这样的事情:
formatTelephone("79152140700") -> "7 (915) 214 08-00"
formatTelephone("791521") -> "7 (915) 21"
我有一个这样的 TextField
TextField("915 214 07 00" , text: $telephoneManager.telephone)
在每次输入数字后,整个文本字段标签都需要通过 func 格式化,并以更好的方式显示用户的输入。
【问题讨论】:
您应该监听文本更改并在每次更改后调用您的 formatTelephone 方法。你可以在这里看到如何做到这一点:***.com/questions/28394933/… 如果您想支持多个国家/地区,自己实施是一场噩梦。我使用了一个很酷的库 -> github.com/marmelroy/PhoneNumberKit 【参考方案1】:为了得到你想要的,你需要使用Combine(视图模型中两个方法的实现取决于你,因为它们完全取决于你的需要):
import SwiftUI
import Combine
class ContentViewModel: ObservableObject
@Published var phoneNumber = ""
private var toCancel: AnyCancellable!
init()
toCancel = $phoneNumber
.filter !self.isFormatValid($0)
.map self.convert($0)
.receive(on: RunLoop.main)
.assign(to: \.phoneNumber, on: self)
private func isFormatValid(_ str: String) -> Bool
//here you must check if _str_ is already in the right format
true //just to make this example compile, but clearly this must be replaced with your code
private func convert(_ str: String) -> String
//convert your string to be in the right format
"string in the correct format" //just to make this example compile, but clearly this must be replaced with your code
deinit
toCancel.cancel()
struct ContentView: View
@ObservedObject var contentViewModel = ContentViewModel()
var body: some View
TextField("Your phone number...", text: $contentViewModel.phoneNumber)
struct ContentView_Previews: PreviewProvider
static var previews: some View
ContentView()
步骤是(查看视图模型初始化):
phoneNumber
是 @Published
属性,因此您可以订阅的发布者“支持它”。那么,让我们订阅那个发布者吧。
您必须检查文本字段中的字符串是否已采用正确的格式。这是最重要的:如果你错过了这一步,你最终会陷入无限循环。这是通过.filter
运算符完成的。仅当 .filter
运算符返回 true 时,才会向下转发事件(在这种情况下,如果字符串格式无效,则返回 true)。
使用.map
运算符,您可以更改字符串(格式错误)并以正确的格式返回字符串。
.receive
允许您在感兴趣的线程上转发事件。在这种情况下,主线程(因为您要更新文本字段)。
.assign
只是将新值分配给文本字段。
【讨论】:
非常感谢。效果很好!但是现在我有一个问题,文本光标(插入符号)在格式化后没有停留在单词的末尾。示例:输入在文本字段“1234”中,当我输入“5”时,字符串“12345”触发格式化功能,它变成类似于“1234-5”的东西,所以字符串变长了,但是光标(插入符号) 像“1234-|5”一样停留在“-”和“5”之间,因此下一个字符将不会拼写在数字的末尾。也许你经历过,如果你再次提供帮助,我会很高兴。 @NikitaK。你找到解决办法了吗?以上是关于如何通过函数格式化 TextField 输入字符串?的主要内容,如果未能解决你的问题,请参考以下文章
如何在附加到 TextField 的 swift @Published didSet 中正确格式化字符串?