Swift / 在 ScrollView 中定义位置后更改设备方向时,SwitUI 应用程序崩溃
Swift / SwitUI App crashes, when changing device Orientation after defining a position in 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
持有对父小部件的引用,它在重建时被释放,但子小部件没有重建,因为参数没有改变所以它命中释放指针.
如果我之前设置了 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
持有对父小部件的引用,它在重建时被释放,但子小部件没有重建,因为参数没有改变所以它命中释放指针.