UITableView, replace cell view with select

Can I replace the cell view for the selected cell? I registered my controller as a data source and delegate. Requests for viewing cells, line numbers, selection status, etc. - everything is fine. In cell selection callbacks, I try to have the table view reload the cell with the new view (and not the actual data!). Basically, I want the cell view to expand and display more baseline data if selected. The problem is that I have no idea how to make the table view request my controller for a new view. I see that the view asks for the height of the cell, but nothing more.

Calling reloadData in a view works, but it is inefficient and comes with a set of its own problems (animation capabilities, saving selection state, etc.).

+6
source share
2 answers

This is the approach I would take for this.

@property (nonatomic, strong) NSIndexPath *selectedIndexPath; 

Set a property of type NSIndexPath for your controller to save the selected pointer path.

 - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { self.selectedIndexPath = indexPath; [tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation: UITableViewRowAnimationNone]; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { if ([indexPath compare:self.selectedIndexPath] == NSOrderedSame) { // Create your custom cell here and return it. } else { // Should create a normal cell and return it. } } 

That's right. Also note that you probably want to deselect. Here's the full code in Swift. Use selectIndexPath in cellForRowAtIndexPath if necessary.

// Select TableViewController import UIKit

class SelectingTableViewController: UITableViewController
{internal var selectedIndexPath: NSIndexPath? = nil

 override func viewDidLoad() { super.viewDidLoad() tableView.estimatedRowHeight = 68.0 tableView.rowHeight = UITableViewAutomaticDimension self.clearsSelectionOnViewWillAppear = false; } override func tableView (tableView:UITableView, didSelectRowAtIndexPath indexPath:NSIndexPath) { print("did select....") // in fact, was this very row selected, // and the user is clicking to deselect it... // if you don't want "click a selected row to deselect" // then on't include this clause. if selectedIndexPath == indexPath { print("(user clicked on selected to deselect)") selectedIndexPath = nil tableView.reloadRowsAtIndexPaths( [indexPath], withRowAnimation:UITableViewRowAnimation.None) tableView.deselectRowAtIndexPath(indexPath, animated:false) return } // in fact, was some other row selected?? // user is changing to this row? if so, also deselect that row if selectedIndexPath != nil { let pleaseRedrawMe = selectedIndexPath! // (note that it will be drawn un-selected // since we're chaging the 'selectedIndexPath' global) selectedIndexPath = indexPath tableView.reloadRowsAtIndexPaths( [pleaseRedrawMe, indexPath], withRowAnimation:UITableViewRowAnimation.None) return; } // no previous selection. // simply select that new one the user just touched. // note that you can not use Apple willDeselectRowAtIndexPath // functions ... because they are freaky selectedIndexPath = indexPath tableView.reloadRowsAtIndexPaths( [indexPath], withRowAnimation:UITableViewRowAnimation.None) } } 
+14
source

You tried:

 - (void)reloadRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation 

Then you can specify only the updated cell to reload. You can also indicate that your table view remembers or forgets the selection status after a reboot:

 tableViewController.clearsSelectionOnViewWillAppear = NO; 

Then you will also have to deal with custom view inside

 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
+2
source

All Articles