我是 XCode/iOS 领域的新手;我已经完成了一些相当大的基于 Storyboard的应用程序,但我从来没有在整个 nib/xib 事情上咬牙切齿。我想对场景使用相同的工具来设计/布局可重用的 View /控件。所以我为我的 View 子类创建了我的第一个 xib 并将其绘制出来:
我已经连接了 socket 并设置了约束,就像我在 Storyboard中习惯的那样。我将 File Owner
的类设置为自定义 UIView
子类的类。所以我假设我可以使用一些 API 来实例化这个 View 子类,并且它会如图所示进行配置/连接。
现在回到我的 Storyboard,我想嵌入/重用它。我在表格 View 原型(prototype)单元格中这样做:
我有一个看法。我已经将它的类设置为我的子类。我已经为它创建了一个导出,所以我可以操纵它。
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上的样子:
蓝色空间基本上是一个 UIView,它将“容纳”您的 xib。
这是你的 xib:
有一个 Action 连接到它上面的一个按钮,它会打印一些文本。
这是最终的结果:
第一个clickMe和第二个的区别在于第一个是使用StoryBoard
添加到UIViewController
的。第二个是使用代码添加的。
关于ios - 如何在 Storyboard 场景中嵌入自定义 View xib?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27807951/