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

时间:2010-12-13 17:58:12

标签: ios xcode interface-builder ibaction iboutlet

我目前正在重构几个共享一些IBOutletIBAction方法的视图控制器。我将插座声明和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。

10 个答案:

答案 0 :(得分:19)

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

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

答案 1 :(得分:14)

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

enter image description here

使用Control +拖放和

进行连接

enter image description here

将其更改回子类

enter image description here

这对我有用

BTW:我使用的是Xcode 6

答案 2 :(得分:3)

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

答案 3 :(得分:3)

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

答案 4 :(得分:0)

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

答案 5 :(得分:0)

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

答案 6 :(得分:0)

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

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

界面生成器

  1. 选择要连接的元素。
  2. 转到实用程序 - > 身份检查员
  3. 将Class更改为您的子类(或超类)。注意:您可能必须输入子类名称并按Enter键。
  4. 你已经完成了!

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

    // YourViewController.h
    
    @interface YourViewController : UIViewController {
    
    IBOutlet UIButton *mybutton;
    }
    

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

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

答案 7 :(得分:0)

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

  • BaseViewControllerIBOutlet,名为contentScrollView。我可以看到以前连接过的5个出口,UIScrollViews在其他UIViewControllers上,由之前参与过该项目的人创建

  • 我尝试将UIScrollViewcontentScrollView联系起来。虽然我的UIViewControllerBaseViewController的子类,但我无法连接它。

  • 我尝试将已连接的UIScrollViews连接为contentScrollView。虽然所有UIViewControllers都是BaseViewController的子类,但我也无法再次连接它们。所以,我开始寻找一个技巧。

  • 我在自己contentScrollView上创建了相同的IBOutlet UIViewController,将scrollView与我自己的contentScrollView插座相关联,然后删除了我刚刚创造的。

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

答案 8 :(得分:0)

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

在@ property' s括号内使用_Nullable似乎解决了这个问题。

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

答案 9 :(得分:0)

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

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

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