如何访问超类中声明的IBOutlet?

问题描述 投票:14回答:10

我目前正在重构几个视图控制器,它们共享一些IBOutlets和IBAction方法。我将插座声明和IBAction方法移动到一个超类中,从子类中删除它们。

现在,当我打开Interface Builder时,我发现我无法看到超类中声明的出口或动作。这些连接仍然存在,因为我在重构之前将它们连接起来,但是它们已经变灰了。 (重要的是要注意连接也是工作,因为我的操作在按下按钮时触发,并且我的插座被正确修改。)

问题是,如何让界面构建器识别来自超类的出口?这是可能的,如果没有,你们都推荐什么?

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

@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。

ios xcode interface-builder ibaction iboutlet
10个回答
20
投票

直到大约一小时前,我才意识到甚至可以连接到界面构建器中的超类。由于这是我能找到的关于如何做到这一点的唯一问题,我会添加我的答案,即使这个问题已经过去了。我的答案是关于Xcode 4,而不是Xcode 3。

据我所知,您无法使用助理编辑器连接到超类中的插座,但您可以通过单击IB中的“文件所有者”来实现。这应该显示Utilities-> Connections Inspector中的所有出口。然后,您可以按Ctrl +单击检查器中的插座(单击“+”符号),然后将其拖到IB中的视图中。


0
投票

我遇到了同样的问题,事实证明这是因为在超类中我将IBOutlets声明为“_Nullable”。例:

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

当我移除_Nullable时,突然IBOutlets再次出现在IB中,一切都很好。 (我只把它们设置为_Nullable,因为Xcode抱怨“指针缺少一个可空性类型说明符”......(不知道为什么)。)


14
投票

IBOutlet问题的解决方案是将类类型更改为身份检查器中的基类

使用Control +拖放连接

把它改回子类

这适合我

顺便说一句:我使用的是Xcode 6


3
投票

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


3
投票

在身份检查器中切换超级和子类允许您跨类连接您的出口。我发现的唯一问题是当您尝试使用UITableViewCell及其子类执行此操作时。我想将默认的textLabel和detailTextLabel实例重新分配给我在Interface Builder中创建的标签。解决方法是创建替换标签,然后覆盖getter以指向这些标签。


0
投票

我很确定IB只会查看您用于查找网点的实际课程,而不是超级课程。我认为最简单的解决方案是将实例变量声明留在超类中,但复制每个子类中的@property行。


0
投票

我在XCode 3.2.6中这样做。我开始使用连接到类的插座,然后创建一个带有额外插座的子类。当我将File的Owner类更改为子类时,IB将超类出口显示为灰色。我将File的所有者切换到超类,然后返回子类,现在所有的出口都显示为不显示。


0
投票

最简单的方法:为子类创建接口和实现文件! 完美的例子:Juggleware's令人敬畏的UIButton的ShadowButton Subclass

确保在项目中创建.h和.m文件。注意:根本不需要#import头文件,因为这只是UIButton的类实例。

在Interface Builder中:

  1. 选择要连接的元素。
  2. 转到实用程序 - > Identity Inspector
  3. 将Class更改为您的子类(或超类)。注意:您可能必须键入子类名称并按Enter。

你完成了!

即使你已经在头文件中声明了一个基本类(UIButton)作为IBOutlet,就像这样......

// YourViewController.h

@interface YourViewController : UIViewController {

IBOutlet UIButton *mybutton;
}

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

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


0
投票

在我目前正在工作的项目中,我们有BaseViewControllerUIScrollView作为IBOutlet并处理键盘出现/消失事件并相应地滑动内容。起初,我无法连接到那个IBOutlet,而不是解决像这样的问题,这与Sosily的答案类似:

  • BaseViewController有一个IBOutlet,叫做contentScrollView。我可以看到5个先前连接的插座,这些插座是其他UIScrollViews上的UIViewControllers,由之前参与该项目的人创建
  • 我试图连接我的UIScrollView作为contentScrollView。虽然我的UIViewControllerBaseViewController的子类,但我无法连接它。
  • 我试图连接已连接的UIScrollViews作为contentScrollView。虽然所有UIViewControllers都是BaseViewController的子类,但我也无法再连接它们。所以,我开始寻找一个技巧。
  • 我在自己的contentScrollView上创建了相同的IBOutlet UIViewController,将scrollView连接到我自己的contentScrollView插座并移除了我刚创建的那个。
  • 现在scrollView作为contentScrollView连接到File的所有者,但唯一的contentScrollView属于BaseViewController。测试并验证是否正确处理了键盘事件。

0
投票

我遇到了一个与超类类似的问题,但这是由于Xcode(8.2)中的一个错误,如果那些出口已经使用_Nullable类型注释声明Swift兼容性,那么Interface Builder不会在Connection Inspector中显示出口。

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

这个Xcode错误似乎会影响任何类中的出口(即不仅仅是超类)。

© www.soinside.com 2019 - 2024. All rights reserved.