如何访问在父类中声明的IBOutlets?

18

我目前正在重构几个视图控制器,这些控制器共享一些IBOutletIBAction方法。我将outlet的声明和IBAction方法移动到了一个超类中,将其从子类中删除。

现在,当我打开Interface Builder时,我发现我看不到超类中声明的outlets或actions。连接仍然存在,因为在重构之前它们已被连接起来,但是它们被灰化了。(需要注意的是,这些连接也有效,因为我的action在按下按钮时会触发,并且我的outlets也被正确地修改。)

问题是,如何让Interface Builder识别超类中的outlets?这是否可能,如果不可能,你们有什么建议?

(只是为了好玩,这里是我的超类头文件:)

@interface TFMainViewController : UIViewController {
    UIImageView *logoImage, *thinkfunImage;
    UIButton *buyFullButton;        
}

@property (nonatomic, retain) IBOutlet UIImageView *logoImage, *thinkfunImage;
@property (nonatomic, retain) IBOutlet UIButton *buyFullButton;

-(IBAction) buyFullVersion;

@end

编辑:如果有人想知道,我正在使用Xcode和IB 3.2.5,配合iOS 4.2 SDK使用。


你最终确定这是否可能了吗?我也希望做同样的事情,但是 IB 似乎无法识别该属性,除非我在子类中重新声明它? - Rog
这个项目有什么新进展吗?我在这里遇到了同样的问题 - 这次是与安装程序插件超类(InstallerPane)有关,但它不是我的,所以我无法修改它 --- 只有文档说我必须将我的.xib连接到超类的某些属性!!!怎么做? - Motti Shneor
10个回答

23

直到一个小时前,我才意识到在接口生成器中连接到超类甚至是可能的。由于这是我找到的唯一关于如何做到这一点的问题,即使这个问题很旧,我也会添加我的答案。我的答案是关于Xcode 4,而不是Xcode 3。

据我所知,你不能使用助理编辑器连接到父类中的输出口,但你可以通过点击IB中的“File's Owner”来实现。这应该在Utilities->Connections Inspector中显示所有的输出口。然后,你可以在检查器中Ctrl + 单击输出口(单击‘+’符号),并将其拖到IB中的视图上。


1
或者只需在助理编辑器中使用Cmd-Click导航到超类,然后您可以从类到IB拖动或反之亦然来连接插座或创建新的插座。 - Kendall Helmstetter Gelner

18

解决IBOutlet的问题的方法是在“Identity Inspector”中将类类型更改为基类。

enter image description here

使用控制+拖放来连接

enter image description here

然后将其更改回子类即可

enter image description here

这对我有用。顺便说一句,我使用的是Xcode 6。


1
我有同样的问题。尝试过使用NSCollectionViewItem,以便可以连接textField输出口,但仍然无法正常工作。 - pvinis

3

IB应该能够看到来自超类的输出,我已经多次这样做而没有任何问题。您确定您正在正确导入超类(使用#import而不是@class)吗?IB需要一些方式来追溯到超类。


Kendall,看一下其他答案,你是否有重复的内容,或者整个声明都在超类中?我正在使用#import,并且可以访问子类中的属性,所以我知道头文件导入是有效的。 - Sam Ritchie
我刚刚为此创建了一个测试项目 - 但它不起作用。在Xcode7.x中,IB仅显示对象实际声明的类的IBOutlets,而不包括其超类的IBOutlets。 - Motti Shneor
我只是在 Xcode 7.3 中使用 Swift 玩了一下,它仍然可以正常工作。我能够在超类中声明 IBOutlet,并将其从 IB 拖到,或者从 IB 拖到 outlet 进行连接。助手编辑器在 Automatic 部分不显示超类,但您可以导航到那里,IB 显示 outlet 来自子类(这在技术上是准确的)。@SamRitchie - 不要复制任何内容,只需在超类中拥有 outlet,而不是在子类中。 - Kendall Helmstetter Gelner

3

在身份检查器中切换超类和子类,可以让您跨类连接输出口。唯一的问题是,当您尝试使用UITableViewCell及其子类进行此操作时会出现问题。我想重新分配默认的textLabel和detailTextLabel实例到我在界面构建器中创建的标签上。解决方法是创建替代标签,然后重写getter以指向这些标签。


0

我在XCode 3.2.6中进行这个操作。我首先将outlets连接到一个类,然后创建了一个子类并添加了额外的outlets。当我将文件的所有者类更改为子类时,IB显示超类的outlets变为灰色。我将文件的所有者切换回超类,然后再切换回子类,现在所有的outlets都显示为非灰色。


0

我遇到了一个类似的超类问题,但这是由于Xcode(8.2)中的一个错误,即如果那些outlet已经使用_Nullable类型注释进行声明以实现Swift兼容性,则Interface Builder不会在连接检查器中显示它们。

在@property的括号内使用nullable似乎可以解决这个问题。

这个Xcode错误似乎影响任何类中的outlet(即不仅限于超类)。


0

我相信IB只会查找你正在使用的实际类来查找outlets,而不是超类。我认为最简单的解决方案是在超类中保留实例变量声明,但在每个子类中复制@property行。


实际上,Interface Builder 列出超类中的属性,但是这些属性必须在头文件中声明(仅限于超类),并且该头文件必须由子类导入(正如 Kendall 所说)。 - Brian

0
在我目前的项目中,我们有一个名为BaseViewController的控制器,其中含有一个UIScrollView作为IBOutlet,用于处理键盘出现/消失事件,并相应地滑动内容。一开始,我无法连接到这个IBOutlet,后来通过以下方法解决了这个问题,这与Sosily的答案类似:

  • BaseViewController有一个称为contentScrollViewIBOutlet。我可以看到5个以前连接到其他UIViewControllers上的UIScrollViews,这些都是由之前参与该项目的人创建的。

  • 我试图将我的UIScrollView连接到contentScrollView。虽然我的UIViewControllerBaseViewController的子类,但我无法连接它。

  • 我尝试将已经连接的UIScrollViews作为contentScrollView连接。虽然所有的UIViewControllers都是BaseViewController的子类,但是我也无法再次连接它们。因此,我开始寻找窍门。

  • 我在自己的UIViewController上创建了相同的contentScrollViewIBOutlet,将scrollView连接到我的contentScrollView插座,并删除了我刚创建的那一个。

  • 现在,scrollView已经作为contentScrollView连接到文件所有者,但唯一的contentScrollView属于BaseViewController。测试并验证键盘事件被正确处理。


0
最简单的方法:为您的子类创建接口和实现文件!
完美的例子:Juggleware's UIButton 的神奇 ShadowButton Subclass
确保在项目中创建.h和.m文件。 注意:根本不需要导入头文件,因为这只是UIButton的一个类实例。
在Interface Builder中:
1. 选择要连接的元素。 2. 转到“实用程序”->“身份检查器”。 3. 将类更改为您的子类(或超类)。 注意:您可能需要输入子类名称并按ENTER键。
你完成了!
即使您已经在头文件中声明了基本类(UIButton)作为IBOutlet,例如...
// YourViewController.h

@interface YourViewController : UIViewController {

IBOutlet UIButton *mybutton;
}

...你在Interface Builder中设置的类(ShadowButton)将覆盖它,因为它在视图层中。

这种方法最好的部分是,你的代码没有任何混乱的依赖问题。


0

我曾经遇到过同样的问题,后来发现是因为在超类中将IBOutlets声明为"_Nullable"。

@property (nonatomic, strong)   IBOutlet UITableView *_Nullable mySuperTableView;

当我移除了_Nullable,突然之间IBOutlets在IB中重新出现了,并且一切都恢复正常了。 (我只是将它们设置为_Nullable,因为Xcode抱怨“指针缺少空性类型说明符”...(不知道为什么)。)

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