
Анимации переходов между представлениями (view transition) были доступны с самой первой версии фреймворка SwiftUI. Фреймворк позволяет указать определенную анимацию перехода, которая будет применяться всякий раз, когда представление удаляется или добавляется в иерархию представлений. С недавних пор фреймворк SwiftUI предлагает нам еще один тип анимаций перехода — анимации переходов для содержимого (content transition). Суть та же, что и раньше. Фреймворк теперь позволяет нам указывать определенную анимацию перехода для содержимого представления, которая будет проигрываться всякий раз, когда оно изменяется. На этой неделе мы с вами разберемся, как использовать новый API для анимирования переходов содержимого в SwiftUI.
В предыдущих версиях SwiftUI мы не могли применять переходы (transition) к содержимому представления. И если вы запустите этот пример на iOS 15, то никакой анимации перехода вы не увидите.
struct ContentView: View { @State private var flag = false var body: some View { VStack { Text(verbatim: "1000") .fontWeight(flag ? .black : .light) .foregroundColor(flag ? .yellow : .red) } .onTapGesture { withAnimation(.default.speed(0.1)) { flag.toggle() } } } }
Предыдущая версия SwiftUI не поддерживает никаких переходов для содержимого представления Text и сразу же применяет изменения без какого-либо визуального эффекта. К счастью, последняя итерация SwiftUI позволяет нам указать анимацию перехода для содержимого представления Text с помощью модификатора представления contentTransition:
struct ContentView: View { @State private var flag = false var body: some View { VStack { Text(verbatim: "1000") .fontWeight(flag ? .black : .light) .foregroundColor(flag ? .yellow : .red) } .contentTransition(.opacity) .onTapGesture { withAnimation(.default.speed(0.1)) { flag.toggle() } } } }
Как видно из приведенного выше примера, единственная строка кода, которую мы добавили, — это модификатор представления contentTransition. Он принимает инстанс выбранной нами анимации перехода, который SwiftUI применяет к представлению при каждом изменении его содержимого. В данном случае поскольку мы используем интерполяцию (interpolate), анимация перехода влияет на размер и цвет текста.
struct ContentView: View { @State private var flag = false var body: some View { VStack { Text(verbatim: "1000") .fontWeight(flag ? .black : .light) .foregroundColor(flag ? .yellow : .red) } .contentTransition(.opacity) .onTapGesture { withAnimation(.default.speed(0.1)) { flag.toggle() } } } }
В этом примере мы используем другой инстанс ContentTransition называемый opacity. В этом случае SwiftUI будет анимировать постепенное появление/исчезновение текста при каждом его изменении.
В SwiftUI есть еще один тип ContentTransition, который работает только с числовым текстом (numericText). Он понимает, как изменилось число, и создает приятный визуальный эффект, изменяющий только часть представления Text, которая представляет число.
struct TextContentView: View { @State private var number = "99" var body: some View { Text(verbatim: number) .font(.system(size: 36)) .contentTransition(.numericText()) .onTapGesture { withAnimation(.default.speed(0.2)) { number = "98" } } } }
Чтобы узнать больше о других вариациях анимации изменений в тексте, читайте статью “AnimatableModifier в SwiftUI”.
Модификатор представления contentTransition передает предоставленный ему инстанс ContentTransition через среду SwiftUI, что позволяет нам получить к нему доступ по определенному EnvironmentKey.
struct MySuperCustomTextView: View { let text: String @Environment(\.contentTransition) private var transition var body: some View { switch transition { case .opacity: drawWithOpacity() case .interpolate: drawWithInterpolation() default: draw() } } // ... }
Здесь мы наблюдаем супер кастомизированное текстовое представление, которое использует среду SwiftUI, чтобы определить, какую технику отрисовки переданного текста следует использовать, на основе используемой анимация перехода.
Существует еще один EnvironmentKey, связанный с анимацией перехода содержимого, который позволяет нам решать, когда мы хотим использовать усиленный GPU рендеринг, оборачивая содержимое с анимацией перехода в drawingGroup.
struct ContentView: View { @State private var flag = false var body: some View { VStack { Text(verbatim: "1000") .fontWeight(flag ? .black : .light) .foregroundColor(flag ? .yellow : .red) } .environment(\.contentTransitionAddsDrawingGroup, true) .contentTransition(.interpolate) .onTapGesture { withAnimation(.default.speed(0.1)) { flag.toggle() } } } }
Сегодня мы с вами разобрали новые техники анимации переходов для содержимого в SwiftUI. В настоящее время их поддерживает не так много представлений, но их количество скорее всего изменится в будущем. Попробуйте поддержать эту фичу в своих представлениях, добавив новые API, которые мы рассмотрели сегодня.
Перевод материала подготовлен в рамках специализации iOS Developer.
ссылка на оригинал статьи https://habr.com/ru/company/otus/blog/698334/
Добавить комментарий