UICollectionView의 (하위 클래스)에 길게 누르기 제스처 인식기를 추가하는 방법을 궁금합니다. 문서에서 기본적으로 추가된다는 것을 읽었지만 방법을 알 수 없습니다.
내가하고 싶은 것은 셀을 길게 누르고 ( github에서 캘린더가 있습니다 ) 어떤 셀을 탭했는지 확인한 다음 작업을 수행합니다. 어떤 세포가 오래 눌 렸는지 알아야합니다. 이 광범위한 질문에 대해 죄송하지만 Google 또는 SO에서 더 나은 것을 찾을 수 없습니다.
답변
목표 -C
당신에 myCollectionViewController.h
파일 추가 UIGestureRecognizerDelegate
프로토콜을
@interface myCollectionViewController : UICollectionViewController<UIGestureRecognizerDelegate>
당신의 myCollectionViewController.m
파일 :
- (void)viewDidLoad
{
// attach long press gesture to collectionView
UILongPressGestureRecognizer *lpgr
= [[UILongPressGestureRecognizer alloc]
initWithTarget:self action:@selector(handleLongPress:)];
lpgr.delegate = self;
lpgr.delaysTouchesBegan = YES;
[self.collectionView addGestureRecognizer:lpgr];
}
-(void)handleLongPress:(UILongPressGestureRecognizer *)gestureRecognizer
{
if (gestureRecognizer.state != UIGestureRecognizerStateEnded) {
return;
}
CGPoint p = [gestureRecognizer locationInView:self.collectionView];
NSIndexPath *indexPath = [self.collectionView indexPathForItemAtPoint:p];
if (indexPath == nil){
NSLog(@"couldn't find index path");
} else {
// get the cell at indexPath (the one you long pressed)
UICollectionViewCell* cell =
[self.collectionView cellForItemAtIndexPath:indexPath];
// do stuff with the cell
}
}
빠른
class Some {
@objc func handleLongPress(gesture : UILongPressGestureRecognizer!) {
if gesture.state != .Ended {
return
}
let p = gesture.locationInView(self.collectionView)
if let indexPath = self.collectionView.indexPathForItemAtPoint(p) {
// get the cell at indexPath (the one you long pressed)
let cell = self.collectionView.cellForItemAtIndexPath(indexPath)
// do stuff with the cell
} else {
print("couldn't find index path")
}
}
}
let some = Some()
let lpgr = UILongPressGestureRecognizer(target: some, action: #selector(Some.handleLongPress))
스위프트 4
class Some {
@objc func handleLongPress(gesture : UILongPressGestureRecognizer!) {
if gesture.state != .ended {
return
}
let p = gesture.location(in: self.collectionView)
if let indexPath = self.collectionView.indexPathForItem(at: p) {
// get the cell at indexPath (the one you long pressed)
let cell = self.collectionView.cellForItem(at: indexPath)
// do stuff with the cell
} else {
print("couldn't find index path")
}
}
}
let some = Some()
let lpgr = UILongPressGestureRecognizer(target: some, action: #selector(Some.handleLongPress))
답변
Swift에 대한 동일한 코드 @abbood의 코드 :
viewDidLoad에서 :
let lpgr : UILongPressGestureRecognizer = UILongPressGestureRecognizer(target: self, action: "handleLongPress:")
lpgr.minimumPressDuration = 0.5
lpgr.delegate = self
lpgr.delaysTouchesBegan = true
self.collectionView?.addGestureRecognizer(lpgr)
그리고 기능 :
func handleLongPress(gestureRecognizer : UILongPressGestureRecognizer){
if (gestureRecognizer.state != UIGestureRecognizerState.Ended){
return
}
let p = gestureRecognizer.locationInView(self.collectionView)
if let indexPath : NSIndexPath = (self.collectionView?.indexPathForItemAtPoint(p))!{
//do whatever you need to do
}
}
대표자를 잊지 마세요 UIGestureRecognizerDelegate
답변
UICollectionView의 대리자를 사용하여 길게 누르기 이벤트 수신
아래 3 가지 방법을 단순화해야합니다.
//UICollectionView menu delegate
- (BOOL)collectionView:(UICollectionView *)collectionView shouldShowMenuForItemAtIndexPath:(NSIndexPath *)indexPath{
//Do something
return YES;
}
- (BOOL)collectionView:(UICollectionView *)collectionView canPerformAction:(SEL)action forItemAtIndexPath:(NSIndexPath *)indexPath withSender:(nullable id)sender{
//do nothing
return NO;
}
- (void)collectionView:(UICollectionView *)collectionView performAction:(SEL)action forItemAtIndexPath:(NSIndexPath *)indexPath withSender:(nullable id)sender{
//do nothing
}
답변
여기 답변은 올바른 인식 사용자 정의 길게 누르 제스처 추가 그러나 문서에 따라 여기를 :의 부모 클래스 UICollectionView
클래스가 설치 default long-press gesture recognizer
당신이 당신의 콜렉션 뷰와 관련된 기본 인식에 사용자 정의 탭 제스처 인식기를 연결해야합니다 있도록 스크롤 상호 작용을 처리합니다.
다음 코드는 사용자 정의 제스처 인식기가 기본 인식기를 방해하지 않도록합니다.
UILongPressGestureRecognizer* longPressGesture = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(handleLongPressGesture:)];
longPressGesture.minimumPressDuration = .5; //seconds
longPressGesture.delegate = self;
// Make the default gesture recognizer wait until the custom one fails.
for (UIGestureRecognizer* aRecognizer in [self.collectionView gestureRecognizers]) {
if ([aRecognizer isKindOfClass:[UILongPressGestureRecognizer class]])
[aRecognizer requireGestureRecognizerToFail:longPressGesture];
}
답변
UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPress:)];
[cell addGestureRecognizer:longPress];
다음과 같은 방법을 추가하십시오.
- (void)longPress:(UILongPressGestureRecognizer*)gesture
{
if ( gesture.state == UIGestureRecognizerStateEnded ) {
UICollectionViewCell *cellLongPressed = (UICollectionViewCell *) gesture.view;
}
}
답변
외부 제스처 인식기를 갖고 UICollectionView에서 내부 제스처 인식기와 충돌하지 않으려면 다음을 수행해야합니다.
제스처 인식기를 추가하고 설정하고 어딘가에 대한 참조를 캡처합니다 (UICollectionView를 서브 클래 싱 한 경우 가장 좋은 옵션은 서브 클래스에 있습니다).
@interface UICollectionViewSubclass : UICollectionView <UIGestureRecognizerDelegate>
@property (strong, nonatomic, readonly) UILongPressGestureRecognizer *longPressGestureRecognizer;
@end
기본 초기화 방법을 재정의 initWithFrame:collectionViewLayout:
하고 initWithCoder:
길게 누르기 제스처 인식기에 대한 설정 방법 추가
@implementation UICollectionViewSubclass
-(instancetype)initWithFrame:(CGRect)frame collectionViewLayout:(UICollectionViewLayout *)layout
{
if (self = [super initWithFrame:frame collectionViewLayout:layout]) {
[self setupLongPressGestureRecognizer];
}
return self;
}
-(instancetype)initWithCoder:(NSCoder *)aDecoder
{
if (self = [super initWithCoder:aDecoder]) {
[self setupLongPressGestureRecognizer];
}
return self;
}
@end
길게 누르기 제스처 인식기를 인스턴스화하고, 대리자를 설정하고, UICollectionView 제스처 인식기를 사용하여 종속성을 설정하도록 설정 메서드를 작성하고 (따라서 기본 제스처가되고 다른 모든 제스처는 해당 제스처가 인식되기 전에 실패 할 때까지 기다림)보기에 제스처를 추가합니다.
-(void)setupLongPressGestureRecognizer
{
_longPressGestureRecognizer = [[UILongPressGestureRecognizer alloc] initWithTarget:self
action:@selector(handleLongPressGesture:)];
_longPressGestureRecognizer.delegate = self;
for (UIGestureRecognizer *gestureRecognizer in self.collectionView.gestureRecognizers) {
if ([gestureRecognizer isKindOfClass:[UILongPressGestureRecognizer class]]) {
[gestureRecognizer requireGestureRecognizerToFail:_longPressGestureRecognizer];
}
}
[self.collectionView addGestureRecognizer:_longPressGestureRecognizer];
}
또한 해당 제스처에 실패하고 동시 인식을 허용하는 UIGestureRecognizerDelegate 메서드를 구현하는 것을 잊지 마십시오 (구현할 필요가있을 수도 있고 필요하지 않을 수도 있으며, 보유한 다른 제스처 인식기 또는 내부 제스처 인식기와의 종속성에 따라 다름).
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
if ([self.longPressGestureRecognizer isEqual:gestureRecognizer]) {
return NO;
}
return NO;
}
이에 대한 자격 증명은 LXReorderableCollectionViewFlowLayout의 내부 구현으로 이동합니다.
답변
스위프트 5 :
private func setupLongGestureRecognizerOnCollection() {
let longPressedGesture = UILongPressGestureRecognizer(target: self, action: #selector(handleLongPress(gestureRecognizer:)))
longPressedGesture.minimumPressDuration = 0.5
longPressedGesture.delegate = self
longPressedGesture.delaysTouchesBegan = true
collectionView?.addGestureRecognizer(longPressedGesture)
}
@objc func handleLongPress(gestureRecognizer: UILongPressGestureRecognizer) {
if (gestureRecognizer.state != .began) {
return
}
let p = gestureRecognizer.location(in: collectionView)
if let indexPath = collectionView?.indexPathForItem(at: p) {
print("Long press at item: \(indexPath.row)")
}
}
또한 UIGestureRecognizerDelegate를 구현하고 viewDidLoad 또는 호출이 필요한 곳에서 setupLongGestureRecognizerOnCollection을 호출하는 것을 잊지 마십시오.