无法在Interface Builder中加载IBDesignable xib

Nic*_*ico 22 xib ios swift ibdesignable

我有一个xib(childXib)文件链接到它的自定义UIViewswift文件UIView.

这是我初始化我的自定义的方式xib:

// 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
}
Run Code Online (Sandbox Code Playgroud)

当我想在另一个()中添加this childXib(xib)时,我收到以下错误:parentXibMyRootView

let view = nib.instantiateWithOwner(self, options: nil)[0] as! UIView
Run Code Online (Sandbox Code Playgroud)

parentXib链接到的文件在哪里MyIBDesignableCustomViewFilename

// 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
}
Run Code Online (Sandbox Code Playgroud)

childXib链接到的文件在哪里Debug.

当我点击调试它Custom classIdentity inspectorxib,不从该行的工作:

let view = nib.instantiateWithOwner(self, options: nil)[0] as! UIView
Run Code Online (Sandbox Code Playgroud)

所有Copy Bundle Resources文件都Build Phasesxib.

知道什么是错的吗?

pri*_*__y 15

第一步:

我将向您介绍IBDesignable和IBInspectable,并向您展示如何利用新功能.没有比创建演示更好的方法来详细说明功能.因此,我们将一起构建一个名为"Rainbow"的自定义界面.

IBDesignable和IBInspectable

使用IBDesignable和IBInspectable,开发人员可以创建实时在Interface Builder中呈现的界面(或视图).通常,要应用此新功能,您需要做的就是通过继承UIView或UIControl创建可视类,然后在Swift中使用@IBDesignable关键字为类名添加前缀.如果您使用的是Objective-C,则使用IB_DESIGNABLE宏代替.这是Swift中的示例代码:

@IBDesignable 
class Rainbow: UIView {
}
Run Code Online (Sandbox Code Playgroud)

在旧版本的Xcode中,您可以编辑用户定义的运行时属性,以在Interface Builder中更改对象的属性(例如layer.cornerRadius).问题是您必须键入属性的确切名称.IBInspectable向前迈进了一步.当您使用IBInspectable为可视类的属性添加前缀时,该属性将向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
 }
Run Code Online (Sandbox Code Playgroud)

构建您的Xcode项目

让我们开始在Xcode中创建一个新项目并选择Single View Application作为模板,并将其命名为RainbowDemo.我们将在此项目中使用Swift作为编程语言,因此在创建项目时不要忘记选择它.

完成后,在Project Navigator中选择Main.storyboard,然后将View对象从Object Library拖到View Controller.将其颜色更改为#38334C(或您想要的任何颜色),并将其大小设置为600乘434.然后将其放在主视图的中心.不要忘记将主视图的颜色更改为视图对象的相同颜色.提示:如果要更改代码的RGB颜色值,只需打开调色板并切换到"滑块"选项卡以更改RGB值.

迷茫?别担心.在完成项目演示后,您将理解我的意思.

使用Xcode 6,您必须为视图配置自动布局约束,以支持所有类型的iOS设备.自动布局在最新版本的Xcode中非常强大.对于简单约束,只需单击"自动布局"菜单的"问题"选项,然后选择"添加缺失约束",Xcode将自动配置视图的布局约束.

在此输入图像描述

创建自定义视图类

现在您已经在storyboard中创建了视图,现在是时候创建我们的自定义视图类了.我们将使用Swift类模板进行类创建.将其命名为"Rainbow".

在此输入图像描述

Then insert the following code in the class:

import UIKit

class Rainbow: UIView {
    required init(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }

    override init(frame: CGRect) {
        super.init(frame: frame)
    }
}
Run Code Online (Sandbox Code Playgroud)

如前所述,visual类是UIView的子类.为了在实时渲染中使用我们的自定义类,我们需要覆盖两个初始化器,如上所示.接下来,通过选择助理编辑器来拆分视图:

在此输入图像描述

完成后,在助理编辑器中选择主故事板,这样您就可以实时查看您正在构建的内容.请记住在Identity检查器下将视图的类名更改为"Rainbow":

实施IBDesignable控件

启用实时渲染控件的第一步是通过在类名前加@IBDesignable来将自定义视图设置为Designable:

@IBDesignable 
class Rainbow: UIView {
    ...
}
Run Code Online (Sandbox Code Playgroud)

你可以看到它有点简单.但这个简单的关键字会让您的开发变得更加容易.接下来,我们将添加一些属性来设置圆的颜色.在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)
Run Code Online (Sandbox Code Playgroud)

在这里,我们使用默认颜色预定义每个属性,并告诉它在每次用户更改其值时重绘视图.最重要的是,我们使用@IBInspectable关键字为每个属性添加前缀.如果转到视图的Attributes inspectable,您应该可以直观地找到这些属性:

很酷,对吗?通过将属性指示为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)
}
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

为了使代码清晰可读,我们创建了一种根据调用者提供的参数绘制完整或半圆的常用方法.使用CAShapeLayer类绘制圆形或圆弧非常简单.您可以使用strokeStart和strokeEnd属性控制stoke的开始和结束.通过将stokeEnd的值更改为0.0到1.0之间,可以绘制完整或部分圆.其余属性仅用于设置笔触颜色,阴影颜色等.您可以查看官方文档,了解CAShapeLayer中所有可用属性的详细信息.

接下来,在Rainbow类中插入以下方法:

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)

}
Run Code Online (Sandbox Code Playgroud)

drawRect方法的默认实现不执行任何操作.为了在视图中绘制圆圈,我们重写方法以实现我们自己的绘图代码.该addCircle方法有三个参数:arcRadius,capRadius和color.的arcRadius是圆的半径,而capRadius是圆形帽的半径.

addCircle方法使用UIBezierPath绘制弧,它的工作方式如下:

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
Run Code Online (Sandbox Code Playgroud)

在drawRect方法中,我们使用不同的半径和颜色调用addCircle方法三次.此图说明了如何绘制圆圈: 在此输入图像描述

提示:如果您需要有关UIBezierPath的更多信息,可以查看Apple的官方文档.

使用IBInspectable属性,您现在可以直接在Interface Builder中更改每个圆的颜色,而无需深入了解代码:

显然,您可以进一步将arcRadius公开为IBInspectable属性.我会把它作为锻炼给你.

在此输入图像描述

在此输入图像描述

有关示例代码,请单击此处:https://github.com/appcoda/Rainbow-IBDesignable-Demo

  • 很好地写了IBDesignable,但未能解决用户对XIB文件的请求. (16认同)
  • 伙计,这绝对是疯狂的,为了一个答案需要付出多少努力!非常尊重@prince。 (2认同)
  • @mobilemonkey同意。我认为这个答案不值得悬赏。 (2认同)

Neb*_*Fox 5

我遇到了同样的问题,并且设法解决了。

迅捷3

let bundle = Bundle(for: MyView.self)
let view = UINib(nibName: "MyView", bundle: bundle).instantiate(withOwner: self) as! MyView
Run Code Online (Sandbox Code Playgroud)

重要的是捆绑


All*_*len 0

对于如下两个错误:

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 ...
Run Code Online (Sandbox Code Playgroud)

我建议进行一次小的快速自我验证可以帮助找出应该解决问题的地方:

  1. 检查 .xib 文件是否已正确添加到项目中
  2. 检查nibName设置是否正确,这里有时会出现拼写错误
  3. 检查插座和动作是否正确连接,包括代码实施