33

Hi friends am new to iphone developing. Am struggle with add badge values on UIBarbutton item on right side. I have tried but i can't solve this problem. Can anyone help me.

Thanks in advance!

Andrei Chevozerov
  • 1,029
  • 1
  • 10
  • 24
Yuvaraj.M
  • 9,741
  • 16
  • 71
  • 100

10 Answers10

30

I know this post is pretty old but with iOS7, MKNumberBadgeView's appearance does not really match the tab bar item badge design. I have found this other component which herits UIBarButtonItem and do the job very well :

https://github.com/TanguyAladenise/BBBadgeBarButtonItem

Hope this may help other iOS7 developers like me

phyzalis
  • 1,236
  • 1
  • 13
  • 24
29

Finally i found the way to add badges on UIBarbutton item. I searched lot but not found the correct answer. So i created UIButton and add it as a Custom view on rightbarbutton item. Add add the MKNumberBadgeView for display the badge number. Below i have add my code for you.

// 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;

Thanks.

Divyesh
  • 19
  • 7
Yuvaraj.M
  • 9,741
  • 16
  • 71
  • 100
  • The results of this code create a very ugly button (but it does work). You've been warned ;) – Ralphleon Feb 20 '12 at 19:06
  • This works better on iOS 5 because you can have more control over the appearance of buttons. Otherwise you end up with ugly buttons in your navigation bar. – Quentamia May 10 '12 at 15:28
21

phyzalis has a good answer, there's a categorized version of his solution here:

UIBarButtonItem+Badge

Here's how you can use it:

// 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";
Mike
  • 1,313
  • 14
  • 17
  • I got the problem that "Property "badgeValue" not found on UIBarButtonItem"? – Chenya Zhang Oct 05 '16 at 20:32
  • Running perfectly fine in iOS 11 in my app. Only issue is that the badge itself does not respond to taps, making the button harder to tap. Fixed this by adding a gesture recogniser to the badge: `UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(buttonPressed)]; [self.navigationItem.rightBarButtonItem.badge addGestureRecognizer:tapGesture];` – Guruniverse Mar 12 '18 at 21:05
  • See my answer on iOS 11 issue from lib's repository on Github https://github.com/mikeMTOL/UIBarButtonItem-Badge/issues/37 – Phu Nguyen May 25 '18 at 07:44
12

I did something similar to MaxMa, but I just went ahead and added the badge directly to the self.navigationController.navigationBar.

enter image description here

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

[self.navigationController.navigationBar addSubview:numberBadge];

Just make sure to remove it from the subview during viewWillDisappear and add it back during viewDidAppear. It still seems a little hacky, but I'm more comfortable with this hack then changing the nav bar z-order.

To remove it during viewWillDisappear

- (void)viewWillDisappear:(BOOL)animated
{
    [super viewWillDisappear:animated];
    [numberBadge removeFromSuperview]; 
}
tilo
  • 14,009
  • 6
  • 68
  • 85
Tod Cunningham
  • 3,691
  • 4
  • 30
  • 32
7

It's simple and the best way !

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];
user
  • 86,916
  • 18
  • 197
  • 190
MaxMa
  • 71
  • 1
  • 3
  • You are relying on the frame to be exactly 230 to the right. Maybe add constraints or something. But this would basically not work for every phone width. – Travis Delly Jul 17 '18 at 20:29
5

Updated for Swift 3:

use below simple code to add the badge on 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()

//Note: Increase your badge as per you received notification.You have to write your code as per your decided your logic i.e. how to maintain that badge count number in database.

Enjoy..!

Kiran Jadhav
  • 3,209
  • 26
  • 29
0

I know this has been solved already,but I thought I might add what I have discovered to this answer for the sake of completeness.

You can also just add MKNumberBadgeView directly to the view for the UIBarButtonItem. Using Monotouch (C#), this is how you get the view for the 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> 

I'm sure it's easy to convert this to Obj-C. You will also need to play around with the Frame for the badge to get it to show up in the right place.

This way you wont have to remove/add the view from the navigationbar.

ceiling cat
  • 496
  • 4
  • 12
0

After searching too many solutions I found this best solution for Objective-C

Goto Following Link and download two files "UIBarButtonItem+Badge.h" and "UIBarButtonItem+Badge.m" and add to your project :

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

Then import in your class :

#import "UIBarButtonItem+Badge.h"

And write down following line to add badge :

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

Hope it will Work !!!

0

Extension to add an UIActivityIndicatorView without replacing the 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
    }
    
}
Dorian Roy
  • 3,094
  • 2
  • 31
  • 51
Allan
  • 308
  • 2
  • 7
0

Here is a simple Swift 4 solution for it (with some customisation) https://github.com/Syngmaster/BadgedBarButtonItem

Just drag and drop the class into your project and you can use it like that:

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)
        }

    }

}
Syngmaster
  • 415
  • 8
  • 13