swift - 使用组合解析电话号码字符串
问题描述
我正在努力思考Combine 的工作原理。我相信当我使用 .assign 运算符来改变我正在操作的 @Published 属性时,我做错了。我已阅读有关发布者、订阅者和运营商的文档。但是如果我不希望它成为函数调用,我对在哪里创建发布者有点松散。
import SwiftUI
import Combine
struct PhoneNumberField: View {
let title: String
@ObservedObject var viewModel = ViewModel()
var body: some View {
TextField(title,text: $viewModel.text)
}
class ViewModel: ObservableObject {
@Published var text: String = ""
private var disposables = Set<AnyCancellable>()
init() {
$text.map { value -> String in
self.formattedNumber(number: value)
}
//something wrong here
.assign(to: \.text, on: self)
.store(in: &disposables)
}
func formattedNumber(number: String) -> String {
let cleanPhoneNumber = number.components(separatedBy: CharacterSet.decimalDigits.inverted).joined()
let mask = "+X (XXX) XXX-XXXX"
var result = ""
var index = cleanPhoneNumber.startIndex
for ch in mask where index < cleanPhoneNumber.endIndex {
if ch == "X" {
result.append(cleanPhoneNumber[index])
index = cleanPhoneNumber.index(after: index)
} else {
result.append(ch)
}
}
return result
}
}
}
struct PhoneNumberParser_Previews: PreviewProvider {
static var previews: some View {
PhoneNumberField(title: "Phone Number")
}
}
解决方案
使用.receive(on:)
:
$text.map { self.formattedNumber(number: $0) }
.receive(on: DispatchQueue.main)
.sink(receiveValue: { [weak self] value in
self?.text = value
})
.store(in: &disposables)
这将允许您监听变量的变化并在队列text
中更新它。如果要更新some 读取的变量,则必须main
使用queue 。main
@Published
View
并且为了避免保留循环(self
-> disposables
-> assign
-> self
)sink
与weak self
.
推荐阅读
- reactjs - 在 onChange 函数中使用时超时未清除
- php - 更改我的 MVC 视图类以允许 AJAX 响应使用视图
- javascript - 我无法提交,因为读取了未定义的属性“值”
- amazon-web-services - 实例类型更改日志
- python - SMOTEBoosting 算法的 Python 包
- python - 如何在 Python 中调试嵌套字典的递归函数?
- html - 在导航栏中对齐图像/图标
- python - 如何通过熊猫结果显示每日直方图在pyecharts或其他?
- android - 我可以在华为 AppGallery 上发布的安卓应用中使用 Facebook Audience Network (FAN) 吗?
- c - 定义后如何重命名函数