كيف يمكنني تتبع مسار الفهرس للزر في خلية عرض الجدول؟

StackOverflow https://stackoverflow.com/questions/2863940

سؤال

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

هل كانت مفيدة؟

المحلول

لقد أنشأت طريقة واحدة للحصول على indexpath ، آمل أن يساعدك ذلك.

إنشاء زر (Amethod :) في CellForrowatIndexPath

-(void) aMethod:(UIButton *)sender
{
    // Calling Magic Method which will return us indexPath.
    NSIndexPath *indexPath = [self getButtonIndexPath:sender];

    NSLog(@"IndexPath: %li", indexPath.row);
    NSLog(@"IndexRow: %li", indexPath.section);
}

// هنا هي الطريقة السحرية للحصول على Button IndexPath

-(NSIndexPath *) getButtonIndexPath:(UIButton *) button
{
    CGRect buttonFrame = [button convertRect:button.bounds toView:groupTable];
    return [groupTable indexPathForRowAtPoint:buttonFrame.origin];
}

نصائح أخرى

إذا كنت تشعر بعدم الارتياح الاعتماد عليها button.superview, ، يجب أن تكون هذه الطريقة أكثر قوة قليلاً من بعض الإجابات الأخرى هنا:

UIButton *button = (UIButton *)sender;
CGRect buttonFrame = [button convertRect:button.bounds toView:self.tableView];
NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:buttonFrame.origin];

توقف هذا عن العمل مع iOS 7; ؛ الدفع إجابة مايك ويلر في حين أن

- (IBAction)clickedButton:(id)sender {
    UIButton *button = (UIButton *)sender;
    UITableViewCell *cell = (UITableViewCell *)button.superview;
    UITableView *tableView = (UITableView *)cell.superview;
    NSIndexPath *indexPath = [tableView indexPathForCell:cell];
}

أو أقصر:

- (IBAction)clickedButton:(id)sender {
    NSIndexPath *indexPath = [(UITableView *)sender.superview.superview indexPathForCell:(UITableViewCell *)sender.superview];
}

كلاهما لم يختبر!

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

يجب إضافة الزر ومعالجه إلى العرف UITableViewCell فئة فرعية ووضعها هناك. هذا هو المكان الذي ينتمي إليه.

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

- (UITableViewCell *)cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    MyCustomCell *cell = ...;

    // ...

    cell.onButtonTapped = ^{
        [self buttonSelectedAtIndexPath:indexPath];
    }

    // OR

    cell.delegate = self;

    // ...
}

(ملاحظة: إذا ذهبت إلى مسار الكتلة ، فستحتاج إلى استخدام ملف __weak الإشارة الذاتية لمنع الاحتفاظ بدورات ، لكنني اعتقدت أن هذا من شأنه أن يثبت المثال).

إذا كنت تأخذ مسار المندوب ، فسيكون لديك طريقة المندوب هذه لتنفيذ:

- (void)cellButtonPressed:(UITableViewCell *)cell
{
    NSIndexPath *indexPath = [self.tableView indexPathForCell:cell];
    // ...
}

يتمتع الكود الخاص بك الآن وصول كامل إلى السياق المناسب عندما يتعامل مع الحدث.

يجب أن يكون تنفيذ هذه الواجهة على فئة الخلايا الخاصة بك واضحًا.

لا أعرف لماذا أحتاج إلى استدعاء Method Superview مرتين للحصول على UitableViewCell.

تحديث:

شكرًا على Qiulang ، لقد حصلت عليه الآن.

"هذا لأن SDK قد أضافت الآن فصلًا خاصًا يسمى UitableViewCellContentView لـ UitableViewCell ، والتي هي مراقبة زر Button الآن." - Qiulang

UIButton *button = (UIButton *)sender;
UITableViewCell *cell = (UITableViewCell *)button.superview.superview;
UITableView *curTableView = (UITableView *)cell.superview;
NSIndexPath *indexPath = [curTableView indexPathForCell:cell];

لقد واجهت نفس المشكلة أيضًا ، وقمت ببناء طريقة متكررة بسيطة تعمل بغض النظر عن عدد المشاهدات العميقة التي تثير السيطرة.

-(NSIndexPath*)GetIndexPathFromSender:(id)sender{

    if(!sender) { return nil; }

    if([sender isKindOfClass:[UITableViewCell class]])
    {
        UITableViewCell *cell = sender;
        return [self.tableView indexPathForCell:cell];
    }

    return [self GetIndexPathFromSender:((UIView*)[sender superview])];
}


-(void)ButtonClicked:(id)sender{
    NSIndexPath *indexPath = [self GetIndexPathFromSender:sender];
}

استخدم هذا العمل المثالي بالنسبة لي.

CGPoint center= [sender center];
CGPoint rootViewPoint = [[sender superview] convertPoint:center toView:_tableView1];
NSIndexPath *indexPath = [_tableView1 indexPathForRowAtPoint:rootViewPoint];
NSLog(@"%@",indexPath);

تحديث سريع 2

إليك كيفية معرفة أي زر تم استغلاله

 @IBAction func yourButton(sender: AnyObject) {


 var position: CGPoint = sender.convertPoint(CGPointZero, toView: self.tableView)
    let indexPath = self.tableView.indexPathForRowAtPoint(position)
    let cell: UITableViewCell = tableView.cellForRowAtIndexPath(indexPath!)! as
    UITableViewCell
    print(indexPath?.row)
    print("Tap tap tap tap")

}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top