IOS 7 - 如何从放置在 UITableViewCell 中的按钮获取 indexPath

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19000356/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 01:40:29  来源:igfitidea点击:

IOS 7 - How to get the indexPath from button placed in UITableViewCell

iphoneiosuitableviewios7

提问by Arun

I've programmatically created a UITableView and added UISwitch to it's cell accessory view.

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

This is my code for UISwitch in cell accessory view in cellForRowAtIndexPathmethod.

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

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

This is the method which is called after the button is clicked.

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

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

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

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

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

I am able to print the index path value in iOS 6 But in iOS 7 it prints nil,

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

Am i missing anything in iOS 7 or there is some other approach to get the indexPath in iOS 7

我是否缺少 iOS 7 中的任何内容,或者还有其他一些方法可以在 iOS 7 中获取 indexPath

Thanks, Arun.

谢谢,阿伦。

回答by lanbo

NSLog(@"%ld",(long)indexPath);is wrong this will print the pointer address of indexPath

NSLog(@"%ld",(long)indexPath);是错误的,这将打印 indexPath 的指针地址

try using following codes

尝试使用以下代码

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

回答by Ishan Handa

Swiftsolution: A UITableView extension like this one can be useful for this.

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

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

Usage becomes easy everywhere.

使用变得容易无处不在。

let indexPath = tableView.indexPathForView(button)

回答by Adnan Aftab

If you have button in cell. You can get cell by calling superview. And then can get Indexpath by this way.

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

 (void)obButtonTap:(UIButton *)sender {

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

回答by Janak Nirmal

You can assign tags to each switch in cellForRowAtIndexPath method like

您可以为 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);
}

回答by Logic

SWIFT 4 :

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

回答by Chris

SWIFT 4 Conversion, creates global extension:

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

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

Usage example:

用法示例:

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

回答by D.C.

You are probably getting burned, making the assumption that the switch's superviewis going to be the tableViewCell. Maybe in iOS 7 they changed the hierarchy to achieve some sort of visual effect; maybe there is a new view inserted in there.

您可能会被烧毁,假设交换机superview将是tableViewCell. 也许在 iOS 7 中他们改变了层次结构来实现某种视觉效果;也许那里插入了一个新视图。

You could possibly subclass UISwitchand give it an indexPathproperty. Then in your cellForRowAtIndexPath, assign it there so you have a reference.

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

回答by Omaty

I think that is dangerous to rely on the position of the button to know which one have been clicked.

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

I prefere create a dictionary taking as a key the button/switch itself, and as a value the indexpath :

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

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

then when the switch/button is triggered I get the indexpath easily from my dictionary :

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

- (void)toggleSetting:(id)sender
{
    UISwitch *selectedSwitch = (UISwitch *) sender;

    NSValue * accessorySwitchKey = [NSValue valueWithNonretainedObject:selectedSwitch];
    NSIndexPath *indexPath = [[self switchIndexDictionary]objectForKey: accessorySwitchKey];
}