【问题标题】:How do I get a view in Interface Builder to load a custom view in another nib?如何在 Interface Builder 中获取视图以在另一个 nib 中加载自定义视图?
【发布时间】:2011-04-26 02:08:44
【问题描述】:

我正在制作一个我想在多个笔尖中使用的自定义小部件。所以我创建了一个新的视图 nib Screen3,添加了一些按钮,现在想要我的 UIAwesomeSauce 小部件。

如果我只是添加一个视图然后更改类标识,它不会从 UIAwesomeSauce nib 获取子元素。如果我去图书馆并切换到类,同样的事情。似乎只有 UIViewController 有“从笔尖加载”的字段,这会很漂亮。

我知道我可以从代码中加载 UIAwesomeSauce nib,获取顶级对象,然后手动放置它。但是 IB 的意义在于,您不必将内容放入代码中。如果我能让 UIAwesomeSauce 出现在库列表中,那就更好了。

已解决 - 由 Nimrod - 继续阅读以获取解释和代码

无论如何,dood,那太好了。我现在可以为愚蠢的真棒东西制作自己的小部件类。让你的 UI nib 的 FileOwner 成为你的类,在里面只有一个普通的 UIView 和你所有的东西。 (小部件笔尖中的单个视图不能是类本身,否则您会在 initWithCoder 中递归。)然后在您要使用它的笔尖中,制作一个普通的 UIView 并更改其类。您将无法真正看到该正方形内的小部件,但可以交易。

Self 现在是一个空白视图,而 tMyActualSelf 是您在另一个 nib 中进行工作的单一视图。耶!

- (id)initWithCoder:(NSCoder*)coder 
{
    if ((self = [super initWithCoder:coder])) 
    {
        UIView *tMyActualSelf = nil;
        // Initialization code
        NSArray *tNibItems = [[NSBundle mainBundle] loadNibNamed:@"UIAwesomeSauce" owner:self options:nil];
        for (id object in tNibItems) 
        {
            if ([object isKindOfClass:[UIView class]])
                tMyActualSelf = (UIView *)[object retain];
        }   
        if( tMyActualSelf ) 
        {
            tMyActualSelf.frame = CGRectMake(0, 0, self.frame.size.width, self.frame.size.height);
            [self addSubview:tMyActualSelf];
        }
    }
    return self;
}

【问题讨论】:

    标签: iphone interface-builder nib custom-view


    【解决方案1】:

    当 UIViewController 是唯一可以指定 nib 负载的东西时,我感到你很痛苦,但我认为这是因为必须有一个文件所有者,它是一个控制器,或者类似的东西,尽管我是不知道为什么 UIView 不能成为文件的所有者。

    我认为您可以将内容放在自定义对象下的库中,但我认为您只能将 UIView 放在那里,而该类只是设置为 UIView 的自定义子类。我实际上考虑过尝试扩展界面构建器,看起来你可以为 OS X 的东西做这件事,但不能为 iPhone 的东西做。它涉及在界面生成器中为新小部件编译代码,以告诉它如何在 IB 中绘制小​​部件。我认为这实际上有一个 OS X 模板。

    我想我可能会在包含所有子视图的 nib 文件中创建一个主视图,然后在 initWithCoder 中:在 UIAwesomeSauce 中打开 nib 文件,加载主视图,然后将其放入 self这样您就可以在 UIAwesomeSauce 视图和子视图(或视情况下的子子视图)之间有一个“不必要的”视图。我不确定这是多么低效,但是在弄乱一些东西时,它看起来像 UIWebView 之类的视图似乎有这些看似不必要的中间观点(IIRC)之一。

    如果您想出更好的解决方案,请告诉我,因为我也想知道。

    编辑

    现在我看它,我认为 UIView 可以是文件的所有者,你只是不能在 IB 中设置它。基本上你会在 UIView 子类中调用类似这样的 nib 加载:

    [bundle loadNibNamed:@"UISpecialSauce" owner:self options:...]

    我认为,如果您在 UISpecialSauce 或其他任何内容中创建插座,那么它们应该被正确分配,因为 owner:self。

    【讨论】:

    • 太棒了,我想给你烤个馅饼。
    • 耶!我终于得到了足够的分数来对帖子进行投票,所以你去吧。 (您应该能够就自己的问题对帖子进行投票,就像您可以就自己的问题对帖子发表评论一样。)
    • 对于任何扫描问题并详细阅读答案的人(如我),提问者会将他的“SOLVED”代码作为编辑放入他的原始问题中。
    【解决方案2】:

    有一个 cocoapod 可能实际上对此有所帮助: https://github.com/mobilejazz/NibWrapper

    它提供了一个包装视图,可以从另一个 NIB 加载子视图。您可以通过运行时属性在接口构建器中指定该 NIB 的名称。

    【讨论】:

    • 谢谢,我在找到您的参考后使用了这个。经过几天的阅读,这是一个很大的帮助。唯一遗憾的是存在一定程度的间接性,因为您必须设置 UIView 占位符(属于 UINibWraper 类),并且从中可以获取对自定义 UIView 的引用。还有另一个 cocoapod 采用了不同的方法,理论上移除了这个额外的层(UIView+NibLoading),但是在自定义视图中使用自动布局约束让我崩溃了。
    猜你喜欢
    • 2012-02-15
    • 1970-01-01
    • 2011-02-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-07
    相关资源
    最近更新 更多