【发布时间】:2025-12-13 21:15:02
【问题描述】:
问题:
- 当用户按下 Home 按钮并返回应用程序时,如何暂停嵌套 UIView 动画以动画化 alpha/不透明度?
- 我在下面的代码中遗漏了什么?谢谢。
背景:
我有一个简单的嵌套 UIView 动画,它在 1 分钟内从 alpha = 0 到 alpha = 1 的不同时间缓慢调整视图的 alpha。
当用户按下 Home 按钮时,UIView 动画不会暂停,因此当应用程序恢复时,UIView 动画会快进到动画的最后,alpha 值会在应用程序恢复时立即从 0 变为 1。
所以,当用户按下设备的 Home 按钮并暂时挂起应用程序时,我尝试暂停 UIView 动画。
我有一个暂停动画 (pauseLayer) 然后重新开始动画 (resumeLayer) 的函数。从UIButton 调用它们时,这两个函数非常有效。它暂停alpha 并按预期恢复动画。 (但是,如果在动画暂停时按下 Home 按钮,当它恢复时,alpha 会立即从 0 变为 1。)
当我尝试在用户按下主页按钮时调用pauseLayer(接收到WillResignActive 通知),然后返回到应用程序(接收到WillEnterForeground 通知),动画不会暂停并且resume,而是在恢复应用时 alpha 立即从 0 变为 1。
它看起来应该有效,但它没有。
代码:
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var myView1: UIView!
@IBOutlet weak var myView2: UIView!
override func viewDidLoad() {
super.viewDidLoad()
setNotifications()
myAnimation()
}
@IBAction func myPauseButton(sender: UIButton) {
let layer = self.view.layer
pauseLayer(layer)
}
@IBAction func myResumeButton(sender: UIButton) {
let layer = self.view.layer
resumeLayer(layer)
}
func setNotifications() {
NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(ViewController.WillEnterForeground(_:)), name: UIApplicationWillEnterForegroundNotification, object: nil)
NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(ViewController.WillResignActive(_:)), name: UIApplicationWillResignActiveNotification, object: nil)
}
func WillEnterForeground(notification : NSNotification) {
let layer = self.view.layer
resumeLayer(layer)
}
func WillResignActive(notification : NSNotification) {
let layer = self.view.layer
pauseLayer(layer)
}
func pauseLayer(layer: CALayer) {
let pausedTime: CFTimeInterval = layer.convertTime(CACurrentMediaTime(), fromLayer: nil)
layer.speed = 0.0
layer.timeOffset = pausedTime
}
func resumeLayer(layer: CALayer) {
let pausedTime: CFTimeInterval = layer.timeOffset
layer.speed = 1.0
layer.timeOffset = 0.0
layer.beginTime = 0.0
let timeSincePause: CFTimeInterval = layer.convertTime(CACurrentMediaTime(), fromLayer: nil) - pausedTime
layer.beginTime = timeSincePause
}
func myAnimation() {
self.myView1.alpha = 0
UIView.animateWithDuration(15, delay: 0, options: [.CurveEaseInOut], animations: {
self.myView1.alpha = 0.1
}, completion: {(finished: Bool) in
UIView.animateWithDuration(15, delay: 0, options: [.CurveEaseInOut], animations: {
self.myView1.alpha = 0.2
}, completion: {(finished: Bool) in
UIView.animateWithDuration(30, delay: 0, options: [.CurveEaseInOut], animations: {
self.myView1.alpha = 1
}, completion: nil)
})
})
self.myView2.alpha = 0
UIView.animateWithDuration(15, delay: 0, options: [.CurveEaseInOut], animations: {
self.myView2.alpha = 0.1
}, completion: {(finished: Bool) in
UIView.animateWithDuration(15, delay: 0, options: [.CurveEaseInOut], animations: {
self.myView2.alpha = 0.2
}, completion: {(finished: Bool) in
UIView.animateWithDuration(30, delay: 0, options: [.CurveEaseInOut], animations: {
self.myView2.alpha = 1
}, completion: nil)
})
})
}
}
编辑:
如果我将if (finished) { 添加到每个部分,然后按主页按钮,然后返回应用程序,动画只会前进到下一部分并停止,不再进行。这样更好,但问题是 resumeLayer 似乎不起作用,所以动画仍然停止并且不会继续。
self.myView2.alpha = 0
UIView.animateWithDuration(15, delay: 0, options: [.CurveEaseInOut, .LayoutSubviews, .AllowUserInteraction, .BeginFromCurrentState], animations: {
self.myView2.alpha = 0.1
}, completion: {(finished: Bool) in
if (finished) {
UIView.animateWithDuration(15, delay: 0, options: [.CurveEaseInOut, .LayoutSubviews, .AllowUserInteraction, .BeginFromCurrentState], animations: {
self.myView2.alpha = 0.2
}, completion: {(finished: Bool) in
if (finished) {
UIView.animateWithDuration(30, delay: 0, options: [.CurveEaseInOut, .LayoutSubviews, .AllowUserInteraction, .BeginFromCurrentState], animations: {
self.myView2.alpha = 1
}, completion: nil)
}
})
}
})
【问题讨论】:
-
也许你应该使用 UIApplicationDidBecomeActive 而不是 UIApplicationWillEnterForeground
-
不幸的是,@Calimari328 没有用,不过谢谢,我没有尝试。
标签: ios swift animation uiview uiviewanimation