Correct way to setting a tag to all cells in TableView

后端 未结 3 669
花落未央
花落未央 2020-12-07 04:43

I\'m using a button inside a tableView in which I get the indexPath.row when is pressed. But it only works fine when the cells can be displayed in

3条回答
  •  囚心锁ツ
    2020-12-07 05:08

    I agree with @matt that this is not a good use of tags, but disagree with him slightly about the solution. Instead of walking up the button's superviews until you find a cell, I prefer to get the button's origin, convert it to table view coordinates, and then ask the table view for the indexPath of the cell that contains those coordinates.

    I wish Apple would add a function indexPathForView(_:) to UITableView. It's a common need, and easy to implement. To that end, here is a simple extension to UITableView that lets you ask a table view for the indexPath of any view that lies inside one of the tableView's cells.

    Below is the key code for the extension, in both Objective-C and Swift. There is a working project on GitHub called TableViewExtension-Obj-C that illustrates the uses of the table view extension below.

    EDIT

    In Objective-C:

    Header file UITableView_indexPathForView.h:

    #import 
    @interface UIView (indexPathForView)
    - (NSIndexPath *) indexPathForView: (UIView *) view;
    @end
    

    UITableView_indexPathForView.m file:

    #import "UITableView_indexPathForView.h"
    
    @implementation UITableView (UITableView_indexPathForView)
    
    - (NSIndexPath *) indexPathForView: (UIView *) view {
      CGPoint origin = view.bounds.origin;
      CGPoint viewOrigin = [self convertPoint: origin fromView: view];
      return [self indexPathForRowAtPoint: viewOrigin];
    }
    

    And the IBAction on the button:

    - (void) buttonTapped: (UIButton *) sender {
      NSIndexPath *indexPath = [self.tableView indexPathForView: sender];
      NSLog(@"Button tapped at indexpPath [%ld-%ld]",
            (long)indexPath.section,
            (long)indexPath.row);
    }
    

    In Swift:

    import UIKit
    
    public extension UITableView {
      func indexPathForView(_ view: UIView) -> IndexPath? {
        let origin = view.bounds.origin
        let viewOrigin = self.convert(origin, from: view)
        let indexPath = self.indexPathForRow(at: viewOrigin)
        return indexPath
      }
    }
    

    I added this as a file "UITableView+indexPathForView" to a test project to make sure I got everything correct. Then in the IBAction for a button that is inside a cell:

    func buttonTapped(_ button: UIButton) {
      let indexPath = self.tableView.indexPathForView(button)
      print("Button tapped at indexPath \(indexPath)")
    }
    

    I made the extension work on any UIView, not just buttons, so that it's more general-purpose.

    The nice thing about this extension is that you can drop it into any project and it adds the new indexPathForView(_:) function to all your table views without having do change your other code at all.

提交回复
热议问题