답변:
먼저 길게 누르기 제스처 인식기를 테이블보기에 추가하십시오.
UILongPressGestureRecognizer *lpgr = [[UILongPressGestureRecognizer alloc]
initWithTarget:self action:@selector(handleLongPress:)];
lpgr.minimumPressDuration = 2.0; //seconds
lpgr.delegate = self;
[self.myTableView addGestureRecognizer:lpgr];
[lpgr release];
그런 다음 제스처 핸들러에서 :
-(void)handleLongPress:(UILongPressGestureRecognizer *)gestureRecognizer
{
CGPoint p = [gestureRecognizer locationInView:self.myTableView];
NSIndexPath *indexPath = [self.myTableView indexPathForRowAtPoint:p];
if (indexPath == nil) {
NSLog(@"long press on table view but not on a row");
} else if (gestureRecognizer.state == UIGestureRecognizerStateBegan) {
NSLog(@"long press on table view at row %ld", indexPath.row);
} else {
NSLog(@"gestureRecognizer.state = %ld", gestureRecognizer.state);
}
}
사용자가 셀을 정상적으로 두드리는 것을 방해하지 않도록 handleLongPress
여러 번 주의해야합니다 (또한 동작 인식기 상태 변경으로 인해 발생 함).
if (gestureRecognizer.state == UIGestureRecognizerStateBegan) ...
.
UITableView
이 아니라 UITableViewCell
...)
Anna-Karenina의 답변을 사용했으며 매우 심각한 버그로 거의 작동합니다.
섹션을 사용하는 경우 섹션 제목을 길게 누르면 해당 섹션의 첫 번째 행을 눌렀을 때 잘못된 결과를 얻을 수 있습니다. 아래에 고정 버전을 추가했습니다 (제스처 상태에 따라 더미 통화 필터링 포함). Anna-Karenina 제안).
- (IBAction)handleLongPress:(UILongPressGestureRecognizer *)gestureRecognizer
{
if (gestureRecognizer.state == UIGestureRecognizerStateBegan) {
CGPoint p = [gestureRecognizer locationInView:self.tableView];
NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:p];
if (indexPath == nil) {
NSLog(@"long press on table view but not on a row");
} else {
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
if (cell.isHighlighted) {
NSLog(@"long press on table view at section %d row %d", indexPath.section, indexPath.row);
}
}
}
}
Swift 5의 답변 (Swift에서 Ricky의 답변 계속)
UIGestureRecognizerDelegate
ViewController에 추가
override func viewDidLoad() {
super.viewDidLoad()
//Long Press
let longPressGesture = UILongPressGestureRecognizer(target: self, action: #selector(handleLongPress))
longPressGesture.minimumPressDuration = 0.5
self.tableView.addGestureRecognizer(longPressGesture)
}
그리고 기능 :
@objc func handleLongPress(longPressGesture: UILongPressGestureRecognizer) {
let p = longPressGesture.location(in: self.tableView)
let indexPath = self.tableView.indexPathForRow(at: p)
if indexPath == nil {
print("Long press on table view, not row.")
} else if longPressGesture.state == UIGestureRecognizer.State.began {
print("Long press on row, at \(indexPath!.row)")
}
}
Dawn Song의 답변과 Marmor의 답변을 결합한 명확한 지침이 있습니다.
길게 누르는 제스처 인식기를 끌어 테이블 셀에 놓으십시오. 왼쪽 목록의 맨 아래로 이동합니다.
그런 다음 단추를 연결하는 것과 같은 방식으로 동작 인식기를 연결하십시오.
액션 핸들러에서 Marmor의 코드 추가
- (IBAction)handleLongPress:(UILongPressGestureRecognizer *)sender {
if (sender.state == UIGestureRecognizerStateBegan) {
CGPoint p = [sender locationInView:self.tableView];
NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:p];
if (indexPath == nil) {
NSLog(@"long press on table view but not on a row");
} else {
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
if (cell.isHighlighted) {
NSLog(@"long press on table view at section %d row %d", indexPath.section, indexPath.row);
}
}
}
}
스위프트 답변 :
대리인 추가 UIGestureRecognizerDelegate
UITableViewController에 를 하십시오.
UITableViewController 내에서 :
override func viewDidLoad() {
super.viewDidLoad()
let longPressGesture:UILongPressGestureRecognizer = UILongPressGestureRecognizer(target: self, action: "handleLongPress:")
longPressGesture.minimumPressDuration = 1.0 // 1 second press
longPressGesture.delegate = self
self.tableView.addGestureRecognizer(longPressGesture)
}
그리고 기능 :
func handleLongPress(longPressGesture:UILongPressGestureRecognizer) {
let p = longPressGesture.locationInView(self.tableView)
let indexPath = self.tableView.indexPathForRowAtPoint(p)
if indexPath == nil {
print("Long press on table view, not row.")
}
else if (longPressGesture.state == UIGestureRecognizerState.Began) {
print("Long press on row, at \(indexPath!.row)")
}
}
Anna Karenina의 훌륭한 답변을 기반으로 UITableView에 작은 범주를 구성했습니다.
이와 같이 일반 테이블 뷰를 처리 할 때 익숙한 편리한 델리게이트 메소드가 있습니다. 확인 해봐:
// UITableView+LongPress.h
#import <UIKit/UIKit.h>
@protocol UITableViewDelegateLongPress;
@interface UITableView (LongPress) <UIGestureRecognizerDelegate>
@property(nonatomic,assign) id <UITableViewDelegateLongPress> delegate;
- (void)addLongPressRecognizer;
@end
@protocol UITableViewDelegateLongPress <UITableViewDelegate>
- (void)tableView:(UITableView *)tableView didRecognizeLongPressOnRowAtIndexPath:(NSIndexPath *)indexPath;
@end
// UITableView+LongPress.m
#import "UITableView+LongPress.h"
@implementation UITableView (LongPress)
@dynamic delegate;
- (void)addLongPressRecognizer {
UILongPressGestureRecognizer *lpgr = [[UILongPressGestureRecognizer alloc]
initWithTarget:self action:@selector(handleLongPress:)];
lpgr.minimumPressDuration = 1.2; //seconds
lpgr.delegate = self;
[self addGestureRecognizer:lpgr];
}
- (void)handleLongPress:(UILongPressGestureRecognizer *)gestureRecognizer
{
CGPoint p = [gestureRecognizer locationInView:self];
NSIndexPath *indexPath = [self indexPathForRowAtPoint:p];
if (indexPath == nil) {
NSLog(@"long press on table view but not on a row");
}
else {
if (gestureRecognizer.state == UIGestureRecognizerStateBegan) {
// I am not sure why I need to cast here. But it seems to be alright.
[(id<UITableViewDelegateLongPress>)self.delegate tableView:self didRecognizeLongPressOnRowAtIndexPath:indexPath];
}
}
}
UITableViewController에서 이것을 사용하려면 새로운 프로토콜을 서브 클래스 화하고 준수해야 할 것입니다.
그것은 나를 위해 잘 작동합니다, 그것이 다른 사람들을 돕기를 바랍니다!
Swift 3 답변, 최신 구문 사용, 다른 답변 통합 및 불필요한 코드 제거.
override func viewDidLoad() {
super.viewDidLoad()
let recognizer = UILongPressGestureRecognizer(target: self, action: #selector(tablePressed))
tableView.addGestureRecognizer(recognizer)
}
@IBAction func tablePressed(_ recognizer: UILongPressGestureRecognizer) {
let point = recognizer.location(in: tableView)
guard recognizer.state == .began,
let indexPath = tableView.indexPathForRow(at: point),
let cell = tableView.cellForRow(at: indexPath),
cell.isHighlighted
else {
return
}
// TODO
}
스토리 보드의 지정된 프로토 타입 셀에 UILongPressGestureRecognizer를 추가 한 다음 viewController의 .m 파일로 제스처를 끌어 액션 메소드를 만듭니다. 내가 말한대로 만들었습니다.
touchesBegan에서 UITouch 타임 스탬프 속성을 사용하여 타이머를 시작하거나 touchesEnded가 시작될 때 타이머를 중지