`
iaiai
  • 浏览: 2180176 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

iOS仿刻度尺demo

 
阅读更多
效果:

.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
  • 大小: 13 KB
分享到:
评论

相关推荐

    ios-刻度尺,身高,体重,用CAShapeLayer实现高效GPU渲染.zip

    在iOS开发中,为了提供高质量的用户体验,开发者经常需要创建自定义视图,例如刻度尺,用于显示身高和体重等信息。这个压缩包“ios-刻度尺,身高,体重,用CAShapeLayer实现高效GPU渲染.zip”就包含了一个使用...

    iOS自定义游标刻度尺

    本主题聚焦于“iOS自定义游标刻度尺”,这是一种特殊的进度条(progressbar)控件,它允许用户通过游标进行交互,调整并显示某个数值范围。这种自定义控件通常用于音乐播放器、视频进度控制或者数据调整等场景。 ...

    swift-DividingRuler-自定义滑动刻度尺滑动标尺实现简单所有参数可完全自定义

    本项目“swift-DividingRuler-自定义滑动刻度尺滑动标尺实现简单所有参数可完全自定义”正是这样一个例子,它提供了一个可高度定制的滑动刻度尺控件。下面我们将深入探讨这个项目的实现原理和关键知识点。 1. **...

    iOS 进度条 刻度尺 动画 渐进色

    综上所述,这个iOS进度条组件融合了渐进色、动画、刻度尺等多种特性,为用户界面带来更丰富的视觉体验。通过深入理解并应用这些知识点,开发者可以创建出更加精美和功能强大的进度条控件,提升应用程序的用户体验。

    swift-iOS高仿抖音appdemo"复制"了抖音个人主页视频播放列表IM即时聊天页面。

    "swift-iOS高仿抖音appdemo"是一个使用Swift编程语言开发的iOS应用项目,旨在模仿和实现抖音应用的主要功能,特别是个人主页、视频播放列表以及即时聊天界面。这个项目对于想要学习如何在Swift中构建类似抖音功能的...

    ios仿淘宝购物车demo

    这个"ios仿淘宝购物车demo"提供了一个基础框架,帮助开发者理解并构建这样的功能。在这个项目中,重点是实现单选、多选以及滑动单行删除等交互特性。下面我们将详细探讨这些知识点。 1. **单选与多选机制**: 在...

    刻滑动刻度尺

    总的来说,滑动刻度尺(UISlider)是iOS应用中一个实用的交互组件,它通过Objective-C的编程实现,提供了一种直观的方式来让用户输入或调整数值。理解和掌握其使用方法对于iOS开发者来说至关重要,特别是在设计需要...

    iOS 3D星球效果demo

    这个名为"iOS 3D星球效果demo"的项目旨在提供一个高性能、流畅的解决方案,克服了当星球数量增加时可能出现的滚动卡顿和交互体验不佳的问题。以下是关于这个Demo涉及的主要知识点的详细解析: 1. **OpenGL ES**:...

    ios-可缩放的刻度尺(子刻度显隐).zip

    在iOS开发中,创建一个可缩放的刻度尺(包括子刻度显隐功能)是一项常见的需求,尤其是在设计各种测量或绘图应用时。这个项目"ios-可缩放的刻度尺(子刻度显隐).zip"提供了一个实现这种功能的思路。以下是对这个实现...

    ios 简单xml解析DEMO绝对可用

    本教程将介绍如何在iOS应用中实现简单的XML解析,并提供了一个名为"UITableViewTricks"的DEMO,供开发者们参考学习。 XML文件结构清晰,易于理解,但在iOS中解析XML数据并非内置功能,需要借助第三方库或者Apple...

    ios-尺子刻度动态.zip

    【标题】"ios-尺子刻度动态.zip" 涉及的知识点主要集中在iOS应用开发上,特别是关于自定义视图(Custom View)和图形绘制(Drawing)方面。在这个项目中,开发者创建了一个动态的尺子应用,能够显示可交互的尺子刻度...

    swift-刻度尺工具采用的时collectionView来实现复用的支持实时回调刻度校准等

    在本项目"swift-刻度尺工具"中,开发者选择使用`UICollectionView`来构建一个功能强大的刻度尺工具,这不仅体现了Swift在UI组件上的灵活性,也展示了`UICollectionView`复用机制的优势。 `UICollectionView`是iOS ...

    IOS中文文字识别DEMO,OCR

    本文将详细解析iOS中文文字识别DEMO及其相关技术,包括OCR(Optical Character Recognition,光学字符识别)技术、图像处理、二值化、滤镜和剪切等关键步骤。 首先,OCR技术是将图像中的文字转换成机器可编辑的文本...

    ios 程序启动动画 demo

    "ios程序启动动画 demo"是一个示例项目,用于展示如何在自己的iOS应用中实现自定义的启动动画。这个压缩包可能包含了必要的代码资源和图片资源,如"淡化程序启动",这可能是一个实现淡入效果的动画。 在iOS应用中...

    IOS高德地图官方demo

    "IOS高德地图官方demo" 是一个专门为iOS开发者设计的示例项目,帮助开发者快速理解和掌握如何在自己的应用中集成高德地图。通过分析这个官方Demo,我们可以学习到以下关键知识点: 1. **集成高德地图SDK**:首先,...

    滑动刻度尺滑动刻度尺。详情 有图有真相 http://blog.csdn.net/liudao7994/article/det

    在iOS、Android以及许多其他平台的开发中,滑动刻度尺都有相应的API支持。 在iOS中,滑动刻度尺被称为UISlider,它是UIControl的一个子类。开发者可以设置它的最小值、最大值、当前值以及滑块的图像。UISlider的...

    iOS仿淘宝搜索记录,多标签自动分布,自动布局!

    仿淘宝搜索记录,多标签自动分布,自动换行展示!不同于collection的是,collection 每一行item平均分布,每一行的间隔不统一,MoreLabels实现的是每一行靠左展示,每一行的标签间隔统一,自动换行!大家根据自己的...

    ios xmpp demo

    ios xmpp demo

    iOS扫描银行卡demo

    本项目“iOS扫描银行卡demo”旨在模仿支付宝等知名应用的银行卡扫描功能,下面我们将深入探讨这一功能的实现原理和技术要点。 首先,我们需要了解的是iOS的图像处理框架——Core Image。Core Image提供了强大的图像...

    ios-仿QQ分组Demo.zip

    在iOS开发中,仿QQ分组Demo是一种常见的实践,它主要展示了如何实现类似QQ应用的分组功能。这个Demo的核心是构建一个用户友好的界面,其中包含可滚动的列表,每个列表项代表一个分组,点击后可以展开或收起对应的...

Global site tag (gtag.js) - Google Analytics