zijievv / swiftui-tab-bar

A highly customizable tab bar view made in SwiftUI
Apache License 2.0
92 stars 10 forks source link

switch between tab will recreate the view? #1

Closed zangqilong198812 closed 1 year ago

zangqilong198812 commented 1 year ago
  1. select tabA, the tabA view show
  2. select tabB, the tabB view show
  3. select tabA again, the tabA View recreate.

can you keep the view exist instead of recreate it? like the system tabView behaviour.

zijievv commented 1 year ago

As far as i know, SwiftUI recreates the view each time you switch between tabs in a TabView, by default. This behaviour is part of SwiftUI's view lifecycle. However, if you want to maintain the state of your views across tab switches and prevent them from being recreated, you can leverage it to create a persistent view model for each tab and retain their states outside of the TabView.

bryan1anderson commented 1 year ago

I can confirm that this is an issue. This is not the way a tab bar in standard iOS works. This can be tested by using a scroll view for one of the tab items. Scroll to a location, switch away, and come back.

Take this example with the standard iOS api. Click on one of the tabs, scroll to the bottom, and then back up. Your tool doesn't handle that case and it's a pretty important one. I also have tested whether or not navigation is destroyed.

It's not just about state is it? Scroll views don't expose their state to us in a way that preservers the EXACT content offset

    TabView(content: {
        ScrollView {
            ForEach(1...40, id: \.self) { int in
                Text("First \(int)")
                    .padding()
            }
        }
        .tabItem {
            Text("First")
        }

        ScrollView {
            ForEach(1...40, id: \.self) { int in
                Text("Second \(int)")
                    .padding()
            }
        }
        .tabItem {
            Text("Second")
        }

    })
zangqilong198812 commented 1 year ago

As far as i know, SwiftUI recreates the view each time you switch between tabs in a TabView, by default. This behaviour is part of SwiftUI's view lifecycle. However, if you want to maintain the state of your views across tab switches and prevent them from being recreated, you can leverage it to create a persistent view model for each tab and retain their states outside of the TabView.

I test scrollview between the system tabview and tabbar, the system TabView will keep the scrollview offset after I switch to other View, but when I use Tabbar repo, it reset the scrollview offset, it proves that Tabbar not maintain the previous state.

zijievv commented 1 year ago

@bryan1anderson @zangqilong198812 I appreciate your effort in helping me understand the misunderstood feature. 🙏 Just fixed the issue.

bryan1anderson commented 1 year ago

@zijievv Appreciate it. Out of curiosity how did you fix it?

zijievv commented 1 year ago

@bryan1anderson The view would be rerendered every time you switched tabs because i was using if-else statement.

if shouldShow {
    tabContentView()
} else {
    Color.clear
}

I resolved this issue by using:

tabContentView()
    .opacity(shouldShow ? 1 : 0)
    .disabled(!shouldShow)
zangqilong198812 commented 1 year ago

Perfect repo. Thanks zijievv