Andoni Da Silva
Andoni Da Silva

Reputation: 1331

SwiftUI - How to avoid to refresh a List when a state var from the same struct is modified

I have a main view which contains a body with a TabView and each tab shows a different list. Also, I have declared at the top of the main class, a state var just for control if I have to show a modal-like view or not.

The problem is that when I change the value of that state var, all body of the main view is redrawn with an animation. This is not a desired behaviour because I am not changing the data associated with the list updating that var.

struct HomeView: View {
    @State private var selection = 0
    @State var modalShown = false //This is the problematic var that makes a list to be updated with an animation

    @EnvironmentObject var filters: UserFilters
    @EnvironmentObject var filtersViewController: FiltersViewController

    init() {
        UITabBar.appearance().backgroundColor = #colorLiteral(red: 0.03921568627, green: 0.03921568627, blue: 0.03921568627, alpha: 1)
        UITabBar.appearance().barTintColor = #colorLiteral(red: 0.03921568627, green: 0.03921568627, blue: 0.03921568627, alpha: 1)
    }

    var body: some View {
        return ZStack {
            TabView(selection: $selection){
                IncidencesView(modalShown: $modalShown) //A view that contains a list that is being refreshing

At least, is there a way to avoid the list updating animation?

Thank you!

Upvotes: 7

Views: 3909

Answers (2)

Asperi
Asperi

Reputation: 258247

At least, is there a way to avoid the list updating animation?

The provided code snapshot is not testable, so just on-the-fly... try the following

IncidencesView(modalShown: $modalShown.animation(nil))

Upvotes: 2

Cenk Bilgen
Cenk Bilgen

Reputation: 1435

Try this.

Make your view, I believe in this case IncidencesView, conform to Equatable. That will require you to overload the == operator and tell SwiftUI exactly under what circumstances the view has changed and when it hasn't changed.

Once you do that, in HomeView modify IncidencesView with the .equitable() view modifier, to tell it's parent HomeView to check if IncidencesView is still equal to it's old self when there is a change of state. If it is still equal to it's old self, don't redraw.

Now even if selection changes, SwiftUI, will check if the current IncidencesView is still equal to the version under this new condition. It will see it is (because selection likely doesn't influence the == function result), and so a new version of the view won't be recreated and drawn.

See this excellent article: https://swiftui-lab.com/equatableview/

Upvotes: 2

Related Questions