ios - UIButton 在 CABasicAnimation 期间不显示选定状态

标签 ios objective-c swift cabasicanimation quartz-core

我有一个 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 内容偏移值设置 self.searchButton.imageView!.layer.timeOffset 来更新 scrollViewDidScroll() { 中的动画状态scrollView.contentOffset.y.

这一切工作正常,UIButton 完全按照我想要的方式进行动画处理,但是当您按下它时通常显示的按钮的选定/突出显示状态不再有效。我假设这是因为我通过设置 layer.speed = 0.0 暂停了 UIButton 内容的任何动画,但是有什么办法可以解决这个问题所以它会起作用吗?

我确实有过使用 2 个 UIButton 的 的想法,每个图像一个,然后为每个图像设置不透明度动画(一个淡出另一个淡入),而不是为一个 的图像设置动画UIButton,但这看起来很乱,而且它还有一个问题,即使在其不透明度为 0 之后,也不会通过顶部按钮将触摸传递到后面的按钮。

有人有什么建议吗?很高兴在 Objective-C 或 Swift 中查看解决方案,并会在需要时自行转换。

最佳答案

最后通过使用 2 个 UIButton 的 解决了这个问题。前面的按钮有第一个图像,第二个按钮有第二个图像。

所以按钮的动画如下:

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")

然后正如我在问题中所述,我通过设置 self.searchButton.imageView!.layer.timeOffset 来更新 scrollViewDidScroll() { 中的动画状态 ScrollView 内容偏移值 scrollView.contentOffset.y

此时唯一的问题是,虽然我们正在为第一个按钮的 opacity 值设置动画并且它在某个时候变为零,但实际系统值不是已更新,即即使第一个按钮的 opacity 显示为 0,如果您要打印此值,它仍将是其初始值(或上次设置的值)。这意味着虽然看起来前面的按钮已经消失并且现在显示后退按钮,但第一个按钮仍然消耗触摸事件,因此后退按钮永远不会显示其选定状态/被按下。

为了克服这个问题,我将 UIButton 子类化并覆盖 pointInside() 方法,该方法在触摸事件发生时调用(您可以将在同一 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类型(我们刚刚创建的类)。

现在每次按下前面的按钮时,pointInside() 都会被调用,如果前面按钮的 timeOffset 值大于 0.5(即它的 opacity 小于 0.5),则返回 false,前置按钮不会接收到触摸。它将传递到后面的 View - 您的后退按钮。

关于ios - UIButton 在 CABasicAnimation 期间不显示选定状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32635893/

相关文章:

iphone - 无法读取 Xcode 4.2 中的符号错误

iphone - 如何检测文件名中的中文/日文字符?

ios - 游戏中心排行榜 - 无法将 GKLeaderboardViewController 委托(delegate)设置为自身(CCLayer)

ios - 将 float 分配到全局数组中

ios - 附加多维字典

ios - 用户通知中心获取授权选项 Swift 3/4 ios10/11

ios - 为 UITableView 设置背景图像会占用内存并卡住应用程序

swift - 一组可散列的自定义元素插入相等的元素

swift - 如何在我的 GameKit 游戏中避免这些循环引用?我正在使用 GKAgents2D 和 GKBehaviours

ios - 队列优先级似乎不对