2012-05-12 2 views
0

Есть ли способ получить ссылку на контроллер вида моего наблюдения? Было несколько случаев, когда мне это понадобилось последние пару месяцев, но я не знал, как это сделать. Я имею в виду, если у меня есть пользовательская кнопка в пользовательской ячейке, и я хочу получить ссылку на контроллер табличного представления, который управляет ячейкой, в которой я сейчас вхожу, есть ли для этого фрагмент кода? Или это то, что я должен просто решить, используя лучшие шаблоны дизайна?Как получить ссылку на контроллер просмотра супервизора?

Спасибо!

ответ

0

Когда я задал этот вопрос, я имел в виду, в ситуации, когда у меня есть пользовательские ячейки с помощью кнопок на них, как может TableViewController знать, какие кнопки ячейки прослушивался. Совсем недавно, читая книгу «IOS рецепты», я получил решение:

-(IBAction)cellButtonTapped:(id)sender 
{ 
NSLog(@"%s", __FUNCTION__); 
UIButton *button = sender; 

//Convert the tapped point to the tableView coordinate system 
CGPoint correctedPoint = [button convertPoint:button.bounds.origin toView:self.tableView]; 

//Get the cell at that point 
NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:correctedPoint]; 

NSLog(@"Button tapped in row %d", indexPath.row); 
} 

Другого решения, немного более хрупкие (хотя проще) будет:

- (IBAction)cellButtonTapped:(id)sender 
{ 
    // Go get the enclosing cell manually 
    UITableViewCell *parentCell = [[sender superview] superview]; 
    NSIndexPath *pathForButton = [self.tableView indexPathForCell:parentCell]; 
} 

И самым многоразовые один можно было бы добавить этот метод к категории UITableView

- (NSIndexPath *)prp_indexPathForRowContainingView:(UIView *)view 
{ 
    CGPoint correctedPoint = [view convertPoint:view.bounds.origin toView:self]; 
    return [self indexPathForRowAtPoint:correctedPoint]; 
} 

А потом, на классе UITableViewController, просто используйте:

- (IBAction)cellButtonTapped:(id)sender 
{ 
    NSIndexPath *pathForButton = [self.tableView indexPathForRowContainingView:sender]; 
} 
3

Ваша кнопка должна предпочтительно не знать о контроллере вида наблюдения.

Однако, если вашей кнопке действительно нужны объекты сообщений, о которых она не должна знать подробностей, вы можете использовать делегирование для отправки сообщений, которые вы хотите передать делегатам.

Создайте протокол MyButtonDelegate и определите методы, которые необходимо реализовать всем, кто соответствует этому протоколу (обратный вызов). У вас также могут быть дополнительные методы.

Затем добавьте свойство на кнопку @property (weak) id<MyButtonDelegate>, чтобы любой класс любого типа мог быть установлен как делегат, если он соответствует вашему протоколу.

Теперь контроллер вида может реализовать протокол MyButtonDelegate и установить себя как делегат. Части кода, требующие знания о контроллере представления, должны быть реализованы в методе делегирования (или методах).

Теперь представление теперь может отправлять сообщения протокола своему делегату (не зная, кто и что это), и делегат может выбрать подходящую вещь для этой кнопки. Таким образом, можно использовать одну и ту же кнопку, потому что она не зависит от того, где она используется.

+3

Пятно на. Проблема номер один, которая, как я вижу, обычно нарушается, заключается в «разделении проблем». –

+0

Спасибо, Дэвид! Ваш ответ также заставило меня понять больше о шаблоне делегирования и свободной связи в iOS для создания кода многократного использования. – Giovanni

-1

Если вы знаете, какой класс является надзором вашего контроллера вида, вы можете просто перебирать массив subviews и typecheck для вашего суперкласса.

например.

UIView *view; 

for(tempView in self.subviews) { 

    if([tempView isKindOfClass:[SuperViewController class] ]) 

     { 
      // you got the reference, do waht you want 

     } 


    }