UFO ET IT

UITableViewCell 내부의 버튼 클릭

ufoet 2023. 6. 2. 21:49
반응형

UITableViewCell 내부의 버튼 클릭

테이블 뷰가 있는 뷰 컨트롤러와 테이블 셀 템플릿을 위한 별도의 니브가 있습니다.셀 템플릿에는 단추가 몇 개 있습니다.표 보기를 정의한 보기 컨트롤러 내에서 클릭한 셀의 색인과 함께 버튼 클릭에 액세스합니다.

그래서 저는.ViewController.h그리고.ViewController.m에는▁가 있는 곳UITableView그리고.TableTemplate.h,TableTemplate.m그리고.TableTemplate.xib여기에 닙이 정의되어 있습니다.는 셀 .ViewController.m.

어떻게 하면 좋을까요?

의 신의에서.cellForRowAtIndexPath:합니다.

cell.yourbutton.tag = indexPath.row;

아래와 같이 단추에 대한 대상 및 작업을 추가합니다.

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

의 아래와 으로 한 ViewControler:

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

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

링크를 선택하여 여러 행 및 섹션에 대한 테이블 보기에서 버튼 클릭을 감지할 수 있습니다.

대표들이 가야 할 길입니다.

다른 답변에서 볼 수 있듯이 보기를 사용하는 것은 구식이 될 수 있습니다.내일 또 다른 포장지가 있을지도 모르고 사용해야 할지도 모릅니다.cell superview]superview]superview]superview]태그를 사용하면 셀을 식별할 수 있는 n개의 if 조건을 갖게 됩니다.이러한 모든 설정 딜러를 방지합니다.이렇게 하면 재사용 가능한 셀 클래스를 만들 수 있습니다. 기본 클래스와 동일한 셀 클래스를 사용할 수 있으며 위임 메서드를 구현하기만 하면 됩니다.)

먼저 셀이 버튼 클릭을 전달(위임)하기 위해 사용할 인터페이스(프로토콜)가 필요합니다. (프로토콜용으로 별도의 .h 파일을 생성하여 테이블 컨트롤러와 사용자 지정클래스에 모두 포함하거나 테이블컨트롤러에 포함될 사용자 지정 클래스에 추가할 수 있습니다.)

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

이 프로토콜을 사용자 지정 셀 및 테이블 보기 컨트롤러에 포함합니다.테이블 뷰 컨트롤러가 이 프로토콜을 확인해야 합니다.

사용자 지정 셀에서 두 가지 속성을 만듭니다.

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

UIButtonIBAaction delegate click : (표시 컨트롤러에 다시 위임해야 하는 사용자 지정클래스의 모든 작업에 대해 동일한 작업을 수행할 수 있습니다.)

- (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 변수를 추가했습니다.스토리보드의 버튼에서 @IBAction을 OptionButtonsCell에 연결하고 거기서 올바른 indexPath를 가진 대리자 메서드를 관심 있는 모든 사람에게 보냅니다.인덱스 경로 셀에서 현재 indexPath를 설정하면 작동합니다 :)

코드 자체를 설명합니다.

스위프트 3 X코드 8

옵션 버튼테이블Cell.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];

여기서 보낸 사람은 이벤트를 보내는 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스토리보드를 사용합니다.

그게 당신에게 도움이 되기를...!!!

Swift 폐쇄 사용:

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
    }
}

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

행 위치의 셀에 단추 추가인덱스 경로:

 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;
    }
}

도움이 되길 바랍니다.

Tarun의 코드는 iOS7에서 작동하지 않습니다. 왜냐하면 UITableViewCell 구조가 바뀌었기 때문입니다. 그리고 그가 대신 "UITableViewCellScrollView"를 받게 되었기 때문입니다.

게시물 iOS 7에서 수퍼뷰가 있는 UITableViewCell 가져오기는 구조의 향후 변경에 관계없이 올바른 상위 뷰를 찾기 위한 루프를 만드는 좋은 솔루션입니다.요약하면 루프를 생성하는 것입니다.

    UIView *superView = [sender superview];
    UIView *foundSuperView = nil;

    while (nil != superView && nil == foundSuperView) {
        if ([superView isKindOfClass:[UITableViewCell class]]) {
            foundSuperView = superView;
        } else {
            superView = superView.superview;
        }
    }

링크에 보다 재사용 가능한 솔루션에 대한 코드가 있지만, 이는 작동합니다.

내게 도움이 됩니다.

 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
     UIButton *Btn_Play = (UIButton *)[cell viewWithTag:101];
     [Btn_Play addTarget:self action:@selector(ButtonClicked:) forControlEvents:UIControlEventTouchUpInside];
}
-(void)ButtonClicked:(UIButton*)sender {
     CGPoint buttonPosition = [sender convertPoint:CGPointZero toView:self.Tbl_Name];
     NSIndexPath *indexPath = [self.Tbl_Name indexPathForRowAtPoint:buttonPosition];
}

스위프트 2.2

해당 버튼에 대한 대상을 추가해야 합니다.

myButton.addTarget(self, action: #selector(ClassName.FunctionName(_:), forControlEvents: .TouchUpInside)

함수 이름: connected //(예: //)

그리고 당신은 그것을 사용하고 있기 때문에 당연히 그 버튼의 태그를 설정해야 합니다.

myButton.tag = indexPath.row

UITableViewCell을 하위 분류하여 이 작업을 수행할 수 있습니다.인터페이스 빌더에서 그것을 사용하고, 그 셀에 버튼을 떨어뜨리고, 콘센트를 통해 연결하면 됩니다.

연결된 함수에서 태그를 가져오는 방법

func connected(sender: UIButton) {
    let buttonTag = sender.tag
    // Do any additional setup
}

스위프트 3와 클로저

사용자 지정 UITableViewCell의 폐쇄를 사용하여 ViewController에 작업을 다시 호출하는 것이 좋은 솔루션입니다.

셀 내:

final class YourCustomCell: UITableViewCell {

    var callbackClosure: (() -> Void)?

    // Configure the cell here
    func configure(object: Object, callbackClosure: (() -> Void)?) {
       self.callbackClosure = callbackClosure
    }


// MARK: - IBAction
extension YourCustomCell {
    @IBAction fileprivate func actionPressed(_ sender: Any) {
        guard let closure = callbackClosure else { return }
        closure()
    }
}

View 컨트롤러에서:테이블 뷰 대리자

extension YourViewController: UITableViewDelegate {

    func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
        guard let cell: YourCustomCell = cell as? YourCustomCell else { return }
        cell.configure(object: object, callbackClosure: { [weak self] in
            self?.buttonAction()
        })
     }
 }

fileprivate extension YourViewController {

    func buttonAction() {
        // do your actions here 
    }
}

셀 내부의 버튼을 하위 분류하는 것이 가장 간단합니다(Swift 3).

class MyCellInfoButton: UIButton {
    var indexPath: IndexPath?
}

셀 클래스에서:

class MyCell: UICollectionViewCell {
    @IBOutlet weak var infoButton: MyCellInfoButton!
   ...
}

표 뷰 또는 집합 뷰의 데이터 원본에서 셀 대기열을 해제할 때 단추에 인덱스 경로를 지정합니다.

cell.infoButton.indexPath = indexPath

따라서 다음 코드를 테이블 뷰 컨트롤러에 넣으면 됩니다.

@IBAction func handleTapOnCellInfoButton(_ sender: MyCellInfoButton) {
        print(sender.indexPath!) // Do whatever you want with the index path!
}

그리고 인터페이스 빌더에서 버튼의 클래스를 설정하고 다음에 연결하는 것을 잊지 마십시오.handleTapOnCellInfoButton함수!


편집됨:

종속성 주입을 사용합니다.종료 호출을 설정하려면 다음과(와)

class MyCell: UICollectionViewCell {
    var someFunction: (() -> Void)?
    ...
    @IBAction func didTapInfoButton() {
        someFunction?()
    }
}

컬렉션 뷰의 대리인에 대한 willDisplay 메서드에서 폐쇄를 주입합니다.

 func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
    (cell as? MyCell)?.someFunction = {
        print(indexPath) // Do something with the indexPath.
    }
}

closure를 사용하여 cell에서 UIViewController로 파라미터 값을 전달하려는 경우

//Your Cell Class
class TheCell: UITableViewCell {

    var callBackBlockWithParam: ((String) -> ()) = {_ in }

//Your Action on button
    @IBAction func didTap(_ sender: Any) {
        callBackBlockWithParam("Your Required Parameter like you can send button as sender or anything just change parameter type. Here I am passing string")
    }
}

//Your Controller
extension TheController: UITableViewDataSource {
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
            let cell = tableView.dequeueReusableCell(withIdentifier: TheCell.identifier, for: indexPath) as! TheCell {
            cell.callBackBlockWithParam = { (passedParamter) in 

             //you will get string value from cell class
                print(passedParamter)     
      }
            return cell
    }
}
// Add action in cell for row at index path -tableView

cell.buttonName.addTarget(self, action: #selector(ViewController.btnAction(_:)), for: .touchUpInside)

// Button Action

  @objc func btnAction(_ sender: AnyObject) {



        var position: CGPoint = sender.convert(.zero, to: self.tableView)


        let indexPath = self.tableView.indexPathForRow(at: position)
        let cell: UITableViewCell = tableView.cellForRow(at: indexPath!)! as
        UITableViewCell




}

swift 4:

inside the cellForItemAt ,
   
cell.chekbx.addTarget(self, action: #selector(methodname), for: .touchUpInside)

then outside of cellForItemAt
@objc func methodname()
{
//your function code
}

@다양한 답변이 가능하지만 셀의 내용 보기 내부에 있는 보기 태그는 다른 용도로 사용되는 경우가 많습니다.대신 셀의 태그(또는 셀의 contentView 태그)를 사용할 수 있습니다.

당신의cellForRowAtIndexPath:메소드, 셀 태그를 인덱스로 지정:

cell.tag = indexPath.row; // or cell.contentView.tag...

아래와 같이 단추에 대한 대상 및 작업을 추가합니다.

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

보낸 사람의 행을 반환하는 메서드를 만듭니다(고마워 @Stenio Ferreira).

- (NSInteger)rowOfSender:(id)sender
{
    UIView *superView = sender.superview;
    while (superView) {
        if ([superView isKindOfClass:[UITableViewCell class]])
            break;
        else
            superView = superView.superview;
    }

    return superView.tag;
}

인덱스 기반 코드 작업:

-(void)yourButtonClicked:(UIButton*)sender
{
     NSInteger index = [self rowOfSender:sender];
     // Your code here
}

CustomTableCell.h는 UITableViewCell입니다.

@property (weak, nonatomic) IBOutlet UIButton *action1Button;
@property (weak, nonatomic) IBOutlet UIButton *action2Button;

가져오기 후 내 VC.m:

@interface MYTapGestureRecognizer : UITapGestureRecognizer
@property (nonatomic) NSInteger dataint;
@end

내부 "cellForRowAt"MyVC.m의 IndexPath":

//CustomTableCell 
CustomTableCell *cell = (CustomTableCell *)[tableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath];

//Set title buttons
[cell.action1Button setTitle:[NSString stringWithString:NSLocalizedString(@"action1", nil)] forState:UIControlStateNormal];
[cell.action2Button setTitle:[NSString stringWithString:NSLocalizedString(@"action2", nil)] forState:UIControlStateNormal];

//Set visibility buttons
[cell.action1Button setHidden:FALSE];
[cell.action2Button setHidden:FALSE];

//Do 1 action
[cell.action1Button addTarget:self action:@selector(do1Action :) forControlEvents:UIControlEventTouchUpInside];

//Do 2 action
MYTapGestureRecognizer *action2Tap = [[MYTapGestureRecognizer alloc] initWithTarget:self action:@selector(do2Action :)];
cancelTap.numberOfTapsRequired = 1;
cancelTap.dataint = indexPath.row;
[cell.action2Button setUserInteractionEnabled:YES];
[cell.action2Button addGestureRecognizer:action2Tap];

My VC.m:

-(void)do1Action :(id)sender{
//do some action that is not necessary fr data
}

-(void)do2Action :(UITapGestureRecognizer *)tapRecognizer{
MYTapGestureRecognizer *tap = (MYTapGestureRecognizer *)tapRecognizer;
numberTag = tap.dataint;
FriendRequest *fr = [_list objectAtIndex:numberTag];

//connect with a WS o do some action with fr data

//actualize list in tableView
 [self.myTableView reloadData];
}
cell.show.tag=indexPath.row;
     [cell.show addTarget:self action:@selector(showdata:) forControlEvents:UIControlEventTouchUpInside];

-(IBAction)showdata:(id)sender
{
    UIButton *button = (UIButton *)sender;

    UIStoryboard *storyBoard;
    storyBoard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
    SecondViewController *detailView = [storyBoard instantiateViewControllerWithIdentifier:@"SecondViewController"];

    detailView.string=[NSString stringWithFormat:@"%@",[_array objectAtIndex:button.tag]];

    [self presentViewController:detailView animated:YES completion:nil];

}

언급URL : https://stackoverflow.com/questions/20655060/get-button-click-inside-uitableviewcell

반응형