如何在故事板场景中嵌入自定义视图xib? [英] How to embed a custom view xib in a storyboard scene?

查看:118
本文介绍了如何在故事板场景中嵌入自定义视图xib?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在XCode / iOS世界中相对较新;我已经完成了一些不错的基于故事板的应用程序,但我并没有在整个nib / xib上扯掉我的东西。我想使用相同的工具为场景设计/布局可重用的视图/控件。所以我为我的视图子类创建了我的第一个xib并绘制了它:

I'm relatively new in the XCode/iOS world; I've done some decent sized storyboard based apps, but I didn't ever cut me teeth on the whole nib/xib thing. I want to use the same tools for scenes to design/layout a reusable view/control. So I created my first ever xib for my view subclass and painted it up:

我连接了插座并设置了约束,就像我以前在故事板中做的那样。我将文件所有者的类设置为我的自定义 UIView 子类的类。所以我假设我可以用一些API实例化这个视图子类,它将如图所示配置/连接。

I have my outlets connected and constraints setup, just like I'm used to doing in the storyboard. I set the class of my File Owner to that of my custom UIView subclass. So I assume I can instantiate this view subclass with some API, and it will configured/connected as shown.

现在回到我的故事板中,我想嵌入/重用这个。我在表格视图原型单元格中这样做:

Now back in my storyboard, I want to embed/reuse this. I'm doing so in a table view prototype cell:

我有一个观点。我已将它的类设置为我的子类。我已经为它创建了一个插座,所以我可以操作它。

I've got a view. I've set the class of it to my subclass. I've created an outlet for it so I can manipulate it.

64美元的问题是在哪里/如何表明它只是放空/未配置是不够的我的视图子类的实例在那里,但要使用我创建的.xib来配置/实例化它?这真的很酷,如果在XCode6中,我可以输入XIB文件用于给定的UIView,但是我没有看到用于执行此操作的字段,因此我假设我必须在代码中执行某些操作。

The $64 question is where/how do I indicate that it's not enough to just put an empty/unconfigured instance of my view subclass there, but to use the .xib I created to configure/instantiate it? It would be really cool, if in XCode6, I could just enter the XIB file to use for a given UIView, but I don't see a field for doing that, so I assume I have to do something in code somewhere.

(我确实在SO上看到了这样的其他问题,但是没有找到任何关于这部分难题的问题,或者最新的XCode6 / 2015 )

我可以通过实施我的表来实现这一目标单元格 awakeFromNib 如下:

I am able to get this to kind of work by implementing my table cell's awakeFromNib as follows:

- (void)awakeFromNib
{
    // gather all of the constraints pointing to the uncofigured instance
    NSArray* progressConstraints = [self.contentView.constraints filteredArrayUsingPredicate: [NSPredicate predicateWithBlock:^BOOL(id each, NSDictionary *_) {
        return (((NSLayoutConstraint*)each).firstItem == self.progressControl) || (((NSLayoutConstraint*)each).secondItem == self.progressControl);
    }]];
    // fetch the fleshed out variant
    ProgramProgressControl *fromXIB = [[[NSBundle mainBundle] loadNibNamed:@"ProgramProgressControl" owner:self options:nil] objectAtIndex:0];
    // ape the current placeholder's frame
    fromXIB.frame = self.progressControl.frame;
    // now swap them
    [UIView transitionFromView: self.progressControl toView: fromXIB duration: 0 options: 0 completion: nil];
    // recreate all of the constraints, but for the new guy
    for (NSLayoutConstraint *each in progressConstraints) {
        id firstItem = each.firstItem == self.progressControl ? fromXIB : each.firstItem;
        id secondItem = each.secondItem == self.progressControl ? fromXIB : each.secondItem;
        NSLayoutConstraint *constraint = [NSLayoutConstraint constraintWithItem: firstItem attribute: each.firstAttribute relatedBy: each.relation toItem: secondItem attribute: each.secondAttribute multiplier: each.multiplier constant: each.constant];
        [self.contentView addConstraint: constraint];
    }
    // update our outlet
    self.progressControl = fromXIB;
}

这么简单吗?或者我为此工作太辛苦了?

Is this as easy as it gets then? Or am I working too hard for this?

推荐答案

你几乎就在那里。您需要覆盖您为视图指定的自定义类中的initWithCoder。

You're almost there. You need to override initWithCoder in your custom class you assigned the view to.

- (id)initWithCoder:(NSCoder *)aDecoder {
    if ((self = [super initWithCoder:aDecoder])) {
        [self addSubview:[[[NSBundle mainBundle] loadNibNamed:@"ViewYouCreated" owner:self options:nil] objectAtIndex:0]];
    }
    return self; }

一旦完成,StoryBoard就会知道在UIView中加载xib。

Once that's done the StoryBoard will know to load the xib inside that UIView.

以下是更详细的解释:

这就是你的 UIViewController 的样子喜欢你的故事板:

This is how your UIViewController looks like on your story board:

蓝色空间基本上是一个将保持你的xib的UIView。

The blue space is basically a UIView that will "hold" your xib.

这是你的xib:

有一个Action连接到其上的按钮,它将打印一些文本。

There's an Action connected to a button on it that will print some text.

这是最终结果:

第一个clickMe与第二个之间的区别在于第一个被添加到 UIViewController 使用 StoryBoard 。第二个是使用代码添加的。

The difference between the first clickMe and the second is that the first was added to the UIViewController using the StoryBoard. The second was added using code.

这篇关于如何在故事板场景中嵌入自定义视图xib?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆