自定义BarButtonItem项:在右上角添加红色点,Swift 4 IOS

时间:2018-12-19 07:16:30

标签: ios swift uinavigationbar uinavigationitem

我想在UIbarButtonItem的右上角添加/设置未读标记为红点,请参见附件图片

enter image description here

我应该怎么做才能在Bar Button项目上添加/设置红点? 用户点击项目后,我想删除红点。

2 个答案:

答案 0 :(得分:1)

UIButton子类

好的,让我们开始创建自定义UIButton子类

class ButtonWithBadge: UIButton {
}

现在让我们创建UIView来代表红点

lazy var badgeView: UIView = {
    let view = UIView()
    view.layer.cornerRadius = 3
    view.backgroundColor = .red
    return view
}()

然后对此子类覆盖init,并在其中添加badgeView到按钮的右上角:设置其约束(右和顶部等于按钮的锚点,宽度和高度为{{的两倍) 1}}的cornerRadius值)

badgeView

接下来创建变量以重置按钮的当前状态:

override init(frame: CGRect) {
    super.init(frame: frame)

    addSubview(badgeView)
    badgeView.translatesAutoresizingMaskIntoConstraints = false
    NSLayoutConstraint.activate([
        badgeView.rightAnchor.constraint(equalTo: rightAnchor, constant: 3),
        badgeView.topAnchor.constraint(equalTo: topAnchor, constant: 3),
        badgeView.heightAnchor.constraint(equalToConstant: badgeView.layer.cornerRadius*2),
        badgeView.widthAnchor.constraint(equalToConstant: badgeView.layer.cornerRadius*2)
    ])
}

required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}

现在让我们创建一些根据var isRead: Bool = false 值隐藏或取消隐藏badgeView的方法

isRead

现在我们有了功能,对吗?因此,让我们在func setBadge() { badgeView.isHidden = isRead } 的末尾和init变量的didSet中调用此函数

isRead

添加到ViewController

首先为按钮和视图创建变量

class ButtonWithProperty: UIButton {

var isRead: Bool = false {
    didSet {
        setBadge()
    }
}

override init(frame: CGRect) {
    ...
    setBadge()
}

例如,现在在lazy var barButton: ButtonWithProperty = { let button = ButtonWithProperty() ... // set color, title, target, etc. return button }() 中将此viewDidLoad添加到barButton并按照您希望的位置放置它:

UINavigationBar

现在,当需要时,您可以轻松更改override func viewDidLoad() { super.viewDidLoad() ... guard let navigationBar = self.navigationController?.navigationBar else { return } navigationBar.addSubview(barButton) barButton.translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate([ barButton.rightAnchor.constraint(equalTo: navigationBar.rightAnchor, constant: -20), barButton.bottomAnchor.constraint(equalTo: navigationBar.bottomAnchor, constant: -6) ]) } 的{​​{1}}变量,并且红点消失或出现

barButton

enter image description here


isRead

内部ViewController:

barButton.isRead = true

答案 1 :(得分:1)

我编写了一个自定义的条形按钮类来解决这个问题,在这里我使用CAShapeLayerUIBarButtonItem的顶部绘制一个点。

// Custom Bar button
class CustomBarButton: UIBarButtonItem
{
    // Unread Mark
    private var unreadMark: CAShapeLayer?

    // Keep track of unread status
    var hasUnread: Bool = false
    {
        didSet
        {
            setUnread(hasUnread: hasUnread)
        }
    }

    // Toggles unread status
    private func setUnread(hasUnread: Bool)
    {
        if hasUnread
        {
            unreadMark            = CAShapeLayer();
            unreadMark?.path      = UIBezierPath(ovalIn: CGRect(x: (self.customView?.frame.width ?? 0) - 10, y: 5, width: 5, height: 5)).cgPath;
            unreadMark?.fillColor = UIColor.red.cgColor
            self.customView?.layer.addSublayer(unreadMark!)
        }
        else
        {
            unreadMark?.removeFromSuperlayer()
        }

    }
}

条形按钮项没有可用的图层属性,因此您需要使用自定义视图创建UIBarButtonItem

// Bar button property
var barButton:CustomBarButton!

// Initialisation
button       = UIButton(type: .custom)
button.frame = CGRect(x: 0, y: 0, width: 70, height: 40)
button.setTitle("Right", for: .normal)
button.setTitleColor(UIColor.green, for: .normal)

// Bar button
barButton = CustomBarButton(customView: button)
button.addTarget(self, action: #selector(toggleStatus(sender:)), for: UIControl.Event.touchUpInside)

// Flexible space (Optional)
let flexibleSpace = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
toolBar.items     = [flexibleSpace, barButton]

IBAction中,您可以使用hasUnread属性来切换状态:

@objc func toggleStatus(sender: AnyObject)
{
    barButton.hasUnread = !barButton.hasUnread
}

它看起来像:

Unread Button