SwiftUI 无法添加 onChange 事件
SwiftUI can not add onChange event
我有一个显示消息列表的视图。每当添加新消息时,我都想滚动到底部。我正在尝试向 ForEach
添加一个 onChange
事件,但这会破坏我的代码并出现一些奇怪的错误:
Referencing instance method 'onChange(of:perform:)' on 'Array' requires that 'Message' conform to 'Equatable'
有时
The compiler is unable to type-check this expression in reasonable time; try breaking up the expression into distinct sub-expressions
当我删除 onChange
时,一切都符合。
这里是 Message
模型:
struct Message: Identifiable {
var id = UUID()
var text: String
var createdAt: Date = Date()
var senderID: String
var seen: Bool
init(dictionary: [String: Any]) {
self.text = dictionary["text"] as? String ?? ""
self.senderID = dictionary["senderID"] as? String ?? ""
self.seen = dictionary["seen"] as? Bool ?? false
}
}
我做错了什么?
`ForEach
struct MessagesView: View {
@ObservedObject var messagesViewModel: MessagesViewModel
var body: some View {
VStack {
ScrollView(.vertical, showsIndicators: false, content: {
ScrollViewReader { reader in
VStack(spacing: 20) {
ForEach(messagesViewModel.request.messages) { message in
Text(message.text)
.id(message.id)
}
.onChange(of: messagesViewModel.request.messages) { (value) in
reader.scrollTo(value.last?.id)
}
}
}
})
}
}
}
如果您的 messages
是 @Published
,则以下内容应该有效(正如我在 Make a list scroll to bottom with SwiftUI 中测试的那样)
struct MessagesView: View {
@ObservedObject var messagesViewModel: MessagesViewModel
var body: some View {
VStack {
ScrollView(.vertical, showsIndicators: false, content: {
ScrollViewReader { reader in
VStack(spacing: 20) {
ForEach(messagesViewModel.request.messages) { message in
Text(message.text)
.id(message.id)
}
.onReceive(messagesViewModel.request.$messages) { (value) in
guard !value.isEmpty else { return }
reader.scrollTo(value.last!.id)
}
}
}
})
}
}
}
我有一个显示消息列表的视图。每当添加新消息时,我都想滚动到底部。我正在尝试向 ForEach
添加一个 onChange
事件,但这会破坏我的代码并出现一些奇怪的错误:
Referencing instance method 'onChange(of:perform:)' on 'Array' requires that 'Message' conform to 'Equatable'
有时
The compiler is unable to type-check this expression in reasonable time; try breaking up the expression into distinct sub-expressions
当我删除 onChange
时,一切都符合。
这里是 Message
模型:
struct Message: Identifiable {
var id = UUID()
var text: String
var createdAt: Date = Date()
var senderID: String
var seen: Bool
init(dictionary: [String: Any]) {
self.text = dictionary["text"] as? String ?? ""
self.senderID = dictionary["senderID"] as? String ?? ""
self.seen = dictionary["seen"] as? Bool ?? false
}
}
我做错了什么?
`ForEach
struct MessagesView: View {
@ObservedObject var messagesViewModel: MessagesViewModel
var body: some View {
VStack {
ScrollView(.vertical, showsIndicators: false, content: {
ScrollViewReader { reader in
VStack(spacing: 20) {
ForEach(messagesViewModel.request.messages) { message in
Text(message.text)
.id(message.id)
}
.onChange(of: messagesViewModel.request.messages) { (value) in
reader.scrollTo(value.last?.id)
}
}
}
})
}
}
}
如果您的 messages
是 @Published
,则以下内容应该有效(正如我在 Make a list scroll to bottom with SwiftUI 中测试的那样)
struct MessagesView: View {
@ObservedObject var messagesViewModel: MessagesViewModel
var body: some View {
VStack {
ScrollView(.vertical, showsIndicators: false, content: {
ScrollViewReader { reader in
VStack(spacing: 20) {
ForEach(messagesViewModel.request.messages) { message in
Text(message.text)
.id(message.id)
}
.onReceive(messagesViewModel.request.$messages) { (value) in
guard !value.isEmpty else { return }
reader.scrollTo(value.last!.id)
}
}
}
})
}
}
}