Reputation: 179
I have a UITableViewController
that has custom cells that I have customized with my own subclass.
In this subclass, I've added a button and I want to push a view into the stack of the navigation controller. I have no idea on how to do that since I don't know how I can access to the navigation controller from my custom cell.
Any idea?
Upvotes: 2
Views: 5032
Reputation: 33428
Use delegation. Here a simple example.
//.h
@protocol MyTableViewCellDelegate;
@interface MyTableViewCell : UITableViewCell
@property (assign, nonatomic) id <MyTableViewCellDelegate> delegate;
//your code here
@end
@protocol MyTableViewCellDelegate <NSObject>
@optional
- (void)delegateForCell:(MyTableViewCell *)cell;
@end
//.m
@implementation MyTableViewCell
@synthesize delegate = _delegate;
- (void)prepareForReuse {
[super prepareForReuse];
self.delegate = nil;
}
- (void)buttonAction {
if ([self.delegate respondsToSelector:@selector(delegateForCell:)])
[self.delegate delegateForCell:self];
}
@end
When you click the button you send a message to the delegate for your cell (e.g. the table view controller that is inserted into the navigation controller).
Here the controller
@implementation YourController
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *reuseIdentifier = @"MyCustomCell";
MyTableViewCell *cell = (id)[tableView dequeueReusableCellWithIdentifier:reuseIdentifier];
if (cell == nil)
cell = [[[MyTableViewCell alloc] initWithMyArgument:someArgument reuseIdentifier:reuseIdentifier] autorelease];
[cell setDelegate:self];
// update your cell
return cell;
}
- (void)delegateForCell:(MyTableViewCell *)cell {
NSIndexPath *indexPath = [self.tableView indexPathForCell:cell];
// do your stuff
[self.navigationController pushViewController:...];
}
@end
Upvotes: 5
Reputation: 9977
Need more infos here. What class holds the table, what class is the tableview delegate?
In the most simple case you're working in one single class. Than it would be [self.navigationController pushViewController: xyz]
.
But if you have your own subclassed UITableViewCells, than you need to communicate between the cell class and the viewcontroller. You could do this via setting a property in the cell class or your own customCell delegate.
You could also just send a Notification ([[NSNotificationCenter defaultCenter] postNotification: @"cellButtonTouchedNotification"]
) on which your viewController is listening ([[NSNotificationCenter defaultCenter] addListener: self target: @selector(...) name: @"cellButtonTouchedNotification"]
). In this case you could use the userInfo property to remember which cell was touched.
Anotherway is to make the button accessible from outside (a property eg). Then you could add the target in your tableViewDelegate's method cellForRowAtIndexPath:
. Smth. like [myCustomCell.button addTarget: self selector: @selector(...)];
You could use tags to identify the row myCustomCell.button.tag = indexPath.row
.
Upvotes: 5
Reputation: 13192
Hold a pointer to your UITableViewController in the cell. You can pass it in the cell's constructor or set it later. Then you can call the pushViewController on the table view controller.
Even more beautiful solution would be to define a delegate for your cell, say ButtonCellDelegate that has a buttonClicked callback. You implement the delegate in your UITableViewController (or any other place where you have access to the view controller). Then you pass the delegate to the cell as described above and call the callback function from the cell when the button is clicked.
Upvotes: 0