Я пришел в SwiftUI из UIKit, и у меня возникли проблемы с тем, что NavigationLink не анимируется при представлении нового представления.
Я настроил структуру представления для включения NavigationLink, когда следующее свойство не равно нулю:
@State private var retrievedDeviceIdentity: Proteus.DeviceIdentity?
Тип Proteus.DeviceIdentity — это базовая структура данных. Это свойство заполняется успешным асинхронным закрытием, а не прямым взаимодействием с пользователем. Следовательно, структура представления настроена таким образом, с использованием инициализатора destination:isActive:label:
NavigationLink:
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()
}
}
}
}
}
Когда retrievedDeviceIdentity
заполнен ненулевым значением, новый вид действительно представлен. Однако перехода к этому представлению со слайдом нет; просто сразу меняется. Находясь в этом новом представлении, нажатие на кнопку «Назад» приводит к переходу слайда обратно в это представление.
Любые идеи, как это исправить? Поскольку я новичок в SwiftUI, если я неправильно настроил новую структуру, я бы также приветствовал отзывы об этом.
(Я использую Xcode 12.3 на macOS Big Sur 11.0.1.)
Я думаю, что это связано с условным внедрением, вместо этого попробуйте постоянно включать его в иерархию представлений (и, таким образом, регистрироваться в NavigationView
), например
VStack {
Form {
// Form building
}
}
.background(
NavigationLink(
destination: AddDeviceLinkDeviceForm(deviceIdentity: retrievedDeviceIdentity),
isActive: .constant(retrievedDeviceIdentity != nil),
label: {
EmptyView()
}
)
.onDisappear() {
updateSyncButtonEnabledState()
}
)
Примечание. Я не уверен, что вы ожидаете от .onDisappear и зачем он вам нужен, возможно, он понадобится для перемещения в какое-то другое место или под другим модификатором.
Я бы сделал его необязательным и обрабатывал внутри AddDeviceLinkDeviceForm.
Я попытался обновить свой код, чтобы он соответствовал вашему, но теперь новое представление вообще не отображается. Я обнаружил, что размещение кода там, где он у меня был, но удаление if let deviceIdentity = retrievedDeviceIdentity
разворачивания заставило анимацию работать.
@Asperi приблизился, но перемещение NavigationLink привело к тому, что представление вообще не отображалось.
Что действительно сработало, так это удаление скобки if
, развертывание retrievedDeviceIdentity
:
var body: some View {
NavigationView {
VStack {
Form {
// Form building
}
NavigationLink(
destination: AddDeviceLinkDeviceForm(deviceIdentity: deviceIdentity),
isActive: .constant(retrievedDeviceIdentity != nil),
label: {
EmptyView()
}
)
.onDisappear() {
updateSyncButtonEnabledState()
}
}
}
Это требовало, чтобы свойство deviceIdentity
AddDeviceLinkDeviceForm было сделано необязательным, чтобы принимать завернутое значение.
Волшебный мир SwiftUI 🙄
Спасибо! Я добавляю его условно, так как
retrievedDeviceIdentity
нужно развернуть, чтобы передать в инициализатор AddDeviceLinkDeviceForm. С вашей логикой безопасно ли принудительно разворачиватьretrievedDeviceIdentity
в этом инициализаторе?