I am working through chapter 15 of The Big Nerd Ranch iOS Book 3rd edition, which deals with subclassing table view cells.
After creating a custom table view cell, a transparent button is added over a thumbnail image on the cell so that the image can be tapped.
Instead of writing the code that executes following the button tap inside the custom table view cell, it is explained that this code should reside in the table view controller that is controlling the table view the custom cell is part of, so as to follow MVC design.
So I add an id pointer to the custom cell that points back at the table view controller and another pointer to the table view so that the cell can obtain its own index path:
showImage: is connected up to the transparent button (not shown above as an outlet), controller is the table view's delegate view controller and tableView is the table view the cell is in.
The book then gets me to type out the following code:
I understand the reason for this to be that if this functionality is implemented this way, then the custom cell can be reused in another project because it checks to see if the necessary method is implemented. What happens when the button is tapped is handled by the delegate view controller, so that code could be different in another project and the custom cell won't care.
I have to say this all feels a bit complicated. Why could the custom cell not have a set of protocol methods that the table view controller would have to conform to? That way, the cell can just go ahead and call the protocol method showImage:atIndexPath. Better still, this method should be called imageTapped:atIndexPath, so that it is entirely generic. I can't see the worth of the first three lines of code and the performSelector line.
The book does say that this is implemented in this way so that advantage can be taken of it in later chapters, but for my own piece of mind, would the following be acceptable and offer the same benefits?
After creating a custom table view cell, a transparent button is added over a thumbnail image on the cell so that the image can be tapped.
Instead of writing the code that executes following the button tap inside the custom table view cell, it is explained that this code should reside in the table view controller that is controlling the table view the custom cell is part of, so as to follow MVC design.
So I add an id pointer to the custom cell that points back at the table view controller and another pointer to the table view so that the cell can obtain its own index path:
Code:
@interface HomepwnerItemCell : UITableViewCell
{
}
@property (weak, nonatomic) IBOutlet UIImageView *thumbnailView;
@property (weak, nonatomic) IBOutlet UILabel *nameLabel;
@property (weak, nonatomic) IBOutlet UILabel *serialNumberLabel;
@property (weak, nonatomic) IBOutlet UILabel *valueLabel;
@property (weak, nonatomic) id controller;
@property (weak, nonatomic) UITableView *tableView;
- (IBAction)showImage:(id)sender;
@end
showImage: is connected up to the transparent button (not shown above as an outlet), controller is the table view's delegate view controller and tableView is the table view the cell is in.
The book then gets me to type out the following code:
Code:
- (IBAction)showImage:(id)sender {
NSString *selector = NSStringFromSelector(_cmd);
selector = [selector stringByAppendingString:@"atIndexPath:"];
SEL newSelector = NSSelectorFromString(selector);
NSIndexPath *indexPath = [[self tableView] indexPathForCell:self];
/*[[self controller] showImage:sender
atIndexPath:indexPath];*/
if (indexPath) {
if ([[self controller] respondsToSelector:newSelector]) {
[[self controller] performSelector:newSelector withObject:sender withObject:indexPath];
}
}
}
I understand the reason for this to be that if this functionality is implemented this way, then the custom cell can be reused in another project because it checks to see if the necessary method is implemented. What happens when the button is tapped is handled by the delegate view controller, so that code could be different in another project and the custom cell won't care.
I have to say this all feels a bit complicated. Why could the custom cell not have a set of protocol methods that the table view controller would have to conform to? That way, the cell can just go ahead and call the protocol method showImage:atIndexPath. Better still, this method should be called imageTapped:atIndexPath, so that it is entirely generic. I can't see the worth of the first three lines of code and the performSelector line.
The book does say that this is implemented in this way so that advantage can be taken of it in later chapters, but for my own piece of mind, would the following be acceptable and offer the same benefits?
Code:
@protocol HomepwnerItemCellDelegateProtocol <NSObject>
@required - (void) imageTapped:(id)sender atIndexPath:(NSIndexPath *)ip;
@end
@interface HomepwnerItemCell : UITableViewCell
{
}
@property (weak, nonatomic) IBOutlet UIImageView *thumbnailView;
@property (weak, nonatomic) IBOutlet UILabel *nameLabel;
@property (weak, nonatomic) IBOutlet UILabel *serialNumberLabel;
@property (weak, nonatomic) IBOutlet UILabel *valueLabel;
@property (weak, nonatomic) id<HomepwnerItemCellDelegateProtocol> controller;
@property (weak, nonatomic) UITableView *tableView;
- (IBAction)showImage:(id)sender;
Code:
- (IBAction)showImage:(id)sender {
NSIndexPath *indexPath = [[self tableView] indexPathForCell:self];
if (indexPath) {
[[self controller] imageTapped:sender atIndexPath:indexPath];
}
}
Last edited: