如何将UIView XIB“导入”到UIViewController XIB中?

时间:2013-03-19 20:06:15

标签: ios interface-builder xib

我在这里看到了一些答案似乎可以解决我所追求的问题,但我无法让它们发挥作用。

MyView是一个UIView子类,其中有一些图像和文本字段在MyView.xib中布局和样式,并绑定到MyView.(h|m)中的IBOutlets。未在XIB中设置File's Owner,但MyView是顶级对象的类。在运行时,我通过NSBundle's loadNibNamed动态地将各种MyView加载到某些视图控制器中。一切都顺其自然。

但我有另一个视图控制器MyVC,在设计时我想填充一些MyView实例。根据直觉,我在MyVC.xib中放置了一个与MyView大小相同的UIView对象,将其类型设置为MyView,在MyVC.h中添加了一个IBOutlet声明,并连接了连接。 / p>

当我跑步时,MyVC不会显示MyView。但调试表明已建立连接,视图确实是MyView,而MyView's awakeFromNib确实执行。我确信MyVC's MyView位于层次结构之上,因为我将其背景设置为漂亮的鲜红色。那么魔鬼在哪里MyView

2 个答案:

答案 0 :(得分:1)

最简单的解决方案是使MyView具有单个子视图,该子视图是其后代视图的其余部分的容器。这为MyVC.xib中的内容与MyView.xib中的内容之间提供了单点联系,并允许您连接两个xib中的出口。

MyVC.xib中,将每个占位符视图的类设置为MyView

MyView.xib中,将顶级视图的类设置为UIView。将文件所有者的类设置为MyView。如果您在MyView上有MyView.xib连接的任何商店,则需要将其重新连接到文件所有者,因为顶级视图不再具有这些商店。

-[MyView initWithCoder:]中,加载MyView.xib并将其顶级视图添加为子视图。未经测试的例子:

+ (UINib *)nib {
    static dispatch_once_t once;
    static UINib *nib;
    dispatch_once(&once, ^{
        nib = [UINib nibWithNibName:NSStringFromClass(self) bundle:[NSBundle bundleForClass:self]];
    });
    return nib;
}

- (id)initWithCoder:(NSCoder *)aDecoder {
    if (self = [super initWithCoder:aDecoder]) {
        NSArray *contents = [[self.class nib] instantiateWithOwner:self options:nil][0];
        UIView *containerView = contents[0];

        // Make sure the container view's size tracks my size.
        containerView.frame = self.bounds;
        containerView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
        self.autoresizesSubviews = YES;
        if ([self respondsToSelector:@selector(setTranslatesAutoresizingMaskIntoConstraints:)]) {
            self.translatesAutoresizingMaskIntoConstraints = YES;
            containerView.translatesAutoresizingMaskIntoConstraints = YES;
        }
        // If you're using autolayout in both xibs, you should probably create
        // constraints between self and containerView here.

        [self addSubview:containerView];
    }
    return self;
}

这样可以将MyView的出口连接到MyVC.xib中的内容和MyView.xib中的内容,并且可以连接{{1}中其他对象的出口}和MyVC.xibMyView.xib的实例。但是,您无法将MyView中其他对象的插座连接到MyVC.xib中的其他对象,反之亦然。

答案 1 :(得分:0)

ORIGINAL:覆盖initWithCoder,这是一个坏主意,如下面的评论所示

新建议:

  • 使用您现有的技术创建MyVC视图(MyView实例基本上是空视图)

然后在MyVC的viewDidLoad:方法:

  • 使用您的笔尖创建新的MyView实例,MyView中的每个实例

  • 将每个空(即占位符)MyView替换为您刚创建的那些,确保框架设置正确(设置任何属性/ ivars,并使用' - (void)exchangeSubviewAtIndex :( NSInteger)index1 withSubviewAtIndex:(NSInteger)index2'用子视图数组中的新视图替换旧视图)