I've come to SwiftUI from UIKit and I'm having trouble with a NavigationLink not animating when presenting a new View.
I've set up the view structure to include the NavigationLink when the following property is non-nil:
@State private var retrievedDeviceIdentity: Proteus.DeviceIdentity?
The Proteus.DeviceIdentity type is a basic data struct. This property is populated by a successful asynchronous closure, rather than a direct user interaction. Hence, the view structure is set up like so, using NavigationLink's destination:isActive:label:
initialiser:
var body: some View {
NavigationView {
VStack {
Form {
// Form building
}
if let deviceIdentity = retrievedDeviceIdentity {
NavigationLink(
destination: AddDeviceLinkDeviceForm(deviceIdentity: deviceIdentity),
isActive: .constant(retrievedDeviceIdentity != nil),
label: {
EmptyView()
}
)
.onDisappear() {
updateSyncButtonEnabledState()
}
}
}
}
}
When retrievedDeviceIdentity
is populated to be non-nil the new View is indeed presented. However, there is no slide transition to that View; it just changes immediately. When in that new view, tapping on the back button does do the slide transition back to this view.
Any ideas how to fix this? As I'm pretty new to SwiftUI if I've set the new structure up wrong then I'd welcome feedback on that too.
(I'm using Xcode 12.3 on macOS Big Sur 11.0.1.)
@Asperi got close, but moving the NavigationLink led to the view not presenting at all.
What did work was removing the if
brace unwrapping retrievedDeviceIdentity
:
var body: some View {
NavigationView {
VStack {
Form {
// Form building
}
NavigationLink(
destination: AddDeviceLinkDeviceForm(deviceIdentity: deviceIdentity),
isActive: .constant(retrievedDeviceIdentity != nil),
label: {
EmptyView()
}
)
.onDisappear() {
updateSyncButtonEnabledState()
}
}
}
This required AddDeviceLinkDeviceForm's deviceIdentity
property to be made optional to accept the wrapped value.