【问题标题】:Use xib without a view controller在没有视图控制器的情况下使用 xib
【发布时间】:2012-08-22 20:50:22
【问题描述】:

我需要创建几个类似的视图
以一种简单的方式,我在 xib 中创建了一些视图(每个全屏)

我有一个视图控制器来使用这个 xib 的视图,代码如下:

NSArray* views = [[NSBundle mainBundle] loadNibNamed:@"MyXibName" owner:nil options:nil];
[self.view addSubview:[views objectAtIndex:aIndex]];

此时,视图显示正常。

现在,这些视图中有一些按钮,所以我为每个视图连接了一个插座

坏事发生了

应用程序因

而崩溃

未捕获的异常 'NSUnknownKeyException',原因:'[ setValue:forUndefinedKey:]:此类不符合键的键值编码

分析:
虽然我的 xib 文件的“文件所有者”已经设置,但是 xib 和唯一的视图控制器之间没有任何联系。

如何获得视图按钮的指针?

【问题讨论】:

    标签: objective-c ios cocoa-touch xib


    【解决方案1】:

    你可以这样做:

    NSNib*      aNib = [[NSNib alloc] initWithNibNamed:@"MyGreatNib" bundle:nil];
    NSArray*    topLevelObjs = nil;
    
    for (SomeClass *obj in myOwnerObjects) {
        topLevelObjs = nil;
    
        if (![aNib instantiateNibWithOwner:obj topLevelObjects:&topLevelObjs])
        {
            NSLog(@"Warning! Could not load nib file.\n");
            return;
        }
    
        for (id topLevelObj in topLevelObjs) {
            if ([topLevelObj isKindOfClass:[NSView class]]) {
                NSView *otView = (NSView *)topLevelObj;
                // set frame...
                [self addSubview:otView];
            }
        }
    }   
    

    【讨论】:

      【解决方案2】:

      -loadView 的默认实现创建视图或加载 NIB。据我所知,在 -loadView 中创建时无法知道视图的最终大小。所以默认视图大小设置为[[UIScreen mainScreen] bounds]. 这是因为在-viewDidLoad 和其他方法中使用零帧视图可能很难工作。

      您的单行实现可能如下所示:

      - (void)loadView {
          self.view = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
      }
      

      您不需要设置自动调整掩码,因为您不知道视图将在什么上下文中显示。调用者负责为您设置正确的框架、自动调整大小的掩码和类似的外部属性(我这样称呼它们)。

      在 UINavigationController 方法中想象一下:

      // we are pushing new VC, view is accessed for the first time
      pushedVC.view.frame = CGRectMake(...);
      

      它正在设置正确的框架,但您的 -loadView 在 -setFrame: 之前被调用。因此,在 -viewDidLoad 期间,您有临时的非零帧,只是为了能够设置子视图和内部自动调整大小。在此之后,为您设置正确的帧,并在 -viewWillAppear: 中设置最终帧。

      【讨论】:

        【解决方案3】:

        哎呀...
        我刚刚发现了一些东西。

        UINib* xib = [UINib nibWithNibName:@"MyXibName" bundle:nil];
        UIView* view = [[xib instantiateWithOwner:self options:nil] lastObject];  
        

        有效!

        【讨论】:

          【解决方案4】:

          您可以通过定义类 UIView 来根据需要设计 xib

          .m 文件中的代码:

          NSArray* objects = [[NSBundle mainBundle] loadNibNamed:@"Interface" owner:nil options:nil];
          
          UIView* mainView = [objects objectAtIndex:0];
          
          for (UIView* view in [mainView subviews]) {
              if([view isKindOfClass:[UILabel class]])
              {
                  UILabel* label = (UILabel*)view;
                  //....As You Wish...
              }
          }
          

          【讨论】:

            猜你喜欢
            • 2013-08-28
            • 1970-01-01
            • 1970-01-01
            • 2011-12-16
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多