ios - 如何在 Storyboard 场景中嵌入自定义 View xib?

标签 ios objective-c xcode interface-builder uistoryboard

我是 XCode/iOS 领域的新手;我已经完成了一些相当大的基于 Storyboard的应用程序,但我从来没有在整个 nib/xib 事情上咬牙切齿。我想对场景使用相同的工具来设计/布局可重用的 View /控件。所以我为我的 View 子类创建了我的第一个 xib 并将其绘制出来:

enter image description here

我已经连接了 socket 并设置了约束,就像我在 Storyboard中习惯的那样。我将 File Owner 的类设置为自定义 UIView 子类的类。所以我假设我可以使用一些 API 来实例化这个 View 子类,并且它会如图所示进行配置/连接。

现在回到我的 Storyboard,我想嵌入/重用它。我在表格 View 原型(prototype)单元格中这样做:

enter image description here

我有一个看法。我已经将它的类设置为我的子类。我已经为它创建了一个导出,所以我可以操纵它。

64 美元的问题是我在哪里/如何表明仅将 View 子类的空/未配置实例放在那里是不够的,而是使用我创建的 .xib 来配置/实例化它?如果在 XCode6 中,我可以只输入 XIB 文件以用于给定的 UIView,那就太酷了,但我没有看到这样做的字段,所以我假设我必须在某处的代码中做一些事情。

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

更新

我可以通过如下实现表格单元格的 awakeFromNib 来完成这项工作:

- (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;
}

那么这很容易吗?还是我为此付出了太多努力?

最佳答案

你快到了。您需要在将 View 分配给的自定义类中覆盖 initWithCoder。

- (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。

这里有更详细的解释:

这就是您的 UIViewController 在 Storyboard上的样子: enter image description here

蓝色空间基本上是一个 UIView,它将“容纳”您的 xib。

这是你的 xib:

enter image description here

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

这是最终的结果:

enter image description here

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

关于ios - 如何在 Storyboard 场景中嵌入自定义 View xib?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27807951/

相关文章:

ios - 为什么它是 "exc_bad_access"而不是 "run-time"或 "compile-time"错误?

ios - 滚动到 PDF 文档中的特定页面

objective-c - 如何使用pdf文件缩放webView

xcode - OS X Mavericks 中 Xcode 5 中架构 x86_64 错误的 undefined symbol

ios - 如何创建具有多个字幕的表格单元格

objective-c - 通过 iOS Objective-C 2.0 解析 Google Search API XML 结果

ios - 钥匙串(keychain)数据存储在哪里?

iphone - 实现自定义 NSMutableArray

ios - iOS 上的字符串到电话号码格式

swift - 哪些 Emoji 字符用作 Swift 标识符?