【问题标题】:Swift / SwitUI App crashes, when changing device Orientation after defining a position in ScrollView在 ScrollView 中定义位置后更改设备方向时,Swift / SwiftUI App 崩溃
【发布时间】:2021-04-05 04:42:41
【问题描述】:

如果我之前设置了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 中的屏幕方向和滚动视图?

【问题讨论】:

  • 提供的代码不足以重现崩溃,你能提供最小的例子吗?
  • 更新了代码——在尝试它是否崩溃时,我发现它不会在模拟器上崩溃。在模拟器上尝试了我的实际应用程序:按预期工作。不过,我在装有 iOS 14 的 iPhone XS 上的这段代码会崩溃。
  • 尝试将 bool 而不是 GeometryProxy 传递给您的 MainScrollView。我有类似的问题,所以这只是一个猜测

标签: ios swift swiftui orientation scroll-position


【解决方案1】:

GeometryProxy 在您尝试将它传递到任何地方时会导致问题(对我来说也是如此)。 SwiftUI 是封闭源代码,所以我无法解释这里发生了什么神奇的指针问题。但是此代码已确认可以按照 cmets 工作。

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 持有对父小部件的引用,该小部件在重建时被释放,但子小部件没有重建,因为参数没有改变,所以它命中了释放指针。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-30
    • 1970-01-01
    相关资源
    最近更新 更多