programmatically adding button to UIToolbar - ios

I am programmatically creating a UIToolbar with this code:
pickerTB = [[UIToolbar alloc]initWithFrame:CGRectMake(0, 0, 320, 44)];
[self.view addSubview:pickerTB];
How do i add one single button to it? It needs to say "Done" and the button must be able to call a method later on.

Try this, If you want to add DONE button on right side of uitoolbar then add flexible button before done button
UIBarButtonItem *flexButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:self action:nil];
UIBarButtonItem *doneButton =[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:#selector(doneButton)];
NSArray *itemsArray = [NSArray arrayWithObjects:flexButton, doneButton, nil];
[toolbar setItems:itemsArray];
-(void)doneButton
{
}
// change toolbar style
[toolbar setBarStyle:UIBarStyleBlackTranslucent];
//change bar button color
[doneButton setTintColor:[UIColor blackColor]];

pickerTB.items = [NSArray arrayWithObjects:[[UIBarButtonItem alloc]initWithTitle:#"Done" style:UIBarButtonItemStyleDone target:self action:#selector(done:)],nil];

This code will really helpful to add button to the UIToolbar present in keyboard or pickerview.
For example:
If you want "Done" button to be inserted in the toolbar of the pickerview. you just have to follow simple steps as follows.
Step 1:
Have to include this code inside "viewDidLoad" to create "Done" button in UIToolbar. "textBoxText" is the name of the Text field.
// create done button in toolbar.
doneToolbar = UIToolbar(frame: CGRectMake(0, 0, self.view.frame.size.width, 50))
doneToolbar.barStyle = UIBarStyle.Default
doneToolbar.items = [UIBarButtonItem(title: "Done", style: UIBarButtonItemStyle.Plain, target: self, action: #selector(FirstViewController.PickerDoneButtonTapped))]
doneToolbar.sizeToFit()
textBoxText.inputAccessoryView = doneToolbar
Step 2:
Code the function of "Done" button that has included in the UIToolbar. I have given that if "Done" button is tapped the PickerView have to disable.
func PickerDoneButtonTapped()
{
textBoxText.resignFirstResponder()
}
Step 3:
Have to call the function in "viewDidload"
self.PickerDoneButtonTapped()
Output:

Related

Action for UIBarButtonItem on toolbar which is placed in pickerview not working

I have a UIPickerview that is created in interface builder. And via code I placed a toolbar as its subview and a done button as the toolbars bar button item. I want to execute an action when the done button is clicked (hide the pickerview and some extra stuff). But for some reason the action for the done button is not working. Here is the code to create the toolbar and the bar button item in viewDidLoad.
UIToolbar *toolBar= [[UIToolbar alloc] initWithFrame:CGRectMake(0,0,320,44)];
toolBar.barTintColor = [UIColor colorWithRed:70/250.0f green:70/250.0f blue:70/250.0f alpha:1.0];
UIBarButtonItem *barButtonDone = [[UIBarButtonItem alloc] initWithTitle:#"Done"
style:UIBarButtonItemStyleDone target:self action:#selector(doneButtonTapped:)];
UIBarButtonItem *flexible = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:self action:nil];
toolBar.items = #[flexible, barButtonDone, flexible];
barButtonDone.tintColor=[UIColor colorWithRed:227/255.0f green:178/255.0f blue:49/255.0f alpha:1.0];
[picker addSubview:toolBar];
[picker bringSubviewToFront:toolBar];
And here is the method doneButtonTapped:
-(void)doneButtonTapped:(UIBarButtonItem *)sender{
NSLog(#"Done button tapped");
picker.hidden = true;
[self.view bringSubviewToFront:txtCity];
[self.view bringSubviewToFront:advancedSearchLine];
[self.view bringSubviewToFront:txtCityLine];
}
I checked in layout debugger while running the app and indeed the done button is in the front of the view, so nothing in front of it to prevent it from working. What am I doing wrong?
you cannot add toolbar as subview of picker view.create a container in UIView add toolbar and picker as subview.
UIView *inputView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, screenWidth, toolBar.frame.size.height + picker.frame.size.height)];
inputView.backgroundColor = [UIColor clearColor];
[inputView addSubview:picker];
[inputView addSubview:toolBar];

Keyboard toolbar for multiple textFields

In my project, some viewControllers have multiple text fields,
I found how to add a toolbar above keyboard with a "Ok" button to hide keyboard when the button is tapped.
The code I am using is this below :
UIBarButtonItem *flex = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:self action:nil];
UIBarButtonItem *barButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:_destField action:#selector(resignFirstResponder)];
UIToolbar *toolbar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, 0, 320, 34)];
toolbar.items = [NSArray arrayWithObjects:flex, barButton, nil];
_destField.inputAccessoryView = toolbar;
How can I easily reuse this code in the same view controller?
The "target" makes this difficult, is there a way without creating a toolbar for each textField?
Thanks!
If this code is in a view controller then there is a simple solution. Change the barButton to something like this:
UIBarButtonItem *barButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:#selector(dismissKeyboard)];
Then add this method to the view controller:
- (void)dismissKeyboard {
[self.view endEditing:YES];
}
That will dismiss the keyboard no matter what view is showing it.
Now you can reuse that toolbar as the inputAccessoryView for any text field/view in the view controller.

ios7 navigation bar : 3 strange dots appearing when back animation with custom button

I would like to use the back navigation animation using
[self.navigationController popViewControllerAnimated:YES]
with a custom button added to the navigation bar.
As I don't want the back button to be seen, i've hidden it with self.navigationItem.hidesBackButton = YES;
But during the back animation, on ios7 (not ios6) 3 dots can be seen sliding in the navigation bar.
They are not appearing with self.navigationItem.hidesBackButton = NO; but of course the button can be seen.
Does anyone has any idea to make them not appearing ?
If you set
self.navigationItem.hidesBackButton = YES
iOS will sometimes generate three dots inside its generic back button.
I solved the problem by setting the text on the generic back button to be empty and then I created my custom button. This is how I set the empty text:
UIBarButtonItem *backButton2 = [[UIBarButtonItem alloc] initWithTitle:#"" style:UIBarButtonItemStylePlain target:nil action:nil];
self.navigationItem.backBarButtonItem = backButton2;
And then I created my custom UIButton and placed it where I wanted it like this:
UIButton *backButton = [[UIButton alloc] initWithFrame:CGRectMake(5, 70/2-22, 44, 44)];
[backButton setImage:[[UIImage imageNamed:#"back_button.png"] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate] forState:UIControlStateNormal];
backButton.tintColor = tintColor;
backButton.imageEdgeInsets = UIEdgeInsetsMake(-2, -15, 0, 0);
[backButton addTarget:self action:#selector(popCurrentViewController) forControlEvents:UIControlEventTouchUpInside];
No need to hide the backButton, you can just add custom back button, it will hide the default button.
- (void) viewDidLoad
{
UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithTitle:#"Back" style:UIBarButtonItemStyleBordered target:self action:#selector(handleBack:)];
self.navigationItem.leftBarButtonItem = backButton;
}
- (void) handleBack:(id)sender
{
[self.navigationController popViewControllerAnimated:YES];
}
Just add these following lines in viewWillAppear method:
Swift:
self.navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .Plain, target: nil, action: nil)
self.navigationItem.leftBarButtonItem = UIBarButtonItem(title: "", style: .Plain, target: nil, action: nil)
Objective C:
self.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:#"" style:UIBarButtonItemStylePlain target:nil action:nil];
self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:#"" style:UIBarButtonItemStylePlain target:nil action:nil];
That's all
navigationItem.backBarButtonItem = nil
Simpler swift version :
let emptyBackButton = UIBarButtonItem(title: "", style: .Plain, target: nil, action: nil)
navigationItem.hidesBackButton = true
navigationItem.backBarButtonItem = emptyBackButton
You don't need to write any code just follow 4 simple step and you done it.
Select your Main.storyboard
Select Navigation Bar in Navigation Controller
Select Attributes Inspector
Clear Tint color

Adding a custom row to the keyboard

I've seen some apps add a custom row to the keyboard. The row may include for example arrows, modifiers, copy and paste etc. I'd like to add one of these in my own app, but what are they really? Are they just toolbars with buttons that is hidden when the keyboard is hidden, or is there a framework/feature made especially for adding rows to the keyboard?
All is simple. You just need assign yours custom row view to UITextField's inputAccessoryView.
The most convenient way is to use UIToolBar as inputAccessoryView.
Read Custom Views for Data Input for more details.
Why need a library for it?
You can create a custom view and pin its movement to the keyboard show/hide notification to make it act like part of keyboard.
My code:
UIToolbar* numberToolbar = [[UIToolbar alloc]initWithFrame:CGRectMake(0, 0, 320, 50)];
numberToolbar.barStyle = UIBarStyleBlackTranslucent;
numberToolbar.items = [NSArray arrayWithObjects:
[[UIBarButtonItem alloc]initWithTitle:#"Cancel" style:UIBarButtonItemStyleBordered target:self action:#selector(cancelNumberPad)],
[[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil],
[[UIBarButtonItem alloc]initWithTitle:#"Apply" style:UIBarButtonItemStyleDone target:self action:#selector(doneWithNumberPad)],
nil];
[numberToolbar sizeToFit];
self.textField.inputAccessoryView = numberToolbar;
Add this when textfield begins editing:
UIButton *doneBtn = [UIButton buttonWithType:UIButtonTypeCustom];
[doneBtn setBackgroundImage:[UIImage imageNamed:#"TextViewDone.png"] forState:UIControlStateNormal];
[doneBtn addTarget:self action:#selector(closeKeyboard) forControlEvents:UIControlEventTouchUpInside];
doneBtn.frame = CGRectMake(self.view.frame.size.width-70,6,64,30);
headerBarView = [[UIView alloc]initWithFrame:CGRectMake(0,headerY,self.view.frame.size.width,40)];
headerBarView.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"TextViewBar.png"]];
[headerBarView addSubview:doneBtn];
[self.view addSubview:headerBarView];
And this when textfield ends editing:
// Action for close keyboard of header bar for UITextView *****
- (void) closeKeyboard
{
[headerBarView removeFromSuperview];
}

How to add a button to UINavigationBar?

How to add a button to UINavigationBar programmatically?
Sample code to set the rightbutton on a NavigationBar.
UIBarButtonItem *rightButton = [[UIBarButtonItem alloc] initWithTitle:#"Done"
style:UIBarButtonItemStyleDone target:nil action:nil];
UINavigationItem *item = [[UINavigationItem alloc] initWithTitle:#"Title"];
item.rightBarButtonItem = rightButton;
item.hidesBackButton = YES;
[bar pushNavigationItem:item animated:NO];
But normally you would have a NavigationController, enabling you to write:
UIBarButtonItem *rightButton = [[UIBarButtonItem alloc] initWithTitle:#"Done"
style:UIBarButtonItemStyleDone target:nil action:nil];
self.navigationItem.rightBarButtonItem = rightButton;
The answers above are good, but I'd like to flesh them out with a few more tips:
If you want to modify the title of the back button (the arrow-y looking one at the left of the navigation bar) you MUST do it in the PREVIOUS view controller, not the one for which it will display. It's like saying "hey, if you ever push another view controller on top of this one, call the back button "Back" (or whatever) instead of the default."
If you want to hide the back button during a special state, such as while a UIPickerView is displayed, use self.navigationItem.hidesBackButton = YES; and remember to set it back when you leave the special state.
If you want to display one of the special symbolic buttons, use the form initWithBarButtonSystemItem:target:action with a value like UIBarButtonSystemItemAdd
Remember, the meaning of that symbol is up to you, but be careful of the Human Interface Guidelines. Using UIBarButtonSystemItemAdd to mean deleting an item will probably get your application rejected.
Adding custom button to navigation bar ( with image for buttonItem and specifying action method (void)openView{} and).
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
button.frame = CGRectMake(0, 0, 32, 32);
[button setImage:[UIImage imageNamed:#"settings_b.png"] forState:UIControlStateNormal];
[button addTarget:self action:#selector(openView) forControlEvents:UIControlEventTouchUpInside];
UIBarButtonItem *barButton=[[UIBarButtonItem alloc] init];
[barButton setCustomView:button];
self.navigationItem.rightBarButtonItem=barButton;
[button release];
[barButton release];
The example below will display a button with a title "Contact" on the navigation bar on the right. Its action calls a method named "contact" from the viewcontroller. Without this line the right button is not visible.
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:#"Contact"
style:UIBarButtonItemStylePlain target:self action:#selector(contact:)];;
In Swift 2, you would do:
let rightButton: UIBarButtonItem = UIBarButtonItem(title: "Done", style: UIBarButtonItemStyle.Done, target: nil, action: nil)
self.navigationItem.rightBarButtonItem = rightButton
(Not a major change) In Swift 4/5, it will be:
let rightButton: UIBarButtonItem = UIBarButtonItem(title: "Done", style: UIBarButtonItem.Style.done, target: nil, action: nil)
self.navigationItem.rightBarButtonItem = rightButton
Why not use the following:
(from Draw custom Back button on iPhone Navigation Bar)
// Add left
UINavigationItem *previousItem = [[UINavigationItem alloc] initWithTitle:#"Back title"];
UINavigationItem *currentItem = [[UINavigationItem alloc] initWithTitle:#"Main Title"];
[self.navigationController.navigationBar setItems:[NSArray arrayWithObjects:previousItem, currentItem, nil] animated:YES];
// set the delegate to self
[self.navigationController.navigationBar setDelegate:self];
swift 3
let cancelBarButton = UIBarButtonItem(title: "Cancel", style: .done, target: self, action: #selector(cancelPressed(_:)))
cancelBarButton.setTitleTextAttributes( [NSFontAttributeName : UIFont.cancelBarButtonFont(),
NSForegroundColorAttributeName : UIColor.white], for: .normal)
self.navigationItem.leftBarButtonItem = cancelBarButton
func cancelPressed(_ sender: UIBarButtonItem ) {
self.dismiss(animated: true, completion: nil)
}

Resources