【问题标题】:How to access IBOutlets declared in superclass?如何访问超类中声明的 IBOutlets?
【发布时间】:2011-05-24 19:56:41
【问题描述】:

我目前正在重构几个视图控制器,它们共享一些 IBOutlets 和 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。

【问题讨论】:

  • 你有没有想过这是否可能?我希望做同样的事情,但除非我在子类中重新声明它,否则 IB 似乎无法识别该属性?
  • 有关于这个项目的消息吗?我在这里遇到了同样的问题——这次是不是我的安装程序插件超类(InstallerPane),所以我不能修改它——只有文档说我必须将我的 .xib 连接到超类的某些属性! !怎么做?

标签: ios xcode interface-builder ibaction iboutlet


【解决方案1】:

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

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

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

【讨论】:

    【解决方案2】:

    我在超类中遇到了类似的问题,但这是由于 Xcode (8.2) 中的一个错误造成的为了兼容 Swift。

    在@property 的括号内使用nullable 似乎可以解决该问题。

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

    【讨论】:

      【解决方案3】:

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

      • BaseViewController 有一个IBOutlet,称为contentScrollView。我可以看到 5 个以前连接的网点,它们分别是 UIScrollViews 和其他 UIViewControllers,由以前参与该项目的人创建

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

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

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

      • 现在滚动视图以contentScrollView 连接到文件的所有者,但唯一的contentScrollView 属于BaseViewController。测试并验证正确处理了键盘事件。

      【讨论】:

        【解决方案4】:

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

        使用 Control + 拖放连接

        改回子类

        这对我有用

        顺便说一句:我使用 Xcode 6

        【讨论】:

        • 我也有同样的问题。尝试过,使用 NSCollectionViewItem,所以我可以连接 textField 插座,但它仍然无法正常工作..
        【解决方案5】:

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

        【讨论】:

          【解决方案6】:

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

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

          界面生成器中:

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

          你已经完成了!

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

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

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

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

          【讨论】:

            【解决方案7】:

            我在 XCode 3.2.6 中执行此操作。我从连接到一个类的插座开始,然后创建一个带有额外插座的子类。当我将 File's Owner 类更改为子类时,IB 将超类插座显示为灰色。我将 File's Owner 切换到超类,然后切换回子类,现在所有的出口都没有显示为灰色。

            【讨论】:

              【解决方案8】:

              直到大约一个小时前,我才意识到甚至可以在接口生成器中连接到超类。由于这是我能找到的关于如何做到这一点的唯一问题,我会添加我的答案,即使这个问题很老。我的回答是关于 Xcode 4,而不是 Xcode 3。

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

              【讨论】:

              • 或者只是在助手编辑器中使用 Cmd-Click 导航到超类,然后您可以从该类拖动到 IB 或反之亦然以连接网点或创建新网点。
              【解决方案9】:

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

              【讨论】:

              • 肯德尔,看看另一个答案,你是在复制任何东西,还是整个声明都在超类中?我正在使用#import,并且确实可以访问子类中的属性,所以我知道标头导入正在工作。
              • 我刚刚为此创建了一个测试项目 - 但它不起作用。从 Xcode 7.x 开始 - IB 只显示为对象声明的实际类的 IBOutlets,而不是其超类的。
              • 我只是在 Swift 的 Xcode 7.3 中使用它,它仍然可以正常工作。我能够在超类中声明一个 IBOutlet,然后从它拖到 IB 中,或者从 IB 拖到出口以连接它。 Assistant 编辑器不会在 Automatic 部分显示超类,但您可以在那里导航,并且 IB 将出口显示为来自子类(这在技术上是准确的)。 @SamRitchie - 不要复制任何东西,只在超类中拥有出口,而不是在子类中。
              【解决方案10】:

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

              【讨论】:

              • 实际上,Interface Builder 列出超类的属性,但它们必须在头文件中声明(仅限超类),并且该头文件必须由子类导入(正如肯德尔所说)。
              猜你喜欢
              • 2016-11-28
              • 2011-07-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2020-02-04
              • 1970-01-01
              • 2012-05-05
              • 1970-01-01
              相关资源
              最近更新 更多