来自 Interface Builder 的自定义 UIView

Posted

技术标签:

【中文标题】来自 Interface Builder 的自定义 UIView【英文标题】:Custom UIView from Interface Builder 【发布时间】:2011-02-02 00:06:12 【问题描述】:

我正在努力让事情井井有条,并为我的应用创建视图层次结构。 例如,我想创建一个自定义视图来显示一些文本,另一个自定义视图来显示进度,然后在使用 View-Based Application 模板创建的主视图中使用所有这些视图。

我知道如何以编程方式创建它 - 你创建 UIView 子类,实现 drawRect 方法,在 Interface Builder 中放置一个空的 UIView 并有可能它是 Class我的自定义课程。我的问题是我想在 Interface Builder 中以编程方式创建这些自定义视图

到目前为止,我已经使用 XIB 文件创建了UIViewController 控制器,并在模板的视图控制器的viewDidLoad 方法中创建了该自定义视图控制器实例并将其视图添加为在 Interface Builder 中添加的空 UIView(与您在编程方法中更改 Class 相同)。

它有效,但它对我来说更像是一种 hack,我很难相信没有更好的方法可以在界面生成器中添加这些自定义视图而无需实现 viewDidLoad 方法并创建控制器并在该方法中添加他们的视图。

【问题讨论】:

【参考方案1】:

这原本是 Ratinho 帖子中的评论,但变得太大了。

虽然我自己的经验与这里和上面提到的一切一致,但有些事情可能会减轻你的痛苦,或者至少让事情变得不那么骇人听闻。

从一个通用类(例如 EmbeddableView)派生所有自定义 UIView 类。将所有 initWithCoder 逻辑包装在此基类中,使用 Class 标识(或可重载方法)来确定要初始化的 NIB。这仍然是一个 hack,但您至少可以形式化接口规则并隐藏机制。

此外,您可以通过使用与您的自定义视图配对的“微控制器”类来进一步增强您的 Interface Builder 体验,以处理它们的委托/操作方法,并通过它自己的委托协议弥合与主 UIViewController 的差距。所有这些都可以使用 Interface Builder 中的连接器连接在一起。

底层 UIViewController 只需要实现足够的功能即可满足“微控制器”委托模式。

您已经了解了通过更改类名和处理 nib 加载来添加自定义视图的详细信息。 “微控制器”(如果使用)可以只是 NSObject 派生类added to the NIB as suggested here。

虽然我已经在孤立的情况下完成了所有这些步骤,但我从来没有采取这种形式的正式解决方案,但经过一些规划,它应该是相当可靠和稳健的。

【讨论】:

【参考方案2】:

为此,您必须为使用自定义控件的类的 Interface Builder 创建一个插件。创建并安装插件后,您将能够通过拖放将视图实例添加到另一个窗口或 Interface Builder 中的视图。要了解如何创建 IB 插件,请参阅 Interface Builder Plug-In Programming Guide 和 Aaron Hillegass 的书 Cocoa Programming for Mac OS X 中有关创建自己的 IB Palette 控件的章节。

Here 是a similar question 已接受答案的原作者的链接。

【讨论】:

【参考方案3】:

也许我没听懂你? 您在界面构建器中有库您可以移动您想要的每个组件并将其放置在您的视图中。 (您可以通过添加 UIView 并在第 4 个选项卡中更改其类名来添加另一个视图)。 然后你用 IBOutlet 声明变量并将它们从你文件所有者的第二个选项卡连接到他们的组件......另一个问题?

【讨论】:

嗯.. 假设我的项目中有 4 个 XIB - 2 个“标准”基于视图的应用程序模板 XIB:MainWindows.xib 和 TestViewController.xib。现在为了保持整洁,我想创建 2 个额外的视图 - 另一个 XIB 中的每个视图:CustomTextView.xib 和 CustomProgressView.xib。我将 UILabel 和 UIButton 添加到第一个,将 UILabel UIProgressView 添加到第二个。现在我想将这两个自定义视图添加到我的 TestViewController.xib 视图中。我该怎么做(除了我这样做的方式和使用 XIB 设计而不是 UIView 子类在 drawRect 中绘制所有内容)? 好的,我想我明白了。如果 CustomTextView 和 CustomProgressView 是视图或扩展它,您应该将 UIView 添加到您的主视图中 - 例如 mainWindow- 和身份检查器(检查器中的第 4 个选项卡) ) 你应该将 Class 从 UIView 更改为你的类(CustomProgressView 例如)。 好的 - 但为此我必须创建一个作为 UIView 子类的类 - 否则 CustomTextView 在 Class 字段中将不可见。如果这样做,我如何将它与我创建的 CustomTextView.xib 文件“连接”?我设法覆盖 initWithCoder 方法,使用 [NSBundle loadNibNamed] 方法加载该 xib 并添加它作为 UIView 子类的子视图返回的第一个视图,但它仍然感觉像黑客攻击,并且应该有更好的方法来做到这一点。 在界面生成器中打开你的XIB,点击cmd+a,cmd+c,然后创建新的普通视图控制器并将其粘贴到它的XIB中;) 嘿——这就是我试图避免的,以保持事物井井有条并创建可重复使用的视图/控件,而不是将所有东西都放在一个笔尖中。现在,我使用有助于加载 XIB 文件并将它们添加到该视图的方法创建了 UIView 子类,并创建了该类的子类,在我使用这些方法加载和“连接”XIB 的地方覆盖了 initWithCoder。如果这是苹果应该解决的“唯一方法”。我不知道为什么他们不能像对 UIView 子类一样,从项目中找到 XIB 文件并将其加载到库中。【参考方案4】:

不幸的是,你不能用 UIKit 做你想做的事。 IB 插件仅适用于 OS X,Apple 明确不允许它们用于 ios 开发。与它们不是静态库有关。谁知道呢,他们总有一天会改变这一点,但我不会屏住呼吸。

【讨论】:

以上是关于来自 Interface Builder 的自定义 UIView的主要内容,如果未能解决你的问题,请参考以下文章