How to get UITextField from inputAccessoryView button click
Asked Answered
O

2

6

I have a dynamic number of UITextFields which all have an inputAccessoryView. This is composed of a UIToolbar which has a button on it. When this button is pressed it calls a method, however, within this method I somehow need the ability to access the underlying UITextField.

Please could someone advise how this is possible?

// Create the toolbar controls
UIBarButtonItem *doneButton = [[UIBarButtonItem alloc] initWithTitle:@"Done" style:UIBarButtonItemStyleDone target:self action:@selector(navigationBarDoneButtonPressed:)];
UIBarButtonItem *flexibleSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];

// Setup the toolbar
navigationToolbar = [[UIToolbar alloc] initWithFrame:CGRectMake(10.0, 0.0, 310.0, 40.0)];
[navigationToolbar setItems:@[flexibleSpace, doneButton]];

// In a UITableView I create a number of cells which contain UITextFields....

// This is the method that gets called when a user presses the done button
- (void)navigationBarDoneButtonPressed:(id)sender
{
    NSLog(@"Based on sender I need to access the underlying UITextField.");
}
Oporto answered 23/8, 2013 at 15:45 Comment(1)
I have added some code which summarises what I've done.Oporto
S
7

You can keep track of the currently focused UITextField in a variable, and use that variable in your inputAccesoryView method:

in your .h file: make sure you're conforming to the UITextFieldDelegate protocol:

@interface MyViewController : UIViewController <UITextFieldDelegate>

and add this property:

@property (assign, nonatomic) UITextField *activeTextField;

In your .m file: While creating your dynamic textfields:

...
theTextField.delegate=self;
...

And add these implementations of the UITextFieldDelegate protocol:

- (void)textFieldDidBeginEditing:(UITextField *)textField
{
    self.activeTextField = textField;
}
- (void)textFieldDidEndEditing:(UITextField *)textField
{
    self.activeTextField = nil;
}

And now, in the method invoked by your inputAccesoryView:

- (void)navigationBarDoneButtonPressed:(id)sender{//Just an example
    self.activeTextField.text=@"Test";
}
Stringer answered 23/8, 2013 at 16:0 Comment(3)
Thanks for your help. Unfortunately I cannot use this pattern though as the UITextField delegate methods are already being used by the UITableViewCell that contains it (in other word the UITableViewCell is set to be the delegate of the UITextField).Oporto
@TheCrazyChimp ok, if this is not a solution you can use the solution that is explained here: #1823817, and use it in your tableView within the inputAccesoryView method. This will give you the UIView that has the focus.Haroldson
Thanks - I used your idea. Basically I ended up creating a delegate method on the subclassed UITableViewCell which was triggered whenever someone begins editing the UITextField within it. That way I was able to maintain a record of the text field being used.Oporto
G
0

I would create UITableViewCell subclass with delegate, e.g.

MyTextEditTableViewCell.h

@class MyTextEditTableViewCell;
@protocol MyTextEditTableViewCellDelegate <NSObject>
- (void)didDoneButtonPressed:(MyTextEditTableViewCell *)sender;
@end

@interface MyTextEditTableViewCell : UITableViewCell
@property (nonatomic, weak) id<MyTextEditTableViewCellDelegate> delegate;
@property (nonatomic, strong) UITextField *textField;
@end

MyTextEditTableViewCell.m

@implementation MyTextEditTableViewCell
- (void)navigationBarDoneButtonPressed:(id)sender
{
    // Call delegate
    if (self.delegate)
          [self.delegate didDoneButtonPressed:self];
}
@end

Your UIViewController subclass (Or UITableViewController)

...
- (void)didDoneButtonPressed:(MyTextEditTableViewCell *)sender {
    UITextField *cellTextField = sender.textField;
    // do some stuff with text field
}

Don't forget to set delegate to cell when you will config it.

Gunman answered 23/8, 2013 at 16:18 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.