好端端的页面怎么突然莫名闪退到上个界面?
最近在用Realm写一个SwiftUI的分账App,虽然很想用SwiftData,但只支持iOS 17+把我劝退了… 实在不想碰CoreData复杂的逻辑,只好使用RealmSwift… 但Realm也是个大坑啊…(还没写,但估计以后我也不会用了)
正文
我的代码大概是这样的:
import RealmSwift
import SwiftUI
struct SplitView: View {
@ObservedRealmObject var split: Split
@State private var editMember: Bool = false
...
var body: some View {
LazyVGrid(columns: [...], content: {
ForEach(editMember ? split.family!.allparticipants : split.participants, id: \.id) { eachman in
Button {
try! rc.r.write { // rc.r is a shared Realm instance
if split.participants.contains(object: eachman) {
split.thaw()!.participants.remove(object: eachman.thaw()!)
} else {
split.thaw()!.participants.append(eachman.thaw()!)
}
}
} label: {
ZStack {
AvatarView(eachman)
}
}
}
})
Button(action: {
editMember.toggle()
}, label: {
Text(editMember ? "Done" : "Edit Member")
})
}
}
好好的怎么就出了这档子事呢?我一修改split
的内容就崩了…
但我一想,估计也不是崩了,应该是被reload结果NavigationView的处理方式就是退回上级了…
上网搜了一下,感觉跟自己猜想的差不多,并且Realm官网也提到
The @ObservedRealmObject property wrapper invalidates a view when an observed object changes.
好家伙,你直接invalidate整个大View而不是使用到它的小View是吧,好好好
虽然我不信,但是我也试了这个里面的答案,哈哈,果然不对。
如果真是这样的话,继续使用@ObservedRealmObject
肯定达咩了,那我们只能另辟蹊径。
尝试
这篇文章是在尝试我的猜想之前写的。你有幸能跟我一同见证我的想法是否能成功
想法很简单:完全放弃@ObservedRealmObject
,使用@ObservedResults
因为@ObservedResults
不会随便invalidate一整个View,所以只会影响使用Results的子View。
尝试一下:
struct SplitView: View {
@ObservedResults(BigBill.self) private var bigBills
private var bigBill: BigBill {
bigBills.filter({$0.id == bigBillId}).first!
}
}
其它代码不动 情况依旧… 官网说
You can perform a quick write to an ObservedResults collection, and the view automatically updates itself when the observed query changes.
终究还是错付了吗…
那我倒是还有一个终极的办法… 好的终极办法也失败了。
失败
详情请看我服了爸爸:NavigationBar和ToolBar修饰符到底该放在哪里啊???
对于作者来说算是彩蛋
卧槽,等一下,原来是这样吗? 我终于知道为什么之前在制作阁楼的时候每当新添加一个东西,其他的View的动画也开始改变了…原来你小子就是罪魁祸首啊 // 好的你小子不是。再见。