ahe*_*eze 7 ios swift swiftui observableobject
我知道,这是“无法在 iOS XX 中工作”问题之一,但我完全陷入困境......
所以我有一个ObservableObject继承自 的类NSObject,因为我需要监听 的委托方法UISearchResultsUpdating。
class SearchBarListener: NSObject, UISearchResultsUpdating, ObservableObject {
@Published var searchText: String = ""
let searchController: UISearchController = UISearchController(searchResultsController: nil)
override init() {
super.init()
self.searchController.searchResultsUpdater = self
}
func updateSearchResults(for searchController: UISearchController) {
/// Publish search bar text changes
if let searchBarText = searchController.searchBar.text {
print("text: \(searchBarText)")
self.searchText = searchBarText
}
}
}
struct ContentView: View {
@ObservedObject var searchBar = SearchBarListener()
var body: some View {
Text("Search text: \(searchBar.searchText)")
.padding()
/// more code that's not related
}
}
Run Code Online (Sandbox Code Playgroud)
问题是,即使print("text: \(searchBarText)")打印得很好,它Text("Search text: \(searchBar.searchText)") 也永远不会更新(在 iOS 13 中)。在 iOS 14 中运行良好。
这是一个最小的可重现示例:
class SearchBarTester: NSObject, ObservableObject {
@Published var searchText: String = ""
override init() {
super.init()
DispatchQueue.main.asyncAfter(deadline: .now() + 5) {
print("updated")
self.searchText = "Updated"
}
}
}
struct ContentView: View {
@ObservedObject var searchBar = SearchBarTester()
var body: some View {
NavigationView {
Text("Search text: \(searchBar.searchText)")
.padding()
}
}
}
Run Code Online (Sandbox Code Playgroud)
5秒后,控制台中打印出“updated”,但Text没有改变。在 iOS 14 中,“搜索文本:已更新”Text的更改符合预期。
但是,如果我不继承NSObject,iOS 13 和 iOS 14都可以工作!
class SearchBarTester: ObservableObject {
@Published var searchText: String = ""
init() {
DispatchQueue.main.asyncAfter(deadline: .now() + 5) {
print("updated")
self.searchText = "Updated"
}
}
}
Run Code Online (Sandbox Code Playgroud)
我认为这个问题与从类继承有关。也许这是 iOS 14 中修复的问题。但是有人知道发生了什么吗?
感谢@Cuneyt的回答!这是最终起作用的代码:
import SwiftUI
import Combine /// make sure to import this
class SearchBarTester: NSObject, ObservableObject {
let objectWillChange = PassthroughSubject<Void, Never>()
@Published var searchText: String = "" {
willSet {
self.objectWillChange.send()
}
}
override init() {
super.init()
DispatchQueue.main.asyncAfter(deadline: .now() + 5) {
print("updated")
self.searchText = "Updated"
}
}
}
Run Code Online (Sandbox Code Playgroud)
似乎在 iOS 13 上,如果您对对象进行子类化并且不ObservableObject直接符合(如 中所示class SearchBarTester: ObservableObject),则需要添加以下样板代码:
@Published var searchText: String = "" {
willSet {
objectWillChange.send()
}
}
Run Code Online (Sandbox Code Playgroud)
但是,调用默认值objectWillChange仍然不起作用,因此您需要自己再次定义它:
let objectWillChange = PassthroughSubject<Void, Never>()
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2105 次 |
| 最近记录: |