SwiftUI TabView 两次调用 init 函数
SwiftUI TabView call the init function twice
我被 tabview 气死了,希望有高手帮忙。
默认情况下,tabview 每次都会初始化所有我不想要的视图,所以我通过添加一个惰性视图来解决它。这是我的代码
http://github.com/BellRinging/TestBug.git
import SwiftUI
struct TabViewIssue: View {
@State private var selected = 0
var body: some View {
TabView(selection: $selected, content: {
LazyView(TestPage(text:"Page1"))
.tabItem {
selected == 0 ? Image(systemName: "book.fill"):Image(systemName: "book")
Text("Page1")
}.tag(0)
LazyView(TestPage(text:"Page2"))
.tabItem {
selected == 1 ? Image(systemName: "book.fill"):Image(systemName: "book")
Text("Page2")
}.tag(1)
})
}
}
struct TestPage: View {
let text : String
init(text : String){
self.text = text
print("init \(text)")
}
var body: some View {
Text(text) //no issue for a sigle view
}
}
struct LazyView<Content: View>: View {
let build: () -> Content
init(_ build: @autoclosure @escaping () -> Content) {
self.build = build
}
var body: Content {
build()
}
}
它工作正常。结果是 "init Page1" ,如果我切换页面 "init Page2" .
然后我将选项卡更改为指向 TestPage2(唯一不同的是视图主体有一个额外的 VStack 项)
LazyView(TestPage2(text:"Page2"))
//将上面的代码改为TestPage2
struct TestPage2: View {
let text : String
init(text : String){
self.text = text
print("init \(text)")
}
var body: some View {
VStack{ //If added a VStack ..tabview init call twice
Text(text)
Text(text)
}
}
}
结果是
初始化第 2 页
初始化第 1 页
初始化第 1 页
初始化第 2 页
初始化函数被调用了两次..它很奇怪
最后,我通过添加额外的结构解决了这个问题
import SwiftUI
struct TabViewIssue: View {
var body: some View {
TabbarView2()
}
}
struct TabbarView2: View {
@State var selectedTab = Tab.game
enum Tab: Int {
case game, search, menu,edit
}
func tabbarItem(text: String, image: String ,selectedImage: String) -> some View {
VStack {
Image(systemName: image)
.imageScale(.large)
Text(text)
}
}
var body: some View {
TabView(selection: $selectedTab) {
LazyView(TestPage(text:"Page1")).tabItem{
self.tabbarItem(text: "Edit", image: "person.fill",selectedImage: "person")
}.tag(Tab.edit)
LazyView(TestPage2(text:"Page2")).tabItem{
self.tabbarItem(text: "Game", image: "book.fill",selectedImage: "book")
}.tag(Tab.game)
}.edgesIgnoringSafeArea(.top)
}
}
我被 tabview 气死了,希望有高手帮忙。
默认情况下,tabview 每次都会初始化所有我不想要的视图,所以我通过添加一个惰性视图来解决它。这是我的代码
http://github.com/BellRinging/TestBug.git
import SwiftUI
struct TabViewIssue: View {
@State private var selected = 0
var body: some View {
TabView(selection: $selected, content: {
LazyView(TestPage(text:"Page1"))
.tabItem {
selected == 0 ? Image(systemName: "book.fill"):Image(systemName: "book")
Text("Page1")
}.tag(0)
LazyView(TestPage(text:"Page2"))
.tabItem {
selected == 1 ? Image(systemName: "book.fill"):Image(systemName: "book")
Text("Page2")
}.tag(1)
})
}
}
struct TestPage: View {
let text : String
init(text : String){
self.text = text
print("init \(text)")
}
var body: some View {
Text(text) //no issue for a sigle view
}
}
struct LazyView<Content: View>: View {
let build: () -> Content
init(_ build: @autoclosure @escaping () -> Content) {
self.build = build
}
var body: Content {
build()
}
}
它工作正常。结果是 "init Page1" ,如果我切换页面 "init Page2" .
然后我将选项卡更改为指向 TestPage2(唯一不同的是视图主体有一个额外的 VStack 项)
LazyView(TestPage2(text:"Page2"))
//将上面的代码改为TestPage2
struct TestPage2: View {
let text : String
init(text : String){
self.text = text
print("init \(text)")
}
var body: some View {
VStack{ //If added a VStack ..tabview init call twice
Text(text)
Text(text)
}
}
}
结果是
初始化第 2 页
初始化第 1 页
初始化第 1 页
初始化第 2 页
初始化函数被调用了两次..它很奇怪
最后,我通过添加额外的结构解决了这个问题
import SwiftUI
struct TabViewIssue: View {
var body: some View {
TabbarView2()
}
}
struct TabbarView2: View {
@State var selectedTab = Tab.game
enum Tab: Int {
case game, search, menu,edit
}
func tabbarItem(text: String, image: String ,selectedImage: String) -> some View {
VStack {
Image(systemName: image)
.imageScale(.large)
Text(text)
}
}
var body: some View {
TabView(selection: $selectedTab) {
LazyView(TestPage(text:"Page1")).tabItem{
self.tabbarItem(text: "Edit", image: "person.fill",selectedImage: "person")
}.tag(Tab.edit)
LazyView(TestPage2(text:"Page2")).tabItem{
self.tabbarItem(text: "Game", image: "book.fill",selectedImage: "book")
}.tag(Tab.game)
}.edgesIgnoringSafeArea(.top)
}
}