버튼을 누를 때 UITableView 셀 행 가져 오기


84

셀 행을 표시하는 tableview 컨트롤러가 있습니다. 각 셀에는 3 개의 버튼이 있습니다. 각 셀의 태그 번호를 1,2,3으로 지정했습니다. 문제는 버튼이 눌러지는 셀을 찾는 방법을 모른다는 것입니다. 나는 현재 버튼 중 하나를 눌렀을 때만 보낸 사람의 태그를 받고 있습니다. 버튼을 눌렀을 때 셀 행 번호를 얻는 방법이 있습니까?

답변:


278

대신이 방법을 사용해야합니다.

CGPoint buttonPosition = [sender convertPoint:CGPointZero toView:self.tableView];
NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:buttonPosition];

Swift 버전 :

let buttonPosition = sender.convert(CGPoint(), to:tableView)
let indexPath = tableView.indexPathForRow(at:buttonPosition)

즉, 당신에게 줄 것이다 indexPath누른 버튼의 위치에 따라. 그런 다음 cellForRowAtIndexPathindexPath.row이 필요하거나 행 번호가 필요한 경우 전화 하면됩니다 .

편집증이라면 테이블 뷰에서 해당 지점을 찾을 수없는 if (indexPath) ...경우를 대비하여 사용하기 전에 확인할 수 indexPath있습니다.

Apple이 뷰 구조를 변경하기로 결정하면 다른 모든 답변이 깨질 수 있습니다.


8
이것은 백만 번. 다른 어떤 것도 작동 하지 않았지만 이것은 완벽했고 지금까지 가장 간단한 해결책이었습니다
ine

2
이 대답은 올바른 솔루션 이기 때문에 작동 합니다. 나머지는 해결 방법입니다. 감사!
Bruno Philipe 2013 년

1
이 경우에는 하지 않는self.tableview을 현재 페이지에있는 내 대답을 참조하십시오.
Ashok

1
보낸 사람이 잘못된 수업이라는 것을 깨달았을 때 이것은 나를 위해 일했습니다. UIButton이 눌 리도록 수정했으며 이제 작동 중입니다!
lordB8r

1
방법이 convertPoint:*to*View아니라는 것을 기억하십시오 convertPoint:*from*View. 나는 ... 엑스 코드 자동 완성을 사용 fromView 방법은 작동하지로 이어지는으로 돌아가 셨습니다
tGilani

40

편집 :이 답변은 구식입니다. 대신이 방법을 사용하십시오.


이 시도:

-(void)button1Tapped:(id)sender
{
    UIButton *senderButton = (UIButton *)sender;
    UITableViewCell *buttonCell = (UITableViewCell *)[senderButton superview];
    UITableView* table = (UITableView *)[buttonCell superview];
    NSIndexPath* pathOfTheCell = [table indexPathForCell:buttonCell];
    NSInteger rowOfTheCell = [pathOfTheCell row];
    NSLog(@"rowofthecell %d", rowOfTheCell);
}

편집 : contentView를 사용하는 경우 대신 buttonCell에 사용하십시오.

UITableViewCell *buttonCell = (UITableViewCell *)senderButton.superview.superview;

1
셀 자체에 하위 뷰를 추가 contentView하지 않고 해당 속성 에만 추가하면 안됩니다. 따라서이 솔루션은 실제로 작동하지 않습니다.

1
저는 @ H2CO3에 동의하고 있으며 수퍼 뷰를 참조하여 이것이 이루어져야한다고 생각하지 않습니다. 아래 더 나은 방법을 참조하십시오 : stackoverflow.com/a/16270198/308315
iwasrobbed 2013

@minimalpop 정답을 변경해 주시겠습니까? 더 나은 Q / A를 위해!
Thomas Besnehard 2014

이것은 아이폰 OS 7. indexPathForRowAtPoint에서 작동하지 않습니다 : 대답 아래
오스틴

UICollectionView로 동일한 버전을 시도했고 완벽하게 작동합니다. 감사합니다!
Claus는

18

사용자 지정 하위보기가있는 셀의 indexPath를 가져 오려면이 방법을 사용하는 것이 좋습니다 ( iOS 7 및 모든 이전 버전과 호환 가능 ).

-(void)button1Tapped:(id)sender {
//- (void)cellSubviewTapped:(UIGestureRecognizer *)gestureRecognizer {
//    UIView *parentCell = gestureRecognizer.view.superview;
    UIView *parentCell = sender.superview;

    while (![parentCell isKindOfClass:[UITableViewCell class]]) {   // iOS 7 onwards the table cell hierachy has changed.
        parentCell = parentCell.superview;
    }

    UIView *parentView = parentCell.superview;

    while (![parentView isKindOfClass:[UITableView class]]) {   // iOS 7 onwards the table cell hierachy has changed.
        parentView = parentView.superview;
    }


    UITableView *tableView = (UITableView *)parentView;
    NSIndexPath *indexPath = [tableView indexPathForCell:(UITableViewCell *)parentCell];

    NSLog(@"indexPath = %@", indexPath);
}

이것도 필요하지 않습니다 self.tablview.

또한 사용자 지정 하위보기에 추가 된 UIGestureRecognizer의 @selector를 통해 동일한 코드를 원하는 경우 유용한 주석 처리 된 코드를 확인하십시오.


uitableviewcontroller에서 찾은 데이터가 필요한 경우 어떻게합니까?
iosMentalist

좋은 대답. 검색 창이 있고 현재 어떤 테이블이 사용되는지 알고 싶다면 이것을 사용할 수도 있습니다.
Suraj K Thomas

테이블 셀 계층이 변경 되었습니까? 어떤 변화가 일어 났는지 이해하도록 도와 주시겠습니까?
Kamaldeep singh Bhatia

3

두 가지 방법이 있습니다.

  1. @ H2CO3가 맞습니다. @ user523234가 제안한 작업을 수행 할 수 있지만 UIButton과 UITableViewCell 사이에 있어야하는 UITableViewCellContentView를 존중하기 위해 약간의 변경이 있습니다. 그래서 그의 코드를 수정하려면 :

    - (IBAction)button1Tapped:(id)sender
    {
        UIButton *senderButton = (UIButton *)sender;
        UITableViewCellContentView *cellContentView = (UITableViewCellContentView *)senderButton.superview;
        UITableViewCell *tableViewCell = (UITableViewCell *)cellContentView.superview;
        UITableView* tableView = (UITableView *)tableViewCell.superview;
        NSIndexPath* pathOfTheCell = [tableView indexPathForCell:tableViewCell];
        NSInteger rowOfTheCell = pathOfTheCell.row;
        NSLog(@"rowofthecell %d", rowOfTheCell);
    }
    
  2. 사용자 지정 UITableViewCell (자신의 하위 클래스)을 만드는 경우 selfIBAction에서 간단히 호출 할 수 있습니다 . 스토리 보드를 사용하거나 셀을 설정할 때 프로그래밍 방식으로 IBAction 함수를 단추에 연결할 수 있습니다.

    - (IBAction)button1Tapped:(id)sender
    {
        UITableView* tableView = (UITableView *)self.superview;
        NSIndexPath* pathOfTheCell = [tableView indexPathForCell:self];
        NSInteger rowOfTheCell = pathOfTheCell.row;
        NSLog(@"rowofthecell %d", rowOfTheCell);
    }
    

2

나는 당신이 셀에 버튼을 추가 가정 cellForRowAtIndexPath하고 내가 무엇을 할 것이라고하는 것은 사용자 정의 클래스의 서브 클래스를 만드는 것입니다 UIButtonA, 추가 태그 라는 rowNumber데이터는 셀에 버튼을 추가하는 동안 것을, 그리고 APPEND를.


3
괜찮지 만 하위 클래스를 만들 이유가 없습니다 UIButton. tag의 공통 속성입니다 UIView.
Rob Napier

내가 무슨 생각을 알고 가정하지 마십시오 UI에게 뭔가하는 것은 아니다 UI , 보정 주셔서 감사합니다!
Derek Li

2

또 다른 간단한 방법 :

  • tableView에서 터치 포인트 얻기

  • 그런 다음 지점에서 셀의 인덱스 경로를 가져옵니다.

  • 색인 경로에 행 색인이 있습니다.

코드는 다음과 같습니다.

- (void)buttonTapped:(id)sender {
    UITapGestureRecognizer *tap = (UITapGestureRecognizer *)sender;
    CGPoint point = [tap locationInView:theTableView];

    NSIndexPath *theIndexPath = [theTableView indexPathForRowAtPoint:point];

    NSInteger theRowIndex = theIndexPath.row;
    // do your stuff here
    // ...
}

1

스위프트 3

참고 : 메타 가 그러한 편집에 대해 눈살을 찌푸리는 것을 제외하고는 위 의 수락 된 답변 에 실제로 가야합니다 .

@IBAction func doSomething(_ sender: UIButton) {
   let buttonPosition = sender.convert(CGPoint(), to: tableView)
   let index = tableView.indexPathForRow(at: buttonPosition)
}

두 가지 사소한 의견 :

  1. 기본 함수에는 변환이없는 송신자 유형이 Any로 있습니다.
  2. CGPointZero는 CGPoint ()로 대체 될 수 있습니다.

완벽하게 작동합니다.

0

한 가지 해결책은 버튼의 수퍼 뷰 또는 뷰 계층 구조에서 더 높은 태그를 확인하는 것입니다 (버튼이 셀의 콘텐츠 뷰에있는 경우).


0

신속하게 코드를 공유하고 싶습니다.

extension UITableView
{
    func indexPathForCellContainingView(view1:UIView?)->NSIndexPath?
    {
        var view = view1;
        while view != nil {
            if (view?.isKindOfClass(UITableViewCell) == true)
            {
                return self.indexPathForCell(view as! UITableViewCell)!
            }
            else
            {
                view = view?.superview;
            }
        }
        return nil
    }
}

0

신속하게 :

@IBAction func buttonAction(_ sender: UIButton) {
    guard let indexPath = tableView.indexPathForRow(at: sender.convert(CGPoint(), to: tableView)) else {
        return
    }
    // do something
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.