首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

为什么当onAppear()放在swiftUI中的NavigationView内的元素上时,会执行两次?(Xcode 12.0)

当将onAppear()放置在SwiftUI中的NavigationView内的元素上时,会执行两次的原因是因为NavigationView在视图层次结构中具有两个层级。

首先,NavigationView本身是一个容器视图,它负责管理导航栏和视图堆栈。当视图首次加载时,NavigationView会出现在屏幕上,从而触发第一次onAppear()回调。

其次,NavigationView内部的元素(例如NavigationLink)也是视图,它们在导航栏中显示为按钮或链接。当用户点击这些按钮或链接时,会导致新的视图被推入导航栈中,并且新的视图将出现在屏幕上。这个过程会触发第二次onAppear()回调。

因此,当将onAppear()放置在NavigationView内的元素上时,会在视图首次加载和每次导航发生时执行两次。

这种行为可以用于在视图加载或导航发生时执行特定的操作,例如加载数据或更新界面。如果你希望只在视图首次加载时执行一次,可以使用状态变量或@State属性包装器来控制onAppear()的执行。

以下是一个示例代码,演示了如何使用状态变量来控制onAppear()的执行:

代码语言:txt
复制
struct ContentView: View {
    @State private var isFirstAppear = true
    
    var body: some View {
        NavigationView {
            VStack {
                Text("Hello, World!")
                    .onAppear {
                        if isFirstAppear {
                            // 只在首次加载时执行
                            print("View appeared for the first time")
                            isFirstAppear = false
                        }
                    }
                
                NavigationLink(destination: DetailView()) {
                    Text("Go to Detail")
                }
            }
        }
    }
}

struct DetailView: View {
    var body: some View {
        Text("Detail View")
    }
}

在上面的示例中,isFirstAppear是一个布尔类型的状态变量,用于跟踪视图是否首次加载。在onAppear()回调中,我们检查isFirstAppear的值,只有在首次加载时执行特定的操作。

希望这个答案能够满足你的需求!如果你有任何其他问题,请随时提问。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

掌握 SwiftUI Safe Area

视图尚未在屏幕可见,该视图 safeAreaInset 也为 0 。...在 SwiftUI ,开发者通常只有在需要获取 StatusBar + NavBar 高度或 HomeIndeicator + TabBar 高度才会使用到 safeAreaInsets 。...SafeAreaRegions 定义了三种安全区域划分: •container由设备和用户界面容器所定义安全区域,包括诸如顶部和底部栏等元素。...从 iOS 14 开始,SwiftUI 计算视图安全区域,将软键盘在屏幕覆盖区域(iPadOS 下,将软键盘缩小后键盘覆盖区域将被忽略)也一并进行考虑。...safeAreaTabbarDemo1 我们只调整了安全区域, SwiftUI 自动在不同设备上进行适配(在 iPhone 13 ,状态条高度为 40 + HomeIndeicator区域高度

7.7K31

SwiftUI 视图生命周期研究

•在 SwiftUI 生成视图值树发现没有对应实例SwiftUI 创建一个实例从而获取它 body 结果。...因此, Cell 视图出现在显示范围(影响容器布局)触发 onAppear,移出显示范围(不影响容器布局)触发 onDisappar。在其存续期内可以反复触发。...父视图恰恰是以该视图是否影响自身布局为依据,来调用 onAppear 和 onDisappear 闭包,这也是为什么这两个修饰器作用范围是父视图而不是视图本身。...更确切表述应该是,视图销毁,将向 task 修饰器闭包发送任务取消信号。至于是否取消,仍由 task 闭包自己决定。...在前文视图值树介绍我们提到, SwiftUI 重建该树,如果树上某个节点(视图) Source of truth 没有发生变化,将不重新计算,直接使用旧值。

4.4K30
  • SwiftUI 与 Core Data —— 安全地响应数据

    开发者在模型编辑器为属性设置了默认值( 取消可选 ),在 Xcode 自动生成托管对象类定义代码仍会将不少类型声明为可选值类型。通过手动修改类型( 将 String?...之所以出现上述情况,是因为 Xcode 模型编辑器 optional 并非对应 Swift 语言中可选值。...事实,在 Xcode 自带 Core Data 模版,就是这样使用。image-20221212101526366但这确实是正确使用方式吗?是否会有严重安全隐患?...在上节演示数据被删除后( 通过 onAppear 闭包延迟操作 ),NavigationView 自动返回到根视图中。在这种情况下,持有该数据视图将伴随着数据删除一并消失。... timestamp 为 nil ,将显示当前时间 Text("\((item.timestamp ??

    3.3K20

    SwiftUI + Core Data App 内存占用优化之旅

    在正常情况下( 惰性容器仅包含一个 ForEach ,且子视图没有使用 id 添加显式标识 ),惰性容器仅创建当前可见范围子视图实例,并对其 body 进行求值( 渲染 )。...子视图进入惰性容器可视区域SwiftUI 会调用它 onAppear 闭包,子视图退出可视区域,会调用 onDisappear 闭包。...图片 Instruments 导致优化后结果显示不准确,内存占用数据将以 App 显示以及 Xcode Navigator Debug 栏内容为准。如果滚动过快,可能导致内存占用增大。...数据多份拷贝 图片数据从 SQLite 经 Core Data 最终通过 SwiftUI 显示,实际在内存至少保存了三份拷贝: 行缓存 托管对象上下文( 托管对象被填充后 ) 显示该图片 SwiftUI...,由于该 Picture 托管对象仅存活于视图 onAppear block ,闭包执行完毕后,Core Data 自动释放上下文以及行缓存对应数据。

    2.4K40

    SwiftUI + Core Data App 内存占用优化之旅

    在正常情况下( 惰性容器仅包含一个 ForEach ,且子视图没有使用 id 添加显式标识 ),惰性容器仅创建当前可见范围子视图实例,并对其 body 进行求值( 渲染 )。...子视图进入惰性容器可视区域SwiftUI 会调用它 onAppear 闭包,子视图退出可视区域,会调用 onDisappear 闭包。...Instruments 导致优化后结果显示不准确,内存占用数据将以 App 显示以及 Xcode Navigator Debug 栏内容为准。如果滚动过快,可能导致内存占用增大。...数据多份拷贝 图片数据从 SQLite 经 Core Data 最终通过 SwiftUI 显示,实际在内存至少保存了三份拷贝: 行缓存 托管对象上下文( 托管对象被填充后 ) 显示该图片 SwiftUI...,由于该 Picture 托管对象仅存活于视图 onAppear block ,闭包执行完毕后,Core Data 自动释放上下文以及行缓存对应数据。

    1.3K10

    聊一聊可组装框架( TCA )

    ,以及在不同界面调用这些状态,使一个界面变化可以立刻反映在另一个界面。...TCA 提供了大量工具来丰富其组装手段,开发者发现组装已不是难事,在开发初始阶段便会从更小粒度来思考功能构成,从而创建出更加强壮、易读、易扩展应用。...IdentifiedArray 确保了将父组件状态( State )某个序列属性切分成独立子组件状态系统稳定性。避免出现因使用 index 修改元素而导致异常甚至应用崩溃情况。...:.seconds(3)) // 时间向前推移 3 秒( 测试并不会占用 3 秒时间,以同步方式进行) _ = await testStore.receive(.timerTick...截至本文写作,TCA[8] 在 GitHub Star 已经达到了 7.2K 。它拥有一个相当活跃社区,问题反馈和解答都十分迅速。

    1.8K20

    onAppear 调用时机

    image-20230328163706115 请忽略例子写法是否合理和值得推荐,仅考虑为什么在第一段代码,出现了数组越界情况;以及第二段代码可以正确运行。...创建实例、求值、布局、渲染 在 SwiftUI ,一个视图在它生命周期中通常会经历四个阶段: 创建实例 视图树,处于可显示分支视图基本都会经历一个阶段。...视图依赖( Source of truth )发生变化后,SwiftUI 重新计算视图结果值,并与旧值进行比较。如发生变化,则用新值替换旧值。...这会让开发者误以为 onAppear 是在视图渲染后( 使用者看到后 )才被调用。但在 SwiftUI onAppear 实际是在渲染前被调用。...在写 SwiftUI 视图生命周期研究[6] 一文,我们只能通过现象来推断 onAppear 调用时机,随着版本不断提高,SwiftUI 4 为我们提供了足够工具让我们可以获得更加确实证据

    1.1K10

    onAppear 调用时机

    图片请忽略例子写法是否合理和值得推荐,仅考虑为什么在第一段代码,出现了数组越界情况;以及第二段代码可以正确运行。...创建实例、求值、布局、渲染在 SwiftUI ,一个视图在它生命周期中通常会经历四个阶段:创建实例视图树,处于可显示分支视图基本都会经历一个阶段。...视图依赖( Source of truth )发生变化后,SwiftUI 重新计算视图结果值,并与旧值进行比较。如发生变化,则用新值替换旧值。...这会让开发者误以为 onAppear 是在视图渲染后( 使用者看到后 )才被调用。但在 SwiftUI onAppear 实际是在渲染前被调用。...在写 SwiftUI 视图生命周期研究 一文,我们只能通过现象来推断 onAppear 调用时机,随着版本不断提高,SwiftUI 4 为我们提供了足够工具让我们可以获得更加确实证据。

    2.1K20

    Ask Apple 2022 与 SwiftUI 有关问答(

    NavigationPath 创建一个完全类型擦除数据集合,它仅要求元素符合 Hashable 协议。...最近,我注意到 SwiftUI 视图 onAppear 在意想不到时间启动,比如 UITabBarController 被创建,而不是视图本身出现时。...2、视图出现在 UITabBarController ,推荐执行代码方法是什么?...惰性容器视图,根据其是否出现在可视区域而反复调用 onAppear 和 onDisapper。但 onAppear 和 onDisappear 并非为视图存续期起点和终点。...A:如果你在 iOS 使用 UITextField 遇到性能问题,你可以尝试避免每个视图都是 UITextField ,默认渲染为 Text ,文本被点击动态切换为 UITextField 。

    12.3K20

    AVKit框架详细解析(四) —— 基于AVKit 和 AVFoundation框架视频流App构建

    是的,你可能可以做一些基本网络。 甚至可能引入一些 JSON 并将一个像样table view与包含文本和图像单元格放在一起。...不幸是,这对您没有帮助! 您想要是循环播放所有这些视频。 看起来您必须以手动方式做事。 您需要做就是跟踪您播放器和当前播放项目。 它到达最后一个视频,您将再次将所有剪辑添加到队列。...2) 有人双击播放器视图,您可以添加一个侦听器。 这会在 2x 和 1x播放速率之间切换。 3) 有人单击播放器视图,您可以添加一个侦听器。 这会切换视频静音状态。...您返回到feed,预览从停止地方恢复。 6. Trying Not to Steal the Show 如果您打算制作一个包含视频应用,那么考虑您应用将如何影响您用户非常重要。...您这样做,您注意到即使视频循环播放器没有发出任何噪音,您音乐也已关闭!

    7K10

    打造可适配多平台 SwiftUI 应用

    例如,在准备开始适配“电影猎手” macOS 版本(已完成 iPad 版本适配),添加好 macOS destination 并进行编译后,你会发现 Xcode 出现了不少类似下面这种错误:...这样就失去了多窗口存在意义。图片为什么会出现这种情况呢?我们都知道 SwiftUI 是一个声明式框架。...对于“电影猎手”当前状态配置来说,我们可以通过将创建 Store 实例位置移动到场景来解决上述问题(将 MovieHunterApp 与 Store 有关代码移动到 ContentView ...一个场景被创建后,通过 onAppear代码,在 App State 创建属于它自己 State 数据,并在场景被删除,通过 onDisappear 里代码,将当前场景 State 清除掉...图片这是因为,在 macOS ,使用 Settings 来声明 Settings 窗口同样是创建了一个新场景,创建一棵独立视图树。

    3.2K80

    掌握 SwiftUI task 修饰器

    详情请参阅 SwiftUI 视图生命周期研究[3] 一文中有关 onAppear 和 onDisappear 章节SwiftUI 为了判断视图状态是否发生了改变,它会在视图存续期内,反复地生成视图类型实例以达成此目的...满足了需要停止由 task 修饰器创建异步任务条件SwiftUI 会给该任务发送任务取消信号,任务必须自行响应该信号并停止作业。...task 为什么没有默认运行在后台线程?...使用 url.lines 和 url.resourceBytes 获取网络数据,系统 API 跳转到后台线程,不过最终仍会回到主线程想要了解并解决这个问题,我们还要从 task 修饰器定义入手...作为一个事件源类型 Source of Truth,每当接收到一个新消息,它都会导致 SwiftUI 对视图 body 重新求值。

    2.2K30

    掌握 SwiftUI task 修饰器

    原文发表于我博客 肘子Swift记事本 task vs onAppear SwiftUI 提供了两个版本 task 修饰器,版本一作用和调用时机与 onAppear 十分类似: public func...满足了需要停止由 task 修饰器创建异步任务条件SwiftUI 会给该任务发送任务取消信号,任务必须自行响应该信号并停止作业。...Task.isCancelled { // 仅在当前任务没被取消执行以下代码 图片 开发者也可以利用 Swift 这种协作式取消机制来实现一些类似 onDisappear 操作。...task 为什么没有默认运行在后台线程?...使用 url.lines 和 url.resourceBytes 获取网络数据,系统 API 跳转到后台线程,不过最终仍会回到主线程 想要了解并解决这个问题,我们还要从 task 修饰器定义入手

    3.6K60

    SwiftUI 动画进阶 — Part4:TimelineView

    请注意,Cadence 不是你可以更改东西,而是反映设备状态东西。文档仅提供了一个例子。在 watchOS ,降低手腕 Cadence 减慢。...为什么左边 emoji 变,而另一个总是悲伤?事实证明, SubView 没有接收到任何变化参数,这意味着它没有依赖关系。SwiftUI 没有理由重新计算视图主体。...除了在每次日期值更改时推进动画阶段,我们还在 onAppear 闭包执行此操作。否则,一开始就会有停顿。 最后一段与 SwiftUI 无关代码是创建 NSSound 实例。...我们调度程序记住最后日期并添加适当偏移量。没有更多偏移量,它会循环回到数组第一个。...通过将它们放在一起,我们将扩展 SwiftUI 动画世界更多可能性。

    3.8K30

    打造可适配多平台 SwiftUI 应用

    例如,在准备开始适配“电影猎手” macOS 版本(已完成 iPad 版本适配),添加好 macOS destination 并进行编译后,你会发现 Xcode 出现了不少类似下面这种错误:...盲目地使用这些解决兼容性代码可能破坏 SwiftUI 创建者苦心,让开发者无法准确地体现不同平台特色。...对于“电影猎手”当前状态配置来说,我们可以通过将创建 Store 实例位置移动到场景来解决上述问题(将 MovieHunterApp 与 Store 有关代码移动到 ContentView ...一个场景被创建后,通过 onAppear代码,在 App State 创建属于它自己 State 数据,并在场景被删除,通过 onDisappear 里代码,将当前场景 State 清除掉...创建一棵独立视图树。

    2.1K10

    SwiftUI 4.0 全新导航系统

    NavigationLink 仍需设定目标视图,造成不必要实例创建开销 较难实现从视图外调用导航功能 “能用,但不好用” 可能就是对老版本编程式导航比较贴切地总结。...⚠️ 在使用堆栈管理系统情况下,请不要在编程式导航混用声明式导航,这样破坏当前视图堆栈数据 下面的代码,如果点击声明式导航,将导致堆栈数据重置。...上述选项并非适用于所有的平台,例如,在 macOS ,detalOnly 不会起作用 如果想在 SwiftUI 4.0 之前版本使用类似的功能,可以参考我在 用 NavigationViewKit...SwiftUI 4.0 ,将 toolbar 认定范围扩大到了 TabView 。...样式 在之前版本 SwiftUI ,NavigationLink 其实一直都是作为一种特殊 Button 存在

    10.3K62
    领券