I've got two classes. One is for ItemController
(extends UITableViewController
) and another is ItemCell
(extends 'UITableViewCell').
When each cell is clicked I push a new controller from within ItemController
's didSelectRowAtIndexPath
.
Additionally, in ItemCell
, I've got couple of small buttons with different tag
for each cell. When any of these buttons are clicked I want to push a new controller. How can I do this?
self.navigationController.pushViewController
from ItemCell
doesn't work since it doesn't have navigationController
I would prefer to see a solution in RubyMotion but if not, thats fine too :)
Edit
I've read that delegate
can be a solution but I'm not sure how to implement it. This is what I've done
ItemController:
def tableView(table_view, cellForRowAtIndexPath: index_path)
data_row = self.data[index_path.row]
cell = table_view.dequeueReusableCellWithIdentifier(CATEGORY_CELL_ID) || begin
rmq.create(ItemCell.initWithSomething(self), :category_cell, reuse_identifier: CATEGORY_CELL_ID).get
end
cell.update(data_row)
cell
end
ItemCell:
class ItemCell < UITableViewCell
attr_accessor :delegate
def initWithSomething(delegate)
@delegate = delegate
end
...use @delegate to push the new controller
end
but I get an error
item_controller.rb:114:in
tableView:cellForRowAtIndexPath:': undefined method
initWithSomething' for ItemCell:Class (NoMethodError)
The general idea is that you cell should tell your view controller that something happened and than is the View Controller that will decided to push the other View Controller.
You can do that with the delegate design pattern:
ItemCell
has a delegate
property that conform to a protocol. For example
@class ItemCell
@protocol ItemCellDelegate
- (void)itemCellDidClickSubmitButton:(ItemCell *)cell;
@end
@interface ItemCell
@property (nonatomic, weak) id<ItemCellDelegate> delegate
...
@end
In tableView:cellForRowAtIndexPath:
you will set the controller as the cell delegate (obviously the view controller should conform to the ItemCellDelegate
):
cell.delegate = self
The button on your cell will trigger an IBAction on the cell itself that in turn will call the delegate method
- (IBAction)submitButtonTapped:(id)sender
{
id <ItemCellDelegate> delegate = self.delegate;
if ([delegate respondToSelector:@selector(itemCellDidClickSubmitButton:)]) {
[delegate itemCellDidClickSubmitButton:self];
}
}
And obviously in your View Controller you should do something like:
#pragma mark - ItemCellDelegate
- (void)itemCellDidClickSubmitButton:(ItemCell)cell
{
UIViewController *controller = // Create the view controller to push
[self.navigationController pushViewController:controller];
}