【问题标题】:IOS 7 - How to get the indexPath from button placed in UITableViewCellIOS 7 - 如何从放置在 UITableViewCell 中的按钮获取 indexPath
【发布时间】:2013-09-30 18:37:03
【问题描述】:

我以编程方式创建了一个 UITableView 并将 UISwitch 添加到它的单元格附件视图中。

这是我在cellForRowAtIndexPath 方法中的单元格附件视图中的 UISwitch 代码。

UISwitch *accessorySwitch = [[UISwitch alloc]initWithFrame:CGRectZero];
[accessorySwitch setOn:NO animated:YES];
[accessorySwitch addTarget:self action:@selector(changeSwitch:) forControlEvents:UIControlEventValueChanged];
cell.accessoryView = accessorySwitch;

这是点击按钮后调用的方法。

- (void)changeSwitch:(UISwitch *)sender{

    UITableViewCell *cell = (UITableViewCell *)[sender superview];

    NSIndexPath *indexPath = [self.filterTableView indexPathForCell:cell];
    NSLog(@"%ld",(long)indexPath);

 ……………. My other code…….
}

我能够在 iOS 6 中打印索引路径值 但在 iOS 7 中它打印 nil,

我是在 iOS 7 中遗漏了什么,还是有其他方法可以在 iOS 7 中获取 indexPath

谢谢, 阿伦。

【问题讨论】:

    标签: iphone ios uitableview ios7


    【解决方案1】:

    NSLog(@"%ld",(long)indexPath);错了会打印indexPath的指针地址

    尝试使用以下代码

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

    【讨论】:

    • 它太打印空了
    • 您也可以打印 sender.center 吗?和根视点
    • 如果你很好奇,同样的事情对于 UICollectionView:CGPoint center = button.center; CGPoint rootViewPoint = [button.superview convertPoint:center toView:collection]; NSIndexPath *indexPath = [集合 indexPathForItemAtPoint:rootViewPoint]; NSDictionary *type = [self.serviceTypes objectAtIndex:indexPath.row];
    【解决方案2】:

    Swift 解决方案: 像这样的 UITableView 扩展对此很有用。

    extension UITableView {
        func indexPathForView(view: AnyObject) -> NSIndexPath? {
            let originInTableView = self.convertPoint(CGPointZero, fromView: (view as! UIView))
            return self.indexPathForRowAtPoint(originInTableView)
        }
    }
    

    在任何地方都可以轻松使用。

    let indexPath = tableView.indexPathForView(button)
    

    【讨论】:

    • 非常好。有效。谢谢。 CGPointZero 在 Swift 中不存在。使用 let originInTableView = self.convert(CGPoint(x: 0,y :0), from: (view as! UIView))
    【解决方案3】:

    如果单元格中有按钮。您可以通过调用 superview 来获取单元格。然后就可以通过这种方式得到Indexpath了。

     (void)obButtonTap:(UIButton *)sender {
    
        UITableViewCell *cell = (UITableViewCell *)sender.superview;
        NSIndexPath *indexPath = [tableView indexPathForCell:cell];
    }
    

    【讨论】:

    • 这不是依赖于 iOS 7 的人...检查您的代码可能与您的代码有问题。
    • iOS 7 改变了层次结构stackoverflow.com/questions/19162725/…
    • 你应该写成 .. UITableViewCell *cell = (UITableViewCell *)sender.superview.superview.superview 然后
    【解决方案4】:

    您可以在 cellForRowAtIndexPath 方法中为每个开关分配标签,例如

    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {    
       UISwitch *accessorySwitch = [[UISwitch alloc]initWithFrame:CGRectZero];
       [accessorySwitch setOn:NO animated:YES];
       [accessorySwitch addTarget:self action:@selector(changeSwitch:) forControlEvents:UIControlEventValueChanged];
       cell.accessoryView = accessorySwitch; 
       accessorySwitch.tag = indexPath.row;    
    }
    
    - (void)changeSwitch:(UISwitch *)sender{
        NSIndexPath *indexPath = [NSIndexPath indexPathWithIndex:[sender tag]];
        NSLog(@"%ld",(long)indexPath);
    }
    

    【讨论】:

    • 但我的代码中同时需要 indexPath.row 和 indexPath.section。
    【解决方案5】:

    SWIFT 4:

    extension UITableView {
        func indexPathForView(view: AnyObject) -> NSIndexPath? {
            let originInTableView = self.convert(CGPoint.zero, from: (view as! UIView))
            return self.indexPathForRow(at: originInTableView)! as NSIndexPath
        }
    }
    

    【讨论】:

    • 如果我要努力获取别人的答案并将其转换为 Swift 4,我至少会修复一些不良做法,例如将 AnyObject 强制解包为 UIView。或者,由于它是 Swift 4,将 NSIndexPath 更改为 IndexPath
    【解决方案6】:

    SWIFT 4 转换,创建全球扩展:

    extension UITableView {
        func indexPathForView(view: UIView) -> IndexPath? {
                let originInTableView = self.convert(CGPoint.zero, from: (view))
                return self.indexPathForRow(at: originInTableView)
            }
    }
    

    使用示例:

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = ...
    cell.myButton.addTarget(self, action: #selector(myButtonAction(_:)), for: .primaryActionTriggered)
    return cell
    
        }
    
    @objc func myButtonAction(_ button:UIButton) {
    
            guard let ip = self.tableView.indexPathForView(view: button) else {
                return
            }
    }
    

    【讨论】:

      【解决方案7】:

      假设开关的superview 将是tableViewCell,您可能会被烧毁。也许在 iOS 7 中他们改变了层次结构以达到某种视觉效果;也许那里插入了一个新视图。

      你可以继承UISwitch 并给它一个indexPath 属性。然后在您的cellForRowAtIndexPath 中,将其分配到那里,以便您有参考。

      【讨论】:

        【解决方案8】:

        我认为依靠按钮的位置来知道哪个按钮被点击是很危险的。

        我更喜欢创建一个字典,将按钮/开关本身作为键,并将索引路径作为值:

        - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
        ...
            UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
            NSValue * accessorySwitchKey = [NSValue valueWithNonretainedObject:[cell settingSwitch]];
            [[self switchIndexDictionary]setObject:indexPath accessorySwitchKey];
        ...
        }
        

        然后当触发开关/按钮时,我很容易从我的字典中获取索引路径:

        - (void)toggleSetting:(id)sender
        {
            UISwitch *selectedSwitch = (UISwitch *) sender;
        
            NSValue * accessorySwitchKey = [NSValue valueWithNonretainedObject:selectedSwitch];
            NSIndexPath *indexPath = [[self switchIndexDictionary]objectForKey: accessorySwitchKey];
        }
        

        【讨论】:

          【解决方案9】:

          Swift5.x

          上测试

          如果你想在点击tableViewCell中的按钮时获取行号,那么下面的函数将起作用。

           @IBAction func buttonClickeAction(_ sender: UIButton) {
                let btnPoint = sender.convert(CGPoint.zero, to: self.tableView)
                let indexPath = self.tableView.indexPathForRow(at: btnPoint)
                print(indexPath?.row)
           }
          

          【讨论】:

            猜你喜欢
            • 2013-03-20
            • 1970-01-01
            • 2017-01-27
            • 2014-09-25
            • 1970-01-01
            • 2011-01-23
            • 2013-04-20
            • 1970-01-01
            • 2014-11-10
            相关资源
            最近更新 更多