Swift/SwitUI应用程序在ScrollView中定义位置后更改设备方向时崩溃



如果我之前设置了scrollPosition,当我更改设备方向时,我的应用程序会不断崩溃。我的ContentView()看起来很像这样——我正在读取显示大小。

GeometryReader { display in
VStack {
HeaderView()
MainScrollView(display: display)
FooterView()
}
}

display传递到MainScrollView(),其中在ScrollViewReader内部,if-else-语句检查它是否应该加载PortraitMainView()或`LandscapeMainView((

struct MainScrollView: View {
var display: GeometryProxy
var body: some View {

ScrollViewReader { scrollPosition in
ZStack {
ScrollView {
if display.size.width > display.size.height {
LandscapeMainView()
} else {
PortraitMainView()
}
}
Button(action: {
withAnimation {
scrollPosition.scrollTo("C", anchor: .top)
}
}, label: {
Text("Scroll to Position C")
} )
}
}
}
}

LandscapeMainView((和PortaitMainView((看起来像这样:

LandscapeMainView: View {
var body: some View {
VStack {
Text("Item A")
.id("A")
Text("Item B")
.id("B")
Text("Item C")
.id("C")
Text("Item D")
.id("D")
Text("Item E")
.id("E")
}
}
}

一切都很好,我可以翻转方向,它从LandscapeMainView()变为PortraitMainView(),反之亦然。此外,设置scrollPosition在横向和纵向模式下也很有魅力。只有在我设置了scrollPosition,然后改变了方向之后,我的设备才会冻结,并将Thread 1: EXC_BAD_ACCESS (code=1, address=0x30)作为输出。屏幕仍然显示纵向模式,在横向上倾斜,留下一半屏幕空白。有没有更好的方法来处理SwiftUI中的屏幕方向和滚动视图?

GeometryProxy在尝试将其传递到任何位置时(对我来说也是如此(都会导致问题。SwiftUI是封闭源代码的,所以我无法解释这里发生了什么神奇的指针问题。但根据评论,该代码已被确认有效。

GeometryReader { display in
VStack {
HeaderView()
MainScrollView(display: display.size.width > display.size.height)
FooterView()
}
}
struct MainScrollView: View {
var display: Boolean
var body: some View {

ScrollViewReader { scrollPosition in
ZStack {
ScrollView {
if display {
LandscapeMainView()
} else {
PortraitMainView()
}
}
Button(action: {
withAnimation {
scrollPosition.scrollTo("C", anchor: .top)
}
}, label: {
Text("Scroll to Position C")
} )
}
}
}
}

额外的好处:ScrollViewProxy也会发生同样的崩溃,要小心。

我没有受过教育的猜测,为什么会发生这种情况:GeometryProxy持有对父窗口小部件的引用,在重建时被释放,但子窗口小部件没有重建,因为参数没有改变,所以它命中了被释放的指针。

最新更新