【问题标题】:iOS - Custom View that can contain other viewsiOS - 可以包含其他视图的自定义视图
【发布时间】:2014-06-07 04:52:27
【问题描述】:

一段时间以来,我一直在使用自定义单元格(带有自己的笔尖)来制作表格,没有任何问题。现在在一个新项目中,我看到需要一个可重用的自定义视图(不是单元格),它会有一个标题、一个按钮和另一个 UIVIew 来保存更多视图。我称它为“部分”:

我们的想法是能够在情节提要中使用此部分(使用 UIView 并相应地设置自定义类)。这样,我在该 UIView 中放置的任何视图实际上都将包含在该部分的内部 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 之后调用一个又一个调用,直到发生 EXC_BAD_ACCESS 错误

我的尝试

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

'NSUnknownKeyException', reason: '[ setValue:forUndefinedKey:]: 这个类不符合 key sectionContainerView 的键值编码

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

我非常感谢您对此提供一些指导。谢谢。

【问题讨论】:

    标签: ios uiview customization nsunknownkeyexception


    【解决方案1】:

    您需要在情节提要中使用名为Custom Container View 的组件。我不能只在此处发布代码,因为它涉及您的故事板中的一些配置,并且代码将取决于您如何了解您的视图/VC,但您可以在此处阅读相关指南:

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

    【讨论】:

    • 您好,感谢您的回复。这真的是答案吗?我的印象是自定义视图控制器更像是用于划分不同的功能 UI 元素。例如,将列表与列表中每个选项显示的内容分开。我正在寻找的只是围绕单个屏幕内容的离散部分的可重复包装。具体示例,一个包含业务详细信息的屏幕,其中包含以下部分:基本描述、图库预览、联系人列表、地址和营业时间。一个给定的屏幕可以有任意数量的这些部分。
    • 这是一种妥协。问题是,与可以作为数组加载的 nib 文件不同,您可以从该数组中挑选要加载的 UIView,Storyboard 文件旨在包含以 UIViewControllers 作为根元素的完整图片,以及连接它们的路径都包含在一个文件。您可以定义要加载的根 VC,或者您可以从情节提要文件自定义加载任意 VC,但我认为您不能将 UIView 作为根元素单独加载,单独加载。
    • 这对我来说仍然很奇怪,但我会调查一下。但是,只是为了争论,假设我没有尝试在此自定义视图中的 IB/Storyboard 中定义更多视图。您是否知道为什么上面的代码在我制作的所有自定义单元格都可以正常工作时却无法正常工作?我仍然想知道我做错了什么只是让自定义视图工作(别介意它有其他内容)。再次感谢您的回复。
    • 不确定,如果我不得不猜测的话,我会看看 XIB 中的所有内容是如何连接的,类类型是否正确定义,以及类是否在代码中扩展了正确的 UI 类。跨度>
    【解决方案2】:

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

    这就是为什么您不能以这种方式在笔尖上使用您设计的 UIView 子类(通过在情节提要上设置视图的类,甚至实际上在另一个笔尖上)。

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

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

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

    但我想这不是你想要的。我认为您想让笔尖上的子视图可以通过“部分”访问,我认为这是笔尖上的根视图。您在 Section 类上创建 IBOutlet(或 IBAction、IBOutletCollection)属性。要将它们与笔尖上的其他对象连接起来,请控制单击笔尖上的“部分”视图,然后您将看到从那里做什么。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-12-27
      • 2017-01-05
      • 1970-01-01
      • 1970-01-01
      • 2010-09-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多