上面的控制器中用到了一个自定义控件类:FKDashLineView,当用户通过UISlider调整phase或通过按钮重设phase时,程序都会修改FKDashLineView的dashPhase属性,从而改变该自定义控件的绘制外观;当用户通过UIPickerView选择不同的列表项时,程序会调用FKDashLineView的setDashPattern:count:方法。
下面是FKDashLineView自定义类的接口代码。
程序清单:codes/12/12.2/DashLineTest/DashLineTest/FKDashLineView.h
- @interface FKDashLineView : UIView
- {
- CGFloat dashPattern[10];
- size_t dashCount;
- }
- @property(nonatomic, assign) CGFloat dashPhase;
- -(void)setDashPattern:(CGFloat*)pattern count:(size_t)count;
- @end
FKDashLineView的实现代码将会重写drawRect:方法来绘制该控件,绘制该控件时将会根据不同的dashPhase参数和dashPattern参数来选择使用不同的点线模式。下面是该自定义控件类的实现代码。
程序清单:codes/12/12.2/DashLineTest/DashLineTest/FKDashLineView.m
- @implementation FKDashLineView
- @synthesize dashPhase;
- -(id)initWithFrame:(CGRect)frame
- {
- self = [super initWithFrame:frame];
- if(self != nil)
- {
- self.opaque = YES;
- self.backgroundColor = [UIColor blackColor];
- // 设置每次清空上一次绘制的内容
- self.clearsContextBeforeDrawing = YES;
- dashCount = 0;
- dashPhase = 0.0;
- }
- return self;
- }
- -(void)setDashPhase:(CGFloat)phase
- {
- // 如果新传入的phase参数与原有dashPash参数不相等
- if(phase != dashPhase)
- {
- dashPhase = phase; // 对dashPhase赋值
- [self setNeedsDisplay]; // 通知该控件重绘自己
- }
- }
- -(void)setDashPattern:(CGFloat *)pattern count:(size_t)count
- {
- // 如果count与dashCount不相等,或者dashPattern数组与pattern数组不相等
- if((count != dashCount) || (memcmp(dashPattern, pattern
- , sizeof(CGFloat) * count) != 0))
- {
- // 将pattern数组的值复制到dashPattern数组
- memcpy(dashPattern, pattern, sizeof(CGFloat) * count);
- dashCount = count; // 对dashCount赋值
- [self setNeedsDisplay]; // 通知该控件重绘自己
- }
- }
- // 重写该方法,绘制该控件
- -(void)drawRect:(CGRect)rect
- {
- CGContextRef ctx = UIGraphicsGetCurrentContext(); // 获取绘图上下文
- CGContextSetRGBStrokeColor(ctx, 1.0, 0.0, 1.0, 1.0); // 设置线条颜色
- CGContextSetLineWidth(ctx, 2.0); // 设置线宽
- // 设置点线模式
- CGContextSetLineDash(ctx, dashPhase, dashPattern, dashCount);
- CGPoint line1[] = {CGPointMake(10.0, 20.0), CGPointMake(310.0, 20.0)};
- CGContextStrokeLineSegments(ctx, line1, 2); // 绘制一条线段
- CGPoint line2[] = {CGPointMake(160.0, 130.0), CGPointMake(160.0, 130.0)};
- CGContextStrokeLineSegments(ctx, line2, 2); // 绘制一条线段
- CGContextStrokeRect(ctx, CGRectMake(10.0, 30.0, 100.0, 100.0)); // 绘制一个矩形
- CGContextStrokeEllipseInRect(ctx, CGRectMake(210.0, 30.0, 100.0, 100.0)); // 绘制一个椭圆
- }
- @end
该程序的关键在于粗体字代码,这行粗体代码设置了绘制图形所用的点线模式,该点线模式的dashPhase、dashPattern都来自该控件的属性。这些属性会随着用户操作界面上的UISlider、UIPickerView改变,这样就可以使用不同的点线模式来绘制该UI控件上的线条了。
编译、运行该程序,可以看到如图12.4所示的结果。
当用户选择UIPickerView的不同列表项目时,可以看到界面上点线模式的实线长度、间距会随选择而动态改变;如果用户拖动界面上的UIPickerView,将会看到点线模式的phase参数不断改变,形成类似动画的效果。这是因为程序采用不同的phase绘制点线时,就会形成线条在流动的错觉。