Helm icon indicating copy to clipboard operation
Helm copied to clipboard

Flickering effect when showing a nested view

Open rojarand opened this issue 3 years ago • 0 comments

I came across strange flickering effect when creating a nested view stack with Helm. It looks like the child view is being open twice. For demonstration purpose I added a nested view to the Navigation example. Additionally there is an infinite transition loop between the most nested views. The gif below shows the issue. helm-issue2

The view with text "Chelsea FC has a lot of supporters" flickers. The "Club Details View" can not be accessed because it is being closed just right after opening that view.

I tested all combinations of dismissable and hold/pass properties. Without a success.

Changes needed to recreate the issue:

  • ContentView.swift
struct ContentView: View {
    var body: some View {
        NavigationEntryView()
    }
}
  • NavigationEntryView.swift
struct NavigationEntryView: View {
    @StateObject private var _helm: Helm = try! Helm(nav: [
        SampleSegue(.a => .b).with(style: .hold),
        SampleSegue(.b => .c).with(style: .hold),
        SampleSegue(.c => .d).with(style: .hold),
    ])
    
    var body: some View {
        NavigationExampleView()
            .environmentObject(_helm)
    }
}
  • NavigationExampleView.swift
struct NavigationExampleView: View {
    @EnvironmentObject private var _helm: Helm<SampleFragment>
    
    var body: some View {
        NavigationView {
            List {
                Section(
                    content: {
                        ForEach(["Porto", "London", "Barcelona"]) { city in
                            NavigationLink(destination: CityContentView(city: city),
                                           isActive: _helm.isPresented(.b, id: city)) {
                                Text(city)
                            }
                        }
                        Button(action: { _helm.present(fragment: .b, id: "London") }) {
                            Text("Select London")
                        }
                    },
                    footer: {
                        if let error = _helm.errors.last {
                            Section {
                                Text("Error: \(error.localizedDescription)")
                                    .foregroundColor(.red)
                            }
                        }
                    }
                )
            }
        }
    }
}

let clubsInCities: [String: [String]] = [
    "Porto": ["FC Porto", "Boavista F.C.‎"],
    "London": ["Chelsea FC", "‎Tottenham Hotspur", "West Ham", "Arsenal"],
    "Barcelona": ["FC Barcelona", "RCD Espanyol‎‎"]
]

struct CityContentView: View {
    @EnvironmentObject private var _helm: Helm<SampleFragment>
    
    let city: String
    var body: some View {
        List(clubsInCities[city] ?? []) { club in
            NavigationLink(destination: ClubContentView(club: club),
                           isActive: _helm.isPresented(.c, id: club)) {
                Text(club)
            }
        }
    }
}

struct ClubContentView: View {
    
    @EnvironmentObject private var _helm: Helm<SampleFragment>
    
    let club: String
    var body: some View {
        NavigationLink(destination: ClubDetailsContentView(club: club),
                       isActive: _helm.isPresented(.d, id: club)) {
            Text("\(club) has a lot of supporters")
        }
    }
}

struct ClubDetailsContentView: View {
    
    let club: String
    var body: some View {
        Text("Details of \(club)")
    }
}

struct NavigationView_Previews: PreviewProvider {
    static var previews: some View {
        NavigationExampleView()
    }
}

Tested with:

  • Xcode: 14.1
  • iOS: 15, 16
  • Helm: 0.0.12-beta

rojarand avatar Feb 06 '23 07:02 rojarand