如何用 Swift 语言构建一个自定控件

 我来答
du小悟
推荐于2016-05-23 · TA获得超过1.4万个赞
知道大有可为答主
回答量:4397
采纳率:88%
帮助的人:2551万
展开全部
用户界面控件是所有应用程序重要的组成部分之一。它们以图形组件的方式呈现给用户,用户可以通过它们与应用程序进行交互。苹果提供了一套控件,例如 UITextField,UIButton,UISwitch。通过工具箱中的这些已有控件,我们可以创建各式各样的用户界面。

然而,有时候你希望界面做得稍微的与众不同,那么此时苹果提供的这些控件就无法满足你的需求。

自定义控件,除了是自己构建二外,与苹果提供的,没什么差别。也就是说,自定义控件不存在于 UIKit 框架。自定义控件跟苹果提供的标准控件一样,应该是通用,并且多功能的。你也会发现,互联网上有一些积极的开发者乐意分享他们自定义的控件。

本文中,你将实现一个自己的 RangeSlider 自定义控件。这个控件是一个两端都可以滑动的,也就是说,你可以通过该控件获得最小值和最大值。你将会接触到这样一些概念:对现有控件的扩展,设计和实现自定义控件的 API,甚至还能学到如何分享你的自定义控件到开发社区中。

注意:本文截稿时,我们还不会贴出关于 iOS 8 beta 版本的截图。所有文中涉及到的截图都是在iOS 8之前的版本中得到的,不过结果非常类似。

目录:
开始
Images vs. CoreGraphics
添加默认的控件属性
添加交互逻辑
添加触摸处理
值改变的通知
结合 Core Graphics 对控件进行修改
处理控件属性的改变
何去何从?

开始
假设你在开发一个应用程序,该程序提供搜索商品价格列表。通过这个假象的应用程序允许用户对搜索结果进行过滤,以获得一定价格范围的商品。你可能会提供这样一个用户界面:两个 UISlider 控件,一个用于设置最低价格,另外一个设置最高价格。然而,这样的设计,不能够让用户很好的感知价格的范围。要是能够提供一个 slider,两端可以分别设置用于搜索的最高和最低的价格范围,就更好了。
你可以通过创建一个 UIView 的子类,然后为可视的价格范围定做一个 view。这对于应用程序内部来说,是 ok的,但是要想移植到别的程序中,就需要花更多的精力了。

最好的办法是将构建一个新的尽可能通用的 UI 控件,这样就能在任意的合适场合中重用。这也是自定义控件的本质。

启动 Xcode,File/New/Project,选中 iOS/Application/Single View Application 模板,然后点击 Next。在接下来的界面中,输入 CustomSliderExample 当做工程名,然后是 Organization Name 和 Organization Identifier,然后,一定要确保选中 Swift 语言,iPhone 选中,Use Core Data 不要选。

最后,选择一个保存工程的地方并单击 Create。

首先,我们需要做出决定的就是创建自定义控件需要继承自哪个类,或者对哪个类进行扩展。

位了使自定义控件能够在应用程序中使用,你的类必须是 UIView 的一个子类。

如果你注意观察苹果的 UIKit 参考,会发现框架中的许多控件,例如 UILabel 和 UIWebView 都是直接继承自 UIView 的。然而,也有极少数,例如 UIButton 和 UISwitch 是继承自 UIControl 的,如下继承图所示:

注意:iOS 中 UI 组件的完整类继承图,请看 UIKit Framework 参考。

UIControl 实现了 target-action 模式,这是一种将变化通知订阅者的机制。UIControl 同样还有一些与控件状态相关的属性。在本文中的自定义空间中,将使用到 target-action 模式,所以从 UIControl 开始继承使用将是一个非常好的切入点。

在 Project Navigator 中右键单击 CustomSliderExample,选择 New File…,然后选择 iOS/Source/Cocoa Touch Class 模板,并单击 Next。将类命名位 RangeSlider,在 Subclass of 字段中输入 UIControl,并确保语言是 Swift。然后单击 Next,并在默认存储位置中 Create 出新的类。

虽然编码非常让人愉悦,不过你可能也希望尽快看到自定义控件在屏幕中熏染出来的模样!在写自定义控件相关的任何代码之前,你应该先把这个控件添加到 view controller中,这样就可以实时观察控件的演进程度。

打开 ViewController.swift,用下面的内容替换之:
import UIKit

class ViewController: UIViewController {
let rangeSlider = RangeSlider(frame: CGRectZero)

override func viewDidLoad() {
super.viewDidLoad()

rangeSlider.backgroundColor = UIColor.redColor()
view.addSubview(rangeSlider)
}

override func viewDidLayoutSubviews() {
let margin: CGFloat = 20.0
let width = view.bounds.width - 2.0 * margin
rangeSlider.frame = CGRect(x: margin, y: margin + topLayoutGuide.length,
width: width, height: 31.0)
}
}
上面的代码根据指定的 frame 实例化了一个全新的控件,然后将其添加到 view 中。为了在应用程序背景中凸显出控件,我们将控件的背景色被设置位了红色。如果不把控件的背景色设置为红色,那么控件中什么都没有,可能会想,控件去哪里了!

编译并运行程序,将看到如下类似界面:

在开始给控件添加可视元素之前,应该先定义几个属性,用以在控件中记录下各种信息。这也是开始应用程序编程接口 (API) 的开始。

注意:控件中定义的方法和属性是你决定用来暴露给别的开发者使用的。稍后你将看到 API 设计相关的内容,现在只需要紧跟就行!

添加默认的控件属性
打开 RangeSlider.swift,用下面的代码替换之:

import UIKit

class RangeSlider: UIControl {
var minimumValue = 0.0
var maximumValue = 1.0
var lowerValue = 0.2
var upperValue = 0.8
}

上面定义的四个属性用来描述控件的状态,提供最大值和最小值,以及有用户设置的 upper 和 lower 两个值。

好的控件设计,应该提供一些默认的属性值,否则将你的控件绘制到屏幕中时,看起来会有点奇怪。

现在是时候开始做控件的交互元素了,我们分别用两个 thumbs 表示高和低两个值,并且让这两个 thumbs 能够滑动。

Images vs. CoreGraphics

在屏幕中渲染控件有两种方法:
1、Images – 为控件构建不同的图片,这些图片代表控件的各种元素。 2、Core Graphics – 利用 layers 和 Core Graphics 组合起来熏染控件。

这两种方法都有利有弊,下面来看看:

Images – 利用图片来构建控件是最简单的一种方法 – 只要你知道如何绘制图片!:] 如果你想要让开发者能够修改控件的外观,那么你应该将这些图片以 UIImage 属性的方式暴露出去。

通过图片的方式来构建的控件,给使用控件的人提供了非常大的灵活度。开发者可以改变每一个像素,以及控件的详细外观,不过这需要非常熟练的图形设计技能 – 并且通过代码非常难以对控件做出修改。

Core Graphics – 利用 Core Graphics 构建控件意味着你必须自己编写渲染控件的代码,这就需要付出更多的代价。不过,这种方法可以创建更加灵活的 API。

使用 Core Graphics,可以把控件的所有特征都参数化,例如颜色、边框厚度和弧度 – 几乎每一个可视元素都通过绘制完成!这种方法运行开发者对控件做出任意调整,以适配相应的需求。
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式