动态表中自定义单元格中的按钮:如何知道动作方法中的哪一行?

时间:2014-05-29 14:08:41

标签: ios objective-c cocoa

我有一张动态内容表。在原型单元格中,我有一个按钮。在该按钮的动作方法中,如何确定按下哪一行的按钮?

(我知道,例如,在segue方法中,可以通过查询表视图的选定路径来确定已按下哪一行,但在这种情况下,实际上没有选择任何行。)

3 个答案:

答案 0 :(得分:2)

使用tag s或在您的单元格中存储indexPath等等,当然有办法实现此目的。

我更喜欢使用类似下面的内容,我认为它比上面更清晰。您可以将其添加到UITableViewController类别。

- (NSIndexPath *)indexPathForCellSubview:(UIView *)subview
{
    if (subview) {
        UITableViewCell *cell = [self tableViewCellForCellSubview:subview];
        return [self.tableView indexPathForCell:cell];
    }
    return nil;
}

- (UITableViewCell *)tableViewCellForCellSubview:(UIView *)subview
{
    if (subview) {
        UIView *superView = subview.superview;
        while (true) {
            if (superView) {
                if ([superView isKindOfClass:[UITableViewCell class]]) {
                    return (UITableViewCell *)superView;
                }
                superView = [superView superview];
            } else {
                return nil;
            }
        }
    } else {
        return nil;
    }
}

使用来自@staticVoidMan的建议进行编辑:

更简洁的实施:

- (UITableViewCell *)tableViewCellForCellSubview:(UIView *)subview
{
    UIView *checkSuperview = subview.superview;

    while (checkSuperview) {
        if ([checkSuperview isKindOfClass:[UITableViewCell class]]) {
            break;
        } else {
            checkSuperview = checkSuperview.superview;
        }
    }
    return (UITableViewCell *)checkSuperview;
}

答案 1 :(得分:1)

您可以使用标签,关联对象或超级视图技巧。

这是一个question,它有三个答案。

的标签

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *CellIdentifier = @"MySpecialCell";
    MySpecialCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (!cell) {
        cell = [[MySpecialCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
        cell.mySpecialTextView.delegate = self;
    }
    cell.mySpecialTextView.tag = indexPath.row;
    return cell;
}

- (void)textViewDidChange:(UITextView *)textView
    int rowOfTextViewThatJustChanged = textView.tag;
}

相关对象

static NSString *const kIndexPathKey = @"indexPathKey";

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *CellIdentifier = @"MultiSelectCell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (!cell) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
        UISwitch *switchView = [[UISwitch alloc] init];
        [switchView addTarget:self action:@selector(switchValueChanged:) forControlEvents:UIControlEventValueChanged];
        cell.accessoryView = switchView;
    }

    UISwitch *switchView = (id)cell.accessoryView;
    [self setIndexPath:indexPath onSwitch:switchView];
    switchView.on = [self isIndexPathSelected:indexPath];

    id item = [self itemAtIndexPath:indexPath];
    cell.textLabel.text = safePerformSelector(item, self.itemDescriptionSelector);
    return cell;
}

- (void)switchValueChanged:(UISwitch *)sender {
    NSIndexPath *indexPath = [self indexPathOfSwitch:sender];
    [self setRowSelected:sender.isOn atIndexPath:indexPath];
    [self.delegate didSelectItem:[self itemAtIndexPath:indexPath] atIndexPath:indexPath selected:sender.isOn sender:self];
}

- (void)setIndexPath:(NSIndexPath *)indexPath onSwitch:(UISwitch *)switchView {
    [switchView setAssociatedObject:indexPath forKey:kIndexPathKey];
}

- (NSIndexPath *)indexPathOfSwitch:(UISwitch *)switchView {
    return [switchView associatedObjectForKey:kIndexPathKey];
}


@implementation NSObject (AssociatedObjects)

- (void)setAssociatedObject:(id)object forKey:(NSString *const)key {
    objc_setAssociatedObject(self, (__bridge const void *)(key), object, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

- (id)associatedObjectForKey:(NSString *const)key {
    return objc_getAssociatedObject(self, (__bridge const void *)(key));
}

@end

答案 2 :(得分:1)

最佳方法:

-(void)buttonMethod:(UIButton *)sender event:(UIEvent *)event
{
    NSSet *touches = [event allTouches];
    UITouch *touch = [touches anyObject];
    CGPoint pointCurrent = [touch locationInView:self.tableView];
    NSIndexPath *indexPath = [self.tableView indexPathForItemAtPoint:pointCurrent];

    //...
}

PS:如果您做过类似的事情:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    //...

    [cell.someButton addTarget:self
                        action:@selector(buttonMethod:event:)
              forControlEvents:UIControlEventTouchUpInside];

    //...
}