SwiftUI 的 onAppear() 和 onDisappear() 在 Xcode 12.1 上多次调用且不一致

Nor*_*ard 7 ios swift swiftui swiftui-list

我在 SwiftUIonAppear()onDisappear()事件中遇到了一些奇怪的行为。我需要能够可靠地跟踪视图何时对用户可见、消失以及任何其他后续出现/消失事件(用例是跟踪移动分析的印象)。

我希望利用与 swiftUI 视图相关的onAppear()onDisappear()事件,但是在使用这些事件时我没有看到一致的行为。行为可能会根据视图修饰符以及我运行应用程序的模拟器而改变。

在下面列出的示例代码中,我希望当ItemListView2出现时,我会在控制台中看到以下打印出来:

button init
button appear
Run Code Online (Sandbox Code Playgroud)

在 iPhone 8 模拟器上,我看到的正是这一点。

但是,在 iPhone 12 模拟器上,我看到:

button init
button appear
button disappear
button appear
Run Code Online (Sandbox Code Playgroud)

当我启用listStyle视图修改器时,事情变得更加奇怪:

button init
button appear
button disappear
button appear
button disappear
button appear
button appear
Run Code Online (Sandbox Code Playgroud)

然而,iPhone 8 保持一致并产生预期的结果。

我还应该指出,在任何情况下,按钮似乎都消失并重新出现在眼前。

这些不一致也不仅仅是模拟器的问题,我在设备上也注意到了它们。

我需要可靠地跟踪这些出现/消失事件。例如,我需要知道列表中的单元格何时出现(滚动到视图中)或消失(滚动到视图外),或者用户何时切换选项卡。

有没有其他人注意到这种行为?对我来说,这似乎是 SwiftUI 中的一个错误,但我不确定,因为我没有足够地使用 SwiftUI 来相信自己能够从 SDK 错误中辨别出程序员错误。如果你们中有人注意到这一点,您是否找到了一个好的解决方法/修复方法?

谢谢,

  • 规范
// Sample code referenced in explanation
// Using Xcode Version 12.1 (12A7403) and iOS 14.1 for all simulators
import SwiftUI

struct ItemListView2: View {

    let items = ["Cell 1", "Cell 2", "Cell 3", "Cell 4"]

    var body: some View {
        ListingView(items: items)
    }
}

private struct ListingView: View {
    let items: [String]

    var body: some View {
        List {
            Section(
                footer:
                    FooterButton()
                    .onAppear { print("button appear") }
                    .onDisappear { print("button disappear") }
            ) {
                ForEach(items) { Text($0) }
            }
        }
//      .listStyle(GroupedListStyle())
    }
}

private struct FooterButton: View {
    init() {
        print("button init")
    }
    var body: some View {
        Button(action: {}) { Text("Button")  }
    }
}
Run Code Online (Sandbox Code Playgroud)

paw*_*222 2

在 SwiftUI 中,您无法控制 a 中的项目何时List 出现消失。视图图由 SwiftUI 内部管理,视图可能随时出现/消失。

但是,您可以将onAppear/onDisappear修饰符附加到最外面的视图:

List {
    Section(footer: FooterButton()) {
        ForEach(items, id: \.self) { 
            Text($0) 
        }
    }
}
.listStyle(GroupedListStyle())
.onAppear { print("list appear") }
.onDisappear { print("list disappear") }
Run Code Online (Sandbox Code Playgroud)