UIButton 在 CABasicAnimation 期间不显示选定状态
UIButton not showing selected state during CABasicAnimation
我有一个 UIButton
,我正在根据它后面 UICollectionView
的当前滚动位置设置动画。我正在执行的动画正在将按钮图像从一个更改为另一个。
我正在使用以下代码来执行动画:
let buttonAnimation: CABasicAnimation = CABasicAnimation(keyPath: "contents")
buttonAnimation.fromValue = UIImage(named: "Search-Button")!.CGImage
buttonAnimation.toValue = UIImage(named: "Search-Button-Reverse")!.CGImage
buttonAnimation.duration = 1.0
self.searchButton.imageView!.layer.speed = 0.0; // Pause the animation
self.searchButton.imageView!.layer.addAnimation(buttonAnimation, forKey: "animateSearchButton")
然后我根据滚动视图内容偏移值 scrollView.contentOffset.y
.
通过设置 self.searchButton.imageView!.layer.timeOffset
来更新 scrollViewDidScroll() {
中的动画状态
一切正常,UIButton
的动画效果完全符合我的要求,但是按下按钮时通常显示的 selected/highlighted 按钮状态不再有效。我假设这是因为我通过设置它的 layer.speed = 0.0
暂停了 UIButton
内容上的任何动画,但是有什么办法可以解决这个问题吗?
我确实有过 2 UIButton's
的想法,每个图像一个,然后为每个图像设置不透明度动画(一个淡出另一个淡入)而不是为一个图像设置动画 UIButton
, 但这看起来很乱,而且它还有一个问题,即使在其不透明度为 0 之后,也不会通过顶部按钮将触摸传递到后面的按钮。
有人有什么建议吗?很高兴在 Objective-C 或 Swift 中查看解决方案,并在需要时自行转换。
如果像这样按下按钮时更改 alpha 会怎么样?
if (button.selected) {
self.button.alpha = 0.5;
} else {
self.button.alpha = 1.0;
}
我相信你会改变按钮出口的属性,而不是动作。
最后用2UIButton's
解决了这个问题。前面的按钮有第一个图像,第二个按钮有第二个图像。
所以按钮的动画如下:
let fadeAnimation: CABasicAnimation = CABasicAnimation(keyPath: "opacity")
fadeAnimation.fromValue = NSNumber(float: 1.0)
fadeAnimation.toValue = NSNumber(float: 0.0)
fadeAnimation.duration = 1.0
fadeAnimation.removedOnCompletion = false
self.searchButton.layer.speed = 0.0; // Pause the animation
self.searchButton.layer.addAnimation(fadeAnimation, forKey: "opacitySearch")
self.profileButton.layer.speed = 0.0; // Pause the animation
self.profileButton.layer.addAnimation(fadeAnimation, forKey: "opacityProfile")
let showAnimation: CABasicAnimation = CABasicAnimation(keyPath: "opacity")
showAnimation.fromValue = NSNumber(float: 0.0)
showAnimation.toValue = NSNumber(float: 1.0)
showAnimation.duration = 1.0
showAnimation.removedOnCompletion = false
self.searchButtonReverse.layer.speed = 0.0; // Pause the animation
self.searchButtonReverse.layer.addAnimation(showAnimation, forKey: "opacitySearchReverse")
self.profileButtonReverse.layer.speed = 0.0; // Pause the animation
self.profileButtonReverse.layer.addAnimation(showAnimation, forKey: "opacityProfileReverse")
然后,正如我在问题中所述,我根据滚动视图内容偏移值 scrollView.contentOffset.y
.[=26= 设置 self.searchButton.imageView!.layer.timeOffset
来更新 scrollViewDidScroll() {
中的动画状态]
此时唯一的问题是,虽然我们正在为第一个按钮的 opacity
值设置动画并且它在某个时候变为零,但实际系统值 不是 已更新,即即使第一个按钮的 opacity
显示为 0,如果您要打印此值,它仍将是其初始值(或上次设置的值)。这意味着虽然看起来前面的按钮已经消失,现在显示后退按钮,但第一个按钮仍然消耗触摸事件,因此后退按钮永远不会显示其选择的 state/be 已按下。
为了克服这个问题,我子classed UIButton
和 override
触摸事件发生时调用的 pointInside()
方法(您可以将以下代码放在下面您的主要 class 在同一个 swift 文件中):
class HeaderButton : UIButton {
override func pointInside(point: CGPoint, withEvent event: UIEvent?) -> Bool {
var useFrontButton = super.pointInside(point, withEvent: event)
if self.layer.timeOffset > 0.5 {
useFrontButton = false
}
return useFrontButton
}
}
然后将前按钮设置为HeaderButton
类型(我们刚刚创建的class)。
现在每次按下前面的按钮,都会调用pointInside()
,如果前面的按钮timeOffset
值大于0.5(即它的opacity
小于0.5) , 然后返回 false
并且前面的按钮将不会接收到触摸。它将传递到后面的视图 - 您的后退按钮。
我有一个 UIButton
,我正在根据它后面 UICollectionView
的当前滚动位置设置动画。我正在执行的动画正在将按钮图像从一个更改为另一个。
我正在使用以下代码来执行动画:
let buttonAnimation: CABasicAnimation = CABasicAnimation(keyPath: "contents")
buttonAnimation.fromValue = UIImage(named: "Search-Button")!.CGImage
buttonAnimation.toValue = UIImage(named: "Search-Button-Reverse")!.CGImage
buttonAnimation.duration = 1.0
self.searchButton.imageView!.layer.speed = 0.0; // Pause the animation
self.searchButton.imageView!.layer.addAnimation(buttonAnimation, forKey: "animateSearchButton")
然后我根据滚动视图内容偏移值 scrollView.contentOffset.y
.
self.searchButton.imageView!.layer.timeOffset
来更新 scrollViewDidScroll() {
中的动画状态
一切正常,UIButton
的动画效果完全符合我的要求,但是按下按钮时通常显示的 selected/highlighted 按钮状态不再有效。我假设这是因为我通过设置它的 layer.speed = 0.0
暂停了 UIButton
内容上的任何动画,但是有什么办法可以解决这个问题吗?
我确实有过 2 UIButton's
的想法,每个图像一个,然后为每个图像设置不透明度动画(一个淡出另一个淡入)而不是为一个图像设置动画 UIButton
, 但这看起来很乱,而且它还有一个问题,即使在其不透明度为 0 之后,也不会通过顶部按钮将触摸传递到后面的按钮。
有人有什么建议吗?很高兴在 Objective-C 或 Swift 中查看解决方案,并在需要时自行转换。
如果像这样按下按钮时更改 alpha 会怎么样?
if (button.selected) {
self.button.alpha = 0.5;
} else {
self.button.alpha = 1.0;
}
我相信你会改变按钮出口的属性,而不是动作。
最后用2UIButton's
解决了这个问题。前面的按钮有第一个图像,第二个按钮有第二个图像。
所以按钮的动画如下:
let fadeAnimation: CABasicAnimation = CABasicAnimation(keyPath: "opacity")
fadeAnimation.fromValue = NSNumber(float: 1.0)
fadeAnimation.toValue = NSNumber(float: 0.0)
fadeAnimation.duration = 1.0
fadeAnimation.removedOnCompletion = false
self.searchButton.layer.speed = 0.0; // Pause the animation
self.searchButton.layer.addAnimation(fadeAnimation, forKey: "opacitySearch")
self.profileButton.layer.speed = 0.0; // Pause the animation
self.profileButton.layer.addAnimation(fadeAnimation, forKey: "opacityProfile")
let showAnimation: CABasicAnimation = CABasicAnimation(keyPath: "opacity")
showAnimation.fromValue = NSNumber(float: 0.0)
showAnimation.toValue = NSNumber(float: 1.0)
showAnimation.duration = 1.0
showAnimation.removedOnCompletion = false
self.searchButtonReverse.layer.speed = 0.0; // Pause the animation
self.searchButtonReverse.layer.addAnimation(showAnimation, forKey: "opacitySearchReverse")
self.profileButtonReverse.layer.speed = 0.0; // Pause the animation
self.profileButtonReverse.layer.addAnimation(showAnimation, forKey: "opacityProfileReverse")
然后,正如我在问题中所述,我根据滚动视图内容偏移值 scrollView.contentOffset.y
.[=26= 设置 self.searchButton.imageView!.layer.timeOffset
来更新 scrollViewDidScroll() {
中的动画状态]
此时唯一的问题是,虽然我们正在为第一个按钮的 opacity
值设置动画并且它在某个时候变为零,但实际系统值 不是 已更新,即即使第一个按钮的 opacity
显示为 0,如果您要打印此值,它仍将是其初始值(或上次设置的值)。这意味着虽然看起来前面的按钮已经消失,现在显示后退按钮,但第一个按钮仍然消耗触摸事件,因此后退按钮永远不会显示其选择的 state/be 已按下。
为了克服这个问题,我子classed UIButton
和 override
触摸事件发生时调用的 pointInside()
方法(您可以将以下代码放在下面您的主要 class 在同一个 swift 文件中):
class HeaderButton : UIButton {
override func pointInside(point: CGPoint, withEvent event: UIEvent?) -> Bool {
var useFrontButton = super.pointInside(point, withEvent: event)
if self.layer.timeOffset > 0.5 {
useFrontButton = false
}
return useFrontButton
}
}
然后将前按钮设置为HeaderButton
类型(我们刚刚创建的class)。
现在每次按下前面的按钮,都会调用pointInside()
,如果前面的按钮timeOffset
值大于0.5(即它的opacity
小于0.5) , 然后返回 false
并且前面的按钮将不会接收到触摸。它将传递到后面的视图 - 您的后退按钮。