Skip to content

[Bug] Destination view doesn't update when item changes #109

@jonkan

Description

@jonkan

In certain setups the flowDestination(item:style:destination:) doesn't update when the item changes, causing an old item to be displayed. I've created an example that demonstrates the bug. It also includes a sheet(item:content:) for comparison.

Steps to reproduce:

  1. Press "First A"
  2. Press "First B"

Expected:
A sheet displaying "First B"

Actual:
A sheet displaying "First A"

Note:

  • The item doesn't have to be identifiable to produce the bug. I did it for comparing with the .sheet and to try changing value only (same id) vs. changing both value and id.
  • If the item state is declared in the view with @State (as opposed to a @Published in a ObservableObject), there's no bug.
  • (Also, the .sheet in my example appears to hit a bug where it's expanded when the item id changes.)

Tested:

  • FlowStacks 0.10.12
  • Xcode 26.1
  • iPhone simulator iOS 26.1, 18.4

Example:
https://github.com/user-attachments/assets/d6ef3cb5-51a7-424d-a80e-c892dee76b95

import SwiftUI
import FlowStacks

enum Item: Identifiable, Hashable {
    case first(String)
    case second(String)

    var id: String {
        switch self {
        case .first: return "First"
        case .second: return "Second"
        }
    }

    var description: String {
        switch self {
        case .first(let value): return "First \(value)"
        case .second(let value): return "Second \(value)"
        }
    }
}

class MyState: ObservableObject {
    @Published var sheetItem: Item?
    @Published var flowItem: Item?
}

@available(iOS 16.4, *)
struct ItemChangesView: View {

    @StateObject private var state = MyState()

    var body: some View {
        FlowStack {
            Grid(verticalSpacing: 10) {
                GridRow {
                    Text("Flow")
                    Text("Sheet")
                }
                .font(.title)
                row("First A", item: .first("A"))
                row("First B", item: .first("B"))
                row("Second A", item: .second("A"))
                row("Second B", item: .second("B"))
                Spacer()
            }
            .flowDestination(item: $state.flowItem, style: .sheet) { item in
                Color.gray.overlay {
                    Text(item.description).font(.title)
                }
                .ignoresSafeArea()
                .presentationDetents([.medium])
                .presentationBackgroundInteraction(.enabled)
            }
            .sheet(item: $state.sheetItem) { item in
                Color.gray.overlay {
                    Text(item.description).font(.title)
                }
                .ignoresSafeArea()
                .presentationDetents([.medium])
                .presentationBackgroundInteraction(.enabled)
            }
        }
    }

    func row(_ title: String, item: Item) -> some View {
        GridRow {
            Button(title) {
                state.sheetItem = nil
                state.flowItem = item
            }
            Button(title) {
                state.sheetItem = item
                state.flowItem = nil
            }
        }
    }

}

@available(iOS 16.4, *)
#Preview {
    ItemChangesView()
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions