反转UIView动画并进行相反的translationX移动

问题描述 投票:0回答:3

我有一个动画UIImageView,它动画化了translationX: -250

我正在使用autoreverse, .repeat重复播放动画。

但是我想发生的事情如下:

translationX: -250
translationX: 0
translationX: 250

并重复-本质上是图像不断从0 > -250 > 0 > +250移动

class ViewController: UIViewController {

  private lazy var imageView: UIImageView = {
    let imageView = UIImageView(image: #imageLiteral(resourceName: "city_image_01"))
    imageView.translatesAutoresizingMaskIntoConstraints = false
    imageView.contentMode = .scaleAspectFill
    return imageView
  }()

  override func viewDidLoad() {
    super.viewDidLoad()

    view.addSubview(imageView)
    NSLayoutConstraint.activate([
      imageView.topAnchor.constraint(equalTo: view.topAnchor),
      imageView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
      imageView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
      imageView.trailingAnchor.constraint(equalTo: view.trailingAnchor)
    ])


    UIView.animate(withDuration: 20, delay: 0, options: [.autoreverse, .repeat, .curveEaseInOut], animations: {
      self.imageView.transform = .init(translationX: -250, y: 0)
    }, completion: { _ in })
  }
}
swift uiview uiviewanimation
3个回答
1
投票

您可以实现触发下一个动画阶段的基本状态机。

class ViewController: UIViewController {

  enum AnimationState {
    case stopped
    case started
    case finishing
  }

  var state: AnimationState = .stopped {
    didSet {
      switch state {
      case .stopped: runAnimation(.init(translationX: -250, y: 0), next: .started)
      case .started: runAnimation(.identity, next: .finishing)
      case .finishing: runAnimation(.init(translationX: 250, y: 0), next: .stopped)
      }
    }
  }

  private lazy var imageView: UIImageView = {
    let imageView = UIImageView(image: #imageLiteral(resourceName: "city_image_01"))
    imageView.translatesAutoresizingMaskIntoConstraints = false
    imageView.contentMode = .scaleAspectFill
    return imageView
  }()

  override func viewDidLoad() {
    super.viewDidLoad()

    view.addSubview(imageView)
    NSLayoutConstraint.activate([
      imageView.topAnchor.constraint(equalTo: view.topAnchor),
      imageView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
      imageView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
      imageView.trailingAnchor.constraint(equalTo: view.trailingAnchor)
    ])

    state = .stopped
  }


  func runAnimation(_ transform: CGAffineTransform, next state: AnimationState) {
    UIView.animate(
      withDuration: 20,
      delay: 0,
      options: [.curveEaseInOut],
      animations: { self.imageView.transform = transform },
      completion: { _ in self.state = state }
    )
  }

}

1
投票

这应该有助于您获得想要获得的动画

        imageView.layer.anchorPoint = CGPoint(x: 0, y: 0.5)
        let animation = CABasicAnimation(keyPath: "position.x")
        animation.duration = 5
        animation.fromValue = 250
        animation.byValue = -500
        animation.autoreverses = true
        animation.repeatCount = .infinity
        self.imageView.layer.add(animation, forKey: "oscilatingAnimation")

enter image description here

希望这会有所帮助


0
投票

如果稍微更改动画块,您将获得想要的效果:

//for the first animation, animate from 0 to -250 (no repeat)
UIView.animate(withDuration: 20, delay: 0, options: [ .curveEaseInOut], animations: {
  self.imageView.transform = .init(translationX: -250, y: 0)
}, completion: { _ in 
      Once that's done, begin a repeating animation between -250 and 250
      UIView.animate(withDuration: 20, delay: 0, options: [.autoreverse, .repeat, .curveEaseInOut], animations: {
      translationX *= -1
      self.imageView.transform = .init(translationX: 250, y: 0)
      }, completion: {_ in}
      )
)
© www.soinside.com 2019 - 2024. All rights reserved.