本章学习视图的重绘机制并继续开发Hypnosister应用,当用户触摸BNRHypnosisView时,圆形的颜色会改变。为了改变圆形的颜色,BNRHypnosisView需要重新绘制自己。在后面的章节中,还会将一个UIScrollView对象添加到Hypnosister的视图层次结构中。
首先要在BNRHypnosisView中声明一个属性,用来表示圆形的颜色。之前的项目一直是在头文件中声明属性的,其实属性也可以在类扩展(class extensions)中声明。
打开BNRHypnosisView.m文件,在文件顶部添加以下代码:
#import "BNRHypnosisView.h"
@interface BNRHypnosisView
@property (strong, nonatomic) UIColor *circleColor;
@end
@implementation BNRHypnosisView
加入的三行代码称为BNRHypnosisView的类扩展。类扩展中声明了一个circleColor属性——为什么要将该属性声明在类扩展中而不是头文件中?原因会在完成改变圆形颜色的功能之后介绍,现在只要将circleColor看成是BNRHypnosisView的一个普通属性即可。
在BNRHypnosisView.m的initWithFrame:方法中,为circleColor属性设置默认颜色,代码如下:
- (instancetype)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
self.backgroundColor = [UIColor clearColor];
self.circleColor = [UIColor lightGrayColor];
}
return self;
}
在drawRect:方法中修改设置线条颜色的代码,使用circleColor作为线条颜色:
// 设置线条宽度为10点
path.lineWidth = 10;
[[UIColor lightGrayColor] setStroke];
[self.circleColor setStroke];
// 绘制路径!
[path stroke];
构建并运行应用,BNRHypnosisView对象绘制的圆形颜色应该与之前的相同。下一步是编写视图被触摸时改变圆形颜色的代码。
当用户触摸视图时,视图会收到touchesBegan:withEvent:消息,该消息用来处理触摸事件。第12章会详细介绍触摸事件与事件处理机制,现在只需要直接覆盖touchesBegan: withEvent:方法即可,这样就可以在BNRHypnosisView被触摸后改变circleColor属性所表示的颜色。
在BNRHypnosisView.m中覆盖touchesBegan:withEvent:,首先向控制台打印一条信息,然后创建一个随机生成的UIColor对象,并赋给circleColor属性。
// BNRHypnosisView被触摸时会收到该消息
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
NSLog(@"%@ was touched", self);
// 获取三个0到1之间的数字
float red = (arc4random % 100) / 100.0;
float green = (arc4random % 100) / 100.0;
float blue = (arc4random % 100) / 100.0;
UIColor *randomColor = [UIColor colorWithRed:red
green:green
blue:blue
alpha:1.0];
self.circleColor = randomColor;
}
构建并运行应用,触摸BNRHypnosisView上的任意位置,控制台会打印视图被触摸的消息,但是圆形的颜色没有改变——BNRHypnosisView没有重新绘制自己。接下来会介绍视图没有重绘的原因以及如何解决这个问题。