Анимация переходов для содержимого в SwiftUI

от автора

Анимации переходов между представлениями (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/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *