1

我有一个问题,我有一个表格,每个单元格中都有一个 UISwitch。当用户单击开关时,我想知道哪个单元格包含开关。

该代码在 ios6 和 ios 7 中断中运行良好:

代码是这样的:

-(IBAction) doToggle:(id)sender {
UISwitch *toggle = (UISwitch *)sender;
MyCell *cell = (MyCell *)((UISwitch *)sender).superview.superview;
NSLog(@"=========== CELL %@", cell.description);
NSDictionary *item = [list objectAtIndex:[cell index]]; //breaks in this line

在 NSLog 我看到以下内容

iOS6:

<MyCell: 0x858b750; baseClass = UITableViewCell; frame = (0 0; 320 44); autoresize = W; layer = <CALayer: 0x858b890>>

IOS 7:

<UITableViewCellScrollView: 0x8e5a290; frame = (0 0; 320 44); autoresize = W+H; gestureRecognizers = <NSArray: 0x8e5a740>; layer = <CALayer: 0x8e5a4c0>; contentOffset: {0, 0}>

有人可以帮我解决这个问题,在此先感谢!

4

9 回答 9

4

我认为比标签杂耍更清洁的解决方案是创建一个具有委托协议的自定义单元格,将方法的目标/操作和单元格添加到 UISwitch 并调用委托(视图控制器)方法-toggleSwitched:(BOOL) switchOnOff onMyCell:(MyCell *) cell和你将实现此委托方法,例如:

-(void)toggleSwitched:(BOOL) switchOnOff onMyCell:(MyCell *) cell
{
    NSIndexPath *indexPath = [self.tableView indexPathForCell:cell];
    // use indexPath to fetch right element
    // ie:
    if(switchOnOff) {
        NSDictionary *item = list[indexPath.row];
    } else {
        // ??
    }
}
于 2013-08-27T22:50:02.387 回答
2

您不应该尝试以这种方式获取数据。如您所见,单元格的结构在 iOS 6 和 iOS 7 中明显不同(我们无法真正谈论,因为 iOS 7 仍处于 NDA 之下)。与其通过“向上爬”子视图路径来获取单元格,不如为您的开关提供一个等于 indexPath.row 的标签,然后使用它来查询您的数据源以获取字典。

-(IBAction) doToggle:(UISwitch *)sender {

    NSDictionary *item = list[sender.tag];
} 
于 2013-08-27T22:04:58.037 回答
2

在 iOS7 之前,cell 的 superview 是UITableView包含它的。从 iOS7 GM 开始(大概也会在公开版本中),单元格的超级视图是 a UITableViewWrapperView,其超级视图是UITableViewCell. 该问题有两种解决方案。

解决方案 #1:创建一个UITableViewCell类别

@implementation UITableViewCell (RelatedTable)

- (UITableView *)relatedTable
{
    if ([self.superview isKindOfClass:[UITableView class]])
        return (UITableView *)self.superview;
    else if ([self.superview.superview isKindOfClass:[UITableView class]])
        return (UITableView *)self.superview.superview;
    else
    {
        NSAssert(NO, @"UITableView shall always be found.");
        return nil;
    }

}
@end

这是一个很好的替代 using cell.superview,使重构现有代码变得容易 - 只需搜索和替换 with [cell relatedTable],并抛出一个断言以确保如果视图层次结构在未来发生变化或恢复,它将显示立即在您的测试中。

解决方案#2:添加一个弱UITableView引用UITableViewCell

@interface SOUITableViewCell

   @property (weak, nonatomic) UITableView *tableView;

@end

这是一个更好的设计,尽管它需要更多的代码重构才能在现有项目中使用。在您tableView:cellForRowAtIndexPath使用 SOUITableViewCell 作为您的单元格类或确保您的自定义单元格类从子类SOUITableViewCell化并将 tableView 分配给单元格的 tableView 属性。在单元格内,您可以使用self.tableView.

于 2013-09-18T14:58:22.370 回答
1

许多开发人员使用自定义视图在旧版本 iOS 的表格视图中显示自定义单元格。如果您是其中之一,那么您将不得不面对一个问题,即您的按钮单击操作将不再适用于 iOS7。

如何解决这个问题:

你有三个选择:

选项 1: 使用新表格单元创建新布局,而不是查看。并将所有布局再次放入表格单元格中。

我知道,这需要付出很多努力。如果您不想这样做,我们有一个非常小的技巧:选项 2

选项 2:为您的按钮创建一个 IBOutlet 并将此按钮添加为单元格内容视图的子视图。

[self.myCell.contentView addSubview:self.btn_click];

上面的代码行将 btn_click 添加为内容视图的子视图。现在按钮点击动作应该可以工作了。

选项 3:

最好的办法 :

i) 取一个插座 UITableViewCell。ii) 将现有视图作为新表格单元格的子视图。iii) 断开自定义单元与现有视图的连接,并将其连接到新的 UITableViewCell。

就是这样,您的 IBAction 现在可以工作了。

可能是您因“类不符合键值编码”的错误消息而崩溃。检查您的旧视图连接并删除所有带有黄色标记的连接。

于 2013-09-30T15:26:01.717 回答
1

我遇到了同样的问题。此代码不保证“ (UITableViewCell *)[[[self superview] superview] superview];”。您可以在 iOS7 上使用此代码。

-(void)buttonClicked:(id)sender
{
    UIButton *button=(UIButton*)sender;
    UITableViewCell *selectedCell = (UITableViewCell*)[self.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:button.tag inSection:0]];
    NSLog("%@",selectedCell.lblTitle.text);
}
于 2013-10-12T13:55:48.517 回答
1

对于那些仍然喜欢像我这样简单而肮脏的修复的人,我认为这将解决您的问题!!!干杯!!!!!

// Patch to get the table view cell because in iOS7 the superview is a butch
- (UITableViewCell *) getTableViewCellFromSubview:(UIView*)subview
{
    UITableViewCell* tableViewCell = nil;

    while (subview.superview != Nil) {
        if ([subview.superview isKindOfClass:[UITableViewCell class]]) {
            tableViewCell = (UITableViewCell*)subview.superview;
            break;
        } else {
            subview = subview.superview;
        }
    }

    return tableViewCell;
}
于 2013-11-05T07:26:44.087 回答
1

试试这个。它对我有用。

NSIndexPath *indexPath;
if (floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_6_1)
{
    indexPath = [self.tableview indexPathForCell:(UITableViewCell*)[[senderButton superview] superview]];

}
else
{
    indexPath = [self.tableview indexPathForCell:(UITableViewCell*)[[[senderButton superview] superview] superview]];
}

NSLog(@"table row - %d and table column - %d",indexPath.row , indexPath.section);
于 2013-12-02T05:23:42.103 回答
0

当 superview 返回意外对象时,API 已更改导致大量崩溃。下面是我用作自定义 UITableViewCell 的自定义 backgroundView 的自定义 uiview 的 tableview 和单元格访问器的示例。这适用于 ios6/ios7。

- (UITableView *)tableView
{
    if (floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_6_1) {
        return (UITableView *)[self cell].superview;
    } else {
        // Load resources for iOS 7 or later
        return (UITableView *)[self cell].superview.superview;
    }

}

- (UITableViewCell *)cell
{
    UIView *v = self;
    while (v && ![v isKindOfClass:[UITableViewCell class]]) v = v.superview;
    return (UITableViewCell *)v;
}
于 2013-09-13T06:08:27.967 回答
0

我按照提供的解决方案#1 Answerbot 解决了同样的问题。(对不起,Answerbot,我还没有足够的声望来投票给你的答案)

但是,在这种情况下,我们应该创建一个 UIView 类别:

@implementation UIView (GetCellFromContentviewSubview)
- (UITableViewCell *)getCellFromContentviewSubview
{
    if ([[[self superview] superview] isKindOfClass:[UITableViewCell class]]) {
        return (UITableViewCell *)[[self superview] superview];
    }
    else if ([[[[self superview] superview] superview] isKindOfClass:[UITableViewCell class]]) {
        return (UITableViewCell *)[[[self superview] superview] superview];
    }
    else{
         NSLog(@"something Panic happens");
    }
    return nil;
}

@end

使用(MyCell *)[mySwitch getCellFromContentviewSubview]replace (MyCell *)[[mySwitch superview] superview],然后,您将获得您的单元格。

iOS7中table view cell的层次结构似乎与iOS6不同,UITableViewCell和UITableViewCellContentView之间有一个UITableViewCellScrollView。

于 2013-09-21T08:45:38.193 回答