Reputation: 401
I was pissed off by the tabview , hope some genius can help .
By default ,tabview will init all the view every time which I don't want it , so I resolved it by adding a lazy view . Here is my code
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()
}
}
It working fine . The result is "init Page1" , "init Page2" if I toggle the page .
Then I change the tab to point to TestPage2 (the only different is the view body has a extra VStack item )
LazyView(TestPage2(text:"Page2"))
//Changed the above code to 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)
}
}
}
The result is
init Page2
init Page1
init Page1
init Page2
The init function be call twice .. It weired
Upvotes: 1
Views: 2102
Reputation: 401
Finally , I have resolved it by adding extra struct
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)
}
}
Upvotes: 2