Last active
December 8, 2021 10:33
-
-
Save davidlawson/e9140d1e5cd533ff503c15111c1908df to your computer and use it in GitHub Desktop.
UIBarButtonItem with badge, Swift 4, iOS 9/10/11
The above code is giving error like "Extra argument 'image' in call "
The above code is giving error like "Extra argument 'image' in call "
The above code is giving error like "Extra argument 'image' in call "
Thanks for this code. There was one problem, that it won't work for numbers greater than 9. I had to modify the code a bit like this:
let size = CGFloat(badgeNumber < 10 ? 18 : 26)
let radius = CGFloat(badgeNumber < 10 ? 9 : 13)
self.label.layer.cornerRadius = radius
self.label.widthAnchor.constraint(equalToConstant: size).isActive = true
self.label.heightAnchor.constraint(equalToConstant: size).isActive = true
self.label.centerXAnchor.constraint(equalTo: view.centerXAnchor, constant: size/2).isActive = true
self.label.centerYAnchor.constraint(equalTo: view.centerYAnchor, constant: -size/2).isActive = true
And removed the line self.label.layer.cornerRadius = 9
from required public init
Great job! Here is a version that keeps the UIBarButtonItem constructors intact and there is no need for observers.
public class BadgeBarButtonItem: UIBarButtonItem
{
@IBInspectable
public var badgeNumber: Int = 0 {
didSet {
self.updateBadge()
}
}
private lazy var label: UILabel = {
let label = UILabel()
label.backgroundColor = .red
label.alpha = 0.9
label.layer.cornerRadius = 9
label.clipsToBounds = true
label.isUserInteractionEnabled = false
label.translatesAutoresizingMaskIntoConstraints = false
label.textAlignment = .center
label.textColor = .white
label.layer.zPosition = 1
return label
}()
private func updateBadge()
{
guard let view = self.value(forKey: "view") as? UIView else { return }
self.label.text = "\(badgeNumber)"
if self.badgeNumber > 0 && self.label.superview == nil
{
view.addSubview(self.label)
self.label.widthAnchor.constraint(equalToConstant: 18).isActive = true
self.label.heightAnchor.constraint(equalToConstant: 18).isActive = true
self.label.centerXAnchor.constraint(equalTo: view.centerXAnchor, constant: 9).isActive = true
self.label.centerYAnchor.constraint(equalTo: view.centerYAnchor, constant: -9).isActive = true
}
else if self.badgeNumber == 0 && self.label.superview != nil
{
self.label.removeFromSuperview()
}
}
}
You can use it this way:
let item = BadgeBarButtonItem(image: UIImage(named: "some_image")),
style: .plain,
target: self,
action: #selector(someAction))
navigationItem.rightBarButtonItem = item
not work!
not show bubble
i know why bubble is not showing reason
guard let view = self.value(forKey: "view") as? UIView else { return }
this statement is only called with else condition
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
We can use it as
let badgeBtn = BadgeBarButtonItem(image: UIImage(named: "notification"), style: .plain, target: self, action: #selector(notificationBtnClick))
badgeBtn?.badgeNumber = 4