我目前正在重构几个共享一些IBOutlet
和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。
答案 0 :(得分:19)
直到大约一小时前,我才意识到甚至可以连接到界面构建器中的超类。由于这是我能找到的关于如何做到这一点的唯一问题,我会添加我的答案,即使这个问题已经过去了。我的答案是关于Xcode 4,而不是Xcode 3。
据我所知,您无法使用助理编辑器连接到超类中的插座,但您可以通过单击IB中的“文件所有者”来实现。这应该显示Utilities-> Connections Inspector中的所有出口。然后,您可以按Ctrl +单击检查器中的插座(单击“+”符号),然后将其拖到IB中的视图中。
答案 1 :(得分:14)
IBOutlet问题的解决方案是将类类型更改为身份检查器中的基类
使用Control +拖放和
进行连接
将其更改回子类
这对我有用
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的类实例。
在界面生成器:
中你已经完成了!
即使你已经在头文件中声明了一个基本类(UIButton)作为IBOutlet,就像这样......
// YourViewController.h
@interface YourViewController : UIViewController {
IBOutlet UIButton *mybutton;
}
...您在Interface Builder(ShadowButton)中设置的类将覆盖它,因为它位于视图层中。
关于这种方法的最好的部分是你的代码没有任何混乱的依赖问题。
答案 7 :(得分:0)
在我目前正在使用的项目中,我们有BaseViewController
UIScrollView
作为IBOutlet
并处理键盘外观/消失事件并相应地滑动内容。起初,我无法连接到那个IBOutlet
,而是解决了这样的问题,这与Sosily的答案类似:
BaseViewController
有IBOutlet
,名为contentScrollView
。我可以看到以前连接过的5个出口,UIScrollViews
在其他UIViewControllers
上,由之前参与过该项目的人创建
我尝试将UIScrollView
与contentScrollView
联系起来。虽然我的UIViewController
是BaseViewController
的子类,但我无法连接它。
我尝试将已连接的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抱怨“指针缺少一个可空性类型说明符”......(不知道为什么)。)