it-swarm.asia

الحصول على زر انقر داخل UITableViewCell

لدي وحدة تحكم عرض مع عرض جدول وبنك الاستثمار القومي منفصلة لقالب خلية الجدول. يحتوي قالب الخلية على بعض الأزرار. أرغب في الوصول إلى زر النقر مع فهرس الخلية التي تم النقر فوقها داخل وحدة تحكم العرض حيث قمت بتحديد طريقة عرض الجدول.

لذلك لدي ViewController.h و ViewController.m حيث لدي UITableView و TableTemplate.h و TableTemplate.m و TableTemplate.xib حيث حددت المنقار. أريد الحدث انقر فوق الزر مع فهرس الخلية في ViewController.m.

أي مساعدة في كيف يمكنني أن أفعل ذلك؟

129
ankit_rck

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

تحديثات للقسم المتعدد:

يمكنك التحقق من هذا الرابط للكشف عن زر انقر في عرض الجدول للصف والقسم متعددة.

247
Mani

المندوبون هم الطريق للذهاب.

كما رأينا مع الإجابات الأخرى التي تستخدم طرق العرض ، قد تصبح قديمة. من يدري غدًا قد يكون هناك غلاف آخر وقد يحتاج إلى استخدام cell superview]superview]superview]superview]. وإذا استخدمت علامات ، فسوف ينتهي بك الأمر إلى عدد n إذا كانت هناك شروط أخرى لتحديد الخلية. لتجنب كل ذلك إعداد المندوبين. (من خلال القيام بذلك ، ستقوم بإنشاء فئة خلية قابلة لإعادة الاستخدام. يمكنك استخدام نفس فئة الخلية كفئة أساسية وكل ما عليك القيام به هو تنفيذ أساليب المفوض.)

نحتاج أولاً إلى واجهة (بروتوكول) تستخدمها الخلية للاتصال بنقرات الزر (المفوض). ( يمكنك إنشاء ملف .h منفصل للبروتوكول وتضمينه في كل من وحدة التحكم في عرض الجدول وفئات الخلايا المخصصة OR فقط قم بإضافته في فئة الخلية المخصصة والتي سيتم تضمينها على أي حال في وحدة تحكم عرض الجدول )

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

تضمين هذا البروتوكول في الخلية المخصصة وجدول عرض وحدة التحكم. وتأكد الجدول تحكم عرض يؤكد على هذا البروتوكول.

في الخلية المخصصة ، قم بإنشاء خاصيتين:

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

في UIButton IBAction ، انقر فوق المفوض: ( يمكن القيام بنفس الشيء لأي إجراء في فئة الخلية المخصصة التي تحتاج إلى إعادة تفويضها لعرض وحدة التحكم )

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

سيكون هذا هو الأسلوب المثالي للحصول على إجراءات زر خلية مخصصة في وحدة تحكم عرض الجدول.

143
GoodSp33d

بدلا من اللعب مع العلامات ، أخذت نهجا مختلفا. جعل المفوض لفئتي الفرعية من UITableViewCell (OptionButtonsCell) وأضاف indexPath var. من الزر الخاص بي في لوحة العمل ، قمت بتوصيلIBAction بـ OptionButtonsCell وهناك أرسل أسلوب المفوض باستخدام indexPath المناسب لأي شخص مهتم. في الخلية لمسار الفهرس ، قمت بتعيين indexPath الحالي ويعمل :)

دع الكود يتحدث عن نفسه:

Swift 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)")
}
52
repoguy

هذا يجب أن يساعد: -

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

هنا المرسل هو مثيل UIButton الذي يرسل الحدث. myTableView هو مثيل UITableView الذي تتعامل معه.

مجرد الحصول على مرجع الخلية الصحيح ويتم كل العمل.

قد تحتاج إلى إزالة الأزرار من محتوى الخلية وعرضها وإضافتها مباشرة إلى مثيل UITableViewCell لأنها طريقة عرض فرعية.

أو

يمكنك صياغة نظام تسمية علامات ل UIButtons مختلفة في cell.contentView. باستخدام هذه العلامة ، يمكنك لاحقًا معرفة معلومات الصف والقسم حسب الحاجة.

29
Tarun

التعليمات البرمجية التالية قد تساعدك.

لقد أخذت 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 باستخدام Storyboard.

نأمل أن تساعدك...!!!

21
Piyush Patel

السبب الذي يعجبني أدناه هو الأسلوب لأنه يساعدني أيضًا في تحديد قسم الجدول.

إضافة زر في الخلية 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];

الحدث addTask:

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

تأمل هذه المساعدة.

12
Yogesh Lolusare

لا يعمل كود تارون على iOS7 ، لأن هيكل UITableViewCell قد تغير والآن سيحصل على "UITableViewCellScrollView" بدلاً من ذلك.

يحتوي هذا المنشور الحصول على UITableViewCell مع superview في iOS 7 على حل جيد لإنشاء حلقة للعثور على العرض الأصل الصحيح ، بغض النظر عن أي تغييرات مستقبلية في الهيكل. يتلخص في إنشاء حلقة:

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

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

يحتوي الرابط على رمز لحل أكثر قابلية لإعادة الاستخدام ، ولكن يجب أن يعمل هذا.

6
Stenio Ferreira

سويفت 2.2

تحتاج إلى إضافة هدف لهذا الزر.

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

اسم الوظيفة: متصل // على سبيل المثال

وبالطبع تحتاج إلى تعيين علامة على هذا الزر لأنك تستخدمه.

myButton.tag = indexPath.row

يمكنك تحقيق ذلك عن طريق فئة فرعية UITableViewCell. استخدمها في أداة إنشاء الواجهة ، وقم بإسقاط زر في تلك الخلية ، وقم بتوصيلها عبر منفذ البيع ، وستذهب إلى هناك.

للحصول على العلامة في الوظيفة المتصلة:

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

سويفت 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()
    }
}

في عرض وحدة التحكم: Tableview المفوض

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

أجد أنه من الأسهل تقسيم فئة فرعية إلى الزر الموجود داخل الخلية (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!
}

ولا تنسَ تعيين فئة الزر في Interface Builder وربطها بوظيفة 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.
    }
}
5
yesleon

عملها بالنسبة لي.

 - (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];
}
4
Yogesh Tarsariya

استخدام سويفت الإغلاق:

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
    }
}
4
valexa
// 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




}
1
Hitesh Chauhan

لـ Swift 4:

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

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

إجابةMani جيدة ، لكن غالبًا ما تستخدم علامات المشاهدة داخل محتوى الخلية للعرض لأغراض أخرى. يمكنك استخدام علامة الخلية بدلاً من ذلك (أو علامة ContentView الخاصة بالخلية):

1) في طريقة cellForRowAtIndexPath: الخاصة بك ، قم بتعيين علامة الخلية كمؤشر:

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

2) إضافة الهدف والعمل لزرك على النحو التالي:

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

3) قم بإنشاء طريقة تقوم بإرجاع صف المرسل (شكرًا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;
}

4) إجراءات الكود على أساس الفهرس:

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

CustomTableCell.h هو UITableViewCell:

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

MyVC.m بعد الاستيراد:

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

داخل "cellForRowAtIndexPath" في MyVC.m:

//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];

MyVC.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];
}
0
Mer