Ios 无法在接口生成器中加载IBDesignable xib
我有一个Ios 无法在接口生成器中加载IBDesignable xib,ios,swift,xib,ibdesignable,Ios,Swift,Xib,Ibdesignable,我有一个xib(childXib)文件,通过其所有者链接到其自定义UIViewswift文件 这就是我初始化自定义视图的方式: // init for IBDesignable override init(frame: CGRect) { super.init(frame: frame) let view = loadViewFromNib() view.frame = bounds addSubview(view) } required init?(cod
xib
(childXib
)文件,通过其所有者链接到其自定义UIView
swift文件
这就是我初始化自定义视图的方式:
// init for IBDesignable
override init(frame: CGRect) {
super.init(frame: frame)
let view = loadViewFromNib()
view.frame = bounds
addSubview(view)
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
addSubview(loadViewFromNib())
}
func loadViewFromNib() -> UIView {
let bundle = NSBundle(forClass: self.dynamicType)
let nib = UINib(nibName: "CommentCellView", bundle: bundle)
let view = nib.instantiateWithOwner(self, options: nil)[0] as! UIView
return view
}
当我想将此xib
(childXib
)添加到另一个xib
(parentXib
)中时,我得到以下错误:
错误:IB Designables:无法呈现MyRootView的实例:代理引发异常
其中MyRootView
是链接到parentXib
错误:IB可指定项:未能更新自动布局状态:代理引发“NSInternalInconsistencyException”异常:无法在捆绑包中加载NIB:“NSBundle(loaded)”,名称为“MyIBDesignableCustomViewFilename”
其中MyIBDesignableCustomViewFilename
是链接到childXib
的文件
当我从标识检查器
中单击自定义类
中的debug
对其进行调试时,它在该行不起作用:
let view = nib.instantiateWithOwner(self, options: nil)[0] as! UIView
所有xib
文件都位于Copy Bundle Resources
的构建阶段
中
知道出了什么问题吗?对于以下两种错误:
error: IB Designables: Failed to render instance of ....
error: IB Designables: Failed to update auto layout status: The agent raised a "NSInternalInconsistencyException" exception: Could not load NIB in bundle ...
我建议进行一次小规模的快速自我验证,这有助于找出应该解决的问题:
@IBDesignable
class Rainbow: UIView {
}
在旧版本的Xcode中,您可以编辑用户定义的运行时属性,以在Interface Builder中更改对象的属性(例如layer.cornerRadius)。问题是您必须输入属性的确切名称。IBInspectable向前迈出了一步。使用IBInspectable作为visual类属性的前缀时,该属性将向Interface Builder公开,以便您可以以非常简单的方式更改其值:
同样,如果您是在Swift中开发应用程序,您需要做的只是在您选择的属性前面加上关键字@IBInspectable。下面是一个示例代码段:
@IBInspectable var firstColor: UIColor = UIColor.blackColor()
{
// Update your UI when value changes
}
@IBInspectable var firstColor: UIColor = UIColor.blackColor()
{
// Update your UI when value changes
}
构建您的Xcode项目
让我们先在Xcode中创建一个新项目,然后选择单视图应用程序作为模板,并将其命名为RainbowDemo。我们将在这个项目中使用Swift作为编程语言,所以在创建项目时不要忘记选择它
完成后,在项目导航器中选择Main.storyboard,并将视图对象从对象库拖动到视图控制器。将其颜色更改为#38334C(或任何您想要的颜色),并将其大小设置为600×434。然后把它放在主视图的中心。不要忘记将主视图的颜色更改为与视图对象相同的颜色。
提示:如果要更改代码的RGB颜色值,只需打开调色板并切换到滑块选项卡即可更改RGB值
困惑?别担心。通过项目演示,您将理解我的意思
使用Xcode 6,您必须为视图配置自动布局约束,以支持所有类型的iOS设备。在最新版本的Xcode中,自动布局功能非常强大。对于简单约束,只需单击“自动布局”菜单的“问题”选项并选择“添加缺少的约束”,Xcode将自动为视图配置布局约束
创建自定义视图类
现在您已经在storyboard中创建了视图,现在是创建自定义视图类的时候了。我们将使用Swift类模板创建类。把它命名为“彩虹”
如前所述,visual类是UIView的一个子类。为了在实时渲染中使用自定义类,我们需要覆盖两个初始值设定项,如上所示。接下来,通过选择助理编辑器拆分视图:
完成后,在助理编辑器中选择主情节提要,以便实时查看正在构建的内容。记住在Identity inspector下将视图的类名更改为“Rainbow”:
实施可设计控件
启用实时渲染控件的第一步是通过在类名前加上@IBDesignable:
@IBDesignable
class Rainbow: UIView {
...
}
正如你所看到的,这有点简单。但是这个简单的关键字会使您的开发更加容易。接下来,我们将添加一些属性来设置圆的颜色。在Rainbow类中插入以下代码行:
@IBInspectable var firstColor: UIColor = UIColor(red: (37.0/255.0), green: (252.0/255), blue: (244.0/255.0), alpha: 1.0)
@IBInspectable var secondColor: UIColor = UIColor(red: (171.0/255.0), green: (250.0/255), blue: (81.0/255.0), alpha: 1.0)
@IBInspectable var thirdColor: UIColor = UIColor(red: (238.0/255.0), green: (32.0/255)
override func drawRect(rect: CGRect) {
// Add ARCs
self.addCirle(80, capRadius: 20, color: self.firstColor)
self.addCirle(150, capRadius: 20, color: self.secondColor)
self.addCirle(215, capRadius: 20, color: self.thirdColor)
}
func addCirle(arcRadius: CGFloat, capRadius: CGFloat, color: UIColor) {
let X = CGRectGetMidX(self.bounds)
let Y = CGRectGetMidY(self.bounds)
// Bottom Oval
let pathBottom = UIBezierPath(ovalInRect: CGRectMake((X - (arcRadius/2)), (Y - (arcRadius/2)), arcRadius, arcRadius)).CGPath
self.addOval(20.0, path: pathBottom, strokeStart: 0, strokeEnd: 0.5, strokeColor: color, fillColor: UIColor.clearColor(), shadowRadius: 0, shadowOpacity: 0, shadowOffsset: CGSizeZero)
// Middle Cap
let pathMiddle = UIBezierPath(ovalInRect: CGRectMake((X - (capRadius/2)) - (arcRadius/2), (Y - (capRadius/2)), capRadius, capRadius)).CGPath
self.addOval(0.0, path: pathMiddle, strokeStart: 0, strokeEnd: 1.0, strokeColor: color, fillColor: color, shadowRadius: 5.0, shadowOpacity: 0.5, shadowOffsset: CGSizeZero)
// Top Oval
let pathTop = UIBezierPath(ovalInRect: CGRectMake((X - (arcRadius/2)), (Y - (arcRadius/2)), arcRadius, arcRadius)).CGPath
self.addOval(20.0, path: pathTop, strokeStart: 0.5, strokeEnd: 1.0, strokeColor: color, fillColor: UIColor.clearColor(), shadowRadius: 0, shadowOpacity: 0, shadowOffsset: CGSizeZero)
}
在这里,我们使用默认颜色预定义每个属性,并告诉它在用户每次更改其值时重新绘制视图。最重要的是,我们在每个属性前面加上@IBInspectable关键字。如果转到视图的“可检查属性”,则应直观地找到以下属性:
很酷,对吧?通过将属性指示为IBInspectable,可以使用颜色选择器直观地编辑它们
好的,让我们开始实现Rainbow类的主要方法
func addOval(lineWidth: CGFloat, path: CGPathRef, strokeStart: CGFloat, strokeEnd: CGFloat, strokeColor: UIColor, fillColor: UIColor, shadowRadius: CGFloat, shadowOpacity: Float, shadowOffsset: CGSize) {
let arc = CAShapeLayer()
arc.lineWidth = lineWidth
arc.path = path
arc.strokeStart = strokeStart
arc.strokeEnd = strokeEnd
arc.strokeColor = strokeColor.CGColor
arc.fillColor = fillColor.CGColor
arc.shadowColor = UIColor.blackColor().CGColor
arc.shadowRadius = shadowRadius
arc.shadowOpacity = shadowOpacity
arc.shadowOffset = shadowOffsset
layer.addSublayer(arc)
}
override func drawRect(rect: CGRect) {
// Add ARCs
self.addCirle(80, capRadius: 20, color: self.firstColor)
self.addCirle(150, capRadius: 20, color: self.secondColor)
self.addCirle(215, capRadius: 20, color: self.thirdColor)
}
func addCirle(arcRadius: CGFloat, capRadius: CGFloat, color: UIColor) {
let X = CGRectGetMidX(self.bounds)
let Y = CGRectGetMidY(self.bounds)
// Bottom Oval
let pathBottom = UIBezierPath(ovalInRect: CGRectMake((X - (arcRadius/2)), (Y - (arcRadius/2)), arcRadius, arcRadius)).CGPath
self.addOval(20.0, path: pathBottom, strokeStart: 0, strokeEnd: 0.5, strokeColor: color, fillColor: UIColor.clearColor(), shadowRadius: 0, shadowOpacity: 0, shadowOffsset: CGSizeZero)
// Middle Cap
let pathMiddle = UIBezierPath(ovalInRect: CGRectMake((X - (capRadius/2)) - (arcRadius/2), (Y - (capRadius/2)), capRadius, capRadius)).CGPath
self.addOval(0.0, path: pathMiddle, strokeStart: 0, strokeEnd: 1.0, strokeColor: color, fillColor: color, shadowRadius: 5.0, shadowOpacity: 0.5, shadowOffsset: CGSizeZero)
// Top Oval
let pathTop = UIBezierPath(ovalInRect: CGRectMake((X - (arcRadius/2)), (Y - (arcRadius/2)), arcRadius, arcRadius)).CGPath
self.addOval(20.0, path: pathTop, strokeStart: 0.5, strokeEnd: 1.0, strokeColor: color, fillColor: UIColor.clearColor(), shadowRadius: 0, shadowOpacity: 0, shadowOffsset: CGSizeZero)
}
First it draws a half circle at the bottom
Next it draws a full small circle at the edge of the arc.
Finally, it draws the other half of the circle
let bundle = Bundle(for: MyView.self)
let view = UINib(nibName: "MyView", bundle: bundle).instantiate(withOwner: self) as! MyView