How to deal with Custom Cells when these are not visible and want to get the cell using indexPath? - iphone

Guys, I didn't find a clean and a simple solution for the following issue. I've a UITableViewController view which uses a UITextFieldCustomCell that I implemented.
The table has several rows, that requires the user to scroll down an enter values on each cell, which contains a UILabel and a UITextField.
Every time the user change the value on the UITextField the UIViewController gets notified and stores the value in a NSDictionary using the cell indexPath.row property, in order to identify what's the key for the cell where the value needs to be stored.
The problem is if the user keep focus on a cell and then scrolls up or down (removing the cell from the view) makes me unable to get the indexPath for the cell, since it's not visible.
So, I cannot store the value since I don't know from which cell the value is coming.
Have anyone run through this issue before?. It seems to be a common design between iPhone applications, does anyone have an idea if is this a good implementation or not?
Thanks!

I assume you're observing textFieldDidEndEditing:. Are you saying it's not firing, or that it is firing, but it's no longer in any of the cells (possibly because it's in the process of being removed)?
Assuming the latter, my approach would be to use setTag: on the UITextField to make it easy to keep track of its index. This would save you from ever hunting around in your cells, even in the case that they are on the screen.

Related

image is reverting to original when scrolling uitableview

I have a button inside each cell. When it's pressed, the image is changed (basically a checkbox) to denote a selection. When you scroll to the bottom ... then scroll back up to the top. The image is reverted to the original image.
This question is pretty similar to this:
Preserve Cell Image After Scrolling UITableView
And others. But, I can't seem to find a good answer. I understand that's it's reverting back to how the uitableview is setup when the cell goes off the screen. But, how do I save the changed image to the uitableview so when it scrolls it doesn't revert to the original?
Thanks in advance! =)
It's changing back because cells are reused. When your cell is going off the screen it is taken out of the view and put back into the reuse pool. Then you're getting it out of the queue again in cellForRowAtIndexPath and setting it back up as the default.
The question you linked to is exactly what you should follow. You should store the state of your cell in your view controller and then when you set it up again in cellForRowAtIndexPath you should load that state and set up the cell appropriately.
One simple way for your method would be to have an NSArray which you set up to be the same size as the number of rows in your table and then in that just store an NSNumber for each row which contains a boolean value on or off for your selection state. When the user toggles, toggle the value in the array and then in cellForRowAtIndexPath read that value and set it up appropriately.
I'm assuming the checkbox in your table view cell is changing state to a selected state because a user selected it. You shouldn't use UI elements to maintain the state of your app. That is, when the user taps the checkbox, you should use that event to somehow reflect that state change in a data object in your app. Then, when that cell needs to be displayed again, you configure it with the state you previously saved. This allows for things like cell reuse, and view unloading and is all-around a good habit.

Custom Cell with Button Memory Problems

I have a custom cell that contains a button in a table view. The button is used as a toggle to essentially serve as a "checkbox" for a user to check off certain items in the list. I was having the issue in which the buttons in these table cells seemed to be sharing memory locations as a result of the dequeuereusablecellwithidentifier. When a button was pressed, it would also press every 4th or 5th button in the list.
I changed it to create my cells in a method into an array which then populates the tableview. This works fine for what I am trying to achieve, however it poses an issue when dealing with large row counts. The tableview itself runs quickly, but the initial load can be 3-4 seconds at times when there are over 100 rows. The iteration to create the cells and then populate it to the tableview is quite cumbersome.
What other methods can you populate a tableview with custom cells and buttons while still retaining unique memory for the buttons within?
Any help would be appreciated!
Thanks :)
You definitely don't want to change the way the creation of cells work- dequeuereusablecellwithidentifier is a very good thing for the reasons your seeing.
The solution is that you should store the result of the button/checkbox press in a separate data structure, like an NSArray full of NSNumber. As your table scrolls and cells are reused, you reset the state of the checkbox to whatever state it should be based on your NSArray.
Good luck!

textFieldShouldBeginEditing: Being Called Multiple Times for UITextField in UITableViewCell

This is an iPad app so it is based on SDK 3.2 (behavior also appears on later iOS release).
I created a custom UITableView cell class which contains a UITextField. The class for the cell adheres to the UITextFieldDelegate protocol and I've implemented the textFieldShouldBeginEditing method to intercept user interaction with the text field.
Everything usually works great but I've noticed that when the user scrolls the tableview and then taps on a field the textFieldShouldBeginEditing is called multiple times, sometimes on two different fields. This leads to users tapping on the field in one row of the table and a field in another row becoming first responder.
Has anyone encountered this behavior?
I'm working on a solution to set a flag to ignore input for a fixed time period but I really hate to do this and would love to know if there is a batter way.
I figured this out. I was reloading the tableview data at the same time as scrolling and it must have been recreating the text fields.
I changed to reloading single lines as I should have been doing anyways and it is working smoothly.

Some cell in table view should be checkmarked?

I am making app where a list of countries to be shown. When the first time app runs the user selects the no. of countries. I stored that list in nsuser defaults. I want to checkmark those countries in the TableView when the app runs again for second time.
One more problem is when I scroll through the TableView and again come to the previous position, the checkmark does not show. Why this happens??
In -tableView:cellForRowAtIndexPath: you should set wether or not a checkmark should be shown based on your internal model (which in your case comes from NSUserDefaults). In the tableView:didSelectRowAtIndexPath:, do not simply make the checkmark visible in the cell, but store in in your internal model as well. This way when a cell is being shown again, it will show up correctly.
This happens because the table Cells are reused so when you Scroll up they are cleaned and reused by the below data and when you go up again all the thing is happened again.
Regarding Checking again on second time.
Just store the index of the row in NSUserDefault and put the condition in cellForRowAtIndexPath that when the index is matched keep it Checked.
Hope this helps..
hAPPY cODING...

A pattern for having the topmost UITableViewCell feature a "Settings" Cell

If it is unclear what I mean from the headline, I am referring to the functionality that is in the Facebook app where to topmost cell in a "Feed" view is a "Load new posts" button that extends upwards "forever". You have to pull it down a bit for it to display it self.
Background
In my case I reload the data for the entire UITableView (plain style) as the user type in a search field (which means fairly often), I then let the user filter the results using a slider. This functionality makes it so that there are more than one version of my data source, an array and a filteredArray.
If I were to implement the functionality the "quick" way I would set my:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [self.productListFiltered count] +1;
}
To return the count plus one, this would give me an extra cell.
Then I would have to go through cellForRowAtIndexPath, DidSelectRowAtIndexPath etc. etc. all the delegate methods for the tableView and do exceptions for when indexPath.row == 0.
It would have to riddle the controller with so many exceptions that it would be unreadable.
I could also try to change my model array, so each time It was set the data source for my tableVIew I would make the NSArray into an NSMutableArray and stuff an "empty" object in the first place.
This would also give some strange code as I would just have to move all the exception code to my CustomTableCellView (a custom view I add to the cell's subview). I populate the TableVIew often and from different places depending on whether the data is filtered or not.
Would it maybe be a better approach to attach a subview to the top of the tableView it self? but how would I go about giving the user the possibility to pull it on screen?
I am having a hard time finding a sound way through this, some way that does not fight the "best practice" for the UITableView.
Hope someone can offer a bit of guidance.
Thank you.
You should just use table sections. The search field and controls go in one section and the data in the second. When you return cells you just need to check the section and then access the data for that section instead of the other.