2011-05-01 70 views
21

我有三个不同的UITableViews,每个都在它自己的视图中,通过选项卡访问。理想情况下,所有三个表都将共享相同的自定义UITableViewCell类和.xib文件。一个具有多个“文件所有者”的xib文件

我从一张表开始,将.xib的类设置为我的自定义类,并将.xib的文件所有者设置为表的父级UIViewController,这非常棒。所有与视图相关的自定义代码都在单元的类中(基于控制器设置的属性的背景图像,基于控制器设置的单元格属性根据标签所需行数的自定义单元高度等) 。

结果很好:单元负责所有的可视布局,并响应用户对单元控件的操作,而视图控制器负责创建单元并设置其数据。

现在我需要重用其他表中的单元格,但是,自定义单元格的.xib具有单个文件所有者这一事实是一个问题。而不是复制.xib文件,是否有一种允许多个控制器拥有它的简单方法?

+0

我想我没有按照你的问题100%。你使用'UITableView'的委托方法' - (UITableViewCell *)cellForRowAtIndexPath:(NSIndexPath *)indexPath'? – joshpaul 2011-05-01 20:05:06

+0

@joshpaul是的。问题在于其他视图控制器无法访问另一个作为所有者的控制器的.xib控件/属性。 – 2011-05-01 20:18:50

+0

我有自定义单元格的xib'File's Owner'设置为NSObject,'Cell'设置为MyCustomTableViewCell。 – joshpaul 2011-05-02 16:13:33

回答

37

笔尖的文件所有者没有严格执行。相反,它仅用于确定可用的出口和操作,并在Interface Builder中设置绑定。无论nib文件中设置的类如何,您都可以使用任何对象加载一个nib作为它的文件所有者。当一个笔尖被加载时,它将向文件的所有者发送消息以重新建立绑定。如果实际的文件所有者对象不能识别这些选择器,则会触发“无法识别的选择器”异常。这意味着如果你的nib将一些UITableViewCell绑定到它的File's Owner的'cell'插座,那么任何具有'cell'属性的对象都可以加载该nib。您只需要小心不要使用此行为来发送无法识别的选择器或意外的插座类。

在你的情况下,考虑创建一个单独的UIViewController子类作为你的笔尖的文件所有者。让您的三个现有控制器都扩展该视图控制器子类。这样,它们都可以继承nib文件所期望的同一组属性,并且都可以安全地加载该nib,同时仍然定义它们自己的自定义行为。

+0

啊,好主意。核心问题是其他视图控制器无法访问实例化的单元格的属性;这很好地解决了这个问题。谢谢。 – 2011-05-01 20:13:20

+0

我一直在为此工作一段时间,而且我非常接近回答我的问题。也许有一点帮助?您的建议如何实际使用的示意图会很棒。我已经尝试过,并且无法获得UITableViewCell的三个不同子类在XIB中共享相同的TVCell。 – mputnamtennessee 2012-01-25 22:45:55

+3

@ mputnamtennessee,你将无法做到。从nib文件加载的视图的类由nib本身定义。上面的答案是参考不同的控制器类从同一个nib文件加载同一个UITableViewCell的实例。这不同于尝试从nib本身中加载在nib中找到的类的多个子类。你似乎有一个不同的问题来解决这可能是值得开一个新的问题。 – Jonah 2012-01-26 01:54:23

4

checked answerthis question讨论了从nib文件加载自定义表格单元格的两种方法,它们不需要将文件的所有者设置为您的特定控制器。这些方法可让您重用不同所有者的单元。

+1

感谢您将我指向这些人,他们都是按照我喜欢的方式来组织工作的好方法。不幸的是,两者都需要对其他代码进行重大的重组,现在我还没有时间。我相信稍后我会为这种选择付费,但是,这是一种代码业力。 :) – 2011-05-01 20:16:30

1

作为文件所有者的“共享”超类并不总是一个好的解决方案。 记住,你可以随时加载厦门国际银行在您的视图,并进行连接,而不使用出口,例如:

UIView *aView = [[NSBundle mainBundle] loadNibNamed:@"MyXibFile" owner:self options:nil] 
//Search subviews by tag. Obviously you need to set the tag on your view in MyXibFile 
UILabel *aLabel = (UILabel*)[aView viewWithTag:996]; 
UILabel *aTextField = (UITextField*)[aView viewWithTag:997]; 
aTextField.delegate = self; 
//etc... 

我不能说这是一个干净的解决方案,但在某些情况下可以工作好过继承。