UIBarButtonItem with UIButton as custom view doesn't show up - ios

I am trying to display a custom UIButton as a UINavigationItem's rightBarButtonItem.
I wrote the following code:
UIButton *inviteButton = [UIButton buttonWithType:UIButtonTypeCustom];
[inviteButton setTitle:#"Invite" forState:UIControlStateNormal];
inviteButton.frame = CGRectMake(0, 0, 30, 30);
inviteButton.backgroundColor = [UIColor redColor];
inviteButton.layer.borderColor = [UIColor blueColor].CGColor;
inviteButton.layer.borderWidth = 1.0f;
UIBarButtonItem *inviteButtonContainer = [[UIBarButtonItem alloc] initWithCustomView:inviteButton];
viewController.navigationItem.rightBarButtonItem = inviteButtonContainer;
Nothing shows up in my navigation bar.
However, with the following code, I can see a basic button:
UIBarButtonItem *inviteButton = [[UIBarButtonItem alloc] initWithTitle:#"Invite"
style:UIBarButtonItemStyleDone
target:self
action:nil];
viewController.navigationItem.rightBarButtonItem = inviteButton;
But it's obviously not what I am after, since I am looking to play with the button appearance.
Edit
I was trying to add the same instance of UIBarButtonItem (inviteButtonContainer) to many navigation bars. Doing that, it's visible on the last navigation bar only.
However, if I use the same instance of a simple UIBarButtonItem (without custom view), it's displayed on every navigation bars. Any idea why?

Your code is fine, just change this line:
viewController.navigationItem.rightBarButtonItem = inviteButtonContainer;
to
self.navigationItem.rightBarButtonItem = inviteButtonContainer;
From the Documentation:
The navigation item used to represent the view controller in a
parent's navigation bar.
self itself represents that it belongs to view controller , so there is no need to mention the view controller instance to add the navigation item.

-> To display custom button in a view controller in which custom bar button is crated (i.e. in self) :
- (void)viewDidLoad {
[super viewDidLoad];
UIButton *inviteButton = [UIButton buttonWithType:UIButtonTypeCustom];
[inviteButton setTitle:#"Invite" forState:UIControlStateNormal];
inviteButton.frame = CGRectMake(0, 0, 70, 30);
inviteButton.backgroundColor = [UIColor redColor];
inviteButton.layer.borderColor = [UIColor blueColor].CGColor;
inviteButton.layer.borderWidth = 1.0f;
UIBarButtonItem *inviteButtonContainer = [[UIBarButtonItem alloc] initWithCustomView:inviteButton];
controller.navigationItem.rightBarButtonItem = inviteButtonContainer;
}
-> To display custom bar button in a view controller that is about to present
eg. To display a view controller after a cell is selected in table view
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
DjDetailsViewController *controller = (DjDetailsViewController *)
[self.storyboard instantiateViewControllerWithIdentifier:#"DjDetailsViewController"];
UIButton *inviteButton = [UIButton buttonWithType:UIButtonTypeCustom];
[inviteButton setTitle:#"Invite" forState:UIControlStateNormal];
inviteButton.frame = CGRectMake(0, 0, 70, 30);
inviteButton.backgroundColor = [UIColor redColor];
inviteButton.layer.borderColor = [UIColor blueColor].CGColor;
inviteButton.layer.borderWidth = 1.0f;
UIBarButtonItem *inviteButtonContainer = [[UIBarButtonItem alloc] initWithCustomView:inviteButton];
controller.navigationItem.rightBarButtonItem = inviteButtonContainer;
[self.navigationController pushViewController:controller animated:YES];
}
I didn’t done major. I just used your code and change frame of custom bar button.
I hope this will help you.

You issue is with your invite button initialiser:
UIButton *inviteButton = [UIButton UIButtonTypeCustom];
UIButtonTypeCustom is an enum value not a class method/convenience constructor.
use
UIButton *inviteButton = [UIButton buttonWithType:UIButtonTypeCustom];
Hope this helps

Related

How to add multiple bar buttons to navigation bar

Initially i have created a dynamic view called 'mainView'.In that,i have added Navigation bar.After that, i Want to add 2 right bar buttons to the navigation bar.If i code like this,its shows view with navigation bar.but its not showing right bar button.
1.Is it possible to add navigation bar without navigation controller?
2.Why the right bar button is not showing?
//mainView Creation
UIView *mainView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
mainView.backgroundColor =[UIColor grayColor];
[self.view addSubview:mainView];
//NavigationBar
UINavigationBar *NavigationBar = [[UINavigationBar alloc]initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 45)];
NavigationBar.backgroundColor = [UIColor orangeColor];
[mainView addSubview:NavigationBar];
//rightbarView Creation
UIView *rightbarView = [[UIView alloc] init];
rightbarView.backgroundColor = [UIColor orangeColor];
//powerCut Button
UIButton *powerCutbutton = [[UIButton alloc] initWithFrame:CGRectMake(150, 20, 50, 14.01)];
[rightbarView addSubview:powerCutbutton];
UIImage *powercutimage = [UIImage imageNamed:#"powercut.jpg"];
[powerCutbutton setImage:powercutimage forState:UIControlStateNormal];
// addConnection button
UIButton *addConnectionbutton = [[UIButton alloc] initWithFrame:CGRectMake(210, 20, 50, 14.01)];
[rightbarView addSubview:addConnectionbutton];
UIImage *addimage = [UIImage imageNamed:#"add.png"];
[addConnectionbutton setImage:addimage forState:UIControlStateNormal];
// Barbutton item
UIBarButtonItem *item = [[UIBarButtonItem alloc] initWithCustomView:rightbarView];
//[self.navigationItem setRightBarButtonItems:[NSArray arrayWithObjects:powerCutbutton, addConnectionbutton, nil]];
// setting rightbar button item
self.navigationItem.rightBarButtonItem = item;
create an array of bar buttons. and setLeftBarButtonItems not setLeftBarButtonItem as :
UIBarButtonItem * barbtn1;
UIBarButtonItem * barbtn2;
UIBarButtonItem * barbtn3;
[self.navigationItem setLeftBarButtonItems:#[barbtn1,barbtn2,barbtn3]];
or
[self.navigationItem setRightBarButtonItems:#[barbtn1,barbtn2,barbtn3]];
hope it will helpful for you

how to override the functionality of the navigation bar created by pushViewController

I have a view controller, which is presented using pushViewController. This methods presents the view controller with a navigation bar, with a back button on the left side (this is a cocoa method, created by apple).
I want the back button to do just what it does right now, but I also want to tweak some things with it's animation.
How can I add code which works between the button being pressed and the actual animation and return?
thank you.
I do similar stuff by adding my custom back button like this:
UIImage *backArrow = [UIImage imageNamed:backButtonImage];
UIButton *aBackButton = [UIButton buttonWithType:UIButtonTypeSystem];
CGSize aBackButtonTextSize = [#"Back" sizeWithFont:[UIFont systemFontOfSize:17]];
aBackButton.frame = CGRectMake(0.0, 0.0, aBackButtonTextSize.width + backArrow.size.width, self.navigationController.navigationBar.frame.size.height);
aBackButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft;
SEL backSelector = NSSelectorFromString(#"backAction");
[aBackButton addTarget:self action:backSelector forControlEvents:UIControlEventTouchUpInside];
[aBackButton setTitle:#"Back" forState:UIControlStateNormal];
[aBackButton setImage:backArrow forState:UIControlStateNormal];
[aBackButton setExclusiveTouch:YES];
aBackButton.titleLabel.font = [UIFont systemFontOfSize:17];
UIBarButtonItem *aLeftBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:aBackButton];
UIBarButtonItem *aNegativeSpacer = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil];
aNegativeSpacer.width = -8;
self.navigationItem.leftBarButtonItems = #[aNegativeSpacer, aLeftBarButtonItem];
And then handle user taps and add my own stuff here:
- (void)backAction {
// My own handlings
}

backBarButtonItem not getting displayed

I know viewcontroller's navigation item's backBarButtonItem gets displayed when another view controller is pushed on stack and this is 2nd viewcontroller from top.
I have viewcontroller A which have following in viewDidLoad
{
[super viewDidLoad];
self.navigationController.navigationBarHidden = NO;
[self.navigationItem setBackBarButtonItem:[UIBarButtonItem itemWithImageNamed:#"ic_header_slide" selectedImage:nil target:nil action:nil]];
}
When I push viewcontroller B, this custom back button is not getting displayed, instead I see default back button which iOS creates.
A extends UITableViewController and B extends UIViewController. I am not setting leftBarButtonItem, leftBarButtonItems, rightBarButtonItem, rightBarButtonItems in any of these navigationItem.
EDIT
I have read about setting leftBarButtonItems. setting leftbarbuttonitems on B works. but I think setting backBarButtonItem on A is correct way of doing that. It is also mentioned in documentation but not working in my case. I want to ask whether there is bug in backBarButtonItem or I have some misunderstanding the way it works and I am not doing it correctly.
To hide the default back button of the navigation bar use,
self.navigationItem.hidesBackButton=TRUE;
Also use the following method to add the custom BarButtons,
- (NSArray*)getLeftNavButtons:(NSString*)image andTarget:(id)target andFrame:(CGRect)frame andSpace:(int)fixedSpace
{
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
button.frame = frame;
button.clipsToBounds = YES;
[button setBackgroundImage:[UIImage imageNamed:image] forState:UIControlStateNormal];
[button addTarget:target action:#selector(leftNavBtnClicked) forControlEvents:UIControlEventTouchUpInside];
UIBarButtonItem *barButton = [[UIBarButtonItem alloc]initWithCustomView:button];
if(SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(#"7"))
{
UIBarButtonItem *negativeSpacer = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace
target:nil action:nil];
negativeSpacer.width = fixedSpace;
return #[negativeSpacer,barButton];
}
else{
return #[barButton];
}
return #[barButton];
}
Just override the default
self.navigationItem.hidesBackButton = YES;
UIBarButtonItem *back = [[UIBarButtonItem alloc]init];
back.title = #"Pick Me";
back.image = #"Your image";
[self.navigationItem setLeftBarButtonItem:back];
Set Right Bar Button Item
self.navigationItem.leftBarButtonItem=[[UIBarButtonItem alloc]init];
UIImage *img1=[UIImage imageNamed:#"edit"];
CGRect frameimg1 = CGRectMake(0, 0, img1.size.width, img1.size.height);
UIButton *signOut=[[UIButton alloc]initWithFrame:frameimg1];
[signOut setBackgroundImage:img1 forState:UIControlStateNormal];
[signOut addTarget:self action:#selector(btnEditClicked:)
forControlEvents:UIControlEventTouchUpInside];
// [signOut setShowsTouchWhenHighlighted:YES];
UIBarButtonItem *barButton=[[UIBarButtonItem alloc]initWithCustomView:signOut];
self.navigationItem.rightBarButtonItem=barButton;
Set Left Bar Button Item
UIImage *img11=[UIImage imageNamed:#"home"];
CGRect frameimg11 = CGRectMake(0, 0, img11.size.width, img11.size.height);
UIButton *signOut1=[[UIButton alloc]initWithFrame:frameimg11];
[signOut1 setBackgroundImage:img11 forState:UIControlStateNormal];
[signOut1 addTarget:self action:#selector(showLeftMenuPressed:)
forControlEvents:UIControlEventTouchUpInside];
UIBarButtonItem *barButton1=[[UIBarButtonItem alloc]initWithCustomView:signOut1];
self.navigationItem.leftBarButtonItem=barButton1;
self.navigationController.navigationBar.barTintColor=ColorNav;
self.navigationController.navigationBar.translucent=FALSE;
Set Navigation Title & Color
self.title = titletext;
[[[self navigationController] navigationBar]setTitleTextAttributes:#{NSForegroundColorAttributeName: textColor}];

Changing Navigatiobar back button action in ios6/ ios 7 compatible applications

I have a navigation controller application, and I need to set the custom action for the navigation back bar button. Tried some workarounds and not yet to find a solution.
Tried
UIBarButtonItem *backBarItem = self.navigationItem.leftBarButtonItem;
backBarItem.target = self;
backBarItem.action = #selector(popToHomeViewController);
Result : No effect. Back button pops to just previous viewController in navigation stack
UIBarButtonItem *customBarItem = [[UIBarButtonItem alloc] initWithTitle:backBarItem.title style:backBarItem.style target:self action:#selector(popViewController)];
self.navigationItem.leftBarButtonItem = customBarItem;
Result : No effect. Back button pops to just previous viewController in navigation stack
UIBarButtonItem *customBarItem = [[UIBarButtonItem alloc] initWithTitle:#"back" style:backBarItem.style target:self action:#selector(popViewController)];
self.navigationItem.leftBarButtonItem = customBarItem;
Result:Now my selector got invoked perfectly and navigated to desired viewController. Here the issue is that the back button not as like as the native back button. It is not having the bold "<" character as I have not mentioned it. If added < character it needs to be changed for ios 6 compatibility.
Any better solution to ensure ios 6 and ios 7 compatible navigation back button with custom selector?
Try this simple example will help you..
- (void)viewDidLoad {
[super viewDidLoad];
UIImage *buttonImage = [UIImage imageNamed:#"back.png"];
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
[button setImage:buttonImage forState:UIControlStateNormal];
button.frame = CGRectMake(0, 0, buttonImage.size.width, buttonImage.size.height);
[button addTarget:self action:#selector(back) forControlEvents:UIControlEventTouchUpInside];
UIBarButtonItem *customBarItem = [[UIBarButtonItem alloc] initWithCustomView:button];
self.navigationItem.leftBarButtonItem = customBarItem;
[customBarItem release];
}
-(void)back {
[self.navigationController popViewControllerAnimated:YES];
}
Make sure you have an button image with the size of a navigation bar back button in your resource folder with name back.png
Feel free if any other assistance is required.
Happy Coding!!!!!
Try this
viewController.navigationItem.hidesBackButton = YES;
//set custom image to button if needed
UIImage *backButtonImage = [UIImage imageNamed:#"back"];
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
[button setImage:backButtonImage forState:UIControlStateNormal];
button.frame = CGRectMake(0, 0, backButtonImage.size.width, backButtonImage.size.height);
[button addTarget:viewController action:#selector(back) forControlEvents:UIControlEventTouchUpInside];
UIView *backButtonView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, backButtonImage.size.width, backButtonImage.size.height)];
[backButtonView addSubview:button];
UIBarButtonItem *customBarItem = [[UIBarButtonItem alloc] initWithCustomView:backButtonView];
viewController.navigationItem.leftBarButtonItem = customBarItem;
and in back method you can customise
- (void)back {
//Your code
}

back button uinavigationcontroller

I'm trying to make a custom back button to pop back to parent in nav controller. I understand I should've made the back button in parent controller itself
self.navigationItem.backBarButtonItem= backBarButton
The button was just default button with custom text, but it worked. None of formatting or fonts showed up.
So instead I made a custom leftBarButton in child VC:
UIButton *backBtn= [[UIButton alloc] init];
backBtn.backgroundColor = [UIColor clearColor];
backBtn.titleLabel.font = [UIFont fontWithName:#"CrimeFighter BB" size:20];
backBtn.titleLabel.textColor = [UIColor whiteColor];
backBtn.titleLabel.text = #"back";
[backBtn addTarget:self action:#selector(pop) forControlEvents:UIControlEventTouchUpInside];
UIBarButtonItem *backBarButton = [[UIBarButtonItem alloc] initWithCustomView:backBtn];
self.navigationItem.leftBarButtonItem = backBarButton;
Its working fine, but the button is not visible at all!
New attempt:
Doing an alloc & init on a UIButton isn't the right way to create a button in code.
The way to programatically create a button is:
UIButton * backBtn = [UIButton buttonWithType: UIButtonTypeRoundedRect];
Original attempt:
You need to give your custom back button a proper size. Try doing this before creating the "UIBarButtonItem".
backBtn.frame = CGRectMake(20.0f, 0.0f, 70.0f, 30.0f);
The last number is the height and the second to last number is the button width.

Resources