反转 UIView 动画并进行相反的 translationX 运动
Reversing a UIView animation and doing the opposite translationX movement
我有一个 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 })
}
}
这应该可以帮助您获得想要的动画
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")
希望对您有所帮助
您可以实现触发下一个动画阶段的基本状态机。
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 }
)
}
}
如果稍微更改动画块,您应该会得到想要的效果:
// 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: {
self.imageView.transform = .init(translationX: 250, y: 0)
}, completion: nil)
})
我有一个 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 })
}
}
这应该可以帮助您获得想要的动画
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")
希望对您有所帮助
您可以实现触发下一个动画阶段的基本状态机。
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 }
)
}
}
如果稍微更改动画块,您应该会得到想要的效果:
// 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: {
self.imageView.transform = .init(translationX: 250, y: 0)
}, completion: nil)
})