Saving data from custom UITableViewCell - ios

I have an edit screen which is comprised of one huge UITableView.
Each cell in the table is a custom UITableViewCell comprising of a UITextField
I am able to load up the table, scroll around and enter information. However, during scrolling the table cells lose the data entered and I understand why this happens.
I realize I need to save the data as soon as the user finishes entering the data using the textFieldDidEndEditing method.
Question: I want to store the data entered in a custom object that is available in the ViewController - how do I access this from the UITableViewCell? Also, how do I identify the row and position of the table cell so that based on the position I can populate a specific attribute in the object
Question: Am I doing this the right way? Or is there a better way to do this?

As you are mentioning only a single text field, we can make do with an NSMutableArray object containing strings for each cell. You will have to fill the array with empty strings and use this info to fill the text field. It will be something like,
textField.text = [textFieldStrings objectAtIndex:indexPath.row];
Since you're doing it programmatically within the view controller, you will have to set the view controller as your text view delegate. You can do
- (void)textFieldDidEndEditing:(UITextField *)textField {
UITableViewCell *cell = (UITableViewCell*)textField.superview;
NSIndexPath *indexPath = [self.tableView indexPathForCell:cell];
... Since you've the index path, you can map it to an array.
[textFieldStrings replaceObjectAtIndexPath:indexPath withObject:textField.text];
}
This would be the basic idea. Start with a mutable array of empty strings and modify them every time the text field is updated by replacing the original text with the new text. Hope this helps.

Related

One click, multiple actions Custom Cell of TableView

What I do
I have a created a custom cell which has a button with a specific image on it. Now depending on some conditions I set that image image1.jpg or image2.jpg.
How I do that
The custom cell is created by creating a protocol where I click that buttons action, I notice in the main interface, that the button is pressed and I pass as a parameter the button instance.
Issue
Now, the problem is when I click that button in a specific cell, I change cell.button's image, but also with that, when I scroll down, I see that there are other cells that have changed their image.
Any idea why is this happening?
Due to the reuse of cells by the UITableView, when the cell moves out of the screen, it is moved to a queue and then reused when there are new cells to load.
If you want to keep each cell's property unique, you will have to reconstruct its values every time. For that you can keep some kind of data array that stores the state/condition of each cell. The array will be ordered by the indexPath of the tableView, and then you can just fetch the state from the array based on the indexPath and update the cell to be the right image.
What is happening is that when you change the image of your cell and later scroll down or up, your cell is being reused to present another information.
To fix that you should check your UITableView data source, see if you're reusing cells in this method:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
I'd recommend to configure the cell before returning it in the previous method, and assign the appropiate image for the button at that time. To achieve that you'd need some mechanism for remembering the state of each cell.
For more information about cell reusing and cell in general you could go to the Apple Docs for UITableViewCell
As described in above answer you can manage button selected and unselected state in array for that you can even add one key in the array that you are using for the data to display.
and on didselect event of table you can change the key of selected field like this
NSMutableDictionary *newDict = [[NSMutableDictionary alloc] init];
NSDictionary *oldDict = self.dict_trans_Details ;
[newDict addEntriesFromDictionary:oldDict];
[newDict setObject:status forKey:#"transactionstatusid"];
[table_transdetails_array replaceObjectAtIndex:self.indexValue withObject:newDict];
Thanks.

how to save the content of a uitextview to a tableview

I have a UITextView and when I press a 'Save' button I would like that the text will get added to a row in my UITableView. I've set up the table view already. I'd also like to get to the UITextView when selecting one on the table view.
First, you need to add the data to your data source. Depending on how your table is set up that might just entail adding an extra string to an array, if you edit your question with more detail I can be more specific here.
Next you call insertRowsAtIndexPaths:withRowAnimation: on your table view, changing the value of the index path depending on where you've added the new data.
[tableView insertRowsAtIndexPaths:#[NSIndexPath indexPathForRow:0 inSection:0] withRowAnimation:UITableViewRowAnimationAutomatic];
The table view will take care of the rest, it will call cellForRowAtIndexPath: to make the new table cell (using the data you just added to the data source) and will even animate it into position for you.
For the second part of your question, you'll need to implement tableView:didSelectRowAtIndexPath: and in there get the appropriate string from your data source based on the selected row, and set the text view accordingly. Something like
textView.text = myDataSourceArray[indexPath.row];
Very basic, but this example should do the trick.
https://cloud.jakota.de/public.php?service=files&t=922500d0732da5ce3cc71b6fdf517a83

How do I get information from a UITableViewCell?

I have a TableView with a prototype cell, in this prototype cell I have a text field.
Well, what I need is to get a information from this text field when it changes. I need to do that to feed a object.
How can I do that ?
Short answer - you don't.
Slightly more in depth answer...
The UITableViewCell is a "view". It is used only to display information to the screen. It is not for storing data in.
In a UITableViewController (i.e. UITableViewDatasource and UITableViewDelegate) you should have an NSArray (or an NSFetchedResultsController) that you use to store information in.
Then using the delegate methods you populate the table with that data.
If the data changes then you reload the table to update the cells.
What should never happen is the following...
Load the table by passing in data to the cell.
The cell then changes its own data and changes what is on the screen.
The controller then reads that data out of the cell.
No, no, no, don't do this.
What should happen is this...
Load the table and configure the cell display to represent the correct part of the data.
When the button is pressed (or text field is changed, etc...) in the cell then call a method back in the controller to update the data accordingly.
Now the data has changed, reload the cell.
It will now show the correct information based on the new data.
You need a custom cell with a public property (IBOutlet) UITextfield. Then you can set your ViewController as the textField's delegate in cellForRowAtIndexPath,
cell.textField.delegate = self;
in this case your ViewController has to implement UITextFieldDelegate protocol.

Best approach for editing text fields in a table view cell

In my app I've got a number of views that need to be in-place editable. I've got the tableviewcells setup to include a UITextField which is enabled, and the text can be changed and this is fine, it works.
My question is what is the best approach to keeping track of these? Should I :
Keep an iVar of each textfield. If so then
How do I make sure each cell has the correct field if it's only instantiated once?
Have a textfield added when the cell is created and simply set its value when configuring the cell. If so then
How do I keep track of the values? If the cell went out of view and then back, its values would be reset to its original value and not the edited value.
What approach do you generally tend to use for this scenario? Especially if there are a large number of cells that you're dealing with.
Store the values for all of your text fields in a mutable array in your data model.
In tableView:willDisplayCell:forRowAtIndexPath: set your text field's value, using the value from your array based on the index path.
When a text field ends editing, store the value back in the array immediately. There is already a protocol for this (so no need to write your own), but it is a little trickier than normal because you are not handed the indexPath and need to find the one associated with your text field:
- (void) textFieldDidEndEditing:(UITextField *)textField {
CGRect location = [self convertRect:textField.frame toView:self.tableView];
NSIndexPath *indexPath = [[self.tableView indexPathsForRowsInRect:location] objectAtIndex:0];
// Save the contents of the text field into your array:
[yourArray replaceObjectAtIndex:indexPath.row withObject:textField.text];
}
Subclass UITableViewCell and add a UITextField in it's init method.
create a protocol for the custom cell class. when UITextField begin editing or end editing call the delegate's method.
in controller, implement the custom cell's protocol and set the indexpath row value to cell's tag in tableView:cellForRowAtIndexPath:
so every time you edit UITextField, you can know in controller which row is editing (via cell's tag)
The best way is to follow MVC and implement your model, which in your case is the textfield values. What you do is store those values in an array, and in your cellForIndexPath method you reference the correct value in the array. For example, the first row of the table (indexPath.row == 0) would retrieve the first element in the array. Changes in the textField would be recorded on the corresponding element in the array.

How can I get the value of a UITableViewCell that is not visible?

I have a table view cell that has many rows with a UITextView. In those UITextView the user can enter values.
The problem that I have is that if I want to get the value of a row when the row is hidden I get nil.
NSString *cellValue = ((UITextField *)[[[self.table cellForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:1]] contentView] viewWithTag:[self.table cellForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:1]].tag]).text;
I was thinking to save the value that the user enters in the UITextField, but if the user clicks a row that performs the calculate the delegate textFieldDidEndEditing is not being called.
I don't know how can I get this values in a secure way.
You should target the data source that is behind the UITableView. The UITableView is just a display mechanism and not the primary resource for getting to data. You can get the index for the cell based on the title, but then I would look tot he data source to get your actual data. Better yet I would just handle all operations against the data source itself if that is possible. When you build the table initially your data source is a list or array of some kind I am sure so you can just use it. You may need to create a variable on the view and retain the list/array there to make sure you have it and you should be all set.
Good Luck!
As mentioned, you would generally use the UITableView data source to access this.
That said, you are probably not seeing the data you expect because the you are using dequeued cells. If the number of cells is small, you could consider caching your own cells in an NSDictionary whose keys are some combination of the section and row, and accessing their view hierarchy via your own cache.
You can access rows that are not currently displayed by directly referring the tableView's dataSource with the wanted IndexPath.
You can achieve this by doing something like this (when using Swift 3):
UITableViewCell cell = self.tableView(self.tableView, cellForRowAt: indexPath)
What is happening most likely is your reusing cells. So when your cell with the textfield goes off screen it gets reused so you cannot access it anymore. What you will need to do is grab the value out the the textfield right after they enter it and store it somewhere. You can use – textField:shouldChangeCharactersInRange:replacementString: so that when ever the user enters a character into the textfield you can save the string.

Resources