@Environment(.解散)的错误导致弹出视图加载一个新版本的自己在iOS 15



导航到INCR: 3,点击导航栏返回按钮或取消按钮,你会注意到相同的视图再次被调用,但这次它是一个新版本,因为onAppear,firstLoad = truerand是不同的值。

如果你注释掉@Environment(.dismiss) var dismissdismiss(),一切都像在iOS 14中那样工作。@Environment(.presentationMode) var presentationMode

也会出现此问题。不确定这是一个bug还是我犯了一个愚蠢的错误,但这个问题导致了我的应用程序大量的问题,因为我必须能够以编程方式解散一个视图,所以任何输入将是感激的。

struct DetailView: View {

@Environment(.dismiss) var dismiss

@State var isPresenting = false

@State var incrInt = 0

@State var firstLoad = true

@State var rand = Int.random(in: 1..<500)

var body: some View {

Text("INCR: (incrInt) RAND: (rand)")

Button("NAVIGATE"){
isPresenting = true
}
Button("DISMISS"){
dismiss()
}

.onAppear(perform: {

if firstLoad{
print("ON APPEAR FIRST LOAD")
print(incrInt)
print(rand)
print("n")
firstLoad = false
}
})

NavigationLink(destination: DetailView(incrInt: (incrInt + 1)), isActive: $isPresenting){}

}
}
struct ContentView: View {
var body: some View {
NavigationView{
VStack{
DetailView()
}
}
}
}

视频链接

https://i.imgur.com/qpu7NT7.mp4

更新1:ViewModel Source of Truth

class DetailViewModel: ObservableObject {

@Published var isPresenting = false

var incr: Int

var rand = Int.random(in: 1..<500)

init(incr: Int){

self.incr = incr

print("INIT FIRST LOAD")
print(incr)
print(rand)
print("n")
}

}
struct DetailView: View {

@Environment(.dismiss) var dismiss

@StateObject var detailViewModel: DetailViewModel

var body: some View {

Text("INCR: (detailViewModel.incr) RAND: (detailViewModel.rand)")


Button("NAVIGATE"){
detailViewModel.isPresenting = true
}
Button("DISMISS"){
dismiss()
}


NavigationLink(destination: DetailView(detailViewModel: DetailViewModel(incr: (detailViewModel.incr + 1))), isActive: $detailViewModel.isPresenting){}


}
}
struct ContentView: View {
var body: some View {
NavigationView{
VStack{
DetailView(detailViewModel: DetailViewModel(incr: 0))
}
}
}
}

我通过将.navigationViewStyle(.stack)添加到NavigationView来解决它。我以为那是iOS上默认的导航视图样式,但也许在iOS 15中改变了。

在你的"代码,你没有使用单一的真理来源。您正在创建并将新的DetailViewModel传递给DetailView每次你点击NavigationLink。只使用1个DetailViewModel,并传递它。此外,你正在改变isPresenting,所以所有依赖于它的视图都将被更新为"new"价值。这层叠不是你想要的。修改你的逻辑。使用DetailViewModel跨视图保持模型的状态是个好主意。试试这样做:

class DetailViewModel: ObservableObject {
// @Published var isPresenting = false  // <-- not relevant

var incr: Int
var rand = Int.random(in: 1..<500)

init(incr: Int) {
self.incr = incr
print("----> DetailViewModel init --> inc: (incr) --> rand: (rand) n")
}

func doIncr(_ incr: Int) {
self.incr = incr
print("----> DetailViewModel doIncr --> inc: (incr) --> rand: (rand) n")
}
}
struct DetailView: View {
@Environment(.dismiss) var dismiss
@ObservedObject var detailViewModel: DetailViewModel
@State var showThyself = false  // <--- here

var body: some View {
Text("DetailView  INCR: (detailViewModel.incr) RAND: (detailViewModel.rand)")
Button("NAVIGATE"){
detailViewModel.doIncr(detailViewModel.incr + 1)
showThyself = true
}
Button("DISMISS"){
dismiss()
}
NavigationLink(destination: DetailView(detailViewModel: detailViewModel), isActive: $showThyself){}
.onAppear {
// do something with the current state of your DetailViewModel
print("----> DetailView onAppear n")
}
}
}
struct ContentView: View {
var detailViewModel = DetailViewModel(incr: 0)  // <--- here
var body: some View {
NavigationView{
VStack{
DetailView(detailViewModel: detailViewModel)
}
}
}
}  

相关内容

  • 没有找到相关文章

最新更新