使用没有视图控制器的xib

时间:2012-08-28 10:49:29

标签: objective-c ios cocoa-touch xib

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

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

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

此时,视图显示正常。

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

发生了不好的事情

app由于

而崩溃
  

未捕获的异常'NSUnknownKeyException',原因:'[< NSObject 0x969db50> setValue:forUndefinedKey:]:此类不是密钥值编码兼容的密钥

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

我怎样才能获得视图按钮的指针?

4 个答案:

答案 0 :(得分:2)

你可以这样做:

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];
        }
    }
}   

答案 1 :(得分:1)

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

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

答案 2 :(得分:0)

糟糕...
我刚发现了一些东西。

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

有效!

答案 3 :(得分:0)

您可以通过定义类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...
    }
}