在Storyboard中使用自定义静态表格视图单元XIB

5

我有一个自定义的静态UITableViewCell,我希望它看起来与右侧详细单元格完全相同(左侧为UILabel,右侧为UILabel),但我想要右侧的UILabel成为可编辑的UITextField。由于我想在我的Storyboard中的多个视图控制器中使用此单元格,因此我决定最好的选择是创建一个名为MyEditableTableViewCell.xib的文件,以及相应的*.h,m文件。我在MyEditableTableViewCell.h中有两个公共属性:

@property (weak, nonatomic) IBOutlet UILabel *textLabel;
@property (weak, nonatomic) IBOutlet UITextField *detailTextField;

这些IBOutlet与.xib文件中的UILabelUITextField相关联。在我的storyboard中,我有一个自定义的UITableViewController子类,在必要的UITableViewCell中更改类为MyEditableTableViewCell。我在视图控制器中有一个属性: @property (weak, nonatomic) IBOutlet MyEditableTableViewCell *myCell; 然而,当我运行应用程序时,该单元格仅显示为空白单元格。对其进行一些检查,发现 [myCell isKindOfClass:[MyEditableTableViewCell class]] 返回 true。然而,UITextField 似乎从未被实例化。当我尝试更改myCell.detailTextField.text时,什么也不会发生,而myCell.detailTextField 看起来是 nil。
希望能得到任何帮助!
2个回答

8
你是如何创建 MyEditableTableViewCell 实例的?我猜想你使用了 [[MyEditableTableViewCell alloc] init] 代替从 nib 文件中加载实例。
你的视图控制器不需要那个属性。你需要使用 -[UITableView registerNib:forCellReuseIdentifier:] 方法将 cell 的 nib 注册到 table view 中。这应该在 viewDidLoad 中完成。然后,当你给 table view 发送 dequeueReusableCellWithIdentifier: 消息时,它会实例化 nib,创建一个 MyEditableTableViewCell 并返回给你。
更新:
如果你在 storyboard 中布局静态单元格,使用 xib 布局单元格有点困难。最简单的方法是直接在 storyboard 中布局 cell 的子视图。如果你有几个相同类型的 cell,可以复制和粘贴子视图到每个 cell 中。
如果你真的想使用 xib,则最简单的方法是按照以下方式构建 cell 的视图层次结构:
MyEditableTableViewCell (in storyboard)
|
+- cell's content view (created automatically by UIKit)
   |
   +- UIView (top-level view of the xib)
      |
      +- UILabel (textLabel)
      |
      +- UITextField (detailTextField)

所以你在storyboard中将单元格类设为MyEditableTableViewCell。然后创建xib。将xib文件的所有者类设置为MyEditableTableViewCell。xib不包含MyEditableTableViewCell。xib的顶级视图只是一个普通的UIView,包含子视图(标签和文本字段)。
-[MyEditableTableViewCell initWithCoder:]中,在执行self = [super initWithCoder:aDecoder]之后,实例化xib,将cell自身作为xib文件的所有者进行传递。单元格可以有与xib中的标签和文本字段连接的插座。
在实例化xib之后,将xib的顶级视图作为self.contentView的子视图添加进去。如果您正在使用自动布局,请在顶级视图和内容视图之间创建约束。否则,请将顶级视图的frame设置为内容视图的bounds,并将autoresizing mask设置为UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight

抱歉如果我表达不清,这些 UITableView 是静态的。dequeueReusableCellWithIdentifier: 从未被调用,也没有任何 UITableViewDataSource 方法被调用。MyEditableTableViewCell 直接放置在故事板中的 UITableView 中。我确实需要在我的视图控制器中拥有 IBOutlet 属性,以便在运行时编辑其文本。 - sethfri
这方面还有什么建议吗,Rob? - sethfri
如果您在故事板中使用静态表视图单元格,则这些单元格必须在故事板中布局。您不能将它们放在单独的xib文件中。 - rob mayoff
那么没有办法重复使用静态配置吗?我每次想要使用它都需要重新布置吗?如果是这种情况,请更新您的答案,我会很乐意接受它。 - sethfri
非常抱歉晚回复 - 但是有没有解释为什么无法在单独的XIB中布局单元格,然后将该UITableView的XIB加载到静态表视图中?我知道你不能这样做,但我真的很想知道原因。 - Jeff

0

尽管静态表格视图不会从nib中获取单元格,但它仍会调用cellForRowAtIndexPath。在那里,您可以取消排队并返回完全未归档的自定义单元格。在IB中设置的自定义单元格上的属性可以通过在cellForRowAtIndexPath上调用super来获取:

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

    // get an empty cell with properties retained from IB
    UITableViewCell *sup = [super tableView:tableView cellForRowAtIndexPath:indexPath];

    if ([sup isKindOfClass:[MyCustomCell class]]) {
          // fetch a fully unarchived cell
          MyCustomCell *cell = [self.tableView dequeueReusableCellWithIdentifier:@"foo" forIndexPath:indexPath];

          // copy properties over...
          [cell copyPropertiesFromCell:(MyCustomCell *)sup];

          return cell;
    }
    return sup;
}

根据情况,这可能比搞乱IB对象更容易。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接