ios - 为什么在 SwiftUI 的 TabView 中切换选项卡时 onDisappear 之后再次调用 onAppear?
问题描述
如果有任何更改,我会在出现选项卡项时调用 API。为什么在调用onDisappear 之后调用onAppear?
这是一个简单的例子:
struct ContentView: View {
var body: some View {
TabView {
NavigationView {
Text("Home")
.navigationTitle("Home")
.onAppear {
print("Home appeared")
}
.onDisappear {
print("Home disappeared")
}
}
.tabItem {
Image(systemName: "house")
Text("Home")
}.tag(0)
NavigationView {
Text("Account")
.navigationTitle("Account")
.onAppear {
print("Account appeared")
}
.onDisappear {
print("Account disappeared")
}
}
.tabItem {
Image(systemName: "gear")
Text("Account")
}.tag(1)
}
}
}
只需运行上面的代码,我们将在 onDisappear 之后看到 onAppear。
Home appeared
---After switch tab to Account---
Home disappeared
Account appeared
Home appeared
有什么办法可以避免这种情况吗?
解决方案
这是一个非常烦人的错误,想象一下这种情况:
Home
viewonAppear
方法包含一个重复获取数据的计时器。通过切换到Account
视图来不可见地触发计时器。
解决方法:
- 为每个嵌入的
NavigationView
内容创建一个独立的视图 @Binding
将当前选择值作为参数传递给独立视图
例如:
struct ContentView: View {
@State var selected: MenuItem = .HOME
var body: some View {
return TabView(selection: $selected) {
HomeView(selectedMenuItem: $selected)
.navigationViewStyle(StackNavigationViewStyle())
.tabItem {
VStack {
Image(systemName: "house")
Text("Home")
}
}
.tag(MenuItem.HOME)
AccountView(selectedMenuItem: $selected)
.navigationViewStyle(StackNavigationViewStyle())
.tabItem {
VStack {
Image(systemName: "gear")
Text("Account")
}
}
.tag(MenuItem.ACCOUNT)
}
}
}
enum MenuItem: Int, Codable {
case HOME
case ACCOUNT
}
主页视图:
struct HomeView: View {
@Binding var selectedMenuItem: MenuItem
var body: some View {
return Text("Home")
.onAppear(perform: {
if MenuItem.HOME == selectedMenuItem {
print("-> HomeView")
}
})
}
}
帐户视图:
struct AccountView: View {
@Binding var selectedMenuItem: MenuItem
var body: some View {
return Text("Account")
.onAppear(perform: {
if MenuItem.ACCOUNT == selectedMenuItem {
print("-> AccountView")
}
})
}
}
推荐阅读
- angular - 如何用我自己的展示组件包装 Ionic、Bootstrap 或 Material
- rest - 通过 REST 查询 COSMOS DB 图顶点
- python - fromstring 不能使用从客户端截取的屏幕截图在 pygame 上显示它们
- r - 在 R 中创建自动增长的数据框
- parallel-processing - 当所有 lscpu 显示 4 个 numa 节点时,使用 --membind=1 或 3 了解失败的 numactl
- amazon-web-services - DynamoDB 一对多的设计思路和问题
- r - geom_errorbar 和 geom_ribbon 一起工作
- vim - vimscript - 自动捕捉窗口调整大小(是否使用自动命令)
- javascript - 在 Javascript 中有效地逐步过滤大型数据集
- reactjs - 视频源不会在 useState() 上更新