2.10 子类化UIControl
iOS 6核心开发手册(第4版)
UIKit提供了许多预先构建的控件,可以直接在应用程序中使用它们。这些控件包括按钮、选项开关和滑块等。但是,为什么要在那里止步不前?不必把自己局限于Apple提供的项目。为什么不创建你自己的控件呢?
秘诀2-5演示了如何子类化UIControl,以从头开始构建新控件。这个示例创建一个简单的拾色器。在使用时,它允许用户通过触摸或者在控件内拖动来选择一种颜色。当用户左右移动时,颜色改将变其色相。上下移动则会调整颜色的饱和度。颜色的亮度和Alpha层次则固定为100%。
这个控件简单易用,因为除了检索触摸的x和y坐标之外,并不涉及太多的交互。它提供了一个基本的示例,用于演示在子类化UIControl时涉及的大多数开发问题。
那么,为什么要构建自定义的控件呢?首先,可以设置你自己的设计风格。放在界面中的元素可以并且应该匹配应用程序的美学标准。如果Apple预先构建的选项开关、滑块和其他GUI元素不能自然地适应你的界面,自定义的控件将满足你的应用程序的需求,而不会牺牲具有凝聚力的设计。
其次,可以创建Apple没有提供的控件。从通过单击一系列星星来选择评级,或者从一组弹出式彩色蜡笔中选择一种颜色,自定义的控件允许应用程序超越SDK中的系统提供的按钮和选项开关来与用户交互。通过子类化UIControl,很容易构建独特的、引人注目的交互式元素。
最后,自定义的控件允许添加一些不能直接或者通过子类化访问的特性。利用相对很少的工作,就可以从零开始构建自定义的按钮和步进器,允许完全按照自己的需要调整它们的交互词汇表。
总是要使自定义的项目看上去与系统提供的项目具有明显的区别。不要纠缠在HIG问题上。如果使用看上去很像的项目,在把应用程序提交给App Store时,可能希望给Apple添加一条注释。要清楚说明创建的是一个新类,而不是使用私有API或者以非App Store安全的方式访问它们的对象。即便如此,仍可能会拒绝你创建潜在的会使最终用户感到困惑的项目。
2.10.1 创建控件
构建UIControl的过程一般涉及4个截然不同的步骤。如秘诀2-5所示,首先子类化UIControl以创建一个新的自定义类。在该类中,布置初始化中的控件的视觉外观。接下来,构建一些方法来跟踪和解释触摸,最后生成事件和可视化的反馈。
几乎所有的控件都提供了某种类型的值。例如,选项开关具有isOn,滑块具有浮点value,文本框则提供text。利用自定义的控件提供的值类型是任意的,可以是整数、浮点数、字符串,或者甚至是一种颜色(比如在秘诀2-5中)。
在秘诀2-5中,控件布局基本上是一个彩色的矩形。更复杂的控件需要更复杂的布局,但是甚至像这里所示的简单布局也可以很好地工作,提供充满凝聚力的最终用户体验所需的所有触摸交互空间和反馈。
2.10.2 跟踪触摸
UIControl实例使用一个嵌入式方法集来处理触摸。这些方法允许控件在与控件对象的整个交互期间跟踪触摸。
beginTrackingWithTouch:withEvent:——当触摸进入控件的界限内时调用。
continueTrackingWithTouch:withEvent:——当触摸保持在控件的界限内时利用重复调用跟随触摸。
endTrackingWithTouch:withEvent:——为事件处理上一次触摸。
cancelTrackingWithEvent:——管理触摸取消。
通过在UIControl子类中实现任何或所有这些方法,来添加自定义的控件逻辑。秘诀2-5使用开始和继续方法定位用户触摸并跟踪它,直到触摸抬起或者离开控件为止。
2.10.3 调度事件
控件使用目标—动作对来通知由事件触发的改变。在构建一个新控件时,必须决定对象将生成什么类型的事件,并添加代码来触发那些事件。
通过调用sendActionsForControlEvents:给自定义的控件添加调度程序。该方法允许把事件(例如UIControlEventValueChanged)发送给控件的目标。控件通过给UIApplication部件发送消息来传送这些更新。如Apple所指出的,应用程序充当所有消息的集中式调度点。
无论类有多简单,都要创建尽可能完整的控件词汇表。你无法准确预期将来将如何使用类。超标准设计事件可以为将来的使用提供灵活性。秘诀2-5为一个非常简单的控件调度了广泛的事件。
在哪里调度事件在很大程度上依赖于最终构建的控件。例如,选项开关控件实际上只对触摸抬起事件感兴趣,这发生在它们的值改变时。与之相比,滑动控件主要与触摸移动事件有关,当控件跟踪手指移动时需要持续进行更新。相应地调整编码,并且要记住在触摸周期的各个部分展示适合的可视化改变。