Hi!
I have noticed weird behaviour when using a NavigationLink with tag and selection binding that is displayed in split view.
The full code is here.
I created a NavigationLink like this:
NavigationLink(
destination: IfLetStore(
self.store.scope(state: { $0.selectedNumber }).actionless,
then: DebugNavigationLinkChildView.init(store:),
else: Text("selectedNumber is nil!")
),
tag: number,
selection: viewStore.binding(get: { $0.selectedNumber }, send: {
print("NavigationLink for \(number) is sending \($0)")
return ViewAction.selectNumber($0)
})
) {
Text("Go to \(number)")
}
What I am observing is that if the view is displayed using a split view and one element is selected and I click another, first the clicked element is sending its tag, then the previously selected element is sending nil.
What this means is that when first selecting 1, then selecting 2 we end up with nil!
This is the debug output when running it on an iPad in landscape:
// Select 1
NavigationLink for 1 is sending Optional(1)
// Select 2
NavigationLink for 2 is sending Optional(2)
NavigationLink for 1 is sending nil
NavigationLink for 2 is sending nil
When running this on an iPhone I get this instead (the view works as expected):
// Select 1
NavigationLink for 1 is sending Optional(1)
// Go back
NavigationLink for 1 is sending nil
NavigationLink for 1 is sending nil
// Select 2
NavigationLink for 2 is sending Optional(2)
So how can I distinguish between a navigation link sending nil because the user went back and because another element is selected?
I guess I could include the sender number as well in the action and then only allow nil when it is coming from the currently selected sender:
case .selectNumber(let sender, let number):
if let number = number {
state.selectedNumber = number
} else if number == nil && sender == state.selectedNumber {
state.selectedNumber = nil
}
But this seems like a hack. Is there a better solution? Am I doing something wrong?