[ios] UITableViewCell 내부에서 버튼 클릭 가져 오기

테이블 뷰가있는 뷰 컨트롤러와 테이블 셀 템플릿에 대한 별도의 펜촉이 있습니다. 셀 템플릿에는 몇 가지 버튼이 있습니다. 테이블보기를 정의 한보 기 컨트롤러 내부에서 클릭 한 셀의 색인과 함께 버튼 클릭에 액세스하고 싶습니다.

그래서 내가 ViewController.h있고 ViewController.m어디에 UITableView있고 TableTemplate.h, TableTemplate.m그리고 TableTemplate.xib펜촉이 정의되어 있습니다. 에 셀 인덱스가있는 버튼 클릭 이벤트를 원합니다 ViewController.m.

내가 어떻게 할 수 있습니까?



답변

1) cellForRowAtIndexPath:방법에서 버튼 태그를 색인으로 지정 하십시오 .

cell.yourbutton.tag = indexPath.row;

2) 다음과 같이 버튼의 대상과 동작을 추가하십시오.

[cell.yourbutton addTarget:self action:@selector(yourButtonClicked:) forControlEvents:UIControlEventTouchUpInside];

3) 다음과 같이 색인을 기반으로 한 코드 작업 ViewControler:

-(void)yourButtonClicked:(UIButton*)sender
{
     if (sender.tag == 0)
     {
         // Your code here
     }
}

여러 섹션에 대한 업데이트 :

이 링크 를 확인하여 여러 행 및 섹션에 대한 테이블보기에서 단추 클릭을 감지 할 수 있습니다 .


답변

대표자들이 갈 길입니다.

다른 답변에서 볼 수 있듯이 뷰를 사용하면 구식이 될 수 있습니다. 내일 또 다른 포장지가있을 수 있으며이를 사용해야 할 수도있는 사람 cell superview]superview]superview]superview]. 태그를 사용하면 셀을 식별하기위한 n 개의 조건이 생길 수 있습니다. 그 모든 설정을 피하기 위해. (이렇게하면 재사용 가능한 셀 클래스가 작성됩니다. 기본 클래스와 동일한 셀 클래스를 사용할 수 있으며 위임 메소드를 구현하기 만하면됩니다.)

먼저 우리는 인터페이스 (프로토콜)가 필요합니다.이 프로토콜은 셀에서 버튼 클릭을 전달 (대리)하는 데 사용됩니다. ( 프로토콜에 대해 별도의 .h 파일을 생성하고 테이블 뷰 컨트롤러와 사용자 정의 셀 클래스 모두에 포함하거나 테이블 뷰 컨트롤러에 포함될 사용자 정의 셀 클래스에 추가 할 수 있습니다 )

@protocol CellDelegate <NSObject>
- (void)didClickOnCellAtIndex:(NSInteger)cellIndex withData:(id)data;
@end

이 프로토콜을 사용자 정의 셀 및 테이블보기 컨트롤러에 포함하십시오. 그리고 테이블 뷰 컨트롤러가이 프로토콜을 확인하는지 확인하십시오.

사용자 정의 셀에서 두 가지 특성을 작성하십시오.

@property (weak, nonatomic) id<CellDelegate>delegate;
@property (assign, nonatomic) NSInteger cellIndex;

UIButtonIBAction를 위임 클릭 ( 같은 뷰 컨트롤러에 다시 위임 할 필요가 사용자 정의 셀 클래스의 모든 행동을 수행 할 수 있습니다 )

- (IBAction)buttonClicked:(UIButton *)sender {
    if (self.delegate && [self.delegate respondsToSelector:@selector(didClickOnCellAtIndex:withData:)]) {
        [self.delegate didClickOnCellAtIndex:_cellIndex withData:@"any other cell data/property"];
    }
}

cellForRowAtIndexPath셀을 큐 해제 한 후 테이블보기 컨트롤러 에서 위의 특성을 설정하십시오.

cell.delegate = self;
cell.cellIndex = indexPath.row; // Set indexpath if its a grouped table.

그리고 테이블 뷰 컨트롤러에서 델리게이트를 구현하십시오.

- (void)didClickOnCellAtIndex:(NSInteger)cellIndex withData:(id)data
{
    // Do additional actions as required.
    NSLog(@"Cell at Index: %d clicked.\n Data received : %@", cellIndex, data);
}

이것은 테이블 뷰 컨트롤러에서 사용자 정의 셀 버튼 동작을 얻는 이상적인 방법입니다.


답변

태그를 사용하는 대신 다른 접근 방식을 취했습니다. UITableViewCell (OptionButtonsCell)의 하위 클래스에 대리자를 만들고 indexPath var를 추가했습니다. 스토리 보드의 버튼에서 @IBAction을 OptionButtonsCell에 연결하고 올바른 indexPath가있는 대리자 메서드를 관심있는 모든 사람에게 보냅니다. 인덱스 경로의 셀에서 현재 indexPath를 설정하고 작동합니다. 🙂

코드 자체를 말하도록하십시오 :

스위프트 3 Xcode 8

OptionButtonsTableViewCell.swift

import UIKit
protocol OptionButtonsDelegate{
    func closeFriendsTapped(at index:IndexPath)
}
class OptionButtonsTableViewCell: UITableViewCell {
    var delegate:OptionButtonsDelegate!
    @IBOutlet weak var closeFriendsBtn: UIButton!
    var indexPath:IndexPath!
    @IBAction func closeFriendsAction(_ sender: UIButton) {
        self.delegate?.closeFriendsTapped(at: indexPath)
    }
}

MyTableViewController.swift

class MyTableViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, OptionButtonsDelegate {...

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "optionCell") as! OptionButtonsTableViewCell
    cell.delegate = self
    cell.indexPath = indexPath
    return cell
}

func closeFriendsTapped(at index: IndexPath) {
     print("button tapped at index:\(index)")
}


답변

이것은 도움이 될 것입니다 :-

UITableViewCell* cell = (UITableViewCell*)[sender superview];
NSIndexPath* indexPath = [myTableView indexPathForCell:cell];

여기서 sender 는 이벤트를 보내는 UIButton 인스턴스입니다.
myTableView 는 처리중인 UITableView 인스턴스입니다.

셀 참조를 올바르게 얻으면 모든 작업이 완료됩니다.

셀의 contentView에서 버튼을 제거하고 하위 뷰이므로 UITableViewCell 인스턴스에 직접 추가해야 할 수도 있습니다.

또는

cell.contentView에서 다른 UIButton에 대한 태그 이름 지정 체계를 공식화 할 수 있습니다. 이 태그를 사용하면 나중에 필요에 따라 행 및 섹션 정보를 알 수 있습니다.


답변

다음 코드가 도움이 될 수 있습니다.

내가 찍은 UITableView라는 이름의 사용자 정의 프로토 타입 셀 클래스와 UITableViewCell내부 UIViewController.

내가 그래서 ViewController.h, ViewController.m그리고 TableViewCell.h,TableViewCell.m

그 코드는 다음과 같습니다.

ViewController.h

@interface ViewController : UIViewController<UITableViewDataSource,UITableViewDelegate>

@property (strong, nonatomic) IBOutlet UITableView *tblView;

@end

ViewController.m

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
    return (YourNumberOfRows);
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{

    static NSString *cellIdentifier = @"cell";

    __weak TableViewCell *cell = (TableViewCell *)[tableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath];

    if (indexPath.row==0) {
        [cell setDidTapButtonBlock:^(id sender)
         {
             // Your code here

         }];
    }
    return cell;
}

커스텀 셀 클래스 :

TableViewCell.h

@interface TableViewCell : UITableViewCell

@property (copy, nonatomic) void (^didTapButtonBlock)(id sender);

@property (strong, nonatomic) IBOutlet UILabel *lblTitle;
@property (strong, nonatomic) IBOutlet UIButton *btnAction;

- (void)setDidTapButtonBlock:(void (^)(id sender))didTapButtonBlock;

@end

UITableViewCell.m

@implementation TableViewCell

- (void)awakeFromNib {
    // Initialization code
    [self.btnAction addTarget:self action:@selector(didTapButton:) forControlEvents:UIControlEventTouchUpInside];

}

- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
    [super setSelected:selected animated:animated];

    // Configure the view for the selected state
}
- (void)didTapButton:(id)sender {
    if (self.didTapButtonBlock)
    {
        self.didTapButtonBlock(sender);
    }
}

참고 : 여기에서는 UIControls스토리 보드를 모두 사용했습니다.

그게 당신을 도울 수 있기를 바랍니다 … !!!


답변

아래 기술을 좋아하는 이유는 테이블 섹션을 식별하는 데 도움이되기 때문입니다.

셀 cellForRowAtIndexPath에 버튼 추가 :

 UIButton *selectTaskBtn = [UIButton buttonWithType:UIButtonTypeCustom];
        [selectTaskBtn setFrame:CGRectMake(15, 5, 30, 30.0)];
        [selectTaskBtn setTag:indexPath.section]; //Not required but may find useful if you need only section or row (indexpath.row) as suggested by MR.Tarun 
    [selectTaskBtn addTarget:self action:@selector(addTask:)   forControlEvents:UIControlEventTouchDown];
[cell addsubview: selectTaskBtn];

이벤트 추가 작업 :

-(void)addTask:(UIButton*)btn
{
    CGPoint buttonPosition = [btn convertPoint:CGPointZero toView:self.tableView];
    NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:buttonPosition];
    if (indexPath != nil)
    {
     int currentIndex = indexPath.row;
     int tableSection = indexPath.section;
    }
}

이 도움을 바랍니다.


답변

스위프트 클로저 사용 :

class TheCell: UITableViewCell {

    var tapCallback: (() -> Void)?

    @IBAction func didTap(_ sender: Any) {
        tapCallback?()
    }
}

extension TheController: UITableViewDataSource {
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
            let cell = tableView.dequeueReusableCell(withIdentifier: TheCell.identifier, for: indexPath) as! TheCell {
            cell.tapCallback = {
                //do stuff
            }
            return cell
    }
}