第一步:
我将向您介绍 IBDesignable 和 IBInspectable,并向大家展示如何利用新功能。没有比创建演示更好的方法来详细说明功能。所以我们将一起构建一个名为“Rainbow”的自定义界面。
IBDesignable 和 IBInspectable
使用 IBDesignable 和 IBInspectable,开发人员可以创建在 Interface Builder 中实时呈现的界面(或视图)。一般来说,要应用这个新特性,你需要做的就是通过子类化 UIView 或 UIControl 创建一个可视类,然后在 Swift 中使用 @IBDesignable 关键字作为类名的前缀。如果您使用的是 Objective-C,则使用 IB_DESIGNABLE 宏。这是 Swift 中的示例代码:
@IBDesignable
class Rainbow: UIView {
}
在旧版本的 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
}
构建你的 Xcode 项目
让我们开始在 Xcode 中创建一个新项目并选择 Single View Application 作为模板,并将其命名为 RainbowDemo。我们将在这个项目中使用 Swift 作为编程语言,所以在创建项目时不要忘记选择它。
完成后,在 Project Navigator 中选择 Main.storyboard 并将 View 对象从 Object Library 拖到 View Controller 中。将其颜色更改为#38334C(或您想要的任何颜色),并将其大小设置为 600 x 434。然后将其放在主视图的中心。不要忘记将主视图的颜色更改为与视图对象相同的颜色。提示:如果要更改代码的 RGB 颜色值,只需打开调色板并切换到滑块选项卡以更改 RGB 值。
感到困惑?不用担心。看完项目演示后你就会明白我的意思了。
使用 Xcode 6,您必须为视图配置自动布局约束以支持所有类型的 iOS 设备。自动布局在最新版本的 Xcode 中非常强大。对于简单的约束,您只需单击 Auto Layout 菜单的 Issues 选项并选择“Add Missing Contraints”,Xcode 就会自动为视图配置布局约束。
创建自定义视图类
现在您已经在故事板中创建了视图,是时候创建我们的自定义视图类了。我们将使用 Swift 类模板来创建类。将其命名为“彩虹”。
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)
}
}
如前所述,视觉类是 UIView 的子类。为了在实时渲染中使用我们的自定义类,我们需要重写两个初始化器,如上所示。接下来通过选择助手编辑器拆分视图:
完成后,在助理编辑器中选择主故事板,这样您就可以实时查看正在构建的内容。请记住在 Identity inspector 下将视图的类名更改为“Rainbow”:
实施 IBDesignable 控件
启用实时渲染控件的第一步是通过在类名前加上 @IBDesignable 前缀,将自定义视图设置为 Designable:
@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)
在这里,我们使用默认颜色预定义每个属性,并告诉它在每次用户更改其值时重新绘制视图。最重要的是,我们在每个属性前面加上 @IBInspectable 关键字。如果您转到视图的 Attributes 检查,您应该可以直观地找到这些属性:
很酷,对吧?通过将属性指示为 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)
}
为了使代码简洁易读,我们根据调用者提供的参数创建了一个绘制整圆或半圆的通用方法。使用 CAShapeLayer 类绘制圆或弧非常简单。您可以使用 strokeStart 和 strokeEnd 属性控制描边的开始和结束。通过在 0.0 和 1.0 之间改变 stokeEnd 的值,您可以绘制完整或部分圆。其余属性仅用于设置描边的颜色、阴影颜色等。您可以查看官方文档了解 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)
}
该drawRect
方法的默认实现什么也不做。为了在视图中画圆,我们重写了方法来实现我们自己的绘图代码。该addCircle
方法接受三个参数:arcRadius、capRadius 和颜色。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
在 drawRect 方法中,我们以不同的半径和颜色调用了 addCircle 方法 3 次。下图说明了如何绘制圆圈:
提示:如果您需要更多关于 UIBezierPath 的信息,可以查看 Apple 的官方文档。
使用 IBInspectable 属性,您现在可以在 Interface Builder 中自由更改每个圆圈的颜色,而无需深入研究代码:
显然,您可以进一步将 arcRadius 公开为 IBInspectable 属性。我会把它作为练习留给你。
示例代码点击这里:https ://github.com/appcoda/Rainbow-IBDesignable-Demo