My suggestion is not doing that. You cannot rely on the content of a UITextField
that is embedded in a cell of a tableView, due to reusability.
Your view controller should be directly tied to the model, thus, changing the text within a textField should update your model immediately, so, when you scroll and a cell gets reused, the proper value is assigned. And when you hit "forward" you just query the content of the model (which, by all means, could probably be a simple NSMutableArray
).
Let's add an NSMutableArray with as many empty strings as there will be textFields (for example 5):
- (instancetype)initWithWhatever...
{
self = [super initWithWhatever];
if (self)
{
_textFieldValues = [NSMutableArray arrayWithCapacity:5];
for (NSInteger i=0; i < 5; i++)
{
_textFieldValues[i] = @"";
}
}
return self;
}
Make sure every textfield points back to your viewController, on cellForRowAtIndexPath:
.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
...
myCell.textField.text = _textFieldValues[indexPath.row];
myCell.textField.tag = 100 + indexPath.row;
myCell.textField.delegate = self;
return myCell
}
The tag is there to identify each cell, other option is to make your own UITextField
subclass or use a custom setValueForKey:
.
Whatever you pick, when you get the delegate method (UITextFieldDelegate
), check against your preferred method, tag in my case:
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
NSString *replaced = [textField.text stringByReplacingCharactersInRange:range withString:string];
_textFieldValues[(textField.tag - 100)] = replaced;
return YES;
}
That will keep the model up to date always, and you don't need to iterate text fields, just over the array:
// Method that gets called when hitting forward
- (IBOutlet)didPressForwardButton:(UIButton*)sender
{
for (NSString *text in _textFieldValues)
{
NSLog(@"UITEXTFIELD TEXT = %@", text);
}
}
Lesson: When working with a UITableView
you should be always mapping what's on the view to what's on the model, and update immediately, you cannot rely on the view to hold the data. In fact, this should extend to anything you do in iOS, views are for shows. If you cannot modify the real model immediately, you would have to encapsulate it in a "transaction" intermediary object and then update the real model.