In my app, I have designed a view in the interface builder.
This view has a toolbar, with some UIBarButtonItem in.
My buttons can be custom images, or default button like share, add,...
Now with iOS7, buttons don't have anymore borders. So I'd like to add some.
Here is what i want to do : add borders like the white lines on my screenshot.
What I've tried is to add a UIButton to the toolbar. In my example, I've set my back button size (12x44). I add this button as a IBOutlet property of my view controller, and try to draw a border to it :
CALayer *cancelBorder = [CALayer layer];
[cancelBorder setFrame:CGRectMake(12, 0, 1, 44)];
[backBorder setBackgroundColor:[[UIColor whiteColor] CGColor]];
[backButton.layer addSublayer:cancelBorder];
But it doesn't work. Anyone has a solution?
Adding UIBarButtonItem to toolbar programmatically may solve your problem.
First, create custom button with images, borders, etc. As HereTrix said, you can add border to this button.
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
button.frame = CGRectMake(10, 0, 30, 30);
button.layer.borderColor = [UIColor blueColor].CGColor;
button.layer.borderWidth = 1.0f;
/* any other button customization */
Then, initialize UIBarButtonItem with that custom button and add this item to your toolbar.
UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithCustomView:button];
self.toolBar.items = #[backButton];
Swift 3 : Below is my full implementation for button customization and event handling.
override func viewDidLoad() {
super.viewDidLoad()
let button = UIButton.init(type: .custom)
button.setTitle("Tester", for: .normal)
button.setTitleColor(.darkGray, for: .normal)
button.layer.borderWidth = 1
button.layer.cornerRadius = 5
button.layer.borderColor = UIColor.darkGray.cgColor
button.addTarget(self, action: #selector(self.handleButton), for: .touchUpInside)
self.navigationItem.rightBarButtonItem = UIBarButtonItem(customView: button)
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
if let button = self.navigationItem.rightBarButtonItem?.customView {
button.frame = CGRect(x:0, y:0, width:80, height:34)
}
}
func handleButton( sender : UIButton ) {
// It would be nice is isEnabled worked...
sender.alpha = sender.alpha == 1.0 ? 0.5 : 1.0
}
Hope this helps
Related
I want to add a Subview on my googleAdBanner-Subview. (as a custom close UIButton).
If I add the UIButton as subview to self.view.addSubview(btn), it is working. But since it may take a while to load an Ad, sometimes the UIButton is visible even tho the googleAdBanner is still invisible.
If I add UIButton as subview of googleAdBanner, the UIButton will not be displayed.
override func viewDidLoad() {
super.viewDidLoad()
let googleAdBanner = GADBannerView(frame:CGRectMake(0,self.view.frame.size.height - 50,self.view.frame.size.width,50))
googleAdBanner.adUnitID = "ca-app-pub-xx"
googleAdBanner.rootViewController = self
googleAdBanner.loadRequest(GADRequest())
self.view.addSubview(googleAdBanner)
let btn: UIButton = UIButton(frame: CGRectMake(self.view.frame.size.width - 25, self.view.frame.size.height - 50, 25, 25))
btn.backgroundColor = UIColor.greenColor()
btn.setTitle("Click Me", forState: UIControlState.Normal)
btn.addTarget(self, action: #selector(RootVC.buttonAction(_:)), forControlEvents: UIControlEvents.TouchUpInside)
btn.tag = 1
googleAdBanner.addSubview(btn)
}
What am I missing? Help is very appreciated.
make your 'btn' sth like: let btn: UIButton = UIButton(frame: CGRectMake(0,0, btnWidth, btnHeight)) after adding that as subview to the banner, then adjust the button frame either by setting the CGrect or auto layout
I have an UIBarButtonItem, which is a non-clickable logo. How do I disable the touch animation for this logo?
I have tried getting at the view:
let view = self.appTitle.performSelector(Selector("view")).takeRetainedValue() as? UIView
view?.userInteractionEnabled = false
but then the app crashes.
The UIBarButtonItem is inside a UiToolbar, created in a storyboard.
This works:
self.appTitle.customView = UIImageView(image: UIImage(named: "footer"))
If you want UIBarButtonItem be don't clicked use
barBtnItem.enabled = false
let transitionOptions: UIViewAnimationOptions = [.TransitionCrossDissolve, .ShowHideTransitionViews]
UIView.transitionWithView(#yourUIBarButtonItem outlet, duration: 1.0, options: transitionOptions, animations: {
self.#yourUIBarButtonItem outlet.enabled = false
}, completion: nil)
If your UIBarButtonItem is in NavigationItem then first assign it to leftBarButtonItem or rightBarButtonItem and then set enabled property of UIBarButtonItem to NO in objective-c and false in swift
Objective-C:
UIImage *menuImage = [UIImage imageNamed:#"menu"];
UIButton *menu = [UIButton buttonWithType:UIButtonTypeCustom];
menu.frame = CGRectMake( 10, 0, menuImage.size.width, menuImage.size.height);
[menu addTarget:self action:#selector(handleBack:) forControlEvents:UIControlEventTouchUpInside];
[menu setImage:menuImage forState:UIControlStateNormal];
UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithCustomView:menu];
self.navigationItem.leftBarButtonItem = backButton;
self.navigationItem.leftBarButtonItem.enabled = NO;
Swift:
var menuImage: UIImage = UIImage(named: "menu")!
var menu: UIButton = UIButton(type: .Custom)
menu.frame = CGRectMake(10, 0, menuImage.size.width, menuImage.size.height)
menu.addTarget(self, action: #selector(self.handleBack), forControlEvents: .TouchUpInside)
menu.setImage(menuImage, forState: .Normal)
var backButton: UIBarButtonItem = UIBarButtonItem(customView: menu)
self.navigationItem.leftBarButtonItem = backButton
self.navigationItem.leftBarButtonItem.enabled = false
I'd like to indicate that a particular UIBarButtonItem is toggled on or off by changing its background color. Mobile Safari uses this feature to indicate whether private browsing is on or off:
How can I do this, since there's no backgroundColor property on UIBarButtonItem?
Create a UIButton and use it as the custom view for the UIBarButtonItem. Then, set the backgroundColor on the button's layer:
UIButton* button = [UIButton buttonWithType:UIButtonTypeCustom];
[button setTitle:#"Test"];
button.layer.backgroundColor = [UIColor redColor].CGColor;
button.layer.cornerRadius = 4.0;
UIBarButtonItem* buttonItem = [[UIBarButtonItem alloc] initWithCustomView:button];
self.toolbarItems = #[buttonItem];
You could instead just use two images. One for selected and one for unselected
- (void)setBackgroundImage:(UIImage *)backgroundImage forState:(UIControlState)state barMetrics:(UIBarMetrics)barMetrics
The above function should help you do this
Swift 5 Answer
let rightBarCancelButton = UIButton(frame: CGRect(x: 0, y: 0, width: 30, height: 30))
let cancelImage = UIImage(systemName: "multiply")
rightBarCancelButton.setImage(cancelImage, for: .normal)
rightBarCancelButton.layer.cornerRadius = 15
rightBarCancelButton.backgroundColor = UIColor.lightGray
let rightBarButton = UIBarButtonItem(customView: rightBarCancelButton)
navigationItem.rightBarButtonItem = rightBarButton
Works like a charm!
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!
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
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.
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";
I did something similar to MaxMa, but I just went ahead and added the badge directly to the self.navigationController.navigationBar.
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];
}
It's simple and the best way !
MKNumberBadgeView *numberBadge = [[MKNumberBadgeView alloc] initWithFrame:CGRectMake(230, -51, 40, 40)];
numberBadge.value = 5;
self.navigationController.navigationBar.layer.zPosition = -1;
[self.view addSubview:numberBadge];
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..!
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.
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 !!!
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)
}
}
}
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
}
}
I create a button programmatically..........
button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[button addTarget:self action:#selector(aMethod:)
forControlEvents:UIControlEventTouchDown];
[button setTitle:#"Show View" forState:UIControlStateNormal];
button.frame = CGRectMake(80.0, 210.0, 160.0, 40.0);
[view addSubview:button];
how can I change title color?
You can use -[UIButton setTitleColor:forState:] to do this.
Example:
Objective-C
[buttonName setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
Swift 2
buttonName.setTitleColor(UIColor.blackColor(), forState: .Normal)
Swift 3
buttonName.setTitleColor(UIColor.white, for: .normal)
Thanks to richardchildan
You created the UIButton is added the ViewController, The following instance method to change UIFont, tintColor and TextColor of the UIButton
Objective-C
buttonName.titleLabel.font = [UIFont fontWithName:#"LuzSans-Book" size:15];
buttonName.tintColor = [UIColor purpleColor];
[buttonName setTitleColor:[UIColor purpleColor] forState:UIControlStateNormal];
Swift
buttonName.titleLabel.font = UIFont(name: "LuzSans-Book", size: 15)
buttonName.tintColor = UIColor.purpleColor()
buttonName.setTitleColor(UIColor.purpleColor(), forState: .Normal)
Swift3
buttonName.titleLabel?.font = UIFont(name: "LuzSans-Book", size: 15)
buttonName.tintColor = UIColor.purple
buttonName.setTitleColor(UIColor.purple, for: .normal)
Solution in Swift 3:
button.setTitleColor(UIColor.red, for: .normal)
This will set the title color of button.
With Swift 5, UIButton has a setTitleColor(_:for:) method. setTitleColor(_:for:) has the following declaration:
Sets the color of the title to use for the specified state.
func setTitleColor(_ color: UIColor?, for state: UIControlState)
The following Playground sample code show how to create a UIbutton in a UIViewController and change it's title color using setTitleColor(_:for:):
import UIKit
import PlaygroundSupport
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = UIColor.white
// Create button
let button = UIButton(type: UIButton.ButtonType.system)
// Set button's attributes
button.setTitle("Print 0", for: UIControl.State.normal)
button.setTitleColor(UIColor.orange, for: UIControl.State.normal)
// Set button's frame
button.frame.origin = CGPoint(x: 100, y: 100)
button.sizeToFit()
// Add action to button
button.addTarget(self, action: #selector(printZero(_:)), for: UIControl.Event.touchUpInside)
// Add button to subView
view.addSubview(button)
}
#objc func printZero(_ sender: UIButton) {
print("0")
}
}
let controller = ViewController()
PlaygroundPage.current.liveView = controller
If you are using Swift, this will do the same:
buttonName.setTitleColor(UIColor.blackColor(), forState: .Normal)
Hope that helps!