Используйте Combine Framework с модификатором анимации SwiftUI

Без сомнения, анимация - это кровь iOS. По большей части легко реализуется в SwiftUI. Это, конечно, при условии, что вы не хотите связывать свои анимации вместе, что, к сожалению, не похоже на то, что Apple добавила в общую схему вещей. Но еще не все потеряно, потому что, проявив нестандартное мышление, мы сможем исправить этот недостаток. Присоединяйтесь ко мне в путешествии, чтобы узнать, как это сделать.

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

Тем не менее, есть решение SwiftUI, которое лучше, чем использование таймеров. Решение SwiftUI, использующее собственный AnimatableModifier, который отслеживает и сообщает, какая часть значения анимации была сделана во время выполнения.

Конечно, вам нужно настроить анимации, которые вы хотите объединить в цепочку, но помимо этого, это работает хорошо.

В этом примере animNumber I, передаваемый в процедуру, - это градусы по кругу, по которому прошел объект. Я использую округление, чтобы убедиться, что меня не поймают из-за ошибок округления, и я сравниваю одно значение, потому что хочу, чтобы оно срабатывало один раз и только один раз.

Между тем, код SwiftUI, использующий эту процедуру, выглядит так:

В этом коде используется метод задержки, который я определил в другой статье, он выглядит так.

func delay(_ delay:Double, closure:@escaping ()->()) {
  
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + Double(Int64(delay * Double(NSEC_PER_SEC))) / Double(NSEC_PER_SEC), execute: closure)
}

Через 2 секунды он обновляет текстовый объект, который я хочу отобразить на экране, а затем начинает его вращать. Когда модификатор chainEffect определяет, что вы достигли примерно 360 градусов, он запускает releaseMessage, который подхватывается текстом, который показывает следующее слово в массиве слов.

Следующий результат, который вы можете увидеть здесь, - это анимированный выше GIF вращающегося текста. Это так просто.

Бон, но в коде, который я вам только что показал, есть небольшая загвоздка. Я применяю анимацию ко всему объекту, а не к отдельным объектам. Представьте, что вы хотите, чтобы слова появлялись одно за другим, по мере того как каждое из них постепенно исчезало.

Для этого сначала я определил вид текстового слова, которое хочу показать:

Это вызывает модификатор, как и последний, с двумя параметрами, первый - текстовое содержимое, второй - его индекс. Мне нужен индекс, потому что rMessage passThroughSubject будет получен всеми TextWord представлениями одновременно, и я хочу выбрать конкретный.

Далее идет код модификатора ChainEffectV:

Код почти идентичен другому методу ChainEffect, за исключением того факта, что я изменил условие завершения.

Наконец, ниже находится новый ContentView.swift, который вызывает TextView несколько раз в цикле. Опять же, в отличие от предыдущего решения, это намного более эффективно, так как оно выкладывает весь дисплей, прежде чем мы попытаемся его анимировать:

Окончательный результат выглядит так:

На всем этом я подошел к концу этой короткой статьи. Спасибо за прочтение.