2014-02-15 2 views
1

У меня простая ситуация. UICollectionView и обычай UICollectionViewCell. У UICollectionView есть панель навигации. Пользовательская ячейка имеет изображение. Я хочу нажать второй контроллер в стек навигации, когда нажимается изображение. Я добавил жестов жесты к изображению внутри пользовательского представления. Как я могу получить доступ к панели навигации в родительском контроллере из ячейки? Или я должен добавить жест нажатия на ссылку на UICollectionView, а не на ячейку UICollectionViewCell?как разговаривать с точки зрения диспетчера с жесты крана

self.templateImage.userInteractionEnabled = YES; 
self.userInteractionEnabled = YES; 
UITapGestureRecognizer *tapGestureRecog = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleSelect:)]; 
[self.templateImage addGestureRecognizer:tapGestureRecog]; 
[self addGestureRecognizer:tapGestureRecog]; 

templateImage - изображение внутри ячейки. Этот код вызывается внутри метода initWithCoderUICollectionViewCell. Поэтому, я думаю, мой вопрос заключается в том, как получить доступ к контроллеру из представления. Обычно это делается с помощью IBAction. Новичок для iOS :)

+0

Почему вы хотите получить доступ к Nav BAr в ячейке? доступ в viewcontroller. – preetam

+0

Показать код в селекторе, чтобы мы могли узнать ваше требование. – preetam

+3

Один распознаватель жестов должен привязываться только к одному виду. – KudoCC

ответ

1

Как упоминалось в других ответах, you can only attach a gesture recognizer to one view.

Вы всегда могли иметь UICollectionView добавить жест распознаватель на вид коллекции ячейки в cellForItemAtIndexPath:

-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{ 
    CustomCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:kCustomCollectionViewCellIdentifier forIndexPath:indexPath]; 
    if (cell.contentView.gestureRecognizers.count == 0) { 
     [cell.contentView addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(myViewWasTapped:)]]; 
    } 

    return cell; 
} 

Если вы идете с этим подходом, вы должны убедиться, что вы не постоянно добавлять жест распознавателей в той же ячейки, если ячейка повторно используется. Вы можете проверить свойство gestureRecognizers вида, чтобы узнать, имеет ли контент cellView уже распознаватель жестов.

Когда ячейка подключена, вы можете получить доступ к представлению, которое было использовано через свойство view объекта gestureRecognizer, переданного вашему методу myViewWasTapped:(UIGestureRecognizer *)sender.

Другой способ сделать это с помощью делегирования - популярного метода передачи информации в iOS. Если вы подклассифицируете UICollectionViewCell, вы можете объявить протокол для «делегата» ячейки. Это, в основном, просто список всех методов, которые должен реализовать объект, если он хочет быть делегатом ячейки. В файле UICollectionViewCell h вы можете объявить протокол следующим образом.

@class CustomCardCollectionViewCell; 

@protocol CustomCollectionViewCellDelegate <NSObject> 
@required 
- (void)customCollectionViewCellWasTapped:(CustomCollectionViewCell *)cell; 
@end 

Тогда в интерфейсе вашей камеры вы объявите свойство, называемое делегатом (хотя вы можете называть его, как хотите). Делегат имеет тип id, который соответствует протоколу CustomCollectionViewCellDelegate или тому, что вы решите назвать своим протоколом.

@interface CustomCollectionViewCell : UICollectionViewCell 
    @property (weak, nonatomic) id<CustomCollectionViewCellDelegate> delegate; 

    //Other interface declaration stuffs. 
@end 

Важно отметить, что UICollectionView придется установить делегат свойство ячейки быть самим собой, когда он создает ячейку. Вы можете думать об этом как обратном указателе (поэтому свойство делегата объявляется слабым) в UICollectionView из CustomCollectionViewCell.

-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{ 
    CustomCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:kCustomCollectionViewCellIdentifier forIndexPath:indexPath]; 
    cell.delegate = self; 

    return cell; 
} 

Преимущество делегации в том, что делегат не должен быть каким-либо конкретным типом объекта, за исключением одного, который соответствует протоколу, который вы определили. Поэтому вам не нужна настраиваемая ячейка, чтобы знать о каких-либо других классах. Ура!

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

[self.delegate customCollectionViewCellWasTapped:self]; 

ПОСЛЕДУЮЩЕГО ВОПРОС

Если вам нужно определить, что конкретные подтаблицы клетки прослушивались, есть несколько способов решения этой проблемы. Один из способов заключается в том, чтобы открыть subview как общедоступное свойство (возможно, по-видимому) в вашем подклассе UICollectionViewCell и подключить UIGestureRecognizer непосредственно к этому подзону, чтобы он срабатывал только при прослушивании subview. Предположим, что subview - это кнопка «звезда», указывающая на фаворита. Это может быть выполнено следующим образом.

-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{ 
    CustomCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:kCustomCollectionViewCellIdentifier forIndexPath:indexPath]; 
    if (cell.contentView.gestureRecognizers.count == 0) { 
     [cell.starView addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(starWasTapped:)]]; 
    } 

    return cell; 
} 

Вы также можете добавить метод делегата к вашему протоколу делегата. Что-то вроде

- (void)customCollectionCell:(CustomCollectionViewCell *)cell starViewWasTapped:(UIView *)starView 

Если вы идете с этим методом, вы можете либо иметь CustomCollectionViewCell прикрепить это жест распознаватель непосредственно к просмотру звезды, или прикрепить жест распознаватель к contentView клетки и вычислить ли locationInView этот жест распознаватель в попадает в рамки starView.

Вам следует избегать добавления распознавателя жестов в представление контента, а UICollectionView вычисляет местоположение касания внутри ячейки, чтобы определить, была ли выбрана звезда. Причина в том, что для этого потребуется, чтобы UICollectionView знал о местонахождении звезды в contentView ячейки. Каждое представление должно отвечать за местоположение его подзонов.

Если звезда была UIButton, вы можете полностью отказаться от UIGestureRecognizer, установив свойство тега на кнопку и, используя UICollectionView, добавьте ее как цель на кнопку. Затем вы можете указать, на какой кнопке была выведена ячейка, проверяя свойство тега кнопки, которая отправляется с действием.

-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{ 
    CustomCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:kCustomCollectionViewCellIdentifier forIndexPath:indexPath]; 
    [cell.starButton addTarget:self action:@selector(starButtonWasTapped:) forControlEvents:UIControlEventTouchUpInside]; 
    cell.starButton.tag = indexPath.row; 

    return cell; 
} 

- (void)starButtonWasTapped:(UIButton *)starButton { 
    //Do something based off of the tag of the button. 
} 
+1

Хороший ответ! Я бы добавил условие, чтобы увидеть, есть ли фактический 'делегат', и если он реализовал этот метод, просто чтобы избежать сбоя. – jbouaziz

+0

Проверка того, есть ли делегат, не требуется, поскольку отправка сообщения в nil ничего не делает в Objective C и поэтому не приведет к сбою. Возможно, было бы хорошо проверить, соответствует ли объект селектору, но метод был объявлен '@ required', поэтому вам может потребоваться ошибка, если делегат фактически не реализует метод, объявленный как необходимый. –

+0

Спасибо @TylerCloutier. Дальнейший вопрос: если прецедент должен был распознать кран для конкретного подсмотра в ячейке. Например, если в ячейке есть звездочка, которая отмечает ячейку в качестве избранного, мне нужно будет определить, была ли нажата звезда или что-то еще в ячейке. Будет ли одно решение состоять в том, чтобы получить местоположение отвода от распознавателя, а затем посмотреть, попадает ли он в рамки/границы звезды. Если это так, звезда была постучана. В моем случае изображение занимает всю ячейку, поэтому ваш предыдущий ответ работает. Но я обобщаю ради обучения. Спасибо ! –

Смежные вопросы