iOS - 可包含其他视图的自定义视图

时间:2014-06-07 04:52:28

标签: ios uiview customization nsunknownkeyexception

有一段时间我一直在使用自定义单元格(带有自己的笔尖)来表没有问题。现在,在一个新项目中,我发现需要一个可重复使用的自定义视图(不是一个单元格),它将拥有一个标题,一个按钮,以及另一个可以容纳更多视图的UIVIew。我将其称为" Section":

enter image description here

这个想法是能够在故事板中使用这个部分(使用UIView并相应地设置自定义类)。这样,我在UIView中放置的任何视图实际上都包含在Section的内部UIView中。

我认为难以实际获得使用IB和Storyboard实际驻留在内部UIView而不是Section的根UIView中的视图。结果只是使自定义视图(没有任何内部视图)不能像我期望的那样工作。这是代码,它基于我已经完成并已经完成的许多自定义单元格(虽然根据通用UIView的特定init方法进行了调整):

#import "SectionContainer.h"

@implementation SectionContainer

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        // Initialization code
        NSArray *nibArray = [[NSBundle mainBundle] loadNibNamed:@"SectionContainer" owner:self options:nil];
        self = [nibArray objectAtIndex:0];
        /*NSArray *nibRoot = [[UINib nibWithNibName:@"SectionContainer" bundle:nil] instantiateWithOwner:self options:nil];
        [self addSubview:[nibRoot objectAtIndex:0]];*/
    }
    return self;
}

- (id)initWithCoder:(NSCoder *)aDecoder
{
    self = [super initWithCoder:aDecoder];
    if (self) {
        // Initialization code
        NSArray *nibArray = [[NSBundle mainBundle] loadNibNamed:@"SectionContainer" owner:self options:nil];
        self = [nibArray objectAtIndex:0];
        /*NSArray *nibRoot = [[UINib nibWithNibName:@"SectionContainer" bundle:nil] instantiateWithOwner:self options:nil];
        [self addSubview:[nibRoot objectAtIndex:0]];*/
    }
    return self;

}

匹配的XIB将其根视图设置为此自定义类(就像我在自定义单元格中一样)

问题

这个自定义类导致一个EXC_BAD_ACCESS代码= 2,从我通过单步调用它可以看出,就好像该类是递归调用的一样。在调用initWithDecoder之后调用call,直到发生EXC_BAD_ACCESS错误

我做了什么

  • 鉴于看似递归的调用,我尝试了另一种方法,我看到将XIB的文件所有者设置为自定义类而不是XIB的根视图。这导致以下错误:

' NSUnknownKeyException',原因:' [setValue:forUndefinedKey:]:此类不是键值sectionContainerView的键值编码兼容

  • 尝试了一种稍微不同的方法(在上面的代码中注释掉),其中XIB的根被添加到自定义类(addSubView)而不是设置为它。这没有改变任何东西,相同的递归调用(如果设置了错误,则上面的错误)

我真的很感激这方面的一些指导。谢谢。

2 个答案:

答案 0 :(得分:0)

您需要在故事板中使用名为Custom Container View的组件。我不能在这里发布代码,因为它涉及到故事板中的一些配置,代码将取决于你如何探测你的观点/ VC,但你可以在这里阅读相关指南:

https://developer.apple.com/library/ios/featuredarticles/ViewControllerPGforiPhoneOS/CreatingCustomContainerViewControllers/CreatingCustomContainerViewControllers.html

答案 1 :(得分:0)

首先,递归调用在initWithCoder:上,加载一个nib意味着通过initWithCoder实现其视图:。

这就是为什么你不能以这种方式使用你在nib上设计的UIView子类(通过在故事板上甚至在另一个nib上设置视图的类)。

使用它的唯一方法是通过nib在代码中实例化它。

Section *sectionView = [[[NSBundle mainBundle] loadNibNamed:nibName owner:owner options:options] objectAtIndex:index];

现在,通过连接你所做的笔尖的东西: 您可以将笔尖上的对象连接到笔尖上找不到的另一个对象。这就是文件所有者的用途。您必须设置其(文件所有者)类,并与其建立连接,并使用其实现连接的类的实例,作为加载笔尖时的所有者参数。

但我猜这不是你想要的。我想你想通过“Section”来访问nib上的子视图,我假设它是nib上的根视图。您可以在Section类上创建IBOutlet(或IBAction,IBOutletCollection)属性。要将它们与笔尖上的其他对象连接起来,控制点击笔尖上的“截面”视图,您将看到从那里做什么。