UIBarButtonItem not responding to click - objective-c

I have a UITableView where I want the user to be able to click two buttons, in the header of the section, one for adding a new record, and the other one for editing them, so I first tried using tableView viewForHeaderInSection and tableView heightForHeaderInSection like this:
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
return 44;
}
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
UIView* v = [[UIView alloc] initWithFrame:CGRectMake(10, 10, 360, 44)];
UIToolbar* tb = [[UIToolbar alloc] initWithFrame:CGRectMake(0, 0, 360, 44)];
UIBarButtonItem* spacer = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:self action:nil];
UIBarButtonItem* addBtn = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:#selector(onAddVehicleInterest:)];
UIBarButtonItem* editBtn = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemEdit target:self action:#selector(onEditVehiclesInterest:)];
[tb setItems:[NSArray arrayWithObjects:spacer, addBtn, editBtn, nil]];
[v addSubview:tb];
return v;
}
- (IBAction)onAddVehicleInterest: (id) sender {
NSLog(#"Add");
}
- (IBAction)onEditVehiclesInterest:(id)sender {
NSLog(#"Edit");
}
When I run the app, I can see the three UIBarButtonItems correctly, and I can click them, but the NSLog line is never called. So I added a UIToolbar directly in the nib file, added the 3 UIBarButtonItem controls to it, and tied the onAddVehicleInterestand onEditVehiclesInterest to the respective buttons. But that doesn't work either...
So, as a last test, I added a UIButton to the nib and tied its Touch Up Inside event to one of the methods, and that works as expected. So I'm confused. What am I doing wrong?

I had a UITapGestureRecognizer on the parent view of the view controller. Once I removed the tap gesture, my UIBarButtonItems began to respond properly to all selectors.

I have also faced the same problem and I get it solved by changing:-
- (IBAction)onAddVehicleInterest: (id) sender {
to
- (IBAction)onAddVehicleInterest: (UIBarButtonItem *) sender {
I also dont know why it was not working earlier, but my problem solved with it.
You can try this.

Try this:
UIBarButtonItem* addBtn;
if([self respondsToSelector:#selector(onAddVehicleInterest:)])
{
addBtn = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:#selector(onAddVehicleInterest:)];
}
UIBarButtonItem* editBtn
if([self respondsToSelector:#selector(onEditVehiclesInterest:)])
{
editBtn = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemEdit target:self action:#selector(onEditVehiclesInterest:)];
}
if(addBtn && editBtn)
{
[tb setItems:[NSArray arrayWithObjects:spacer, addBtn, editBtn, nil]];
}

Related

UIBarButtonItem target/action not working

I am implementing a view with a date picker and a toolbar.
I have the following code:
-(id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
self.toolbar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, 0, CGRectGetWidth(frame), 44)];
UIBarButtonItem *cancelButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel
target:self
action:#selector(didSelectCancelButton)];
UIBarButtonItem *flexible = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
UIBarButtonItem *doneButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone
target:self
action:#selector(didSelectDoneButton)];
NSArray *buttons = #[cancelButton, flexible, doneButton];
[self.toolbar setItems:buttons
animated:NO];
self.datePicker = [[UIDatePicker alloc] initWithFrame:CGRectMake(0, 50, CGRectGetWidth(frame), 216)];
[self addSubview:self.datePicker];
[self addSubview:self.toolbar];
}
return self;
}
- (IBAction)didSelectCancelButton {
if ([self.delegate respondsToSelector:#selector(datePickerDidCancelDateSelection:)]) {
[self.delegate datePickerDidCancelDateSelection:self];
}
}
- (IBAction)didSelectDoneButton {
NSLog(#"");
}
But when I click the buttons, no action is performed. The methods are not invoked.
Can you tell what am I doing wrong?
Thanks
EDIT:
Turned out there was a gesture recognizer that was capturing the touch events.
Fixing that resolved this problem.
I suspect your date picker (which is as wide as the toolbar is) is somehow inhibiting your buttons from getting user touches.
Try reversing these two lines to this:
[self addSubview:self.datePicker];
[self addSubview:self.toolbar];
Do you have any UIGestureRecognizer objects, if you do try to disable them and test.

Adding UIBarButtonItem's to a UIToolbar

I need to add buttons to the UIToolbar of a UINavigationController, which is also my root. I want the UIToolbar to appear when a specific UIViewController is shown. Therefore, I placed this code in my viewDidLoad method of my UIViewController subclass:
UIBarButtonItem* item = [[UIBarButtonItem alloc] initWithTitle:#"Title" style:UIBarButtonItemStyleBordered target:self action:#selector(doSomething)];
item.width = 300;
item.tintColor = [UIColor whiteColor];
UIBarButtonItem* item2 = [[UIBarButtonItem alloc] initWithTitle:#"Title2" style:UIBarButtonItemStyleBordered target:self action:#selector(doSomething)];
NSMutableArray* theItems = [self.navigationController.toolbar.items mutableCopy];
[theItems addObject:item];
[theItems addObject:item2];
[self.navigationController.toolbar setBarStyle:UIBarStyleBlackOpaque];
[self.navigationController setToolbarHidden:NO animated:YES];
[self.navigationController setToolbarItems:theItems animated:NO];
//self.navigationController.toolbarItems = theItems; // Tried both
UILabel* label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 100, 20)];
label.text = #"kjhdkjhadsda";
[self.navigationController.toolbar addSubview:label];
This only shows the UILabel in the correct position, nothing else appears. The UILabel is useless for me, it is just a test. I also tried to allocate a new array instead of copying the one from the component. Ignore the missing releases, this is only test code.
I read many questions about this but no answer seem to help making it work. Any idea what might not be ok in this code?
Seems that you are trying make mutable copy of nil in line
[self.navigationController.toolbar.items mutableCopy];
By default method navigationController.toolbar.items nas no items and returns nil
Update
Method - (void)setToolbarItems:(NSArray*)toolbarItems animated:(BOOL)animated does nothing if you send it to UINavigationController. You need to set toolbar items to that controller who is managed by a navigation controller. This line will make your buttons visible:
[self setToolbarItems:theItems animated:NO];

Resizing UIToolbar when UISearchBar becomes active

I have an UIToolbarwith 5 items:
UIBarButtonItem with image
UIBarButtonItem flex width
UIBarButtonItem with custom view (UISearchBar)
UIBarButtonItem flex width
UIBarButtonItem with image
When I select the UISearchBar, I get it to keep its correct size and become active. However, I would like the image to the left and to the right to disappear and give the UISearchBar the full width of the UIToolbar. How do I do that?
This is what I have:
https://dl.dropbox.com/u/3077127/demo_1.mov
And this is what I want:
https://dl.dropbox.com/u/3077127/demo_2.mov
This is my code:
#pragma mark View lifecycle
- (void)viewDidLoad {
[...]
SearchBar *mySearchBar = [[SearchBar alloc] init];
mySearchBar.delegate = self;
[mySearchBar sizeToFit];
[mySearchBar setAutocapitalizationType:UITextAutocapitalizationTypeNone];
[mySearchBar setTintColor:[UIHelpers getSlColor]];
CGRect searchBarFrame = mySearchBar.frame;
searchBarFrame.size.width = 218;
[mySearchBar setFrame:searchBarFrame];
UIView *searchBarContainer = [[UIView alloc] initWithFrame:mySearchBar.frame];
[searchBarContainer addSubview:mySearchBar];
[searchBarContainer setTag:99];
UIBarButtonItem *left = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:#"location-arrow"] style:UIBarButtonItemStyleBordered target:self action:nil];
UIBarButtonItem *right = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:#"location-arrow"] style:UIBarButtonItemStyleBordered target:self action:nil];
UIBarButtonItem *flex = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil];
UIBarButtonItem *search = [[UIBarButtonItem alloc] initWithCustomView:searchBarContainer];
NSArray *items = [[NSArray alloc] initWithObjects:left, flex, search, flex, right, nil];
UIToolbar *toolbar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, 0, 320, 44)];
[toolbar setItems:items];
[toolbar setTintColor:[UIHelpers getSlColor]];
self.tableView.tableHeaderView = toolbar;
self.tableView.tableFooterView = [[UIView alloc] initWithFrame:CGRectNull];
[...]
[super viewDidLoad];
}
#pragma mark -
Here is my answer to a similar question posted here
The key to a correct animation is to specify UIViewAnimationOptionLayoutSubviews as an option for the animation.
Not sure if you have tried this, but maybe you can use the UISearchBarDelegate methods to get notified when the user clicks on the search bar.
Example:
#pragma mark - UISearchBarDelegate Methods
- (BOOL)searchBarShouldBeginEditing:(UISearchBar *)searchBar {
// Remove the right and left buttons from the ToolBar
[self updateToolBarWithImages:NO];
}
- (BOOL)searchBarShouldEndEditing:(UISearchBar *)searchBar {
// Add back the right and left buttons to the ToolBar
[self updateToolBarWithImages:YES];
}
#pragma mark - Private Methods
// Custom method used to Update the ToolBar
- (void)updateToolBarWithImages:(BOOL)iShowImages {
// Logic to update ToolBar based on the BOOL value in showImages
// use "setItems:animated:" method of UIToolBar to set the ToolBar Items
[toolBar setItem:items animated:YES];
}
You shouldn't use a ToolBar for that.
Simply use a NavigationBar, with your 2 right and left ButtonItems, plus add to the NavigationBar's titleView a SearchBar with the appropriate delegates.
So you don't have to resize your NavigationBar. It's just about adding/removing the NavigationBar's right and left ButtonItems animated like so:
if (self.searchBar.isActive) {
[self.navigationItem setLeftBarButtonItem:nil animated:YES];
[self.navigationItem setRightBarButtonItem:nil animated:YES];
}
else {
[self.navigationItem setLeftBarButtonItem:self.leftButton animated:YES];
[self.navigationItem setRightBarButtonItem:self.rightButton animated:YES];
}
Hope this helps!

Add button to navigationbar programmatically

Hi I need to set the button on right side, in navigation bar, programatically , so that if I press the button I will perform some actions. I have created the navigation bar, programatically by;
navBar=[[UINavigationBar alloc]initWithFrame:CGRectMake(0,0,320,44) ];
Similarly, I need to add the button, on the right side of this navigation bar. For that I used,
1.
UIView* container = [[UIView alloc] init];
// create a button and add it to the container
UIButton* button = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 130, 44.01)];
[container addSubview:button];
[button release];
// add another button
button = [[UIButton alloc] initWithFrame:CGRectMake(160, 0, 50, 44.01)];
[container addSubview:button];
[button release];
// now create a Bar button item
UIBarButtonItem* item = [[UIBarButtonItem alloc] initWithCustomView:container];
// set the nav bar's right button item
self.navigationItem.rightBarButtonItem = item;
[item release];
2.
UIImage *im;
im=[UIImage imageNamed:#"back.png"];
[button setImage:im forState:UIControlStateNormal];
[im release];
backButton = [[UIBarButtonItem alloc] initWithCustomView:button];
[backButton setImageInsets:UIEdgeInsetsMake(0, -10,5, 5)];
[self.navigationItem setRightBarButtonItem:backButton];
3.
UIBarButtonItem *refreshItem = [[UIBarButtonItem alloc] initWithTitle:#"button" style:UIBarButtonItemStylePlain target:self action:#selector(refreshLogsAction:)];
self.navigationItem.rightBarButtonItem = refreshItem;
[refreshItem release];
I tried all these ways, but none is displaying the button on the right hand side.
Inside my UIViewController derived class, I am using the following inside viewDidLoad:
UIBarButtonItem *flipButton = [[UIBarButtonItem alloc]
initWithTitle:#"Flip"
style:UIBarButtonItemStyleBordered
target:self
action:#selector(flipView:)];
self.navigationItem.rightBarButtonItem = flipButton;
[flipButton release];
This adds a button to the right hand side with the title Flip, which calls the method:
-(IBAction)flipView
This looks very much like you #3, but it is working within my code.
UIImage* image3 = [UIImage imageNamed:#"back_button.png"];
CGRect frameimg = CGRectMake(15,5, 25,25);
UIButton *someButton = [[UIButton alloc] initWithFrame:frameimg];
[someButton setBackgroundImage:image3 forState:UIControlStateNormal];
[someButton addTarget:self action:#selector(Back_btn:)
forControlEvents:UIControlEventTouchUpInside];
[someButton setShowsTouchWhenHighlighted:YES];
UIBarButtonItem *mailbutton =[[UIBarButtonItem alloc] initWithCustomView:someButton];
self.navigationItem.leftBarButtonItem =mailbutton;
[someButton release];
///// called event
-(IBAction)Back_btn:(id)sender
{
//Your code here
}
SWIFT:
var image3 = UIImage(named: "back_button.png")
var frameimg = CGRect(x: 15, y: 5, width: 25, height: 25)
var someButton = UIButton(frame: frameimg)
someButton.setBackgroundImage(image3, for: .normal)
someButton.addTarget(self, action: Selector("Back_btn:"), for: .touchUpInside)
someButton.showsTouchWhenHighlighted = true
var mailbutton = UIBarButtonItem(customView: someButton)
navigationItem?.leftBarButtonItem = mailbutton
func back_btn(_ sender: Any) {
//Your code here
}
To add search button on navigation bar use this code:
UIBarButtonItem *searchButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemSearch target:self action:#selector(toggleSearch:)];
self.navigationController.navigationBar.topItem.rightBarButtonItem = searchButton;
and implement following method:
- (IBAction)toggleSearch:(id)sender
{
// do something or handle Search Button Action.
}
How to add an add button to the navbar in swift:
self.navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .Add, target: self, action: "onAdd:")
onAdd:
func onAdd(sender: AnyObject) {
}
self.navigationItem.rightBarButtonItem=[[[UIBarButtonItem alloc]initWithTitle:#"Save" style:UIBarButtonItemStylePlain target:self action:#selector(saveAction:)]autorelease];
-(void)saveAction:(UIBarButtonItem *)sender{
//perform your action
}
Swift version, add this in viewDidLoad:
var doneButton = UIBarButtonItem(title: "Done", style: UIBarButtonItemStyle.Plain, target: self, action: "doneButton:")
navigationItem.rightBarButtonItem = doneButton
And this in your View Controller class
func doneButton(sender: UIBarButtonItem) {
println(111)
}
Use following code:
UIBarButtonItem *customBtn=[[UIBarButtonItem alloc] initWithTitle:#"Custom" style:UIBarButtonItemStylePlain target:self action:#selector(customBtnPressed)];
[self.navigationItem setRightBarButtonItem:customBtn];
Simple use native editBarButton like this
self.navigationItem.rightBarButtonItem = self.editButtonItem;
[self.navigationItem.rightBarButtonItem setAction:#selector(editBarBtnPressed)];
and then
- (void)editBarBtnPressed {
if ([infoTable isEditing]) {
[self.editButtonItem setTitle:#"Edit"];
[infoTable setEditing:NO animated:YES];
}
else {
[self.editButtonItem setTitle:#"Done"];
[infoTable setEditing:YES animated:YES];
}
}
Have fun...!!!
In ViewDidLoad method of ViewController.m
UIBarButtonItem *cancel = [[UIBarButtonItem alloc] initWithTitle:#"Cancel" style:UIBarButtonItemStyleBordered target:self action:#selector(back)];
[self.navigationItem setLeftBarButtonItem:cancel];
"(back)" selector is a method to dissmiss the current ViewController
Try this.It work for me.
Add button to navigation bar programmatically, Also we set image to navigation bar button,
Below is Code:-
UIBarButtonItem *Savebtn=[[UIBarButtonItem alloc]initWithImage:
[[UIImage imageNamed:#"bt_save.png"]imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]
style:UIBarButtonItemStylePlain target:self action:#selector(SaveButtonClicked)];
self.navigationItem.rightBarButtonItem=Savebtn;
-(void)SaveButtonClicked
{
// Add save button code.
}
If you are not looking for a BarButtonItem but simple button on navigationBar then below code works:
UIButton *aButton = [UIButton buttonWithType:UIButtonTypeCustom];
[aButton setBackgroundImage:[UIImage imageNamed:#"NavBar.png"] forState:UIControlStateNormal];
[aButton addTarget:self
action:#selector(showButtonView:)
forControlEvents:UIControlEventTouchUpInside];
aButton.frame = CGRectMake(260.0, 10.0, 30.0, 30.0);
[self.navigationController.navigationBar addSubview:aButton];
Hello everyone !! I created the solution to the issue at hand where Two UIInterface orientations are wanted using the UIIMagePicker.. In my ViewController where I handle the segue to the UIImagePickerController
**I use a..
-(void) editButtonPressed:(id)sender {
BOOL editPressed = YES;
NSUserDefaults *boolDefaults = [NSUserDefaults standardUserDefaults];
[boolDefaults setBool:editPressed forKey:#"boolKey"];
[boolDefaults synchronize];
[self performSegueWithIdentifier:#"photoSegue" sender:nil];
}
**
Then in the AppDelegate Class I do the following.
- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window {
BOOL appDelBool;
NSUserDefaults *boolDefaults = [NSUserDefaults standardUserDefaults];
appDelBool = [boolDefaults boolForKey:#"boolKey"];
if (appDelBool == YES)
return (UIInterfaceOrientationMaskPortrait);
else
return UIInterfaceOrientationMaskLandscapeLeft;
}

Adding UIBarButtonItem to UINav..Controller

i am not sure what i am missing here. I Have a custom UINavigationController and i am trying to add a persistant UIBarButtonItem to the bar.
-(void)viewDidLoad
{
self.navigationBar.barStyle = UIBarStyleBlack;
UIBarButtonItem *bbi = [[UIBarButtonItem alloc] initWithTitle:#"Nope..."
style:UIBarButtonItemStyleBordered
target:self
action:#selector(goBack:)];
self.navigationItem.leftBarButtonItem =bbi;
[bbi release];
}
-(void)goBack:(id)sender
{
NSLog(#"go back now");
}
what am i missing here? - BTW, i do not want to/ will not use IB.
UPDATE:
Currently this is the closest i can get:
-(void)viewDidLoad
{
self.navigationBar.barStyle = UIBarStyleBlack;
UINavigationBar *navBar = [[UINavigationBar alloc] initWithFrame:CGRectMake(0, 20, 320, 44)];
navBar.barStyle = UIBarStyleBlack;
UINavigationItem *navItem = [[UINavigationItem alloc] initWithTitle:#"Currently Playing..."];
[navBar pushNavigationItem:navItem animated:NO];
UIBarButtonItem *editButton = [[UIBarButtonItem alloc] initWithTitle:#"Close" style:UIBarButtonItemStyleBordered target:self action:#selector(goBack:)];
navItem.rightBarButtonItem = editButton;
[self.view addSubview:navBar];
[editButton release];
[navItem release];
[navBar release];
[super viewDidLoad];
}
It's terrible i have to add an entire navbar to a UINavigationController that already has a navbar....if i try to use the existing, i get this error:
'NSInternalInconsistencyException', reason: 'Cannot call pushNavigationItem:animated: directly on a UINavigationBar managed by a controller.'
....really???
navigationItem must not be set on the UINavigationController instance but on the view controller of the view which is displayed "inside" the navigation controller.
Setting self.navigationItem on your navigation controller would work if your controller was itself pushed into another navigation controller.