文档章节

在Xcode6中使用IBDesignable创建自定义控件(翻译)

冷漠叻荭颜
 冷漠叻荭颜
发布于 2015/05/14 21:24
字数 1887
阅读 28
收藏 0

英文原文地址

在Xcode的旧版本中,试图创建一个自定义控件,并不是很容易,因为在IB中,并不能实时预览到你的设计成果,只能在模拟器中测试。对于设计一个单一组件,可能需要花费大量时间。

Xcode6的发布,苹果为开发者构建自定义控件推出了新功能IBDesignableIBInspectable,允许在IB中实时预览设计成果。很明显,这是一个巨大的生产力效益。

在本教程中,将介绍IBDesignable IBInspectable,以及展示如何利用这个新功能。除过创建demo示例没有更好地方式来阐述这一新特性,因此,创建一个"Rainbow"自定义界面。

效果图


IBDesignable和IBInspectable

使用IBDesignable和IBInspectable,开发者创建界面(或视图)可以实时呈现在IB中。一般来说,为了使用这个新特性,你需要做的是创建一个UIView或者UIControl的子类,然后在定义类的前面加上@IBDesignable关键字。如果是OC,使用IB_DESIGNABLE宏。下面是Swift示例代码:

@IBDesignable
class Rainbow: UIView {
}

在Xcode旧版本中,你可以在IB中编辑User Defined Runtime Attributes来改变一个对象的属性(例如:layer.cornerRadius),问题是你需要确切知道属性名。IBInspectable只需要一步,对一个可视化类的属性前面加上IBInspectable关键字前缀,该属性会在暴露在IB中,这就是一个更改属性值更简单的方法。

IB属性

你如果使用Swift开发app,你需要做的只是在你选择的属性前面加上@IBInspectable关键字,下面是个示例代码片段:

@IBInspectable var firstColor: UIColor = UIColor.blackColor() {
   // 值改变时更新UI
}

创建Xcode项目

创建一个新的Xcode项目,选择Single View Application模板,起名为RainbowDemo,在此项目中,将使用Swift语言,因此,创建项目时不要忘记勾选。

完成后,选择Main.storyboard文件,设置View Controller的根视图View的背景颜色Hex Color值为38334C(或者任何你想要的颜色)。然后从对象库中拖一个View放进View Controller,设置它的大小Width为600,Height为434,然后把它放在根视图的中心,设置新视图View和根视图相同背景颜色。

提示:如果想改变RGB颜色值,只需打开调色板和切换到滑块标签来改变RGB值

设置背景颜色

在Xcode6中,为了适配各个iOS设备,你必须为视图View配置自动布局约束。对于简单的约束,你可以在自动布局菜单单击Issues选项,选择Add Missing Contraints,Xcode将自动为View添加布局约束。

添加约束


创建自定义View类

现在,你已经在storyboard中创建了一个View,是时候创建自定义View类了。使用Cocoa Touch Class文件模板,创建自定义类文件,继承自UIView,起名为"Rainbow"。

创建自定义View类

在自定义类中插入以下代码:

import UIKit

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

如前所述,这个可视化类是UIView的子类,让自定义类实时呈现,需要override上述两个方法。然后,打开辅助编辑器,更改新拖的View的自定义类为Rainbow类。


实现IBDesignable控制

为了实现实时预览,在自定义类前面加一个前缀@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), blue: (53.0/255.0), alpha: 1.0)

在这里,我们预先定义每个属性一个默认颜色,每次用户更改它们的值时会重绘视图。更重要的是,我们为每个属性加了一个@IBInspectable关键字前缀,现在去IB的属性检查器,你可以直观地发现这些属性:

IB中的属性

很酷,对吧?IBInspectable通过指示属性,你可以使用颜色选择器可视化地编辑它们。

在Rainbow类中,为了在屏幕上画一个圆,插入以下代码:

func addOval(lineWidth: CGFloat, path: CGPathRef, strokeStart: CGFloat, strokeEnd: CGFloat, strokeColor: UIColor, fillColor: UIColor, shadowRadius: CGFloat, shadowOpacity: Float, shadowOffset: 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.shadowRadius = shadowRadius
   arc.shadowOpacity = shadowOpacity
   arc.shadowOffset = shadowOffset
   layer.addSublayer(arc)
}

为了保证代码的简洁和可读性,我们定义了依据方法调用者传入参数来绘制一个完整的圆或者半圆的公共方法。利用CAShapeLayer类可以很简单的画一个圆或圆弧。你可以使用strokeStart和strokeEnd属性控制渲染的开始和结束。通过改变strokeEnd的值在0.0到1.0之间,你可以绘制一个完整或者部分的圆。其余的属性是只是用于设置渲染颜色,阴影颜色等,在CAShaperLayer官方文档中可以查看更详细的所有可用属性。

接下来,添加以下方法:

override func drawRect(rect: CGRect) {
    // 添加圆弧
    addCircle(80, capRadius: 20, color: firstColor)
    addCircle(150, capRadius: 20, color: secondColor)
    addCircle(215, capRadius: 20, color: thirdColor)
}

func addCircle(arcRadius: CGFloat, capRadius: CGFloat, color: UIColor) {
    let x = CGRectGetMidX(bounds)
    let y = CGRectGetMidY(bounds)
    
    // 底部圆弧
    let pathBottom = UIBezierPath(ovalInRect: CGRectMake((x - (arcRadius/2)),
        (y - (arcRadius/2)), arcRadius, arcRadius)).CGPath
    addOval(20.0, path: pathBottom, strokeStart: 0, strokeEnd: 0.5,
        strokeColor: color, fillColor: UIColor.clearColor(),
        shadowRadius: 0, shadowOpacity: 0, shadowOffset: CGSizeZero)
    
    // 中间圆弧
    let pathMiddle = UIBezierPath(ovalInRect: CGRectMake((x - (capRadius/2)) - (arcRadius/2),
        (y - (capRadius/2)), capRadius, capRadius)).CGPath
    addOval(0.0, path: pathMiddle, strokeStart: 0, strokeEnd: 1.0,
        strokeColor: color, fillColor: color,
        shadowRadius: 5.0, shadowOpacity: 0.5, shadowOffset: CGSizeZero)
    
    // 顶部圆弧
    let pathTop = UIBezierPath(ovalInRect: CGRectMake((x - (arcRadius/2)),
        (y - (arcRadius/2)), arcRadius, arcRadius)).CGPath
    addOval(20.0, path: pathTop, strokeStart: 0.5, strokeEnd: 1.0,
        strokeColor: color, fillColor: UIColor.clearColor(),
        shadowRadius: 0, shadowOpacity: 0, shadowOffset: CGSizeZero)
}

drawRect:方法默认什么也不做,为了在自定义View中画圆,我们override此方法来实现自己的绘制代码。addCircle:方法有三个参数:arcRadius,capRadius和color。arcRadius是圆弧的半径,capRadius是圆弧边缘半径。

addCircle:方法利用UIBezierPath画圆弧的简单工作原理:

  1. 首先,在底部画了个半圆弧
  2. 接下来,在圆弧边缘画了一个完整的小圆
  3. 最后,画了另一半圆弧

drawRect:方法中,我们调用了addCircle:方法三次,传入的参数指定圆弧该怎样画:

画圆弧原理

利用IBInspectable属性,你可以在IB中自由改变每个圆弧的颜色,而不需要写代码:

显然,你可以进一步利用@IBInspectable暴露arcRadius属性,便可以在IB中修改绘制圆弧半径。

修改半径


总结

通过本教程后,你现在了解了在Xcode6中如何利用IBDesignable和IBInspectable实时预览界面。利用这个新特性,你可以更高效创建自定义组件。

RainbowDemo地址

© 著作权归作者所有

上一篇: swift语法学习
下一篇: swift语法学习
冷漠叻荭颜
粉丝 2
博文 2
码字总数 3621
作品 0
海淀
程序员
私信 提问
在Xcode6使用IBDesignable自定义控件

你有没有尝试过在旧版xcode里创建过自定义控件?不是很容易。主要是因为你在Interface Builder(以下简称IB)里看不到实时的效果,每次你要查看修改的效果,只能重新运行,这样很麻烦,你可能...

swingcoder
2016/07/14
7
0
【Swift】使用贝塞尔曲线绘制表情

1、创建一个基于UIView名为FaceView的类 我们不直接在HappinessViewController(根视图控制器) 中实现,而是将FaceView完全独立出来,这正是遵循了MVC的设计原则。我们主要通过贝塞尔曲线来实...

魔笛GNR
2016/07/17
0
0
如何设计一个 iOS 控件?(iOS 控件完全解析)

[置顶] 如何设计一个 iOS 控件?(iOS 控件完全解析) 目录(?)[+] 代码的等级:可编译、可运行、可测试、可读、可维护、可复用 前言 一个控件从外在特征来说,主要是封装这几点: 对外在特征的封...

法斗斗
2016/01/04
23
0
如何设计一个 iOS 控件?(iOS 控件完全解析)

如何设计一个 iOS 控件?(iOS 控件完全解析) 一个控件从外在特征来说,主要是封装这几点: 对外在特征的封装,能让我们在多种环境下达到 PM 对产品的要求,并且提到代码复用率,使维护工作保持...

法斗斗
2016/03/16
57
0
IBInspectable / IBDesignable可视化控件编程讲解/使用/封装

前言: 在以前我们使用xib,SB,nib 设置一个view的圆角 边框需要通过一下界面非常的繁琐,所以一般情况下更倾向于使用代码来设置反而更加简单 在现在 IBInspectable 属性彻底的解决了这个问题...

冰泪_
2016/05/23
1K
0

没有更多内容

加载失败,请刷新页面

加载更多

佳博标签打印问题-

由于网页打印不行,要么sdk 写成activex,这样浏览器支持又有局限。 因此,采用客户端编写打印服务启动,定时轮询服务端打印队列,从服务的获取打印队列进行打印。 服务端web 点击打印,讲打...

mellen
13分钟前
0
0
Jmeter利用JMXMon插件监控服务器JVM情况

1、Jmeter下载JMXMon插件 2、Jmeter 添加 JMXMon请求 远程监控JVM状态需要在JVM启动时候加上一段参数才行,在tomcat bin目录下找到catalina.sh 在# OS specific support. $var _must_ be set...

覃光林
14分钟前
1
0
Qt编写安防视频监控系统(界面很漂亮)

一、前言 视频监控系统在整个安防领域,已经做到了烂大街的程序,全国起码几百家公司做过类似的系统,当然这一方面的需求量也是非常旺盛的,各种定制化的需求越来越多,尤其是这几年借着人脸...

飞扬青云
19分钟前
1
0
Python的requests库中的Put方式使用

1.后端接口 @PutMapping public ResponseEntity<MyObject> putMyObject( @RequestBody MyObject myObject) { ... } Put请求参数在请求体里面。 1.前端请求 import requestsimpo......

亚林瓜子
20分钟前
0
0
全站加速(DCDN)- IP应用加速产品解读

5月22日下午15点,阿里云全站加速(DCDN)-IP应用加速如期发布。IP应用加速是阿里云自主研发的一款更高效、更安全、更便捷的动态加速产品,结合阿里云CDN本身的资源优势,利用就近接入、智能...

迷你芊宝宝
24分钟前
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部