ios - How to resume core animation when the app back to foreground -
i have imageview , want rotate 360° time, found issue when app enters background
, foreground
, rotate animation stopped. , don't want re-call function rotate360degree()
when app foreground, reason want rotate-animation start @ position left when entering background, instead of rotating 0 again. when call function resumerotate()
, doesn't work.
the extension follow:
extension uiimageview { // 360度旋转图片 func rotate360degree() { let rotationanimation = cabasicanimation(keypath: "transform.rotation.z") // 让其在z轴旋转 rotationanimation.tovalue = nsnumber(value: .pi * 2.0) // 旋转角度 rotationanimation.duration = 20 // 旋转周期 rotationanimation.iscumulative = true // 旋转累加角度 rotationanimation.repeatcount = maxfloat // 旋转次数 rotationanimation.autoreverses = false layer.add(rotationanimation, forkey: "rotationanimation") } // 暂停旋转 func pauserotate() { layer.pauseanimation() } // 恢复旋转 func resumerotate() { layer.resumeanimation() } }
here layer extension :
var pausetime:cftimeinterval! extension calayer { //暂停动画 func pauseanimation() { pausetime = converttime(cacurrentmediatime(), from: nil) speed = 0.0 timeoffset = pausetime } //恢复动画 func resumeanimation() { // 1.取出时间 pausetime = timeoffset // 2.设置动画的属性 speed = 1.0 timeoffset = 0.0 begintime = 0.0 // 3.设置开始动画 let starttime = converttime(cacurrentmediatime(), from: nil) - pausetime begintime = starttime } }
i can solve above 'stopped' issue cadisplaylink, animation not rotate position left(rotate time). wonder how solve cadisplaylink? , how above core animation?
displaylink = cadisplaylink(target: self, selector: #selector(rotateimage)) displaylink.add(to: .current, formode: .commonmodes) func rotateimage(){ let angle = cgfloat(displaylink.duration * double.pi / 18) artworkimageview.transform = artworkimageview.transform.rotated(by: angle) }
you can uikit
's higher-level block based animation api. if want continuously rotating view 20.0 second duration. can function like:
func animateimageview() { uiview.animate(withduration: 10.0, delay: 0.0, options: [.beginfromcurrentstate, .repeat, .curvelinear], animations: { [unowned self] in var transform = self.imageview.transform transform = transform.concatenating(cgaffinetransform(rotationangle: cgfloat.pi)) self.imageview.transform = transform }, completion: { _ in uiview.animate(withduration: 10.0, delay: 0.0, options: [.beginfromcurrentstate, .curvelinear], animations: { [unowned self] in var transform = self.imageview.transform transform = transform.concatenating(cgaffinetransform(rotationangle: cgfloat.pi / 2.0)) self.imageview.transform = transform }) }) }
this rotate view 180 degrees once complete rotate 180 360 degree rotation. .repeat
option cause repeat indefinitely. however, animation stop when app backgrounded. that, need save state of presentation layer of view being rotated. can storing cgaffinetransform
of presentation layer , setting transform view being animated when app comes foreground. here's example uiimageview
class viewcontroller: uiviewcontroller { @iboutlet weak var imageview: uiimageview! var imageviewtransform = cgaffinetransform.identity override func viewdidload() { super.viewdidload() notificationcenter.default.addobserver(self, selector: #selector(self.didenterbackground), name: .uiapplicationdidenterbackground, object: nil) notificationcenter.default.addobserver(self, selector: #selector(self.willenterforeground), name: .uiapplicationwillenterforeground, object: nil) } override func viewdidappear(_ animated: bool) { super.viewdidappear(animated) animateimageview() } deinit { notificationcenter.default.removeobserver(self) } func didenterbackground() { imageviewtransform = imageview.layer.presentation()?.affinetransform() ?? .identity } func willenterforeground() { imageview.transform = imageviewtransform animateimageview() } func animateimageview() { uiview.animate(withduration: 10.0, delay: 0.0, options: [.beginfromcurrentstate, .repeat, .curvelinear], animations: { [unowned self] in var transform = self.imageview.transform transform = transform.concatenating(cgaffinetransform(rotationangle: cgfloat.pi)) self.imageview.transform = transform }, completion: { _ in uiview.animate(withduration: 10.0, delay: 0.0, options: [.beginfromcurrentstate, .curvelinear], animations: { [unowned self] in var transform = self.imageview.transform transform = transform.concatenating(cgaffinetransform(rotationangle: cgfloat.pi / 2.0)) self.imageview.transform = transform }) }) } }
which results in this:
Comments
Post a Comment