当我在Swift中对UIBarButtonItem进行子类化时,我遇到了这种奇怪的行为。我写了一个名为super.init的自定义init方法(customView:...) 问题是badgeLabel文本从未更新过,所以我开始探索出了什么问题。
首先我发现调用了两个init方法,我的自定义方法是“init(target:AnyObject,selector:Selector)”,之后基本的方法也是“init()”
真正奇怪的是,badgeLabel(常量)块也为每个init方法执行了两次。所以碰巧我显示了在第一次初始化调用时创建的徽章标签,但是badgeLabel变量实际上是对第二次初始化调用时创建的标签的引用,并且从未显示或添加到视图中。
不确定Apple是否打算采用这种行为,或者对Swift和Objective-C一起工作只是必要的陌生/邪恶。如何优雅地解决这个问题的任何想法?
以下是代码:
@objc class MYChatBarButton: UIBarButtonItem {
let badgeLabel: UILabel = {
let bl = UILabel(frame: CGRectMake(0, 0, 15, 15))
bl.backgroundColor = UIColor.clearColor()
bl.text = "0"
...
return bl
}()
override init() {
super.init()
}
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
init(target: AnyObject, selector: Selector) {
let badgeView = UIView(frame: CGRectMake(27, 2, 15, 15))
badgeView.backgroundColor = UIColor(hexString: "ff7d00", andAlpha: 1.0)
badgeView.layer.cornerRadius = badgeView.frame.size.width/2
badgeView.userInteractionEnabled = false
badgeView.addSubview(badgeLabel)
let button = UIButton.buttonWithType(.Custom) as UIButton
button.frame = CGRectMake(0, 0, 35, 44)
button.addTarget(target, action: selector, forControlEvents: .TouchUpInside)
button.tintColor = UIColor.whiteColor()
button.setImage(UIImage(named: "chat_icon")?.imageWithRenderingMode(.AlwaysTemplate), forState: .Normal)
button.imageEdgeInsets = UIEdgeInsets(top: 0, left: 7, bottom: 5, right: 0)
button.addSubview(badgeView)
super.init(customView: button)
updateBadge()
}
func unreadChatMsgCountDidChange(n: NSNotification) {
updateBadge()
}
func updateBadge() {
let unwatchedTotal = ...
badgeLabel.text = "\(unwatchedTotal)"
if unwatchedTotal > 0 {
badgeLabel.hidden = false
} else {
badgeLabel.hidden = true
}
}
}