开发者

How to get UITableViewCell's index from its edited UITextField

I'm working on an iPhone based BI project.

I have a UITextField in a UITextViewCell, the UITextFieldDelegate points to my UITableViewController, I haven't done any sub-classing for the UITextViewCell nor the UITextField.

Now after the text field end editing on the delegate

  -(void)textFieldDidEndEditing:(UITextField*)textField

I need to know the row index of the current cell I'm editing, is there any way to get the parent cell of the text field? Or can I set some property to the textfield like 'rowIndex' when I create the cell? I really need this val开发者_StackOverflowue inorderto save the new text.

Thank you. May the Force be with you.


With the changes in the UITableViewCell class in iOS 7 you have to have a more dynamic way to get to the parent cell. You can get to the UITextField's cell by using the following snippet (which you should put in textFieldDidEndEditing: delegate method)

// Get the cell in which the textfield is embedded
id textFieldSuper = textField;
while (![textFieldSuper isKindOfClass:[UITableViewCell class]]) {
    textFieldSuper = [textFieldSuper superview];
}
// Get that cell's index path
NSIndexPath *indexPath = [self.tableView indexPathForCell:(UITableViewCell *)textFieldSuper];

The snippet works in both iOS 6 and iOS 7.


The real question you are asking is about how to know where to save changes to your data model when the user enters data into a text field within a table cell.

@Ole Begemann's suggestion to use the tag property is perfectly valid. It depends on your data model. If all you need is a single integer to identify where the value gets in your model then store that integer in the tag property of each text field. Since you are not using sections, the row index is equivalent to having the entire index path.

Keep in mind that all views have a tag property. So you could store the row index in cell.contentView.tag and the column index in textField.tag. From the text field you get the content view with textField.superview. If a different view is the superview of textField use that instead.

If you need something more complex than that to identify the location in your model to save the text field contents then you'll need to do something different. I would either subclass UITableViewCell or UITextField and store whatever info you need in a property you define in the subclass.


If you have added your UITextField in UITableViewCell as Subviews, So you could access the UITableViewCell from your UITextField's superview property.

Try with below.

UITableViewCell* myCell = (UITableViewCell*)textField.superview ;

Let me know for any issue you face .

Edited:

you will get the row from tag property of your UITextField So

NSUInteger  myRow = myTextField.tag;

As you said your application does'nt support have multiple sections,it means you have all your rows at 0 section.

NSUInteger  mySection = 0;

Now Construct a NSIndexPath instance from the above information.

NSIndexPath *myIndexPath =[NSIndexPath indexPathForRow:myRow  inSection:mySection]; //Do'nt release myIndexPath instance.

UITableViewCell* myCell = [myTableView cellForRowAtIndexPath:myIndexPath];

Now you have myCell which is at myRow in your UITableView


For iOS 7, it's a bit different. If aTextField is an object of kind: UITextField iOS 6: [[aTextField superView] superView]

iOS 7: [[[aTextField superView] superView] superView]

Apple has added a ScrollView between UItableViewCell and its contentView.

Edit: The scroll view is gone in iOS 8.

iOS 8: [[aTextField superView] superView]


As others have suggested, you can get the current cell by accessing the text field's superview. From there, you can easily find the index path of the current cell using the UITableView method -indexPathForCell:.

Update

While I still think the above is the simplest and best way to do it, it is possible that it could cause a slowdown in a large table view (if -indexPathForCell: involves a linear search). I just read another interesting idea: represent the section and row as unsigned shorts, pack them into a single integer and store the result in the view's (text field's) tag property (source).


You can set textfield.tag to the row index when you return the cell in tableView:cellForRowAtIndexPath:.


Keep in mind that if you have a long table of cells, these might get deallocated because of the size of the UITableView's frame.

Since iOS reuses the cell, if you have multiple similar cells try to do this: begin editing a cell tapping on a UITextField, scroll down to another cell until the selected UITextField is out of the view and now see what happens in the -(void)textFieldDidEndEditing:(UITextField*)textField method. You will notice that textFiled.superview is a NULL pointer since the cell has been deallocated and you cannot access it anymore.

The sole solution that comes across my mind is to store the cell attributes you need in a property via the -(void)textFieldDidBeginEditing:(UITextField*)textField method.


There is actually no need to worry about what cell index is currently subject for editing. I am using this code

UIView *tableViewCellView = [[field superview] superview];
if(floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_6_1)
{
     // Need to traverse one step more up the visual tree
     tableViewCellView = [tableViewCellView superview];
}
[self.tableView scrollRectToVisible:[tableViewCellView frame] animated:YES];

in conjunction with BSKeyboardControls delegate method to successfully scroll the selected field into view. Tested with ios5 and upwards

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜