挺长时间没有撰写技术文章了,今天给大家介绍的虽然不是常用到的标尺demo,但是从这个demo中我们可以学习到别人的绘图是怎么实现的。。。
和以往一样,首先我要强调的是思路。
1.我们要考虑标尺中长短线段不一的实现,还有数字的显示.
先上代码:
(.h)
#import
typedefNS_ENUM(NSUInteger, RulerDirection) {
RulerDirectionHorizontal, //横向
RulerDirectionVertical, //纵向
};
typedefNS_ENUM(NSUInteger, RulerFace) {
RulerFace_up_left,//横向朝上,纵向朝左
RulerFace_down_right,//横向朝下,纵向朝右
};
typedef struct LineColor {
CGFloat R;
CGFloat G;
CGFloat B;
} CustomeColor;
//c 函数构造结构体
CustomeColorcustomColorMake(CGFloatR,CGFloatG,CGFloatB);
typedef void(^Handler)(void);
@interfaceRullerView :UIView
/**
长刻度的长度 默认 fit(24)
*/
@property (nonatomic,assign) float h_height;
/**
短刻度的长度 默认 fit(12)
*/
@property (nonatomic,assign) float m_height;
/**
标尺显示的最小值,默认 0
*/
@property (nonatomic,assign) NSInteger lockMin;
/**
标尺显示的最大值,默认 360
*/
@property (nonatomic,assign) NSInteger lockMax;
/**
一个刻度代表的值是多少,默认 1
*/
@property (nonatomic,assign) NSInteger unitValue;
/**
默认横向滚动
*/
@property (nonatomic,assign) RulerDirection rulerDirection;
/**
默认朝上,朝左
*/
@property (nonatomic,assign) RulerFace rulerFace;
/**
是否显示刻度值
*/
@property (nonatomic,assign)BOOL isShowRulerValue;
/**
标尺数字颜色
*/
@property (nonatomic,strong) UIColor *txtColor;//标尺上数字的颜色
/**
标尺线的颜色
*/
@property (nonatomic) CustomeColor lineColor;//标尺线的颜色
/**
指针位置,默认居中
*/
@property (nonatomic,assign) CGRect pointerFrame;
/**
标尺视图的背景颜色 默认白色
*/
@property(nonatomic,strong)UIColor*rulerBackgroundColor;
- (void)drawRuler:(Handler)block;
#pragma 自定义的宏
//屏幕尺寸
#define cy_ScreenW [UIScreen mainScreen].bounds.size.width
#define cy_ScreenH [UIScreen mainScreen].bounds.size.height
//视图尺寸
#define cy_selfWidth self.bounds.size.width
#define cy_selfHeight self.bounds.size.height
//px宏除2
#define cy_px(value) (value)/2.0
//按宽度适配
#define cy_fit(value) (cy_px(value))*cy_ScreenW/375.0
// RGB颜色转换(16进制->10进制)
#define UIColorFromRGB(rgbValue)\
\
[UIColor colorWithRed:((float)((rgbValue &0xFF0000) >>16))/255.0\
green:((float)((rgbValue &0xFF00) >>8))/255.0\
blue:((float)(rgbValue &0xFF))/255.0\
alpha:1.0]
@end
(.m)
#import "RullerView.h"
@interface RullerView()
{
float_unitPX;//标尺单位长度
float_coarseness;//标尺粗
float_num_height;//数字高度
float_num_top;//数字头部位置
float_mark_bottom;//刻度尾部位置
float_short_mark_top;//短刻度头部位置
float_long_mark_top;//长刻度头部位置
}
@end
@implementation RullerView
- (instancetype)initWithFrame:(CGRect)frame {
self= [superinitWithFrame:frame];
if(self) {
}
return self;
}
- (void)start {
self.backgroundColor = _rulerBackgroundColor?_rulerBackgroundColor:[UIColor whiteColor];
_unitPX=cy_fit(14);
_coarseness = cy_fit(1);
_num_height = cy_fit(24);
_txtColor = UIColorFromRGB(0xDDDDDD);
_lineColor = customColorMake(221, 221, 221);
if (_rulerDirection == RulerDirectionHorizontal) {
if (_rulerFace == RulerFace_up_left) {
_mark_bottom=cy_selfHeight/2.0;
_short_mark_top = _mark_bottom-_m_height;
_long_mark_top = _mark_bottom-_h_height;
_num_top=_mark_bottom+cy_fit(10);
// _long_mark_top-_num_height-cy_fit(10);
}else if (_rulerFace == RulerFace_down_right) {
_mark_bottom=cy_selfHeight/2.0;
_short_mark_top = _mark_bottom+_m_height;
_long_mark_top = _mark_bottom+_h_height;
_num_top = _long_mark_top+_num_height-cy_fit(10);
}else{
NSAssert(NO,@"error");
}
}else if (_rulerDirection == RulerDirectionVertical) {
if (_rulerFace == RulerFace_up_left) {
_mark_bottom=cy_selfWidth/2.0;
_short_mark_top = _mark_bottom-_m_height;
_long_mark_top = _mark_bottom-_h_height;
_num_top = _long_mark_top-_unitPX*8+cy_fit(10);
}else if (_rulerFace == RulerFace_down_right) {
_mark_bottom=cy_selfWidth/2.0;
_short_mark_top = _mark_bottom+_m_height;
_long_mark_top = _mark_bottom+_h_height;
_num_top = _long_mark_top-cy_fit(10);
}else{
NSAssert(NO,@"error");
}
}else{
NSAssert(NO,@"error");
}
}
- (void)drawRuler:(Handler)block {
[selfstart];
if(block) {
block();
}
[self setNeedsDisplay];
}
//绘制方法
- (void)drawRect:(CGRect)rect {
[superdrawRect:rect];
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetRGBStrokeColor(context,self.lineColor.R,self.lineColor.G,self.lineColor.B,1.0);
CGContextSetLineWidth(context, _coarseness);
//画轴
CGPointaPoints[2];//X轴
if (_rulerDirection == RulerDirectionHorizontal) {
aPoints[0] =CGPointMake(0,_mark_bottom);//起始点
aPoints[1] =CGPointMake(cy_selfWidth,_mark_bottom);//终点
}else if (_rulerDirection == RulerDirectionVertical) {
aPoints[0] =CGPointMake(_mark_bottom,0);//起始点
aPoints[1] =CGPointMake(_mark_bottom,cy_selfHeight);//终点
}else{
NSAssert(NO,@"error");
}
CGContextAddLines(context, aPoints,2);//添加线
CGContextDrawPath(context, kCGPathStroke); //根据坐标绘制路径
//画刻度
for (NSInteger i=_lockMin/_unitValue; i<(_lockMax/_unitValue+1); i++) {
CGContextSetRGBStrokeColor(context,self.lineColor.R,self.lineColor.G,self.lineColor.B,1.0);
CGContextSetLineWidth(context, _coarseness);
CGPointaPoints[2];//X轴
if (_rulerDirection == RulerDirectionHorizontal) {
aPoints[0] =CGPointMake(_pointerFrame.origin.x+_pointerFrame.size.width/2.0+_unitPX*i, i%10==0?_long_mark_top:_short_mark_top);//起始点
aPoints[1] =CGPointMake(_pointerFrame.origin.x+_pointerFrame.size.width/2.0+_unitPX*i, _mark_bottom);//终点
}else if (_rulerDirection == RulerDirectionVertical) {
aPoints[0] =CGPointMake(i%10==0?_long_mark_top:_short_mark_top,_pointerFrame.origin.y+_pointerFrame.size.height/2.0+_unitPX*i);//起始点
aPoints[1] =CGPointMake(_mark_bottom,_pointerFrame.origin.y+_pointerFrame.size.height/2.0+_unitPX*i);//终点
}else{
NSAssert(NO,@"error");
}
CGContextAddLines(context, aPoints,2);//添加线
CGContextDrawPath(context, kCGPathStroke); //根据坐标绘制路径
if(_isShowRulerValue&& i%10==0) {
NSMutableParagraphStyle *textStyle = [[NSMutableParagraphStyle defaultParagraphStyle] mutableCopy];
textStyle.lineBreakMode = NSLineBreakByWordWrapping;
textStyle.alignment = NSTextAlignmentCenter;
UIFont *font = [UIFont systemFontOfSize:_num_height];
NSDictionary *attributes = @{NSForegroundColorAttributeName:self.txtColor,NSFontAttributeName:font, NSParagraphStyleAttributeName:textStyle};
if (_rulerDirection == RulerDirectionHorizontal) {
[@(i*_unitValue).stringValue drawInRect:CGRectMake(_pointerFrame.origin.x+_pointerFrame.size.width/2.0+_unitPX*(i-4), _num_top, _unitPX*8, _num_height) withAttributes:attributes];
}else if (_rulerDirection == RulerDirectionVertical) {
[@(i*_unitValue).stringValue drawInRect:CGRectMake(_num_top, _pointerFrame.origin.y+_pointerFrame.size.height/2.0+_unitPX*(i-1), _unitPX*8, _num_height) withAttributes:attributes];
}else{
NSAssert(NO,@"error");
}
}
}
}
//c 函数构造结构体
CustomeColorcustomColorMake(CGFloatR,CGFloatG,CGFloatB) {
CustomeColorl;l.R= R/255.0;l.G= G/255.0;l.B= B/255.0;returnl;
}
@end
这里面着重强调的两个点:一个是自定义标尺绘图视图类要暴露一个绘图回调block给外面。