UIView子类有自己的XIB

Tho*_*asM 21 iphone objective-c interface-builder uiview subclassing

我创建了一个自定义的UIView子类,并且不希望在UIView子类的代码中布局UI.我想用xib.所以我做的是以下内容.

我创建了一个类"ShareView",它是UIView的子类.我创建了一个XIB文件,其文件所有者设置为"ShareView".然后我链接我在"ShareView.h"中声明的一些出口.

接下来我有一个ViewController,MainViewController,它将ShareView添加为子视图.这段代码:

NSArray *arr = [[NSBundle mainBundle] loadNibNamed:@"ShareView" owner:nil options:nil];
UIView *fv = [[arr objectAtIndex:0] retain];
fv.frame = CGRectMake(0, 0, 320, 407);
[self.view addSubview:fv];
Run Code Online (Sandbox Code Playgroud)

但是现在我在ShareView中声明的插座上出现了NSUnknownKeyException错误.

我做这一切的原因是因为我想要一个UIView,在一个单独的XIB文件中有自己的逻辑.我在几个地方读到ViewControllers只用于管理全屏,即不是屏幕的一部分......那么我做错了什么?我想在单独的类中使用ShareView的逻辑,所以我的MainController类不会因为ShareView的逻辑而膨胀(我认为这是解决这个问题的一种方法吗?)

Yan*_*yer 26

ThomasM,

我们对自定义视图中的行为进行封装有类似的想法(例如,带有最小/最大/当前值的伴随标签的滑块,内部控件也会处理值更改的事件).

在我们当前的最佳实践中,我们将在Interface Builder(ShareView.xib)中设计ShareView ,如Eimantas在其答案中所述.然后,我们将ShareView嵌入到视图层次结构中MainViewController.xib.

我写了我们如何在iOS开发者博客中将自定义视图Nib嵌入到其他Nib中.-awakeAfterUsingCoder:在您的自定义视图中覆盖了难题,将从MainViewController.xib加载的对象替换为从"嵌入式"Nib(ShareView.xib)加载的对象.

这些方面的东西:

// ShareView.m
- (id) awakeAfterUsingCoder:(NSCoder*)aDecoder {
    BOOL theThingThatGotLoadedWasJustAPlaceholder = ([[self subviews] count] == 0);
    if (theThingThatGotLoadedWasJustAPlaceholder) {
        // load the embedded view from its Nib
        ShareView* theRealThing = [[[NSBundle mainBundle] loadNibNamed:NSStringFromClass([ShareView class]) owner:nil options:nil] objectAtIndex:0];

        // pass properties through
        theRealThing.frame = self.frame;
        theRealThing.autoresizingMask = self.autoresizingMask;

        [self release];
        self = [theRealThing retain];
    }
    return self;
}
Run Code Online (Sandbox Code Playgroud)

  • 你是对的ARC.请参阅我的后续帖子,网址为http://blog.yangmeyer.de/blog/2012/07/09/an-update-on-nested-nib-loading/ (4认同)

Eim*_*tas 6

您将已加载的xib的所有者定义为nil.由于xib中的文件所有者本身已连接出口并且被定义为ShareView您的实例,因此您将获得有关未知密钥的异常(nil没有为您定义的已过期属性ShareView).

您应该将xib的加载器定义为所有者(即负责加载xib的视图控制器).然后将单独的UIView对象添加到xib并将其定义为ShareView.然后在加载xib时.

ShareView *shareView = [[[[NSBundle mainBundle] loadNibNamed:@"ShareView" owner:self options:nil] objectAtIndex:0] retain];
Run Code Online (Sandbox Code Playgroud)

您还可以将其定义shareViewIBOutlet视图控制器的界面(并将文件所有者的插座连接到xib本身中的该视图).然后,当您加载xib时,不需要重新分配shareView实例变量,因为xib加载过程将直接将视图重新连接到实例变量.