【发布时间】:2019-07-10 11:23:14
【问题描述】:
我发现我认为是@ObjectBinding 中的一个错误。对于 @BindableObject 异步调用其 didChange.send() 的情况,有时依赖于该更改的视图不会失效,因此它们的主体不再被请求,它们的外观也不会更新。
List 视图中的行应该每秒更新一次。起初它工作正常。但是,当使用“+”按钮添加新行时,事情开始横向发展。
我使行可点击,所以当它们被点击时,@State 变量会改变以改变文本的颜色。由于正确检测到此绑定,因此视图无效并且其外观发生变化。这表明计时器实际上正在运行,即使视图在被点击后才显示它。
请注意,以下代码的唯一目的是演示这种奇怪的行为。我不是在寻找解决方法。带着这个问题,我的目的是确认这是否是一个错误,如果不是,我做错了什么。
在某些其他情况下,将 @ObjectBinding 替换为 @EnvironmentObject 可以解决此问题。但在这种情况下,它只会有一点改善。
我在回答另一个问题时遇到了这个问题:SwiftUI and Combine not working smoothly when downloading image
更新:顺便说一句,如果@ObjectBinding 被@State 替换,一切顺利。
import SwiftUI
import Combine
struct Row: Equatable {
let id: Int
let name: String
}
struct ContentView : View {
@State private var rows: [Row] = [Row(id: 0, name: "Row #0"), Row(id: 1, name: "Row #1")]
var body: some View {
NavigationView {
List(rows.identified(by: \.id)) { row in
RowView(row: row, rowData: RowData())
}
.navigationBarItems(trailing:
Button(action: {
self.addRow()
}, label: {
Text("+").font(.system(size: 36.0))
}))
}
}
func addRow() {
rows.append(Row(id: rows.count, name: "Row #\(rows.count)"))
}
}
struct RowView: View {
let row: Row
@ObjectBinding var rowData: RowData
@State private var showBlue = false
var body: some View {
Text("\(row.name) - Seconds \(rowData.value)").foregroundColor(showBlue ? Color.blue : Color.primary)
.tapAction {
self.showBlue.toggle()
}
}
}
class RowData: BindableObject {
var didChange = PassthroughSubject<Void, Never>()
var value: Int = 1 {
didSet { didChange.send() }
}
init() {
update()
}
func update() {
DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(1)) {
self.value += 1
self.update()
}
}
}
【问题讨论】:
标签: swiftui