如何访问超类中声明的 IBOutlet?
我目前正在重构几个共享一些 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。
I'm currently refactoring a couple of view controllers that share a few IBOutlet
s and IBAction
methods. I moved the outlet declarations and the IBAction
method into a superclass, cutting these out of the subclasses.
Now, when I open up Interface Builder, I find that I can't see the outlets or actions declared in the superclass. The connections still exist, as I'd wired them up before the refactoring, but they're grayed out. (It's important to note that the connections also WORK, as my action fires on a button press, and my outlets are modified properly.)
The question is, how can I get interface builder to recognize outlets from a superclass? Is this possible, and, if not, what do you all recommend?
(Just for fun, here's my superclass header file:)
@interface TFMainViewController : UIViewController {
UIImageView *logoImage, *thinkfunImage;
UIButton *buyFullButton;
}
@property (nonatomic, retain) IBOutlet UIImageView *logoImage, *thinkfunImage;
@property (nonatomic, retain) IBOutlet UIButton *buyFullButton;
-(IBAction) buyFullVersion;
@end
EDIT: in case anyone's wondering, I'm using Xcode and IB 3.2.5, with the iOS 4.2 SDK.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(10)
直到大约一个小时前,我才意识到甚至可以连接到接口生成器中的超类。由于这是我能找到的关于如何执行此操作的唯一问题,因此我将添加我的答案,即使这个问题很旧。我的答案是关于 Xcode 4,而不是 Xcode 3。
据我所知,您无法使用助理编辑器连接到超类中的插座,但您可以通过单击 IB 中的“文件所有者”来做到这一点。这应该显示“实用程序”->“连接检查器”中的所有插座。然后,您可以按住 Ctrl 键并单击检查器中的插座(单击“+”号),并将其拖到 IB 中的视图中。
I didn't realize it was even possible to connect to superclasses in interface builder until about an hour ago. Since this was the only question I could find regarding how to do this, I'll add my answer, even though this question is old. My answer is with regard to Xcode 4, not Xcode 3.
As far as I can tell, you can't connect to outlets in a superclass using the assistant editor, but you can do it by clicking on "File's Owner" in IB. That should show all the outlets in Utilities->Connections Inspector. You can then Ctrl+Click on the outlet in the inspector (click on the '+' sign), and drag it over to your view in IB.
IBOutlet 问题的解决方案.. 是在身份检查器中将类类型更改为基类
使用 Control + 拖放进行连接,
将其更改回子类
这对我有用
顺便说一句:我使用 Xcode 6
The solution for the problem with the IBOutlet .. is to change the class type to the Base Class in the identity inspector
connect using Control + drag and drop and
change it back to the child class
This works for me
BTW: i used Xcode 6
IB 应该能够看到超类的出口,我已经这样做过很多次了,没有任何问题。您确定正确导入超类(使用 #import 而不是 @class)吗? IB 需要某种方式来追踪超类。
IB should be able to see outlets from superclasses, I have done this a number of times with no issues. Are you sure you are importing the superclass correctly (using #import instead of @class)? IB needs some way to track back to the superclass.
在身份检查器中的超级类和子类之间切换允许您跨类连接您的插座。我发现的唯一问题是当您尝试使用 UITableViewCell 及其子类执行此操作时。我想将默认的textLabel和detailTextLabel实例重新分配给我在Interface Builder中创建的标签。解决方法是创建替代标签,然后重写 getter 以指向这些标签。
Switching between the super and subclass in the identity inspector allows you to connect your outlets across the classes. The only issue I found is when you attempt to do this with a UITableViewCell and its subclass. I wanted to re-assign the default textLabel and detailTextLabel instances to labels I create in Interface Builder. The workaround is to create substitute labels and then override the getters to point to these instead.
我很确定 IB 只查看您用来查找出口的实际类,而不是超类。我认为最简单的解决方案是将实例变量声明保留在超类中,但在每个子类中复制
@property
行。I'm pretty sure that IB only looks at the actual class you're using to find outlets, and not at superclasses. I think that the easiest solution would be to leave the instance variable declarations in the superclass, but duplicate the
@property
lines in each subclass.我在 XCode 3.2.6 中这样做。我从连接到一个类的插座开始,然后创建一个带有附加插座的子类。当我将文件所有者类更改为子类时,IB 将超类出口显示为灰色。我将文件的所有者切换到超类,然后又切换回子类,现在所有出口都显示不是灰色的。
I'm doing this in XCode 3.2.6. I started with outlets connected to a class, and then made a subclass with additional outlets. When I changed the File's Owner class to the subclass, IB showed the superclass outlets as greyed out. I switched File's Owner to the superclass, then back to the subclass and now all outlets are showing not greyed out.
最简单的方法:为您的子类创建接口和实现文件!
完美的例子:Juggleware很棒的ShadowButton UIButton 的子类。
确保创建 .h &项目中的 .m 文件。
注意:根本不需要
#import
头文件,因为这只是 UIButton 的一个类实例。在Interface Builder中:
你完成了!
即使您已在头文件中将基本类 (UIButton) 声明为 IBOutlet,如下所示...
...您在 Interface Builder (ShadowButton) 中设置的类将覆盖它,因为它位于视图层中。
这种方法最好的部分是您的代码没有任何混乱的依赖问题。
The simplest way: create interface and implementation files for your subclass(es)!
Perfect example: Juggleware's awesome ShadowButton Subclass of UIButton.
Make sure to create the .h & .m files in your project.
NOTE: There is no need to
#import
the header files at all since this is simply a class instance of UIButton.In Interface Builder:
You're done!
Even if you have declared a basic class (UIButton) as IBOutlet in your header file like so...
...the class you've set in Interface Builder (ShadowButton) will overwrite it since it's in the view layer.
The best part about this approach is that your code doesn't have any messy dependency issues.
在我当前正在工作的项目中,我们有一个
BaseViewController
,其中UIScrollView
作为IBOutlet
并处理键盘出现/消失事件并相应地滑动内容。起初,我无法连接到该IBOutlet
,然后解决了这样的问题,这类似于 Sosily 的答案:BaseViewController
has anIBOutlet< /code>,称为
contentScrollView
。我可以看到 5 个先前连接的插座,它们是其他UIViewControllers
上的UIScrollViews
,由以前参与该项目的人员创建我尝试连接我的
UIScrollView
作为contentScrollView
。虽然我的UIViewController
是BaseViewController
的子类,但我无法连接它。我尝试将已连接的
UIScrollViews
连接为contentScrollView
。尽管所有UIViewControllers
都是BaseViewController
的子类,但我也无法再次连接它们。因此,我开始寻找技巧。我在自己的
UIViewController
上创建了相同的contentScrollView
IBOutlet
,将scrollView
连接到我自己的< code>contentScrollView 出口并删除了我刚刚创建的出口。现在,scrollView 作为
contentScrollView
连接到文件的所有者,但唯一的contentScrollView
属于BaseViewController
。测试并验证键盘事件是否正确处理。On the project I am currently working, we have a
BaseViewController
with aUIScrollView
asIBOutlet
and handles keyboard appearance/disappearance events and slides the content accordingly. At first, I could not connect to thatIBOutlet
, than solved the problem like this, which is similar to Sosily's answer:BaseViewController
has anIBOutlet
, calledcontentScrollView
. I can see 5 previously connected outlets, which areUIScrollViews
on otherUIViewControllers
, created by people who previously worked on the projectI tried to connect my
UIScrollView
as thecontentScrollView
. Although myUIViewController
is a subclass ofBaseViewController
, I cannot connect it.I tried to connect already connected
UIScrollViews
as thecontentScrollView
. Although allUIViewControllers
are subclasses ofBaseViewController
, I cannot connect them again, as well. So, I started to look for a trick.I have created the same
contentScrollView
IBOutlet
on my ownUIViewController
, connected thescrollView
to my owncontentScrollView
outlet and removed the one that I have just created.Now the scrollView is connected as
contentScrollView
to File's Owner, but the onlycontentScrollView
belongs to theBaseViewController
. Tested and verified that keyboard events are handled correctly.我在超类中遇到了类似的问题,但这是由于 Xcode (8.2) 中的一个错误,如果这些出口已使用
_Nullable
声明,则 Interface Builder 不会在连接检查器中显示出口类型注释以实现 Swift 兼容性。在 @property 的括号内使用
nullable
似乎可以解决该问题。这个 Xcode 错误似乎会影响任何类(即不仅仅是超类)中的出口。
I ran into a similar problem with a superclass, but it was due to a bug in Xcode (8.2) where Interface Builder doesn't show outlets in the Connection Inspector if those outlets have been declared with a
_Nullable
type annotation for Swift compatibility.Using
nullable
inside @property's parentheses appears to work around the problem.This Xcode bug seems to affect outlets in any class (ie. not just superclasses).
我遇到了同样的问题,事实证明这是因为在超类中我将 IBOutlets 声明为“_Nullable”。
示例:
当我删除 _Nullable 时,IBOutlets 突然重新出现在 IB 中,一切又恢复正常。
(我只将它们设置为 _Nullable 因为 Xcode 抱怨“指针缺少可为空类型说明符”...(不知道为什么)。)
I had the same problem, and it turns out it was because in the superclass I had the IBOutlets declared as "_Nullable".
Example:
When I removed the _Nullable, suddenly the IBOutlets reappeared in IB and all was good again.
(I had only set them to _Nullable because Xcode was complaining "pointer is missing a nullability type specifier"... (don't know why). )