Анимация SwiftUI: как настроить анимацию перехода (затухание, ЗАТЕМ появление)

Этот код создаст анимацию, которая плавно затухает значения всякий раз, когда я меняю self.myTextString:

// In some View's body method
Text(self.myTextString)
.transition(.opacity)
.animation(.easeInOut(duration: 0.6), value: self.myTextString)

Мне хотелось бы, чтобы старое значение полностью исчезло, а затем начало исчезать в новом значении.

Не казалось ясным/очевидным, как это сделать. Нужно ли мне делать собственный переход? Есть ли где-нибудь примеры, когда кто-то делал такое? (Пусть исходящий что-то сделает и завершится, тогда входящий сможет начать анимацию?)

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
0
84
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Я не думаю, что вы можете реализовать это как один переход, вам нужно очистить текст, а затем установить новое значение.

Один из способов сделать это — использовать withAnimation с обратным вызовом completion:

struct ContentView: View {
    let part1 = "The quick brown fox"
    let part2 = "jumps over the lazy dog"
    @State private var myTextString = ""
    @State private var showPart1 = true

    var body: some View {
        VStack {
            Text(myTextString)
                .animation(.easeInOut(duration: 0.6), value: myTextString)
                .frame(height: 50)

            Picker("Selection", selection: $showPart1) {
                Text(part1).tag(true)
                Text(part2).tag(false)
            }
            .pickerStyle(.segmented)
            .fixedSize()
            .padding()
            .onChange(of: showPart1, initial: true) { oldVal, newVal in
                withAnimation {
                    myTextString = ""
                } completion: {
                    myTextString = newVal ? part1 : part2
                }
            }
        }
    }
}

Animation

Некоторые примечания:

  • Переход происходит только тогда, когда одно представление заменяется другим. Если для отображения изменяющегося текста используется одно и то же представление Text (другими словами, меняется только контент), то на самом деле перехода не происходит, а только анимированное изменение. Таким образом, модификатор .transition не требуется.

  • Вместо модификатора .transition модификатор .contentTransition может оказаться полезным.

  • В этом примере Text имеет фиксированную высоту, потому что, когда он очищен, он занимает меньше места, чем когда он имеет значение. В противном случае это изменение приводит к тому, что Picker в том же самом VStack немного перемещается.

Ответ принят как подходящий

Если вы знаете задержку, вы можете сделать асимметричный переход и задержать их, чтобы они выглядели так, как вам нравится:

Text(self.myTextString)
    .transition(
        .asymmetric(
            insertion: .opacity.animation(.easeIn.delay(0.6)),
            removal: .opacity.animation(.easeOut)
        )
    )
    .id(myTextString)
    .animation(.default, value: self.myTextString)

Demo

Note transition works for new objects (new identities)

в противном случае вам нужно разбить переход на два отдельных состояния (например, состояние загрузки и состояние завершения) и запустить триггер для каждого отдельно.

Это именно то, что я искал! Я не осознавал, что можно изменить переход с помощью свойства анимации таким образом. Большое спасибо!

horseshoe7 12.06.2024 16:06

Другие вопросы по теме