TabView Reloads all Tab

I wish to ask suggestion on how to avoid this.

i dont want every tab switch to reload the component..worse, fetch from url

s this where mvvm comes in? so that even if component is reloaded, the mvvm data will be used? i think it is overkill though.

my first and 3rd tab fetches data and loads markers in a map. my 2nd tab is a wkwebview that loads a url

i noticed that whej i switch to the 3rd tab, the 1st tab gets reloaded still. thoughts on how to avood reloading?

also tried setting tag to each tab item and setting a state variable to tab view to keep track of tab switching. to no avail.

thoughts?

Could you show the code of the 1st Tab, to see where reload occurs.

This is the tab struct

struct AtlasTabView: View {
   
  @EnvironmentObject var appData: AppData
  @State var reload = false
   
  private var urlRequest: URLRequest?
   
  init() {
    setupData()
  }
   
  var body: some View {
    TabView {
      ValleyFaultSystemTiView()
      .tabItem {
        Label("tab 1", systemImage: "waveform.path.ecg")
      }
       
      WebView(request: urlRequest!)
        .tabItem {
          Label("tab 2", systemImage: "waveform.path.ecg.rectangle")
        }
       
      Text("temp")
      .tabItem {
        Label("tab 3", systemImage: "bird")
      }
    }
  }
}

This is my web view struct

struct WebView : UIViewRepresentable {
   
  let request: URLRequest
  let reload = false
   
  func makeUIView(context: Context) -> WKWebView {
    return WKWebView()
  }
   
  func updateUIView(_ uiView: WKWebView, context: Context) {
    guard context.coordinator.needsToLoadURL else { return }
    uiView.load(URLRequest(url: request.url!))
  }
   
  func makeCoordinator() -> WebView.Coordinator {
    Coordinator()
  }

  class Coordinator {
    var needsToLoadURL = true
  }
}

And this is the 1st tab struct

struct ValleyFaultSystemTiView: View, FeaturesNeeded {
   
  @EnvironmentObject var appData: AppData
  @ObservedObject private var locationManager = LocationManager()
   
  @State private var cameraPosition: GMSCameraPosition?
  @State private var coordinateBounds: GMSCoordinateBounds?
  @State private var circlePopulations = [GMSCircle]()
  @State private var markerShelters = [GMSMarker]()
  @State private var polylinesOfFault = [GMSPolyline]()
  @State private var polylines = [GMSPolyline]()
  @State private var selectedMarker: GMSMarker?
   
  var body: some View {
    MapView(
      circles: circlePopulations,
      markers: markerShelters,
      polylines: polylines,
      cameraPosition: cameraPosition,
      selectedMarker: selectedMarker,
      coordinateBounds: coordinateBounds
    )
    .onAppear() {       
      if let path = Bundle.main.path(forResource: "test", ofType: "kml") {
        do {
          // process markers here
        } catch {
          print(error)
        }
      }
      else {
        print("file not found")
      }
    }
  }
}

@Claude31 I am not sure if the right place is in onAppear since this is in a tab. But if i switch to tab 3, the print code will still be executed inside the // process markers here comment. Currrently, I am getting data from a resource file in the project (problem persists). Once i can fix avoiding having to reload each tab when switching, i will get the data from a url.

Seems that even with a simple view, the component in the tab still gets reloaded

@State private var currentTab = 0      
  var body: some View {
    TabView(selection: $currentTab) {
      Text("he")
        .tabItem {
          Label("boo", systemImage: "bird")
        }
        .tag(0)
       
      LAVAView()
        .tabItem {
          Label(StringTool.localize("lava"), systemImage: "bird")
        }
        .tag(1)
    }

my lava view containst just a text

struct LAVAView: View {  
  init() {
    print("init lava view")
  }
   
  var body: some View {
    Text("hello world")
  }
}

Thoughts @claude31 ?

I tested this very simple code.

struct ContentView: View {
    
    var body: some View {
        NavigationView {
            TabView {
                TestView()
                    .tabItem {
                        Image(systemName: "person.3")
                    }
                TestView3()
                    .tabItem {
                        Image(systemName: "person.2")
                    }
            }
            .navigationTitle("Test")
        }
        .navigationViewStyle(.stack)
    }
}

struct TestView: View {
    init() {
      print("init Test view")
    }
    var body: some View {
        List {
            Text("test1")
            Text("test2")
            Text("test3")
        }
        .listStyle(.plain)
    }
}

struct TestView2: View {
    init() {
      print("init Test view 2")
    }
    var body: some View {
        List {
            Text("test4")
            Text("test5")
            Text("test6")
        }
        .listStyle(.plain)
    }
}

In the console, I get

init Test view
init Test view 2

When view is first displayed. But no more log when I switch tabs.

I tested with your code (slightly modified to get it compiling as Label("boo", systemImage: "bird") causes error):

struct ContentView: View {
    @State private var currentTab = 0
    var body: some View {
        TabView(selection: $currentTab) {
            Text("he")
                .tabItem {
                   Image(systemName: "person.3")
                }
                .tag(0)
            
            LAVAView()
                .tabItem {
                    Image(systemName: "person.2")// StringTool.localize("lava"), systemImage: "bird")
                }
                .tag(1)
        }
    }
}

struct LAVAView: View {
    init() {
        print("init lava view")
    }
    
    var body: some View {
        Text("hello world")
    }
}

Don't get any print on console when I switch tabs.

TabView Reloads all Tab
 
 
Q