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

发布于 2024-10-07 02:34:38 字数 720 浏览 5 评论 0原文

我目前正在重构几个共享一些 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。

I'm currently refactoring a couple of view controllers that share a few IBOutlets 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(10

何处潇湘 2024-10-14 02:34:38

直到大约一个小时前,我才意识到甚至可以连接到接口生成器中的超类。由于这是我能找到的关于如何执行此操作的唯一问题,因此我将添加我的答案,即使这个问题很旧。我的答案是关于 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.

黑色毁心梦 2024-10-14 02:34:38

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

enter image description here

connect using Control + drag and drop and

enter image description here

change it back to the child class

enter image description here

This works for me

BTW: i used Xcode 6

恋竹姑娘 2024-10-14 02:34:38

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.

梦过后 2024-10-14 02:34:38

在身份检查器中的超级类和子类之间切换允许您跨类连接您的插座。我发现的唯一问题是当您尝试使用 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.

注定孤独终老 2024-10-14 02:34:38

我很确定 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.

牵你手 2024-10-14 02:34:38

我在 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.

只为守护你 2024-10-14 02:34:38

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

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

Interface Builder中:

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

你完成了!

即使您已在头文件中将基本类 (UIButton) 声明为 IBOutlet,如下所示...

// YourViewController.h

@interface YourViewController : UIViewController {

IBOutlet UIButton *mybutton;
}

...您在 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:

  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.

You're done!

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

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

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

江心雾 2024-10-14 02:34:38

在我当前正在工作的项目中,我们有一个 BaseViewController ,其中 UIScrollView 作为 IBOutlet 并处理键盘出现/消失事件并相应地滑动内容。起初,我无法连接到该 IBOutlet,然后解决了这样的问题,这类似于 Sosily 的答案:

  • BaseViewController has an IBOutlet< /code>,称为 contentScrollView。我可以看到 5 个先前连接的插座,它们是其他 UIViewControllers 上的 UIScrollViews,由以前参与该项目的人员创建

  • 我尝试连接我的 UIScrollView 作为 contentScrollView。虽然我的 UIViewControllerBaseViewController 的子类,但我无法连接它。

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

  • 我在自己的UIViewController上创建了相同的contentScrollViewIBOutlet,将scrollView连接到我自己的< code>contentScrollView 出口并删除了我刚刚创建的出口。

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

On the project I am currently working, we have a BaseViewController with a UIScrollView as IBOutlet and 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:

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

  • I tried to connect my UIScrollView as the contentScrollView. Although my UIViewController is a subclass of BaseViewController, I cannot connect it.

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

  • I have created the same contentScrollView IBOutlet on my own UIViewController, connected the scrollView to my own contentScrollView outlet and removed the one that I have just created.

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

一曲琵琶半遮面シ 2024-10-14 02:34:38

我在超类中遇到了类似的问题,但这是由于 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).

梦醒时光 2024-10-14 02:34:38

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

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

当我删除 _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:

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文