Супер крутая анимация для iOS | Кодементор

В некоторых случаях создание пользовательской анимации в iOS может быть довольно простым, но не всегда. Некоторые анимации могут быть очень сложными.

Это анимация, которую мы попытаемся воспроизвести. Это выглядит легко, не так ли? Потому что вы можете просто анимировать положение движущегося вида, но сидеть сложа руки и думать о том, как вы собираетесь анимировать вид вокруг в круглой форме.

Две вещи, на которые следует обратить внимание, прежде чем мы начнем:

  1. Четыре представления в центре будут называться staticViews.
  2. Вид, прыгающий вверх и вниз, будет называться movingView.
    Таким образом, для достижения круговой анимации мой собственный подход будет заключаться в использовании UIBezierPath для рисования пути анимации (PS: это мой собственный подход. Не означает, что он лучший). Я нарисовал путь, прежде чем соединить пути Безье вместе

1_OivEwubPB78hw_tAfkgobw.png

Я знаю, я не могу рисовать, чтобы спасти свою жизнь 😂, но так будут выглядеть мои собственные пути Безье, и мои статические представления будут иметь тот же кадр с тем же размером, но с другим началом, потому что ось x будет другой Capeesh?

Теперь перейдем к Xcode, давайте закодируем пути Безье.

let bezierPath = UIBezierPath()
bezierPath.move(to: CGPoint(x: 25.5, y: 185.5))
bezierPath.addCurve(to: CGPoint(x: 25.5, y: 56.5), controlPoint1: CGPoint(x: 25.5, y: 185.5), controlPoint2: CGPoint(x: 25.5, y: 88.75))
bezierPath.addCurve(to: CGPoint(x: 72.5, y: 67.5), controlPoint1: CGPoint(x: 25.5, y: 24.25), controlPoint2: CGPoint(x: 60.75, y: 64.75))
bezierPath.addCurve(to: CGPoint(x: 108.5, y: 185.5), controlPoint1: CGPoint(x: 84.25, y: 70.25), controlPoint2: CGPoint(x: 108.5, y: 185.5))
bezierPath.addCurve(to: CGPoint(x: 136.5, y: 299.5), controlPoint1: CGPoint(x: 108.5, y: 185.5), controlPoint2: CGPoint(x: 129.5, y: 271))
bezierPath.addCurve(to: CGPoint(x: 186.5, y: 279.5), controlPoint1: CGPoint(x: 143.5, y: 328), controlPoint2: CGPoint(x: 174, y: 284.5))
bezierPath.addCurve(to: CGPoint(x: 202.5, y: 185.5), controlPoint1: CGPoint(x: 199, y: 274.5), controlPoint2: CGPoint(x: 202.5, y: 185.5))
bezierPath.addCurve(to: CGPoint(x: 217.5, y: 67.5), controlPoint1: CGPoint(x: 202.5, y: 185.5), controlPoint2: CGPoint(x: 213.75, y: 97))
bezierPath.addCurve(to: CGPoint(x: 261.5, y: 67.5), controlPoint1: CGPoint(x: 221.25, y: 38), controlPoint2: CGPoint(x: 261.5, y: 67.5))
bezierPath.addCurve(to: CGPoint(x: 291.5, y: 185.5), controlPoint1: CGPoint(x: 261.5, y: 67.5), controlPoint2: CGPoint(x: 284, y: 156))
bezierPath.addCurve(to: CGPoint(x: 335.5, y: 299.5), controlPoint1: CGPoint(x: 299, y: 215), controlPoint2: CGPoint(x: 335.5, y: 299.5))
UIColor.black.setStroke()
bezierPath.lineWidth = 0

Обратите внимание, что я сделал lineWidth равным 0, потому что мы не хотим, чтобы на экране отображалась черная линия.

Я также изменил положение staticViews на конечную точку каждой кривой.

1_lq4hREVJONfU7wNYtCIvYw.png

Теперь задача состоит в том, как анимировать movingView вокруг пути. Я думал, что могу просто анимировать центр movingView или положение, но результат был совсем не приятным, потому что он не анимировал кривые и все еще имел квадратный край, поэтому я нашел ключ CAKeyframeAnimation, который позволяет вам анимировать вдоль пути и это называется анимация вдоль пути

let animation = CAKeyframeAnimation(keyPath: "position")
animation.path = bezierPath.cgPath
animation.repeatCount = 0
animation.duration = 3.0
animation.delegate = self
movingView.layer.add(animation, forKey: "animate along path")
movingView.center = CGPoint(x: 0, y: frame.maxY)
timer = Timer.scheduledTimer(timeInterval: 0.01, target: self, selector: #selector(fireTimer), userInfo: nil, repeats: true)

Запуск приложения дал мне такой результат:

1_HQsuMaAWUIe1_OT68BoR8g.gif

Бум! это определенно поведение, которое я ожидал! ♨️

Теперь следующая задача — эффект капли воды, который немного сложен, но самое простое решение — изменить масштаб movingView при переходе от одного staticView к другому, что означает, что всякий раз, когда он приземляется на staticView, он меняет свой масштаб. что довольно легко. Все, что мне нужно было сделать, это использовать старый добрый UIView Animate.

fileprivate func scaleMethod() {
    UIView.animate(withDuration: 0.75, animations: {
        self.movingView.transform = .identity
    }) { _ in
        self.movingView.transform = CGAffineTransform(scaleX: 0.5, y: 0.5)
        self.scaleMethod()
    }
}

Обратите внимание, что исходным преобразованием для movingView было CGAffineTransform(scaleX: 0,5, y: 0,5). Надеюсь, это имеет смысл.

Фу! Итак, у нас есть масштабная анимация и кривая анимация 🥳

Теперь, если вы заметили, что градиент movingView изменяется, когда он попадает в определенный staticView. Это, вероятно, самая простая вещь, поэтому я поставил ее последней. Для этого я установил таймер, когда CAKeyframeAnimation выше запускается каждые 0,01 секунды, чтобы проверить текущую позицию movingView.

Чтобы получить текущий кадр movingView во время анимации, мне нужно было получить PresentationLayer

пусть кадр = self.movingView.layer.presentationLayer()?.frame

if (f?.origin.x)! >= self.circleTwo.frame.origin.x{
rectV.applyGradient(colours: [UIColor(red:1.00, green:0.89, blue:0.35, alpha:1.0), UIColor(red:1.00, green:0.65, blue:0.32, alpha:1.0)])
}else if (f?.origin.x)! >= self.circleThree.frame.origin.x{
rectV.applyGradient(colours: [UIColor(red:0.47, green:0.62, blue:0.05, alpha:1.0), UIColor(red:0.67, green:0.73, blue:0.47, alpha:1.0)])
}else if (f?.origin.x)! >= self.circleFour.frame.origin.x{
rectV.applyGradient(colours: [UIColor(red:0.96, green:0.69,        blue:0.10, alpha:1.0), UIColor(red:0.95, green:0.15, blue:0.07, alpha:1.0)])
}

Наконец результат

1_4orbT2VlpwWL17sPklrUYg.gif

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

Похожие записи

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

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