There are so many different ways to accomplish these goals of yours. Here's one:
You mentioned that you don't like recreating instances of WebView... I concur. I localized both WebView , and WebPage into ContentView. WebView stays in the body, and I call .load() on WebPage when a new Tab is selected. It's been a while since I used TabView for anything.
It seems like there might be a .init ( selection:Binding < Hashable >) to call, but all I saw were Tab's that required the setting of a new View with each instance. Not very appropriate when we want to maintain a single View and load new Data. Maybe I missed something. There's probably a new modifier? I changed Color.red to EmptyView(), and set a frame or two.
I wish I could tell you more about the performance issues you mentioned. Maybe someone more qualified could speak to that. I don't see much issue.
Tested and working on macOS 26 & #Previews iPhone 16e , iOS 26.
Here's your code back.
enum Tabs: String , Hashable , CaseIterable {
case home , cnn , fox , msnbc
var url: URL? {
switch self {
case .home : URL ( string: "https://www.stackoverflow.com" )
case .cnn : URL ( string: "https://www.cnn.com" )
case .fox : URL ( string: "https://www.foxnews.com" )
case .msnbc : URL ( string: "https://www.msnbc.com" )
}
}
var label: Label < Text , Image > {
switch self {
case .home : Label ( "Home" , systemImage: "house" )
case .cnn : Label ( "CNN" , systemImage: "tv" )
case .fox : Label ( "FOX" , systemImage: "newspaper" )
case .msnbc : Label ( "MSNBC" , systemImage: "paperclip" )
}
}
// var tab: Tab < Tabs , EmptyView , Label < Text , Image > > {
// Tab ( value: self , content: { EmptyView() } , label: { self.label } )
// }
}
@available( iOS 26.0 , macOS 26.0 , * )
struct ContentView: View {
@State private var selectedTab: Tabs = .home
@State private var webPage: WebPage = .init()
private static var macOSIgnoresSafeArea: Edge.Set {
#if os( macOS )
.top #else
[ ] #endif
}
var body: some View {
VStack {
WebView ( self.webPage )
.edgesIgnoringSafeArea ( Self.macOSIgnoresSafeArea )
TabView ( selection: self.$selectedTab ) {
ForEach ( Tabs.allCases , id: \.self ) { tab in
Tab ( value: tab , content: { EmptyView() } , label: { tab.label } )
}
}
.frame ( height: 50 )
}
.task ( id: self.selectedTab ) { self.webPage.load ( selectedTab.url ) }
}
}