TabView 使用 TCA 破坏了 Xcode 16 上的导航

问题描述 投票:0回答:1

在 TabView 中使用 NavigationStack 时,我发现行为不一致。在我的带有 Xcode 16.0 的设备 (iOS 17.6.1) 上,导航回根目录并再次点击按钮后,“向下钻取”停止工作。它在模拟器上运行良好,在使用 Xcode 15 构建时在我的设备上也运行良好。

如果我删除

TabView
,一切都会按预期运行。

如果这是 Xcode、编译器、SwiftUI 或 TCA 的错误,您有什么想法吗?或者我在这里遗漏了什么?

import ComposableArchitecture
import SwiftUI

@main
struct DemoApp: App {
    var body: some Scene {
        WindowGroup {
            TabView {
                NavigationStack {
                    FeatureView(store: .init(initialState: .init(), reducer: {
                        Feature()
                    }))
                }
            }
        }
    }
}

@Reducer
struct Feature: Equatable {
    @Reducer(state: .equatable)
    public enum Destination  {
        case drillDown(Feature)
    }
    
    @ObservableState
    struct State: Equatable {
        @Presents var destination: Destination.State?
    }
    
    enum Action {
        case destination(PresentationAction<Destination.Action>)
        case drillDownButtonTapped
    }
    
    public var body: some Reducer<State, Action> {
        Reduce { state, action in
            switch action {
            case .destination:
                return .none
            case .drillDownButtonTapped:
                state.destination = .drillDown(Feature.State())
                return .none
            }
        }
        .ifLet(\.$destination, action: \.destination)
    }
}

struct FeatureView: View {
    @Bindable var store: StoreOf<Feature>
    var body: some View {
        Button("Drill Down") {
            store.send(.drillDownButtonTapped)
        }
        .navigationDestination(
            item: $store.scope(state: \.destination?.drillDown, action: \.destination.drillDown)
        ) { store in
            FeatureView(store: store)
        }
    }
}
swiftui swiftui-tabview swiftui-navigationstack swift-composable-architecture
1个回答
0
投票

我也注意到了这个问题,它只发生在 XCode 16 上。

我可以确认该问题也与

Button
内有
TabView
有关。我注意到,如果您长按按钮,它会记录点击。

解决方法是向您的

Button
添加一个最短持续时间为 0 的长按手势,在您的身体中您可以执行以下操作:

注意:请务必删除按钮操作关闭,否则可能会导致您的操作被注册两次。

   Button("Drill Down") {
        // touch up
        // no longer needed
    }
   .onLongPressGesture(minimumDuration: 0, perform: {}) { pressing in
        if pressing {
            // touch down
            store.send(.drillDownButtonTapped)
        }
    }
    .navigationDestination(
        item: $store.scope(state: \.destination?.drillDown, action: \.destination.drillDown)
    ) { store in
        FeatureView(store: store)
    }
© www.soinside.com 2019 - 2024. All rights reserved.