在故事板中,如何制作用于多个控制器的自定义单元格? [英] In a storyboard, how do I make a custom cell for use with multiple controllers?

查看:20
本文介绍了在故事板中,如何制作用于多个控制器的自定义单元格?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在我正在开发的应用中使用故事板.在应用程序中有列表用户,每个都包含另一个集合(列表的成员,用户拥有的列表).因此,相应地,我有 ListCellUserCell 类.目标是让它们在整个应用程序中(即,在我的任何 tableview 控制器中)可重复使用.

I'm trying to use storyboards in an app I'm working on. In the app there are Lists and Users and each contains a collection of the other (members of a list, lists owned by a user). So, accordingly, I have ListCell and UserCell classes. The goal is to have those be re-usable throughout the app (ie, in any of my tableview controllers).

这就是我遇到问题的地方.

That's where I'm running into a problem.

如何在故事板中创建可在任何视图控制器中重复使用的自定义 tableview 单元格?

以下是我迄今为止尝试过的具体事情.

Here are the specific things I've tried so far.

  • 在控制器 #1 中,添加了一个原型单元,将类设置为我的 UITableViewCell 子类,设置重用 ID,添加标签并将它们连接到类的插座.在 Controller #2 中,添加了一个空的原型单元格,将其设置为与以前相同的类并重用 id.当它运行时,当单元格显示在控制器 #2 中时,标签永远不会出现.在控制器 #1 中工作正常.

  • In Controller #1, added a prototype cell, set the class to my UITableViewCell subclass, set the reuse id, added the labels and wired them to the class's outlets. In Controller #2, added an empty prototype cell, set it to the same class and reuse id as before. When it runs, the labels never appear when the cells are shown in Controller #2. Works fine in Controller #1.

在不同的 NIB 中设计每种细胞类型,并连接到适当的细胞类别.在故事板中,添加了一个空的原型单元格并设置其类并重用 id 来引用我的单元格类.在控制器的 viewDidLoad 方法中,为重用 ID 注册这些 NIB 文件.显示时,两个控制器中的单元格都像原型一样是空的.

Designed each cell type in a different NIB and wired up to the appropriate cell class. In storyboard, added an empty prototype cell and set its class and reuse id to refer to my cell class. In controllers' viewDidLoad methods, registered those NIB files for the reuse id. When shown, cells in both controllers were empty like the prototype.

将两个控制器中的原型保留为空并设置类并将 id 重用于我的单元类.完全在代码中构建单元格的 UI.单元格在所有控制器中都能完美运行.

Kept prototypes in both controllers empty and set class and reuse id to my cell class. Constructed the cells' UI entirely in code. Cells work perfectly in all controllers.

在第二种情况下,我怀疑原型总是覆盖 NIB,如果我杀死了原型单元,注册我的 NIB 以获得重用 ID 会起作用.但是这样我就无法设置从单元格到其他帧的转场,这才是使用故事板的真正意义所在.

In the second case I suspect that the prototype is always overriding the NIB and if I killed the prototype cells, registering my NIB for the reuse id would work. But then I wouldn't be able to setup segues from the cells to other frames, which is really the whole point of using storyboards.

归根结底,我想要两件事:在故事板中连接基于 tableview 的流程,并以视觉方式而不是在代码中定义单元格布局.到目前为止,我不知道如何获得这两个.

At the end of the day, I want two things: wire up tableview based flows in the storyboard and define cell layouts visually rather than in code. I can't see how to get both of those so far.

推荐答案

据我所知,您想要:

  1. 在 IB 中设计一个可用于多个故事板场景的单元格.
  2. 根据单元格所在的场景,从该单元格配置独特的故事板转场.

不幸的是,目前没有办法做到这一点.要了解您之前的尝试为何无效,您需要更多地了解故事板和原型表视图单元格的工作原理.(如果您不关心为什么这些其他尝试没有成功,请随时离开.除了建议您提交错误之外,我没有什么神奇的解决方法可供您使用.)

Unfortunately, there is currently no way to do this. To understand why your previous attempts didn't work, you need to understand more about how storyboards and prototype table view cells work. (If you don't care about why these other attempts didn't work, feel free to leave now. I've got no magical workarounds for you, other than suggesting that you file a bug.)

从本质上讲,故事板只不过是 .xib 文件的集合.当您从故事板加载具有一些原型单元格的表视图控制器时,会发生以下情况:

A storyboard is, in essence, not much more than a collection of .xib files. When you load up a table view controller that has some prototype cells out of a storyboard, here's what happens:

  • 每个原型单元实际上都是它自己的嵌入式迷你笔尖.因此,当表视图控制器加载时,它会遍历每个原型单元格的笔尖并调用 -[UITableView registerNib:forCellReuseIdentifier:].
  • 表格视图向控制器询问单元格.
  • 你可能调用了 -[UITableView dequeueReusableCellWithIdentifier:]
  • 当您请求具有给定重用标识符的单元格时,它会检查它是否已注册笔尖.如果是,它会实例化该单元格的一个实例.这由以下步骤组成:

  • Each prototype cell is actually its own embedded mini-nib. So when the table view controller is loading up, it runs through each of the prototype cell's nibs and calls -[UITableView registerNib:forCellReuseIdentifier:].
  • The table view asks the controller for the cells.
  • You probably call -[UITableView dequeueReusableCellWithIdentifier:]
  • When you request a cell with a given reuse identifier, it checks whether it has a nib registered. If it does, it instantiates an instance of that cell. This is composed of the following steps:

  1. 查看单元格的类,如单元格的笔尖中所定义.调用 [[CellClass alloc] initWithCoder:].
  2. -initWithCoder: 方法遍历并添加子视图并设置在笔尖中定义的属性.(IBOutlets 可能也被连接到这里,虽然我没有测试过;它可能发生在 -awakeFromNib)
  1. Look at the class of the cell, as defined in the cell's nib. Call [[CellClass alloc] initWithCoder:].
  2. The -initWithCoder: method goes through and adds subviews and sets properties that were defined in the nib. (IBOutlets probably get hooked up here as well, though I haven't tested that; it may happen in -awakeFromNib)

  • 你可以随意配置你的单元.

  • You configure your cell however you want.

    这里需要注意的重要一点是,单元格的和单元格的视觉外观之间是有区别的.您可以创建同一类的两个单独的原型单元格,但它们的子视图布局完全不同.事实上,如果你使用默认的 UITableViewCell 样式,这正是正在发生的事情.例如,默认"样式和字幕"样式都由同一个 UITableViewCell 类表示.

    The important thing to note here is there is a distinction between the class of the cell and the visual appearance of the cell. You could create two separate prototype cells of the same class, but with their subviews laid out completely differently. In fact, if you use the default UITableViewCell styles, this is exactly what's happening. The "Default" style and the "Subtitle" style, for example, are both represented by the same UITableViewCell class.

    这很重要:单元格的与特定的视图层次结构没有一对一的相关性.视图层次结构完全由注册到该特定控制器的原型单元中的内容决定.

    This is important: The class of the cell does not have a one-to-one correlation with a particular view hierarchy. The view hierarchy is determined entirely by what's in the prototype cell that was registered with this particular controller.

    还要注意,细胞的重用标识符未在某些全球细胞药房中注册.重用标识符仅在单个 UITableView 实例的上下文中使用.

    Note, as well, that the cell's reuse identifier was not registered in some global cell dispensary. The reuse identifier is only used within the context of a single UITableView instance.

    根据这些信息,让我们看看在您的上述尝试中发生了什么.

    Given this information, let's look at what happened in your above attempts.

    在 Controller #1 中,添加了一个原型单元,将类设置为 myUITableViewCell 子类,设置复用id,添加标签和连线他们到班级的网点.在控制器 #2 中,添加了一个空的原型单元,将其设置为相同的类并像以前一样重用 id.什么时候它运行,当单元格显示时标签永远不会出现控制器#2.在控制器 #1 中工作正常.

    In Controller #1, added a prototype cell, set the class to my UITableViewCell subclass, set the reuse id, added the labels and wired them to the class's outlets. In Controller #2, added an empty prototype cell, set it to the same class and reuse id as before. When it runs, the labels never appear when the cells are shown in Controller #2. Works fine in Controller #1.

    这是意料之中的.虽然两个单元格具有相同的类,但传递给控制器​​ #2 中单元格的视图层次结构完全没有子视图.所以你得到了一个空单元格,这正是你放入原型中的内容.

    This is expected. While both cells had the same class, the view hierarchy that was passed to the cell in Controller #2 was entirely devoid of subviews. So you got an empty cell, which is exactly what you put in the prototype.

    在不同的 NIB 中设计每种电池类型并连接到适当的细胞类别.在故事板中,添加了一个空的原型单元格并设置它的类并重用 id 来引用我的单元类.在控制器的 viewDidLoad 方法,为重用 ID.显示时,两个控制器中的单元格都是空的,就像原型.

    Designed each cell type in a different NIB and wired up to the appropriate cell class. In storyboard, added an empty prototype cell and set its class and reuse id to refer to my cell class. In controllers' viewDidLoad methods, registered those NIB files for the reuse id. When shown, cells in both controllers were empty like the prototype.

    同样,这是意料之中的.重用标识符在故事板场景或笔尖之间不共享,因此所有这些不同的单元格具有相同的重用标识符这一事实毫无意义.您从 tableview 中返回的单元格的外观将与故事板场景中的原型单元格相匹配.

    Again, this is expected. The reuse identifier is not shared between storyboard scenes or nibs, so the fact that all of these distinct cells had the same reuse identifier was meaningless. The cell you get back from the tableview will have an appearance that matches the prototype cell in that scene of the storyboard.

    不过,这个解决方案很接近.正如您所指出的,您可以以编程方式调用 -[UITableView registerNib:forCellReuseIdentifier:],传递包含单元格的 UINib,然后您将返回同一个单元格.(这不是因为原型覆盖"了笔尖;您只是没有在 tableview 中注册笔尖,所以它仍在查看嵌入在故事板中的笔尖.)不幸的是,这种方法有一个缺陷——无法将故事板 segue 连接到独立笔尖中的单元格.

    This solution was close, though. As you noted, you could just programmatically call -[UITableView registerNib:forCellReuseIdentifier:], passing the UINib containing the cell, and you'd get back that same cell. (This isn't because the prototype was "overriding" the nib; you simply hadn't registered the nib with the tableview, so it was still looking at the nib embedded in the storyboard.) Unfortunately, there's a flaw with this approach — there's no way to hook up storyboard segues to a cell in a standalone nib.

    保持两个控制器中的原型为空并设置类并重用 id到我的细胞课.完全在代码中构建单元格的 UI.细胞在所有控制器中都能完美运行.

    Kept prototypes in both controllers empty and set class and reuse id to my cell class. Constructed the cells' UI entirely in code. Cells work perfectly in all controllers.

    自然.希望这并不令人意外.

    Naturally. Hopefully, this is unsurprising.

    所以,这就是它不起作用的原因.您可以在独立的笔尖中设计单元格并在多个故事板场景中使用它们;您目前无法将故事板 segue 连接到这些单元格.不过,希望您在阅读本文的过程中学到了一些东西.

    So, that's why it didn't work. You can design your cells in standalone nibs and use them in multiple storyboard scenes; you just can't currently hook up storyboard segues to those cells. Hopefully, though, you've learned something in the process of reading this.

    这篇关于在故事板中,如何制作用于多个控制器的自定义单元格?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

  • 查看全文
    相关文章
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆