i have this set up in my app
im trying to change between the textfield with the uibarbutton but it aint working
i have this code
-(void)setToolBar {
UIToolbar* Toolbar = [[UIToolbar alloc]initWithFrame:CGRectMake(0, 0, 320, 50)];
Toolbar.items = [NSArray arrayWithObjects:
[[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil],
[[UIBarButtonItem alloc]initWithImage:[UIImage imageNamed:#"backwardIcon"] style:UIBarButtonItemStylePlain target:self action:#selector(prevTextField)],
[[UIBarButtonItem alloc]initWithImage:[UIImage imageNamed:#"forwardIcon"] style:UIBarButtonItemStylePlain target:self action:#selector(nextTextField)], nil];
[Toolbar sizeToFit];
self.txtNombre.inputAccessoryView = Toolbar;
self.txtAM.inputAccessoryView = Toolbar;
self.txtAP.inputAccessoryView = Toolbar;
self.txtEmail.inputAccessoryView = Toolbar;
self.txtPass.inputAccessoryView = Toolbar;
}
-(void)nextTextField {
if(self.txtNombre){
[self.txtNombre resignFirstResponder];
[self.txtAP becomeFirstResponder];
}else if(self.txtAP){
[self.txtAP resignFirstResponder];
[self.txtAM becomeFirstResponder];
}else if(self.txtAM){
[self.txtAM resignFirstResponder];
[self.txtTel becomeFirstResponder];
}else if(self.txtTel){
[self.txtTel resignFirstResponder];
[self.txtEmail becomeFirstResponder];
}else if(self.txtEmail){
[self.txtEmail resignFirstResponder];
[self.txtPass becomeFirstResponder];
}else{
[self.txtPass resignFirstResponder];
}
}
-(void)prevTextField{
if(self.txtAP){
[self.txtNombre becomeFirstResponder];
[self.txtAP resignFirstResponder];
}else if(self.txtAM){
[self.txtAP becomeFirstResponder];
[self.txtAM resignFirstResponder];
}else if(self.txtTel){
[self.txtAM becomeFirstResponder];
[self.txtTel resignFirstResponder];
}else if(self.txtEmail){
[self.txtTel becomeFirstResponder];
[self.txtEmail resignFirstResponder];
}else if(self.txtPass){
[self.txtEmail becomeFirstResponder];
[self.txtPass resignFirstResponder];
}
}
any ideas on what am i doing wrong since it just changes between the first two text fields
Instead of checking:
if(self.txtNombre)
you should be checking
if([self.txtNombre isFirstResponder])
For all textfields of course.
That is checking that your UITextField is currently being edited.
Also I would suggest, to make an NSArray from those UITextFields to make those methods looking nicer. Right now if you want to add more textfield, you need to copy paste a lot and rename properties - also easy to make mistake with that.
Related
On the right is picker view toolbar button 'Next' and want to call textFieldShouldReturn method on its action via #selector. But it gives me error Undeclared Selector.
This is button's code,
UIBarButtonItem *nextBtn = [[UIBarButtonItem alloc] initWithTitle:#"Next" style:UIBarButtonItemStylePlain target:self action:#selector("textFieldShouldReturn here")];
And this is my textFieldShouldReturn method,
-(BOOL)textFieldShouldReturn:(UITextField *)textField
{
[textField resignFirstResponder];
self.addScrollView.contentSize = CGSizeMake(320, 1800);
[self.addScrollView setContentOffset:CGPointMake(0, 0 ) animated:NO];
if (textField == industryTxtField) {
[subIndustryTxtField becomeFirstResponder];
}
else if (textField == subIndustryTxtField) {
[address1TxtField becomeFirstResponder];
}
ScreenShot
Try like this ...
UIBarButtonItem *nextButton = [[UIBarButtonItem alloc] initWithTitle:#"Next" style:UIBarButtonItemStylePlain target:self action:#selector(moveToNextField)];
-(void)moveToNextField
{
if (industryTxtField.isFirstResponder)
{
[subIndustryTxtField becomeFirstResponder];
}
else if (subIndustryTxtField.isFirstResponder)
{
[address1TxtField becomeFirstResponder];
}
}
I have a button:
#property (weak, nonatomic) IBOutlet UIBarButtonItem *addTaskBtn;
...
// Add new task button action.
- (IBAction)addTaskBtnAction:(id)sender {
}
I want a keyboard with a textfield accessory toolbar to pop up when I press my button. That textfield should also become the firstresponder which causes kind of a paradox...
I find it impossible to show a keyboard without making it a first responder of an existing textfiled, but I am trying to create a textfield as a toolbar of a keyboard.
The best example for this is in this app: https://todoist.com/ - they managed to do exactly what I am trying to achieve.
Any ideas?
Try this code for the hidden textfield:
make txtHidden as hidden and make it first responder on button click
- (IBAction)btnOpenTextfield:(id)sender {
[self.txtHidden becomeFirstResponder];
}
- (void) setupToolbar {
UIToolbar *keyboardToolBar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, 0, 320, 42)];
self.txtToolbar = [[UITextField alloc] initWithFrame:CGRectMake(8, 6, 250, 30)];
UIBarButtonItem *textBtn = [[UIBarButtonItem alloc] initWithCustomView:self.txtToolbar ];
UIBarButtonItem *postBtn = [[UIBarButtonItem alloc]initWithTitle:#"Post" style:UIBarButtonItemStyleBordered target:self action:#selector(postComment)];
[keyboardToolBar setItems: [NSArray arrayWithObjects:textBtn,postBtn,nil]];
self.txtHidden.inputAccessoryView = keyboardToolBar;
}
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField {
if (textField == self.txtHidden) {
[self setupToolbar];
}
return true;
}
- (void)textFieldDidBeginEditing:(UITextField *)textField {
[self performSelector:#selector(changeResponder) withObject:nil afterDelay:0.1];
[self changeResponder];
}
- (void) changeResponder {
[self.txtToolbar becomeFirstResponder];
}
This is not the best way but you can try this till you get any other better solution
I have searched the entire internet and tried different ways to implement UITextFieldShouldReturn, but when I run it in the simulator it just doesn't work.
What I'm trying to do is move from the first textfield(emailTextField) to the second one( nameTextField ) when user clicks next button on the keyboard. The same for the second textfield's keyboard and dismiss the keyboard when user clicks done button on the last textfield( numberTextField ).
Here is my code, can anyone help me with this?
#import "ViewController.h"
#interface ViewController () <UITextFieldDelegate>
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.emailTextField.placeholder = #"Your Pitt Email(optional)";
self.nameTextField.placeholder = #"Lost ID Name";
self.numberTextField.placeholder = #"Lost ID Series Number(optional)";
[self.emailTextField.delegate self];
[self.nameTextField.delegate self];
[self.numberTextField.delegate self];
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(dismissKeyboard)];
[self.view addGestureRecognizer:tap];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
//release delegate
-(void)dealloc{
self.emailTextField.delegate = nil;
self.nameTextField.delegate = nil;
self.numberTextField.delegate = nil;
}
//dismiss keyboard when it's called
-(void)dismissKeyboard{
[self.emailTextField resignFirstResponder];
[self.nameTextField resignFirstResponder];
[self.numberTextField resignFirstResponder];
}
//when a textfield begins editing, this will happen
-(void)textFieldDidBeginEditing:(UITextField *)textField{
if(textField == self.emailTextField){
textField.placeholder = #"";
}else if(textField == self.nameTextField){
textField.placeholder = #"";
}else{
textField.placeholder = #"";
}
}
//when a textfield ends editing, this will happen
-(void)textFieldDidEndEditing:(UITextField *)textField{
if(textField == self.emailTextField){
textField.placeholder = #"Your Pitt Email(optional)";
[self textFieldShouldReturn:self.emailTextField];
}else if(textField == self.nameTextField){
textField.placeholder = #"Lost ID Name";
[self textFieldShouldReturn:self.nameTextField];
}else{
textField.placeholder = #"Lost ID Series Number(Optional)";
[self textFieldShouldReturn:self.numberTextField];
}
}
//return button set up
-(BOOL)textFieldShouldReturn:(UITextField *)textField{
[textField resignFirstResponder];
return YES;
}
//when confirm is pressed
- (IBAction)confirmButton:(id)sender {
[self dismissKeyboard];
}
#end`
Change
[self.emailTextField.delegate self];
to
self.emailTextField.delegate = self;
Also remove those delegates from dealloc. You can put them from viewDidDisappear
Try this code snippet. Here i am taking only two
UITextFields.
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
if (textField==_txtEmail)
{
[_txtEmail resignFirstResponder];
[_txtPassword becomeFirstResponder];
}
else if (textField==_txtPassword)
{
[_txtPassword resignFirstResponder];
}
return YES;
}
This function is enough to return keyboard from text fields.
-(BOOL)textFieldShouldReturn:(UITextField *)textField{
[textField resignFirstResponder];
return YES;
}
Your these 3 lines are not working.
[self.emailTextField.delegate self];
[self.nameTextField.delegate self];
[self.numberTextField.delegate self];
If you are using storyboard, connect delegates of the text fields with the view.
You can use this code.It is working for me..
-(void)tool{
UIToolbar *toolbar = [[UIToolbar alloc] init];
[toolbar setBarStyle:UIBarStyleBlackTranslucent];
[toolbar sizeToFit];
UIBarButtonItem *flexButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:self action:nil];
UIBarButtonItem *doneButton =[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:#selector(resignKeyboard)];
[doneButton setTintColor:[UIColor whiteColor]];
UIBarButtonItem *Next = [[UIBarButtonItem alloc]initWithTitle:#"Next" style:UIBarButtonItemStylePlain target:self action:#selector(Nextbutton)];
[Next setTintColor:[UIColor whiteColor]];
NSArray *itemsArray = [NSArray arrayWithObjects:Next,flexButton,doneButton,nil];
[toolbar setItems:itemsArray];
[FirstNameTextField setInputAccessoryView:toolbar];
[LastNameTextfield setInputAccessoryView:toolbar];
[EmailAddressTextField setInputAccessoryView:toolbar];
[PasswordTextfield setInputAccessoryView:toolbar];
[ConfirmPasswordTextfield setInputAccessoryView:toolbar];}
-(void)Nextbutton{
if ([FirstNameTextField isFirstResponder])
{
[LastNameTextfield becomeFirstResponder];
}
else if ([LastNameTextfield isFirstResponder])
{
[EmailAddressTextField becomeFirstResponder];
}
else if ([EmailAddressTextField isFirstResponder])
{
[PasswordTextfield becomeFirstResponder];
}
else if ([PasswordTextfield isFirstResponder])
{
[ConfirmPasswordTextfield becomeFirstResponder];
}
else if ([ConfirmPasswordTextfield isFirstResponder])
{
[ConfirmPasswordTextfield resignFirstResponder];
}}
-(void)resignKeyboard{
[FirstNameTextField resignFirstResponder];
[EmailAddressTextField resignFirstResponder];
[LastNameTextfield resignFirstResponder];
[PasswordTextfield resignFirstResponder];
[ConfirmPasswordTextfield resignFirstResponder];}
First of all you need to set the delegate right. Then You need to give your next textfield the becomeNextResponder call which should be ideally done in the shouldReturn delegate method.
In your viewDidLoad method, paste this.
self.emailTextField.tag = 2000;
self.nameTextField.tag = 3000;
self.numberTextField.tag = 4000;
Now edit your textFieldShouldReturn method like this:
-(BOOL)textFieldShouldReturn:(UITextField *)textField{
[textField resignFirstResponder];
if(textfield.tag<4000)
{
UITextField *nextTextField = (UITextField *)[self.view viewWithTag:textField.tag+1000];
[nextTextField becomeFirstResponder];
}
return YES;
}
you can always use a library to accomplish what you need to do !!
use this library : tpAvoidKeyboard
Read how to use it and there you go all the next buttons and clicks outside text fields to dismiss the keyboard and the the done button on the last textfield to dismiss the keyboard, all those features are already implemented
In my Project I have two UITextFields, one is used for Postal Code another one is used for Phone Number , so I used the Keyboard in NumberPad, Here I used the UIToolbar for both UITextFields for hide values, but my problem is TextField is does not identify the correct Tags in custom Methods for hide the textfields. How to resolve this issue
and my code is
- (void)viewDidLoad
{
[super viewDidLoad];
numberToolbar = [[UIToolbar alloc]initWithFrame:CGRectMake(0, 0, 320, 50)];
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:#"Done" style:UIBarButtonItemStyleDone target:self action:#selector(doneWithNumberPad:)],
nil];
}
- (IBAction)cancelNumberPad:(UITextField*)textField {
NSLog(#"The user is typing in text field %d",textField.tag);
if (textField.tag==50) {
[txtPostalCode resignFirstResponder];
txtPostalCode.text=#"";
}
else
{
[txtphoneno resignFirstResponder];
txtphoneno.text = #"";
}
}
- (IBAction)doneWithNumberPad:(UITextField*)textField {
NSLog(#"The user is typing in text field %d",textField.tag);
if (textField==txtPostalCode) {
[txtPostalCode resignFirstResponder];
}
else
{
[txtphoneno resignFirstResponder];
}
}
-(void)textFieldDidBeginEditing:(UITextField *)textField
{
if (textField.tag==50) {
textField.inputAccessoryView = numberToolbar;
}
else if
(textField.tag==5) {
textField.inputAccessoryView = numberToolbar;
}
}
in my console report is
2014-05-03 14:06:23.614 why-Q[2000:60b] The user is typing in text field 0
how to get the correct tag in custom methods
//yourviewcontroller.h
#interface ViewController : UIViewController {
int tag;
}
//yourviewcontroller.m
- (void)viewDidLoad {
[super viewDidLoad];
tag = 0;
}
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField// return NO to disallow editing.
{
tag = textField.tag;
return YES;
}
- (IBAction)cancelNumberPad:(UITextField*)textField {
NSLog(#"The user is typing in text field %d",tag);
}
- (IBAction)doneWithNumberPad:(UITextField*)textField {
NSLog(#"The user is typing in text field %d",tag);
}
I'm using the following code to move to the next field using the UITextField delegate and also I'm adding a toolbar to the keyboard with the previous, next and ok buttons. The code is working fine.
Like you see the keyboard return button logic is pretty generic, using the UITextField tags, and that's good because I'm gonna use the piece of code all around. Now I will need to write the previous and next buttons logic, and I'm lost. Any ideas?
UPDATE (complete code, with some modifications, thanks to #8vius that spent some time with me in the chat to make it work):
//
// SigninViewController.m
//
#import "SigninViewController.h"
#implementation SigninViewController
#synthesize firstResponder = _firstResponder;
#synthesize toolbar;
#synthesize email;
#synthesize password;
- (void)move:(UIBarButtonItem*)sender {
NSInteger tag = self.firstResponder.tag;
if ([sender.title isEqualToString:#"Anterior"]) {
tag -= 1;
} else if ([sender.title isEqualToString:#"Próximo"]) {
tag += 1;
}
UITextField *nextTextField = (UITextField*)[self.view viewWithTag:tag];
if (nextTextField && tag > 0) {
[nextTextField becomeFirstResponder];
} else {
[self.firstResponder resignFirstResponder];
self.firstResponder = nil;
}
}
- (void)ok:(id)sender {
[self.view endEditing:YES];
self.firstResponder = nil;
}
- (void)textFieldDidBeginEditing:(UITextField*)textField {
self.firstResponder = textField;
}
- (BOOL)textFieldShouldReturn:(UITextField*)textField {
NSInteger tag = textField.tag + 1;
UITextField *nextTextField = (UITextField*)[self.view viewWithTag:tag];
if (nextTextField) {
[nextTextField becomeFirstResponder];
} else {
[textField resignFirstResponder];
self.firstResponder = nil;
}
return NO;
}
- (void)viewDidLoad {
[super viewDidLoad];
self.email.delegate = self;
self.password.delegate = self;
if (self.toolbar == nil)
{
self.toolbar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, 44)];
UIBarButtonItem* previous = [[UIBarButtonItem alloc] initWithTitle:#"Anterior" style:UIBarButtonItemStyleBordered target:self action:#selector(move:)];
UIBarButtonItem* next = [[UIBarButtonItem alloc] initWithTitle:#"Próximo" style:UIBarButtonItemStyleBordered target:self action:#selector(move:)];
UIBarButtonItem* space = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:(UIBarButtonSystemItemFlexibleSpace) target:nil action:nil];
UIBarButtonItem* ok = [[UIBarButtonItem alloc] initWithTitle:#"Ok" style:UIBarButtonItemStyleBordered target:self action:#selector(ok:)];
[self.toolbar setItems:[[NSArray alloc] initWithObjects:previous, next, space, ok, nil]];
[self.toolbar setTranslucent:YES];
[self.toolbar setTintColor:[UIColor blackColor]];
}
for (UIView* view in self.view.subviews) {
if ([view isKindOfClass:[UITextField class]]) {
[(UITextField*)view setInputAccessoryView:toolbar];
}
}
}
- (void)viewDidUnload {
self.email = nil;
self.password = nil;
[super viewDidUnload];
}
#end
It's quite simple, when you load your view you set the tag property on your text fields depending on the order you want them in, then you have to just traverse the tag element on the fields:
- (void)toggleTextfield:(UIBarButtonItem *)sender {
NSInteger nextTag = self.firstResponder.tag;
if ([sender.title isEqualToString:#"Previous"] && nextTag > 1) {
nextTag -= 1
} else if ([sender.title isEqualToString:#"Next"]) {
nextTag += 1;
}
UITextField *nextTextField = (UITextField *)[self.view viewWithTag:nextTag];
if (nextTextField) {
[nextTextField becomeFirstResponder];
}
}
And keep track of who is the first responder:
-(void)textFieldDidBeginEditing:(UITextField *)textField {
self.firstResponder = textField;
}
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
[textField resignFirstResponder];
self.firstResponder = nil;
return YES;
}
And when you load your view, you bind the buttons to the toggle action:
UIBarButtonItem *previousButton = [[UIBarButtonItem alloc] initWithTitle:#"Previous"
style:UIBarButtonItemStyleBordered
target:self
action:#selector(toggleTextfield:)];
UIBarButtonItem *nextButton = [[UIBarButtonItem alloc] initWithTitle:#"Next"
style:UIBarButtonItemStyleBordered
target:self
action:#selector(toggleTextfield:)];
In my case, for instance, I set up my text fields inside a table view, so in my cellForRowAtIndexPath method I set the tag property to be the row of the indexPath.
EDIT: You have to set the firstResponder property for it to work.
In your .h file:
#property UIView *firstResponder
In your .m file:
#synthesize firstResponder = _firstResponder;