Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SwiftUI - Why is TabView and its contents sometimes not refreshing when I change tabs on macOS?

I'm trying to make a tabbed application on macOS with SwiftUI, and I have an odd issue with TabView.

When I have two tabs with TextFields each and save their text states to their respective private variables, something odd happens: When I switch from tab A to tab B after entering text into tab A's TextField, the tab indicator shows that I am still on tab A, but the content shows tab B's content. When I click on the button for tab B once again, it will still show tab B's content. Furthermore, when I press the button for tab A afterward, it will show the content of tab A, but the indicator for the tab still shows that I am on tab B.

What might I possibly be doing wrong?

Here is an example that illustrates my issue:

import SwiftUI

struct ContentView: View {
    var body: some View {
        TabView
            {
                TabAView()
                    .tabItem({Text("Tab A")})
                TabBView()
                    .tabItem({Text("Tab B")})
        }
    }
}

struct TabAView: View {
    @State private var text = ""
    var body: some View {
        VStack{
            Text("Tab A")
            TextField("Enter", text: $text)
        }
    }
}

struct TabBView : View {
    @State private var text = ""
    var body: some View {
        VStack {
            Text("Tab B")
            TextField("Enter", text: $text)
        }
    }
}

Here's a screen capture of the issue occurring: And here is a GIF of the issue occurring

like image 722
chungmcl Avatar asked Dec 23 '19 06:12

chungmcl


1 Answers

This is definitely a bug in SwiftUI's implementation of TabView. But you can easily work around the problem by binding to TabView selection and setting the current tab manually like so:

struct ContentView: View {
    @State private var currentTab = 0
    var body: some View {
        TabView(selection: $currentTab)
            {
                TabAView()
                    .tabItem({Text("Tab A")})
                    .tag(0)
                    .onAppear() {
                        self.currentTab = 0
                    }
                TabBView()
                    .tabItem({Text("Tab B")})
                    .tag(1)
                    .onAppear() {
                        self.currentTab = 1
                    }
        }
    }
}

This bug only seems to manifest itself when the user changes tabs while a TextField has focus.

If you make the above changes to your code, it will work as expected.

Screen capture of fix working

like image 67
Atreya Ranganath Avatar answered Nov 09 '22 00:11

Atreya Ranganath