正如其他答案中提到的,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
屬性以查看單元格的contentView是否已具有手勢識別器。
當點擊單元格時,您可以訪問通過傳遞到您的方法myViewWasTapped:(UIGestureRecognizer *)sender
中的gestureRecognizer的view
屬性點擊的視圖。
另一種方法是使用委託,這是一種在iOS中傳遞信息的流行方法。如果您繼承UICollectionViewCell,則可以爲單元的「委託」聲明一個協議。基本上,這只是一個對象應該實現的所有方法的列表,如果它想成爲單元的委託的話。在你的UICollectionViewCell h文件中,你可以用下面的方式聲明協議。
@class CustomCardCollectionViewCell;
@protocol CustomCollectionViewCellDelegate <NSObject>
@required
- (void)customCollectionViewCellWasTapped:(CustomCollectionViewCell *)cell;
@end
然後在你的單元格的界面中,你會聲明一個名爲delegate的屬性(儘管你可以稱它爲任何你想要的)。代表的類型爲id
,它符合協議CustomCollectionViewCellDelegate
或您決定調用協議的任何內容。
@interface CustomCollectionViewCell : UICollectionViewCell
@property (weak, nonatomic) id<CustomCollectionViewCellDelegate> delegate;
//Other interface declaration stuffs.
@end
重要的是,UICollectionView則要設置單元格的委託財產是自己時,它會創建細胞。你可以把它看作是一個返回指針(這就是爲什麼委託屬性被聲明爲弱)到CustomCollectionViewCell的UICollectionView。
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
CustomCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:kCustomCollectionViewCellIdentifier forIndexPath:indexPath];
cell.delegate = self;
return cell;
}
委託的好處是委託不必是任何特定類型的對象,除非符合您定義的協議。因此,您不需要自定義單元來了解任何其他類。萬歲!
當單元格的手勢識別器檢測到敲擊時,您還需要記住讓單元調用它的委託方法。
[self.delegate customCollectionViewCellWasTapped:self];
跟進質詢,
如果需要檢測該小區的特定子視圖被竊聽,有解決該問題的一些方法。一種方法是將子視圖作爲UICollectionViewCell的子類中的公共屬性(可能只是readonly)公開,並將UIGestureRecognizer直接附加到該子視圖,以便僅在觸擊子視圖時觸發。假設該子視圖是指示最愛的星形按鈕。這可以通過以下方式完成。
-(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
重視它的手勢識別直接嚮明星視圖或手勢識別器連接到電池的內容查看並計算是否手勢識別的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