如何在UIBarbutton项目上添加徽章?

33

大家好,我是刚接触 iPhone 开发的新手。我正在尝试在导航栏右侧的 UIBarbutton 上添加角标数字,但一直无法解决这个问题。请问有没有人可以帮助我呢?

先行致谢!

10个回答

30

我知道这篇文章已经很老了,但是在iOS7中,MKNumberBadgeView的外观并不完全符合选项卡栏项目标记的设计。

我发现了这个继承自UIBarButtonItem并且可以很好地完成工作的其他组件:

https://github.com/TanguyAladenise/BBBadgeBarButtonItem

希望这能帮助像我一样的其他iOS7开发人员


29

最终我找到了在UIBarbutton项上添加徽章的方法。我搜索了很多但没有找到正确的答案。因此,我创建了UIButton并将其添加为rightbarbutton项上的自定义视图。添加MKNumberBadgeView以显示徽章数字。以下是我的代码。

// Initialize NKNumberBadgeView...
MKNumberBadgeView *number = [[MKNumberBadgeView alloc] initWithFrame:CGRectMake(60, 00, 30,20)];
number.value = 10;

// Allocate UIButton
UIButton *btn = [UIButton  buttonWithType:UIButtonTypeCustom];
    btn.frame = CGRectMake(0, 0, 70, 30);
    btn.layer.cornerRadius = 8;
    [btn setTitle:@"Button" forState:UIControlStateNormal];
    [btn addTarget:self action:nil forControlEvents:UIControlEventTouchUpInside];
    //[btn setBackgroundColor:[UIColor blueColor]];
    [btn setBackgroundColor:[UIColor colorWithRed:0.0 green:0.0 blue:0.1 alpha:0.2]];
    btn.font = [UIFont systemFontOfSize:13];
    //[btn setFont:[UIFont systemFontOfSize:13]];
    [btn addSubview:number]; //Add NKNumberBadgeView as a subview on UIButton

// Initialize UIBarbuttonitem...
UIBarButtonItem *proe = [[UIBarButtonItem alloc] initWithCustomView:btn];
self.navigationItem.leftBarButtonItem = proe;

谢谢。


这段代码的结果会创建一个非常丑陋的按钮(但它确实能工作)。你已经被警告了 ;) - Ralphleon
这在iOS 5上效果更好,因为您可以更好地控制按钮的外观。否则,您的导航栏中会出现丑陋的按钮。 - Quentamia

21

phyzalis有一个很好的答案,这里有他解决方案的分类版本:

UIBarButtonItem+Badge

以下是如何使用它的方法:

// Build your regular UIBarButtonItem with Custom View
UIImage *image = [UIImage imageNamed:@"someImage"];
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
button.frame = CGRectMake(0,0,image.size.width, image.size.height);
[button addTarget:self action:@selector(buttonPress:) forControlEvents:UIControlEventTouchDown];
[button setBackgroundImage:image forState:UIControlStateNormal];

// Make BarButton Item
UIBarButtonItem *navLeftButton = [[UIBarButtonItem alloc] initWithCustomView:button];
self.navigationItem.leftBarButtonItem = navLeftButton;

// this is the key entry to change the badgeValue
self.navigationItem.leftBarButtonItem.badgeValue = @"1";

我遇到了一个问题:“UIBarButtonItem上找不到属性“badgeValue”?” - Chenya Zhang
在我的应用程序中,在iOS 11上运行得非常好。唯一的问题是徽章本身不响应轻拍,使按钮更难以轻敲。通过向徽章添加手势识别器来解决这个问题:UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(buttonPressed)]; [self.navigationItem.rightBarButtonItem.badge addGestureRecognizer:tapGesture]; - Guruniverse
请查看我在Github上lib存储库中关于iOS 11问题的答案:https://github.com/mikeMTOL/UIBarButtonItem-Badge/issues/37 - Phu Nguyen

12

我做了类似于MaxMa的事情,但我直接将徽章添加到了self.navigationController.navigationBar上。

输入图像描述

MKNumberBadgeView *numberBadge = [[MKNumberBadgeView alloc] initWithFrame:CGRectMake(35, 0, 40, 40)];
numberBadge.value = 1;

[self.navigationController.navigationBar addSubview:numberBadge];

确保在viewWillDisappear期间将其从子视图中移除,并在viewDidAppear时将其添加回去。这仍然看起来有些不正规,但我比改变导航栏z-order更舒适。

在viewWillDisappear期间删除它

- (void)viewWillDisappear:(BOOL)animated
{
    [super viewWillDisappear:animated];
    [numberBadge removeFromSuperview]; 
}

你如何在 viewWillDisappear 中移除它?你能添加那段代码吗? - daniel
1
没问题,我添加了一个示例来展示当视图消失时如何移除它。 - Tod Cunningham

7
这是最简单且最好的方法! enter image description here
MKNumberBadgeView *numberBadge = [[MKNumberBadgeView alloc] initWithFrame:CGRectMake(230, -51, 40, 40)];
numberBadge.value = 5;

self.navigationController.navigationBar.layer.zPosition = -1;
[self.view addSubview:numberBadge];

你依赖于框架恰好在右边230。也许添加约束或其他内容。但这基本上对于每个手机宽度都不起作用。 - Travis Delly

5

针对Swift 3进行更新:

使用以下简单代码在UIBarButtonItem上添加徽章:

// Variable Declartion

var badgeCount = Int()

// Instance Method

    func setUpBadgeCountAndBarButton() {
        // badge label
        let label = UILabel(frame: CGRect(x: 10, y: -05, width: 25, height: 25))
        label.layer.borderColor = UIColor.clear.cgColor
        label.layer.borderWidth = 2
        label.layer.cornerRadius = label.bounds.size.height / 2
        label.textAlignment = .center
        label.layer.masksToBounds = true
        label.textColor = .white
        label.font = label.font.withSize(12)
        label.backgroundColor = .red
        label.text = "\(self.badgeCount)"

        // button
        let rightButton = UIButton(frame: CGRect(x: 0, y: 0, width: 35, height: 35))
        rightButton.setBackgroundImage(UIImage(named: "notification_dash"), for: .normal)
        rightButton.addTarget(self, action: #selector(notificationBarButtonClick), for: .touchUpInside)
        rightButton.addSubview(label)

        // Bar button item
        let rightBarButtomItem = UIBarButtonItem(customView: rightButton)
        navigationItem.rightBarButtonItem = rightBarButtomItem
    }

// Call To Method

self.badgeCount = 11
self.setUpBadgeCountAndBarButton()

//注意:根据您收到的通知,增加您的徽章。您需要按照自己决定的逻辑编写代码,即如何在数据库中维护该徽章计数器。
祝您愉快..!

0

在搜索了很多解决方案之后,我找到了这个最好的Objective-C解决方案

前往以下链接下载两个文件"UIBarButtonItem+Badge.h""UIBarButtonItem+Badge.m"并添加到你的项目中:

https://github.com/mikeMTOL/UIBarButtonItem-Badge

然后在你的类中导入:

#import "UIBarButtonItem+Badge.h"

并写下以下代码以添加徽章:

self.navigationItem.rightBarButtonItem.badgeValue = @"1"; //your value 

希望它能够工作!!!

0

添加一个UIActivityIndicatorView的扩展,而不替换UIBarButtonItem。

extension UIBarButtonItem {
    
    func startLoading() {
        guard let view = self.value(forKey: "view") as? UIView else { return }
        let loading = UIActivityIndicatorView(activityIndicatorStyle: .gray)
        loading.frame = view.bounds
        loading.startAnimating()
        view.addSubview(loading)
        view.bringSubview(toFront: loading)
        let buttonView = view.subviews.first
        buttonView?.alpha = 0.1
    }
    
    func stopLoading() {
        guard let view = self.value(forKey: "view") as? UIView else { return }
        let loading = view.subviews.filter({ $0 is UIActivityIndicatorView }).first
        loading?.removeFromSuperview()
        let buttonView = view.subviews.first
        buttonView?.alpha = 1.0
    }
    
}

0

我知道这个问题已经解决了,但是为了完整起见,我想添加我所发现的内容到这个答案中。

你也可以直接将MKNumberBadgeView添加到UIBarButtonItem的视图中。使用Monotouch(C#),这是获取UIBarButtonItem视图的方法:

        //barbutton is some UIBarButtonItem. Make sure to check for view. In
        //ViewDidLoad(), the view for the barbutton might not exist yet.
        Selector sel = new Selector("view");
        var handle = Messaging.intptr_objc_msgSend(barbutton.Handle, sel.Handle);
        var view = Runtime.GetNSObject(handle) as UIView;
        var mkBadge = ...    //the badge
        view.Add(badge);
        view.Layer.ZPosition = <some large number> 

我相信将其转换为Obj-C并不困难。您还需要尝试调整徽章的框架,以使其出现在正确的位置。

这样,您就不必从导航栏中删除/添加视图了。


0

这是一个简单的Swift 4解决方案(带有一些自定义)https://github.com/Syngmaster/BadgedBarButtonItem

只需将该类拖放到您的项目中,您就可以像这样使用它:

class ViewController: UIViewController {

    let btn = BadgedButtonItem(with: UIImage(named: "your_image"))

    override func viewDidLoad() {
        super.viewDidLoad()

        btn.badgeTextColor = .black
        btn.badgeTintColor = .yellow
        btn.position = .right
        btn.hasBorder = true
        btn.borderColor = .red
        btn.badgeSize = .medium
        btn.badgeAnimation = true

        self.navigationItem.rightBarButtonItem = btn

        btn.tapAction = {
            self.btn.setBadge(with: 4)
        }

    }

}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接