如何在不“连接”它们的情况下以编程方式访问 NIB 中的 UI 元素?

Posted

技术标签:

【中文标题】如何在不“连接”它们的情况下以编程方式访问 NIB 中的 UI 元素?【英文标题】:How can I programmatically access UI elements in a NIB without 'wiring' them? 【发布时间】:2010-02-18 21:31:57 【问题描述】:

我正在考虑编写一些辅助函数,以便更轻松地对 iPhone NIB 中的 UI 元素进行简单更改。主要是 - 我想通过 Interface Builder 中的名称访问 UILabel 或其他元素。这可能吗?有更聪明的方法吗?

示例

假设我想制作一个显示“Hello World”的超级简单的 iPhone 应用程序。我开始一个新项目,然后打开 NIB 并将 UILabel 拖到我的视图中,并为其命名为“LblMain”。现在,假设我已经包含了方便的辅助函数,我想为标签分配一些新文本,如下所示:

[helper setText:@"Hello World" forLabel:@"LblMain"];

-或-

UILabel *ObjTmp = [helper getUILabel:@"LblMain"];
ObjTemp.text = @"Hello World";

现在 - 诀窍是我没有添加:

IBoutlet UILabel *ObjLblMain;

.h 文件中的任何位置 - 我只是动态访问该标签 - 这不是很好吗?!

现在,对于简单的应用程序,要添加更多标签或图像,我可以将它们拖到我的 NIB 中,在该元素的检查器窗口中为它们分配名称,然后立即在代码中访问它们,而无需添加它们的口吃和麻烦.h 文件。

动机

基本上,我很沮丧,因为我必须连接 NIB 中的每个元素 - 这是我宁愿避免的大量口吃和记账。 我可以为设计提供一些命名约定,它们可以生成 NIB,而无需与实现密切相关。

【问题讨论】:

8 个月后,我决定深入挖掘一下。这不是一个完整的解决方案,但是一旦您指向一个已标记为可访问的对象,您就可以通过“[lbl accessibilityLabel];”读取它的标签。这可能是某人的开始。 【参考方案1】:

加载对象后,名称 100% 无法访问,我也一直认为这很奇怪。

可以访问的是“标签”,如果你真的想在不定义出口的情况下访问一个元素,你可以设置(仅限整数)“标签”值,然后在包含标签元素的超级视图中调用viewWithTag:传入相同的整数。不要忘记默认值为“0”,所以请使用其他内容。

【讨论】:

【参考方案2】:

您绝对可以以编程方式加载 NIB,查找所有对象并查询它们以找出指向什么的对象。看看Loading Nib Files Programmatically。但问题是 Interface Builder Identity Name 没有暴露在 IB 之外。所以我不确定你会使用什么作为“forLabel”参数。 “名称”字段只是为 IB 文档窗口提供便利。它不是 NSObject 上的属性。

【讨论】:

我知道我之前看到过一些参考,但我完全无法放置/重新找到它。谢谢。嗯,关于向代码发送“名称”之类的无害方式的任何建议?比如可能在“辅助功能”中添加一个“提示”,然后在运行时清除它 - 或类似的东西? 我可以将标签中的 .xib 文件预处理为提示。【参考方案3】:

可以通过元素标签来完成: 假设您有名为“yourView”的 UIView xib 文件,其中有 UILabel,您希望无需连线即可访问它。

    在“yourView”xib 文件中为 UILabel 设置标签,假设您将 UILabel 标签设置为 100。 在任何地方加载“yourView”后,使用此代码无需任何接线即可获得 UILabel。UILabel* yourlabel =(UILabel*) [yourView viewWithTag: 100]; //do whatever you want to your label.

【讨论】:

【参考方案4】:

我认为您可以尝试在某些外部编辑器中将 xib 作为 XML 打开并查看编译器如何看待它,然后您可能会这样做

【讨论】:

【参考方案5】:

对于 ios6+,您可以使用 restoreId 代替 tag,使其更“可读”,例如,您可以在 nib 文件和恢复 id 中设置相同的名称。

如果您不想将 nib 中的所有插座链接到视图控制器,您仍然可以通过在当前视图子视图树中搜索来访问它们。请注意,子视图排列是一棵树(您可以在 nib 文件中看到同一棵树),因此如果您有嵌套视图,则需要进行一些递归。

例如:

UIButton *nibButtonView = nil;
for (UIView *view in [self.view subviews])
    if ([view.restorationIdentifier isEqualToString:@"myNibButtonView"])
        nibButtonView = (UIButton *)view;
    

[nibButtonView setTitle:@"Yeah" forState:UIControlStateNormal];

在您的 nib 文件中,您应该有一个 restoreId 等于“myNibButtonView”的按钮,您可以在身份检查器(实用程序的第三列)中找到 restoreId 文本字段

如果您有大量网点并且不想将它们全部链接起来,您可以使用它。

【讨论】:

以上是关于如何在不“连接”它们的情况下以编程方式访问 NIB 中的 UI 元素?的主要内容,如果未能解决你的问题,请参考以下文章

如何在不使用 UINavigationController 的情况下以编程方式进入 rootViewController

如何在不编码窗口状态的情况下以编程方式终止 NSApp?

如何在不使用命令的情况下以编程方式关闭/重启 linux 机器(运行时)

如何在不使用外部主机的情况下以编程方式查找设备的外部 IP 地址?

如何在不使用第三方的情况下以编程方式从 Chase 下载我的银行交易?

在没有按钮连接的情况下以编程方式执行 Segue?