我如何确定一个视图在SwiftUI的最后一行代码之前完全呈现?

swift朋克

我有一些代码,它们必须在View完全渲染和绘制之后必须被解雇,正如我们所知道的,我们对某个View拥有onAppear或onChange,它们对于了解View是否已出现或正在更改中很有用,但是它们是确保视图已100%渲染没有用,例如,如果我们在视图中获得了ForEach,List或Form,则可以看到View,但是由于层次结构,ForEach仍可以在View上工作,所以这意味着View可以没有完全加载,如果您给它一个动画修改器,那么它也会变得更加引人注目,因此您也可以看到它,所以我的目标是知道我如何才能100%确保将所有内容渲染到我的View中,而不再行代码运行以渲染视图?

感谢您的阅读和帮助


例:

import SwiftUI


struct ContentView: View {

    var body: some View {

        HierarchyView()
            .onAppear() { print("HierarchyView"); print("- - - - - - - - - - -") }

    }

}



struct HierarchyView: View {

    var body: some View {

        ZStack {

            Color
                .blue
                .ignoresSafeArea()
                .onAppear() { print("blue"); print("- - - - - - - - - - -")  }

            VStack {
                
                Text("Top text")
                    .onAppear() { print("Top Text") }
                
                Spacer()
                    .onAppear() { print("Top Spacer") }
                
            }
            .onAppear() { print("Top VStack"); print("- - - - - - - - - - -")  }

            VStack {

                VStack {

                    VStack {

                        ForEach(0..<3, id:\..self) { index in
                            
                            Text(index.description)
                                .onAppear() { print(index.description); if (index == 0) { print("Last of second ForEach!!!") } }
                            
                        }
  
                    }
                    .onAppear() { print("Middle VStack Inside DEEP"); print("- - - - - - - - - - -")  }

                }
                .onAppear() { print("Middle VStack Inside"); print("- - - - - - - - - - -")  }

            }
            .onAppear() { print("Middle VStack Outside"); print("- - - - - - - - - - -")  }
            
            
            
            VStack {
                
                Spacer()
                    .onAppear() { print("Bottom Spacer") }
                
                
                ForEach(0..<3, id:\..self) { index in
                    
                    Text(index.description)
                        .onAppear() { print(index.description); if (index == 0) { print("Last of first ForEach!!!") } }
                    
                }

                
                
                
                Text("Bottom text")
                    .onAppear() { print("Bottom Text") }
                
            }
            .onAppear() { print("Bottom VStack"); print("- - - - - - - - - - -")  }
            
            
        }
        .onAppear() { print("ZStack of HierarchyView"); print("- - - - - - - - - - -") }
        
        
    }
 
}
新开发者

AFAIK没有通用的方法来告诉所有可能的后代视图何时“出现”(即会触发它们的视图onAppear)。

根据您的想法,“出现”与“呈现”不同。一般而言,每个视图都决定何时渲染其子级。例如,LazyVStack仅在需要渲染时创建其元素。符合的自定义视图UIViewControllerRepresentable可以决定执行其所需的任何操作。

考虑到这一点(假设render ==出现),您可以采用的方法是“跟踪”您关心的“已出现”的视图,并在所有视图都触发时触发回调。

您可以创建一个视图修饰符来跟踪每个视图的“渲染”状态,并用于PreferenceKey收集所有这些数据:

struct RenderedPreferenceKey: PreferenceKey {
    static var defaultValue: Int = 0
    static func reduce(value: inout Int, nextValue: () -> Int) {
        value = value + nextValue() // sum all those remain to-be-rendered
    }
}

struct MarkRender: ViewModifier {
    @State private var toBeRendered = 1
    func body(content: Content) -> some View {
        content
            .preference(key: RenderedPreferenceKey.self, value: toBeRendered)
            .onAppear { toBeRendered = 0 }
    }
}

然后,创建便利方法View以简化其用法:

extension View {
    func trackRendering() -> some View {
        self.modifier(MarkRender())
    }

    func onRendered(_ perform: @escaping () -> Void) -> some View {
        self.onPreferenceChange(RenderedPreferenceKey.self) { toBeRendered in
           // invoke the callback only when all tracked have been set to 0,
           // which happens when all of their .onAppear are called
           if toBeRendered == 0 { perform() }
        }
    }
}

用法是:

VStack {
    ForEach(0..<3, id:\..self) { index in
        Text("\(index)").trackRendering()
    }
}
.onRendered {
    print("Rendered")
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

如何在html代码中选择第一个表格的最后一行?

来自分类Dev

如何找到与我的最后一个值相同的最后一行并输出该行的编号?

来自分类Dev

函数在下一行代码之前完全执行。

来自分类Dev

在最后一行代码的主要方法中,我有一个目录可以从我的桌面运行 maze.txt

来自分类Dev

Python Tkinter树视图-如何确定是否显示最后一个孩子?

来自分类Dev

如何制作一个按钮来关闭使用UIHostingController / SwiftUI呈现的视图?

来自分类Dev

最后一个命令**之前的退出代码?

来自分类Dev

如何检测END之前的awk中的最后一行?

来自分类Dev

我不完全确定我的代码有什么问题,我的IDE给我一个错误

来自分类Dev

在代码的最后一行,我无法打印出结果

来自分类Dev

如何使用jQuery检测一行中的最后一个元素?

来自分类Dev

如何使用记事本++重复一行的最后一个单词

来自分类Dev

如何删除div特定宽度的第一行的最后一个li :: after

来自分类Dev

如何在MySQL中获取上一个最后一行

来自分类Dev

如何在MySQL中获取上一个最后一行

来自分类Dev

如何使用jQuery检测一行中的最后一个元素?

来自分类Dev

如何在php的最后一行更新一个值

来自分类Dev

如何查看一行中最后一个填充的值?

来自分类Dev

如何在PostgreSQL中的一行上获取第一个和最后一个值

来自分类Dev

在表格的最后一行之前添加一行

来自分类Dev

我已将 PCA 相关的 matlab 代码转换为 python 代码,我该如何更正 python 的最后一行代码?

来自分类Dev

我怎样才能让一个函数等到代码前一行完成

来自分类Dev

如何使一行始终显示(使用一个视图)

来自分类Dev

如何使一行始终显示(使用一个视图)

来自分类Dev

如何获取输出的最后一行或退出代码

来自分类Dev

如何使用 Windows 批处理脚本获取文件最后一行的最后一个单词?

来自分类Dev

从工作表中一个表的最后一行复制/粘贴到另一最后一行

来自分类Dev

我想创建一个新列,其中关于 3 个组的第一行和最后一行是 2,否则为 NA

来自分类Dev

找到一行的第一个和最后一个跨度

Related 相关文章

  1. 1

    如何在html代码中选择第一个表格的最后一行?

  2. 2

    如何找到与我的最后一个值相同的最后一行并输出该行的编号?

  3. 3

    函数在下一行代码之前完全执行。

  4. 4

    在最后一行代码的主要方法中,我有一个目录可以从我的桌面运行 maze.txt

  5. 5

    Python Tkinter树视图-如何确定是否显示最后一个孩子?

  6. 6

    如何制作一个按钮来关闭使用UIHostingController / SwiftUI呈现的视图?

  7. 7

    最后一个命令**之前的退出代码?

  8. 8

    如何检测END之前的awk中的最后一行?

  9. 9

    我不完全确定我的代码有什么问题,我的IDE给我一个错误

  10. 10

    在代码的最后一行,我无法打印出结果

  11. 11

    如何使用jQuery检测一行中的最后一个元素?

  12. 12

    如何使用记事本++重复一行的最后一个单词

  13. 13

    如何删除div特定宽度的第一行的最后一个li :: after

  14. 14

    如何在MySQL中获取上一个最后一行

  15. 15

    如何在MySQL中获取上一个最后一行

  16. 16

    如何使用jQuery检测一行中的最后一个元素?

  17. 17

    如何在php的最后一行更新一个值

  18. 18

    如何查看一行中最后一个填充的值?

  19. 19

    如何在PostgreSQL中的一行上获取第一个和最后一个值

  20. 20

    在表格的最后一行之前添加一行

  21. 21

    我已将 PCA 相关的 matlab 代码转换为 python 代码,我该如何更正 python 的最后一行代码?

  22. 22

    我怎样才能让一个函数等到代码前一行完成

  23. 23

    如何使一行始终显示(使用一个视图)

  24. 24

    如何使一行始终显示(使用一个视图)

  25. 25

    如何获取输出的最后一行或退出代码

  26. 26

    如何使用 Windows 批处理脚本获取文件最后一行的最后一个单词?

  27. 27

    从工作表中一个表的最后一行复制/粘贴到另一最后一行

  28. 28

    我想创建一个新列,其中关于 3 个组的第一行和最后一行是 2,否则为 NA

  29. 29

    找到一行的第一个和最后一个跨度

热门标签

归档