xcode 如何访问超类中声明的IBOutlets?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4431881/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-14 20:00:33  来源:igfitidea点击:

How to access IBOutlets declared in superclass?

iosxcodeinterface-builderibactioniboutlet

提问by Sam Ritchie

I'm currently refactoring a couple of view controllers that share a few IBOutlets and IBActionmethods. I moved the outlet declarations and the IBActionmethod into a superclass, cutting these out of the subclasses.

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

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.)

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

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.

编辑:如果有人想知道,我使用的是 Xcode 和 IB 3.2.5,以及 iOS 4.2 SDK。

回答by arsenius

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.

直到大约一个小时前,我才意识到甚至可以连接到界面构建器中的超类。由于这是我能找到的关于如何做到这一点的唯一问题,我会添加我的答案,即使这个问题很老。我的答案是关于 Xcode 4,而不是 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.

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

回答by Sosily

The solution for the problem with the IBOutlet .. is to change the class type to the Base Class in the identity inspector

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

enter image description here

在此处输入图片说明

connect using Control + drag and drop and

使用 Control + 拖放和连接

enter image description here

在此处输入图片说明

change it back to the child class

将其改回子类

enter image description here

在此处输入图片说明

This works for me

这对我有用

BTW: i used Xcode 6

顺便说一句:我使用了 Xcode 6

回答by Kendall Helmstetter Gelner

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.

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

回答by Lee Probert

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.

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

回答by Yunus Nedim Mehel

On the project I am currently working, we have a BaseViewControllerwith a UIScrollViewas IBOutletand handles keyboard appearance/disappearance events and slides the content accordingly. At first, I could not connect to that IBOutlet, than solved the problem like this, which is similar to Sosily's answer:

在我目前的工作项目,我们有一个BaseViewControllerUIScrollView作为IBOutlet和手柄键盘出现/消失的事件和幻灯片的内容相应。起初,我无法连接到那个IBOutlet,而不是像这样解决了这个问题,这类似于 Sosily 的回答:

  • BaseViewControllerhas an IBOutlet, called contentScrollView. I can see 5 previously connected outlets, which are UIScrollViewson other UIViewControllers, created by people who previously worked on the project

  • I tried to connect my UIScrollViewas the contentScrollView. Although my UIViewControlleris a subclass of BaseViewController, I cannot connect it.

  • I tried to connect already connected UIScrollViewsas the contentScrollView. Although all UIViewControllersare subclasses of BaseViewController, I cannot connect them again, as well. So, I started to look for a trick.

  • I have created the same contentScrollViewIBOutleton my own UIViewController, connected the scrollViewto my own contentScrollViewoutlet and removed the one that I have just created.

  • Now the scrollView is connected as contentScrollViewto File's Owner, but the only contentScrollViewbelongs to the BaseViewController. Tested and verified that keyboard events are handled correctly.

  • BaseViewController有一个IBOutlet,叫做contentScrollView。我可以看到 5 个以前连接的插座,它们UIScrollViews在其他上UIViewControllers,由以前从事该项目的人创建

  • 我试图将我的UIScrollView作为contentScrollView. 虽然 myUIViewController是 的子类BaseViewController,但我无法连接它。

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

  • 我自己创建了相同contentScrollViewIBOutletUIViewController,将其连接scrollView到我自己的contentScrollView插座并删除了我刚刚创建的插座。

  • 现在 scrollView 已连接contentScrollView到 File's Owner,但仅contentScrollView属于BaseViewController. 测试并验证键盘事件处理正确。

回答by user2067021

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 _Nullabletype annotation for Swift compatibility.

我在超类中遇到了类似的问题,但这是由于 Xcode (8.2) 中的一个错误,如果这些插座已使用_Nullable类型注释声明为 Swift 兼容性,则 Interface Builder 不会在连接检查器中显示插座。

Using nullableinside @property's parentheses appears to work around the problem.

使用nullable内部@财产的括号似乎解决该问题。

This Xcode bug seems to affect outlets in any class (ie. not just superclasses).

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

回答by BobCowe

I had the same problem, and it turns out it was because in the superclass I had the IBOutlets declared as "_Nullable". Example:

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

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

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). )

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

回答by Denis Hennessy

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 @propertylines in each subclass.

我很确定 IB 只查看您用来查找出口的实际类,而不是超类。我认为最简单的解决方案是将实例变量声明保留在超类中,但@property在每个子类中复制这些行。

回答by Michael57

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.

我在 XCode 3.2.6 中这样做。我从连接到一个类的插座开始,然后用额外的插座制作了一个子类。当我将 File's Owner 类更改为子类时,IB 将超类网点显示为灰色。我将 File's Owner 切换到超类,然后返回到子类,现在所有出口都没有显示为灰色。

回答by Mike Rapadas

The simplest way: create interface and implementation files for your subclass(es)!
Perfect example: Juggleware'sawesome ShadowButton Subclassof UIButton.

最简单的方法:为你的子类创建接口和实现文件!
完美的例子:Juggleware很棒的ShadowButtonUIButton子类

Make sure to create the .h & .m files in your project. NOTE: There is no need to #importthe header files at all since this is simply a class instanceof UIButton.

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

In Interface Builder:

界面生成器中

  1. Select the element you which to connect.
  2. Go to Utilities-> Identity Inspector
  3. Change the Class to your subclass (or superclass). NOTE: You might have to type in your subclass name and hit ENTER.
  1. 选择要连接的元素。
  2. 转到实用程序->身份检查器
  3. 将类更改为您的子类(或超类)。注意:您可能需要输入您的子类名称并按 ENTER。

You're done!

你完成了!

Even if you have declared a basic class (UIButton) as IBOutlet in your header file like so...

即使您已经在头文件中将基本类 (UIButton) 声明为 IBOutlet ,就像这样......

// YourViewController.h

@interface YourViewController : UIViewController {

IBOutlet UIButton *mybutton;
}

...the class you've set in Interface Builder (ShadowButton) will overwrite it since it's in the view layer.

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

The best part about this approach is that your code doesn't have any messy dependency issues.

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