Как упоминалось в других ответах, 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.
}
Почему вы хотите получить доступ к Nav BAr в ячейке? доступ в viewcontroller. – preetam
Показать код в селекторе, чтобы мы могли узнать ваше требование. – preetam
Один распознаватель жестов должен привязываться только к одному виду. – KudoCC