Saturday, August 23, 2014

Reuse a UITableViewCell in multiple UITableViewControllers: Xib + Stroyboard

My project has two UITableViewController that will display two kinds of articles. The detailed article content will be displayed in a UIWebView(See the Figure below).
Using prototype cells in a stroyboard would cause a little duplication. You need to duplicate the prototype cells in the two UITableViews. One day in the future, if you need to change the style of the Cell, then you have to that twice(at least you have copy the prototype cell from one UITableViewController to the other). The combination of Xib and Stroyboard can solve this problem elegantly. Here is what I did:

  • Create an empty Xib and add a UITableViewCell into it.
    Design your Cell with whatever format you need in the Xib.
    Set the identifier of this cell as: "RNArticleCellID-1img"
  • Delete the Prototype Cells from The UITableView, set the row height as that defined in Xib
  • Create segue.
    Segue should be linked from the ParentVC to the DestinationVC (NOT from the Prototype Cell)
    Set the identifier of the segue as: "
    ShowArticleDetailFromCoach" and style as: "push"
  • Move to the implementation of the UITablveViewContllers.
    add the following code section to: 
    viewDidLoad
    [self.tableView registerNib:[UINib nibWithNibName:@"RNArticleCell-1img" bundle:[NSBundle mainBundle]] forCellReuseIdentifier:@"RNArticleCellID-1img"];

get the cell:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{

    RNArticleTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"RNArticleCellID-1img" forIndexPath:indexPath];

Note that if you define the segue to go from the TableView instead of the cell, the segue will not be triggered by clicking on a cell. What you can do in this case is to use the didSelectRowAtIndexPath method and trigger the segue manually there. For example, add the following code segment:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    [self performSegueWithIdentifier:@"ShowArticleDetailFromCoach" sender:self];
}

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    if([segue.identifier isEqualToString:@"ShowArticleDetailFromCoach"]) {
        // Get the new view controller using [segue destinationViewController].
        // Pass the selected object to the new view controller.
        RNArticleDetailVC *articleVC = [segue destinationViewController];
        NSIndexPath *path = [self.tableView indexPathForSelectedRow];
        NSInteger row = path.row;
        articleVC.articleDict = [self.articles objectAtIndex:row];
        articleVC.sourceName = @"managershare";
    }
}




No comments: