您不必将按钮用作自定义视图,它实际上可以使用更少的代码使用 UIImageView 并添加 UITapGestureRecognizer。
我希望我下面的解决方案可以帮助我在这个问题上苦苦挣扎了很长时间的人,直到我得到了条形按钮项目来接收点击并让它与我想要的所有功能一起工作。就我而言,我制作了一个“警报铃”栏按钮项目,当有通知时会发出叮当声,然后在点击时切换到新的 tableview 控制器。
这是我的解决方案(Swift 5):
@IBOutlet weak var notifyBell: UIBarButtonItem!
func updateNumNotesAndAnimateBell(_ numNotes: Int) {
guard let image = UIImage(named: "alertBellFill_\(numNotes)") else { return }
let imageView = UIImageView(image: image)
notifyBell.customView = imageView
notifyBell.customView?.contentMode = .center
let tap = UITapGestureRecognizer(target: self, action: #selector(notifyBellPressed))
notifyBell.customView?.addGestureRecognizer(tap)
let scaleTransformA = CGAffineTransform(scaleX: 0.8, y: 0.8)
let rotateTransformA = CGAffineTransform(rotationAngle: 0.0)
let hybridTransformA = scaleTransformA.concatenating(rotateTransformA)
let rotateTransformB = CGAffineTransform(rotationAngle: -1*CGFloat.pi*20.0/180.0)
let hybridTransformB = scaleTransformA.concatenating(rotateTransformB)
notifyBell.customView?.transform = hybridTransformA
UIView.animate(withDuration: 3,
delay: 1,
usingSpringWithDamping: 0.1,
initialSpringVelocity: 10,
options: [.allowUserInteraction, .curveEaseInOut],
animations: {
self.notifyBell.customView?.transform = numNotes > 0 ? hybridTransformB : scaleTransformA
},
completion: nil
)
}
@objc func notifyBellPressed(_ sender: UIBarButtonItem) {
performSegue(withIdentifier: "goToNotificationsTVC", sender: self)
}
我的主要发现是:
-- .allowUserInteraction 必须包含在动画选项中,否则 UIBarButtonItem 在动画完成之前不会处于活动状态。
-- 在使用 CGAffineTransform(rotationAngle: ) 时,您可能必须声明 YourBarButtonItem.customView?.contentMode = .center ,否则它会在尝试旋转时扭曲您的图像。
-- 上面的代码包括一个缩放动画和旋转动画,这取决于我有多少通知。零通知时,图像是一个空铃铛,否则,它会在铃铛图像中显示通知数量。我可能可以通过更新标签来做到这一点,但我已经为每个标签制作了单独的 PNG,所以效果很好。