BellRinging
BellRinging

Reputation: 401

SwiftUI TabView call the init function twice

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

Answers (1)

BellRinging
BellRinging

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

Related Questions