在 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)
}
}
}
我也注意到了这个问题,它只发生在 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)
}