UITableView-didSelectRowAtIndexPath Problems when call didSelectRowAtIndexPath - iphone

I have a UITableView with CustomCell, in my CustomCell I added UIImage,UILabel...
But, when I selected cell in row 1 and remove UIImage on it : [[cell.contentView viewWithTag:TAG_FOR_TOPIMAG]removeFromSuperview]; However, cell at index 7 was changed same cell 1.

Table view reuses cells (dequeueReusableCell...).
So, the same cell (view) may be used for more than 1 index in the table.
After you change a cell's layout (add/remove/modify subviews) then this cell (view) will appear modified each time it is presented on the screen - even if it represents different index each time.
For example, in your case you probably have maximum of 6 cells visible in the same time on the screen.
Therefore, you have modified some cell (it was displayed for index 1 once you have modified it), after that you have scrolled the table, the cell with index 1 has disappeared from the screen, then the cell with index 7 should be presented (during the scrolling). The table will use the same cell (exactly the same UITableViewCell object) that was used for displaying row with index 1.
But you have removed the image from it...
You have to keep it in mind all the time when you work with tables.
In your case I would suggest you to set the visibility of the image view to hidden and restore it in each tableView"cellForRowAtIndexPath: method (NOT inside the if (cell == nil) statement - after it).

Related

iphone: changing status of several segment controllers at once in custom cell

I have a tableView with the custom cell (see image below.)
Taking a three row table as an example, if a user changes segment controller in row 0 to "Yes," can I automatically change the segment controllers in rows 1 & 2 to "No?"
I am using the following to detect a segment change:
- (void)seg_changed:(id) sender {
cell=(switchCell*) [[sender superview] superview];
UITableView *table=(UITableView*) [cell superview];
NSIndexPath *path=[table indexPathForCell:cell];
NSLog(#"been pressed %d si %d",path.section, path.row);
}
Much appreciated.
In this method you call just tell those other segment controllers to set their values to "NO". The hard part is figuring out where those two other controls are. You have to do the hard work of tracking them.
If your design ensures there are always two more cell with segmented controls you can just access the correct cells by incrementing the path.row value.
This change can tell your data model that a value has changed, the model object then updates the associated values, and notifies the cells displaying those other values.
You can add an array to this cell class that keeps track of what other cells should be modified with this change.
Edit: (to respond to a comment) To change the setting displayed on the segmented control just set the property selectedSegmentIndex of the UISegmentedControl to the appropriate value. "Yes" should be 0, and "No" should be 1.

Preserve Cell Image After Scrolling UITableView

I have a custom UITableViewCell which acts as a check list. As the user clicks on the selected item, it goes from red to green indicating a selection, however as the users scrolls further down the list, once they come back up to the top, the image has changed back to it's default red value.
How do I go about preserving the state of an image as the tableview recycles cells?
Thanks
Sounds like you are using the UITableViewCells to store the state of your table data. This is the wrong approach because the cells are reused. You should keep state in an separate 'data store'. This can simply be an array you keep in memory in your UITableViewController subclass or something persistent like SQLite or Core Data. This state is then transferred back to the cell when the table view asks you to in tableView:cellForRowAtIndexPath:.
I had the same problem. Use:
MyTableViewCell* cell = [tableView dequeCellWithReuseIdentifier:#"MyTableViewCell"];
if (cell == nil) { /* create cell */ }
/* and now you reset the properties of that cell */
cell.text = [myCellText objectAtIndex:indexPath.row];
The key here is to reset the properties of dequeued table cell based on the indexPath. This does mean you will have to keep around enough state to re-create any table cell--including the images you are using.

iPhone: Cells order changes in UITableView Section After Call to reloadSections: Method

I have a table with two sections. A segmented control in first sections changes which rows are displayed in the second section. My problem is that the order of the rows and which row are displayed in the second section shifts improperly upon each subsequent press of a button in the segmented control.
I allow a user to add a product to a shopping list 3 different ways: by name, by barcord and by taking a picture with a camera. I have 3 buttons in a UISegmentedControl so the users can select which method to use. Depending on which segement the user selects the fields in the second segment should change to show cells relevant to that method.
Section 0:
0 row with segmented control showing name, barcode and camera buttons
Section 1:
// button zero, name button
0 row with textfield
1 row with textfield
or
// button 1, barcode button
0 row with textfield
or
// button 2, camera button
// shows camera view
I've put placeholders in each UITextField.
Each time a button in the segmented control is clicked, I call a pickOne: method that updates the tablevew. In that method, I construct a NSIndexSet with NSRange of (1, 1), and then I call the reloadSections: method of the UITableViewController with the NSIndexSet as a parameter.
When the view appears for the first time, everything is ok but when I click the buttons repeatedly, the order of the cells changes. Cells containing the two textFields for the button0 and the new placeHolders are written over the old ones.
Worse, sometimes when I click on button 0, it shows me only the second cell of the two cells.
My detailed code can be seen here http://pastebin.com/9GwMpCS9
I'm seeing a couple of problems.
The first big one is that you're adding subviews into the cells bypassing the contentView. Subviews in predefined styles are broken up into different parts depending on their roles. You have the editing control, the content view, and the accessory view. While you can add directly to the cell's view, there'll be odd behavior because the predefined cells are expecting the content to be in the content view.
I think what's causing your problem is that you're adding subviews every time a cell is decorated but you never remove them. When a cell is dequeued there's no guarantee that everything is restored to the pristine new condition as if it was alloc'ed. Things like custom accessory views that aren't removed can be left behind. I'm pretty sure that's happening. You're collecting visual trash on cells that should be clean.
I believe your problem is here.
// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
//....
if(addMode == NAME) {
if(indexPath.row == 0) {
[cell addSubview:nameTextField];
}
else if(indexPath.row == 1) {
[cell addSubview:categoryTextField];
}
}
else if(addMode == BARCODE) {
[cell addSubview:barcodeTextField];
}
else if(addMode == SCAN){
//Scanning mode
}
}
return cell;
}
This because the table always shows has having two sections, this method is always called for section 1. Regardless of the input type selected, it creates or dequeue a cell and returns it. Whenever addMode==SCAN, it randomly dequeues one of the previously used cells for the name or barcode addMode and returns that.
I suggest that you remove the SCAN logic from the table altogether or that you create a row for the camera.
I think the latter the best UI. With the first two buttons, the users is presented with a choice in the second section. You should maintain that pattern with the camera choice. Just have a cell that displays a button that evokes the camera. Yes, it adds a second step but establishes a kinetic pattern for the user: Select input type in section one then select an appropriate cell in section two. The user shouldn't have to stop and think each time whether they need to hit one of the rows in section two or not. They should just do so automatically.

UItableview returns more row?

i have done like
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 3;
}
tableview is in UITableViewStylePlain.but it shows correctly 3 data on 3 tableview cell.but after that there is empty tableview cells ...but when i declared UITableViewStyleGrouped, it shows only 3 tableview cells... perfectly...what i have to do disappear empty tableview cell
in UITableViewStylePlain..any help pls?
Your table contains 3 table cells and those cells beneath it are not empty table cells. The row seperators are just drawn based on the previous row height giving the impression that there are more cells than you actually specified.
You could set the separatorStyle of the table view to UITableViewCellSeparatorStyleNone, either in code or in Interface Builder. But doing so disables the seperators all together, so you would have to draw some kind of separator yourself in your cells if you still wanted a grafical separation between the actual cells.
Another option would be to set the color of the separator to the color of the background of the table.
I myself would not worry about this if you're application has a standard table look, as it's default behaviour & users should be used to seeing that. Altough I must admit that I have set the separatorStyle to none in a previous project, because the table had a look that deviated from the standard table look. I did have to draw a fine separator line at the bottom in the table cell.

How do I set a custom cell for non databound TableCells

I am happily able to set the styling of my tableviewcells using the cellForRowAtIndexPath delegate, but I want to set the background of all the nonpopulated cells which are still on the screen
hey, basically any cell which is part of your tableview belongs to a particular index and particular row
so incase you are not populating a particular section via data source - you can still get a reference to a cell in that indexPath by manually calling the cellForRowAtIndexPath delegate, and passing the section as well as row index
it returns you a cell. assign it to your private variable and edit it the way you want to.
Use the visibleCells method on your table view. Then do what you wish to the cells.
Alternately, you could call indexPathsForVisibleRows to get just the index paths. Then call cellForRowAtIndexPath: to get the cell corresponding to each index path.