效果:
1.png.h文件
//
// SXSRulerControl.h
// SXSInvestScaleSlider
//
// Created by Angela on 16/9/26.
// Copyright © 2016年 iaiai. All rights reserved.
//
#import
IB_DESIGNABLE //轻量级标尺控件
@interface SXSRulerControl : UIControl
@property (nonatomic, assign) IBInspectable CGFloat selectedValue;//选中的数值
@property (nonatomic, assign) IBInspectable NSInteger minValue;//最小值
@property (nonatomic, assign) IBInspectable NSInteger maxValue;//最大值
@property (nonatomic, assign) IBInspectable NSInteger valueStep;//步长
@property (nonatomic, assign) IBInspectable CGFloat minorScaleSpacing;//小刻度间距,默认值 `8.0`
@property (nonatomic, assign) IBInspectable CGFloat majorScaleLength;//主刻度长度,默认值 `40.0`
@property (nonatomic, assign) IBInspectable CGFloat middleScaleLength;//中间刻度长度,默认值 `25.0`
@property (nonatomic, assign) IBInspectable CGFloat minorScaleLength;//小刻度长度,默认值 `10.0`
@property (nonatomic, strong) IBInspectable UIColor *rulerBackgroundColor;//刻度尺背景颜色,默认为 `clearColor`
@property (nonatomic, strong) IBInspectable UIColor *scaleColor;//刻度颜色,默认为 `lightGrayColor`
@property (nonatomic, strong) IBInspectable UIColor *scaleFontColor;// 刻度字体颜色,默认为 `darkGrayColor`
@property (nonatomic, assign) IBInspectable CGFloat scaleFontSize;//刻度字体尺寸,默认为 `10.0`
@property (nonatomic, strong) IBInspectable UIColor *indicatorColor;//指示器颜色,默认 `redColor`
@property (nonatomic, assign) IBInspectable CGFloat indicatorLength;//指示器长度,默认值为 `40.0`
@property (nonatomic, assign) IBInspectable NSInteger midCount;//几个大格标记一个刻度
@property (nonatomic, assign) IBInspectable NSInteger smallCount;//一个大格里面几个小格
@end
.m文件
//
// SXSRulerControl.m
// SXSInvestScaleSlider
//
// Created by iaiai on 16/9/26.
// Copyright © 2016年 iaiai. All rights reserved.
//
#import "SXSRulerControl.h"
#define kMinorScaleDefaultSpacing 20 // 小刻度间距
#define kMajorScaleDefaultLength 25.0 //主刻度高度
#define kMiddleScaleDefaultLength 17.0 //中间刻度高度
#define kMinorScaleDefaultLength 10.0 //小刻度高度
#define kRulerDefaultBackgroundColor ([UIColor clearColor]) //刻度尺背景颜色
#define kScaleDefaultColor ([UIColor lightGrayColor]) //刻度颜色
#define kScaleDefaultFontColor ([UIColor darkGrayColor]) //刻度字体颜色
#define kScaleDefaultFontSize 10.0 //刻度字体
#define kIndicatorDefaultColor ([UIColor redColor]) //指示器默认颜色
#define kIndicatorDefaultLength 80 //指示器高度
@interface SXSRulerControl ()
@end
@implementation SXSRulerControl{
UIScrollView *_scrollView;
UIImageView *_rulerImageView;
UIView *_indicatorView;
}
#pragma mark - 构造函数
- (instancetype)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
[self setupUI];
}
return self;
}
- (void)layoutSubviews {
[super layoutSubviews];
if (_rulerImageView.image == nil) {
[self reloadRuler];
}
CGSize size = self.bounds.size;
_indicatorView.frame = CGRectMake(size.width * 0.5, size.height - self.indicatorLength, 1, self.indicatorLength);
// 设置滚动视图内容间距
CGSize textSize = [self maxValueTextSize];
CGFloat offset = size.width * 0.5 - textSize.width;
_scrollView.contentInset = UIEdgeInsetsMake(0, offset, 0, offset);
}
#pragma mark - 设置属性
//指示器颜色
- (void)setIndicatorColor:(UIColor *)indicatorColor {
_indicatorView.backgroundColor = indicatorColor;
}
////选中的数值
- (void)setSelectedValue:(CGFloat)selectedValue {
if (selectedValue <</span> _minValue || selectedValue > _maxValue || _valueStep <= 0) {
return;
}
_selectedValue = selectedValue;
[self sendActionsForControlEvents:UIControlEventValueChanged];
CGFloat spacing = self.minorScaleSpacing;
CGSize size = self.bounds.size;
CGSize textSize = [self maxValueTextSize];
CGFloat offset = 0;
// 计算偏移量
CGFloat steps = [self stepsWithValue:selectedValue];
offset = size.width * 0.5 - textSize.width - steps * spacing;
_scrollView.contentOffset = CGPointMake(-offset, 0);
}
#pragma mark - UIScrollViewDelegate
- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset {
CGFloat spacing = self.minorScaleSpacing;
CGSize size = self.bounds.size;
CGSize textSize = [self maxValueTextSize];
CGFloat offset = targetContentOffset->x + size.width * 0.5 - textSize.width;
NSInteger steps = (NSInteger)(offset / spacing + 0.5);
targetContentOffset->x = -(size.width * 0.5 - textSize.width - steps * spacing) - 0.5;
}
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
if (!(scrollView.isDragging || scrollView.isTracking || scrollView.isDecelerating)) {
return;
}
CGFloat spacing = self.minorScaleSpacing;
CGSize size = self.bounds.size;
CGSize textSize = [self maxValueTextSize];
CGFloat offset = 0;
offset = scrollView.contentOffset.x + size.width * 0.5 - textSize.width;
NSInteger steps = (NSInteger)(offset / spacing + 0.5);
CGFloat value = _minValue + steps * _valueStep/(_midCount*_smallCount);
if (value != _selectedValue && (value >= _minValue && value <= _maxValue)) {
_selectedValue = value;
[self sendActionsForControlEvents:UIControlEventValueChanged];
}
}
#pragma mark - 绘制标尺相关方法
- (void)reloadRuler {
UIImage *image = [self rulerImage];
if (image == nil) {
return;
}
_rulerImageView.image = image;
_rulerImageView.backgroundColor = self.rulerBackgroundColor;
[_rulerImageView sizeToFit];
_scrollView.contentSize = _rulerImageView.image.size;
// 水平标尺靠下对齐
CGRect rect = _rulerImageView.frame;
rect.origin.y = _scrollView.bounds.size.height - _rulerImageView.image.size.height;
_rulerImageView.frame = rect;
// 更新初始值
self.selectedValue = _selectedValue;
}
- (UIImage *)rulerImage {
// 1. 常数计算
CGFloat steps = [self stepsWithValue:_maxValue];
if (steps == 0) {
return nil;
}
// 水平方向绘制图像的大小
CGSize textSize = [self maxValueTextSize];
CGFloat height = _scrollView.frame.size.height-_rulerImageView.frame.size.height ;
CGFloat startX = textSize.width;
CGRect rect = CGRectMake(0, 0, steps * self.minorScaleSpacing + 2 * startX, height);
// 2. 绘制图像
UIGraphicsBeginImageContextWithOptions(rect.size, NO, 0);
// 1> 绘制刻度线
UIBezierPath *path = [UIBezierPath bezierPath];
for (NSInteger i = _minValue; i <= _maxValue; i += _valueStep) {
// 绘制主刻度下
CGFloat x = (i - _minValue) / _valueStep * self.minorScaleSpacing * (_midCount*_smallCount) + startX;
[path moveToPoint:CGPointMake(x, height)];
[path addLineToPoint:CGPointMake(x, height - self.majorScaleLength)];
// 绘制主刻度上
[path moveToPoint:CGPointMake(x, 0)];
[path addLineToPoint:CGPointMake(x,self.majorScaleLength)];
if (i == _maxValue) {
break;
}
// 绘制小刻度线下
for (NSInteger j = 1; j < (_midCount*_smallCount); j++) {
CGFloat scaleX = x + j * self.minorScaleSpacing;
[path moveToPoint:CGPointMake(scaleX, height)];
CGFloat scaleY = height - ((j%_smallCount == 0) ? self.middleScaleLength : self.minorScaleLength);
[path addLineToPoint:CGPointMake(scaleX, scaleY)];
}
// 绘制小刻度线上
for (NSInteger j = 1; j < (_midCount*_smallCount); j++) {
CGFloat scaleX = x + j * self.minorScaleSpacing;
//上
[path moveToPoint:CGPointMake(scaleX, 0)];
CGFloat scaleY =((j%_smallCount == 0) ? self.middleScaleLength : self.minorScaleLength);
//上
[path addLineToPoint:CGPointMake(scaleX, scaleY)];
}
}
[self.scaleColor set];
[path stroke];
// 2> 绘制刻度值
NSDictionary *strAttributes = [self scaleTextAttributes];
for (NSInteger i = _minValue; i <= _maxValue; i += _valueStep) {
NSString *str = @(i).description;
CGRect strRect = [str boundingRectWithSize:CGSizeMake(MAXFLOAT, MAXFLOAT)
options:NSStringDrawingUsesLineFragmentOrigin
attributes:strAttributes
context:nil];
strRect.origin.x = (i - _minValue) / _valueStep * self.minorScaleSpacing *( _midCount*_smallCount) + startX - strRect.size.width * 0.5;
strRect.origin.y =_scrollView.frame.size.height*0.5-textSize.height*0.5;
[str drawInRect:strRect withAttributes:strAttributes];
}
UIImage *result = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return result;
}
- (CGFloat)stepsWithValue:(CGFloat)value {
if (_minValue >= value || _valueStep <= 0) {
return 0;
}
return (value - _minValue) / _valueStep *( _midCount*_smallCount);
}
- (CGSize)maxValueTextSize {
NSString *scaleText = @(self.maxValue).description;
CGSize size = [scaleText boundingRectWithSize:CGSizeMake(MAXFLOAT, MAXFLOAT)
options:NSStringDrawingUsesLineFragmentOrigin
attributes:[self scaleTextAttributes]
context:nil].size;
return CGSizeMake(floor(size.width), floor(size.height));
}
- (NSDictionary *)scaleTextAttributes {
CGFloat fontSize = self.scaleFontSize * [UIScreen mainScreen].scale * 0.6;
return @{NSForegroundColorAttributeName: self.scaleFontColor,
NSFontAttributeName: [UIFont boldSystemFontOfSize:fontSize]};
}
#pragma mark - 设置界面
- (void)setupUI {
// 滚动视图
_scrollView = [[UIScrollView alloc] initWithFrame:self.bounds];
_scrollView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
_scrollView.showsVerticalScrollIndicator = NO;
_scrollView.showsHorizontalScrollIndicator = NO;
_scrollView.delegate = self;
_scrollView.layer.borderWidth=0.5;
_scrollView.layer.borderColor=kScaleDefaultColor.CGColor;
[self addSubview:_scrollView];
// 标尺图像
_rulerImageView = [[UIImageView alloc] init];
[_scrollView addSubview:_rulerImageView];
// 指示器视图
_indicatorView = [[UIView alloc] init];
_indicatorView.backgroundColor = self.indicatorColor;
[self addSubview:_indicatorView];
}
#pragma mark - 属性默认值
//小刻度间距
- (CGFloat)minorScaleSpacing {
if (_minorScaleSpacing <= 0) {
_minorScaleSpacing = kMinorScaleDefaultSpacing;
}
return _minorScaleSpacing;
}
//主刻度长度
- (CGFloat)majorScaleLength {
if (_majorScaleLength <= 0) {
_majorScaleLength = kMajorScaleDefaultLength;
}
return _majorScaleLength;
}
//中间刻度长度
- (CGFloat)middleScaleLength {
if (_middleScaleLength <= 0) {
_middleScaleLength = kMiddleScaleDefaultLength;
}
return _middleScaleLength;
}
//小刻度长度
- (CGFloat)minorScaleLength {
if (_minorScaleLength <= 0) {
_minorScaleLength = kMinorScaleDefaultLength;
}
return _minorScaleLength;
}
//刻度尺背景颜色
- (UIColor *)rulerBackgroundColor {
if (_rulerBackgroundColor == nil) {
_rulerBackgroundColor = kRulerDefaultBackgroundColor;
}
return _rulerBackgroundColor;
}
//刻度颜色
- (UIColor *)scaleColor {
if (_scaleColor == nil) {
_scaleColor = kScaleDefaultColor;
}
return _scaleColor;
}
// 刻度字体颜色
- (UIColor *)scaleFontColor {
if (_scaleFontColor == nil) {
_scaleFontColor = kScaleDefaultFontColor;
}
return _scaleFontColor;
}
//刻度字体尺寸
- (CGFloat)scaleFontSize {
if (_scaleFontSize <= 0) {
_scaleFontSize = kScaleDefaultFontSize;
}
return _scaleFontSize;
}
//指示器颜色
- (UIColor *)indicatorColor {
if (_indicatorView.backgroundColor == nil) {
_indicatorView.backgroundColor = kIndicatorDefaultColor;
}
return _indicatorView.backgroundColor;
}
//指示器长度
- (CGFloat)indicatorLength {
if (_indicatorLength <= 0) {
_indicatorLength = kIndicatorDefaultLength;
}
return _indicatorLength;
}
@end
在控制器中使用:
//
// SXSRulerControlVC.m
// SXSInvestScaleSlider
//
// Created by Angela on 16/9/26.
// Copyright © 2016年 iaiai. All rights reserved.
//3.8M
#import "SXSRulerControlVC.h"
#import "SXSRulerControl.h"
@interface SXSRulerControlVC ()<</span>UITextFieldDelegate>
@property (nonatomic, strong) UITextField *textfield;
@property (nonatomic, strong) SXSRulerControl *ruler;
@end
@implementation SXSRulerControlVC
- (void)viewDidLoad {
[super viewDidLoad];
_textfield=[[UITextField alloc]initWithFrame:CGRectMake(80, 100, 100, 40)];
_textfield.backgroundColor=[UIColor lightGrayColor];
_textfield.textAlignment=NSTextAlignmentCenter;
_textfield.delegate=self;
[self.view addSubview:_textfield];
_ruler = [[SXSRulerControl alloc] initWithFrame:CGRectMake(20, 0,[UIScreen mainScreen].bounds.size.width-40, 80)];
_ruler.center = self.view.center;
[self.view addSubview:_ruler];
_ruler.backgroundColor = [UIColor colorWithWhite:0.93 alpha:1];
_ruler.midCount=2;//几个大格标记一个刻度
_ruler.smallCount=5;//一个大格几个小格
_ruler.minValue = 0;// 最小值
_ruler.maxValue = 3000;// 最大值
_ruler.valueStep = 400;// 两个标记刻度之间相差大小
//每个小格格大值计算为:ruler.valueStep÷(ruler.midCount*ruler.smallCount)
_ruler.selectedValue = 1000;// 设置默认值
[_ruler addTarget:self action:@selector(selectedValueChanged:) forControlEvents:UIControlEventValueChanged]; // 添加监听方法
}
- (void)selectedValueChanged:(SXSRulerControl *)ruler {
_textfield.text = [NSString stringWithFormat:@"%.f", ruler.selectedValue];
}
-(void)textFieldDidEndEditing:(UITextField *)textField{
_ruler.selectedValue=textField.text.integerValue;
}
-(void)textFieldDidBeginEditing:(UITextField *)textField{
_ruler.selectedValue=textField.text.integerValue;
}
@end
网友评论