iOS 金融类游标尺选择数值 ZBRulerView
2018-06-28 本文已影响12人
biyuhuaping
最近产品看别的app有游标尺选金额,要我们也加上,好吧,开干!先看看效果:
游标尺
首先我要可以设置最大值、最小值、和默认指向的值:
@property (nonatomic, assign) double minValue; // 最小值,默认为0
@property (nonatomic, assign) double maxValue; // 最大值,必需设置
@property (nonatomic, assign) double defaultValue; // 默认值,默认为0
初始化试图:
- (instancetype)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
_scrollWidth = kScreenWidth;
self.backgroundColor = [UIColor whiteColor];
[self addSubview:self.scrollView];
[self addSubview:self.textField];
[self addSubview:self.markLine];
[self addSubview:self.bottomLine];
_minValue = 0; //设置默认初始值
}
return self;
}
难点是根据数值画刻度:
- (void)createIndicator{
for (NSUInteger i = self.minValue, j = 0; i <= self.maxValue; i+=kMinScale, j++) {
_scrollWidth += kPadding;
[self drawSegmentWithValue:i idx:j];
}
self.scrollView.contentSize = CGSizeMake(_scrollWidth-kPadding, CGRectGetHeight(self.frame));
}
- (void)drawSegmentWithValue:(NSUInteger)value idx:(NSUInteger)idx {
UIBezierPath *path = [UIBezierPath bezierPath];
CGFloat x = kScreenWidth*0.5 + kPadding*idx;
[path moveToPoint:CGPointMake(x, CGRectGetHeight(self.frame)-5)];
if (value % (kMinScale*10) == 0 || value == _minValue) { //每10个刻度,do something
[path addLineToPoint:CGPointMake(x, CGRectGetHeight(self.frame)-10-5-10)];
UILabel *numLabel = [[UILabel alloc] initWithFrame:CGRectMake(x-50*0.5, CGRectGetHeight(self.frame)-20-10-5-5, 50, 10)];
numLabel.font = [UIFont systemFontOfSize:12];
numLabel.textAlignment = NSTextAlignmentCenter;
numLabel.textColor = [UIColor redColor];
numLabel.text = [NSString stringWithFormat:@"%ld", value];
[self.scrollView addSubview:numLabel];
} else if (value % (kMinScale*2) != 0) { //每2个刻度,do something
[path addLineToPoint:CGPointMake(x, CGRectGetHeight(self.frame)-10)];
} else{
[path addLineToPoint:CGPointMake(x, CGRectGetHeight(self.frame)-10-5)];
}
CAShapeLayer *line = [[CAShapeLayer alloc] init];
line.lineWidth = 1;
line.strokeColor = [UIColor orangeColor].CGColor;
line.path = path.CGPath;
[self.scrollView.layer addSublayer:line];
}
通过执行UIScrollViewDelegate实时显示滚到的数值
#pragma mark - UIScrollViewDelegate
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
CGFloat num = scrollView.contentOffset.x;
double value = (num / kPadding) * kMinScale + self.minValue;
if (value < self.minValue) {
value = self.minValue;
}else if (value > self.maxValue) {
value = self.maxValue;
}
self.textField.text = [NSString stringWithFormat:@"%.f", value];
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView{
CGFloat num = scrollView.contentOffset.x;
NSInteger value = (num / kPadding) * kMinScale + self.minValue;
value = value - value % kMinScale;
[self.scrollView setContentOffset:CGPointMake((value-_minValue)/kMinScale*kPadding, 0) animated:YES];
self.textField.text = [NSString stringWithFormat:@"%ld", value];
}
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate{
if(!decelerate){
//OK,真正停止了,do something
CGFloat num = scrollView.contentOffset.x;
NSInteger value = (num / kPadding) * kMinScale + self.minValue;
value = value - value % kMinScale;
[self.scrollView setContentOffset:CGPointMake((value-_minValue)/kMinScale*kPadding, 0) animated:YES];
self.textField.text = [NSString stringWithFormat:@"%ld", value];
}
}
通过实现UITextFieldDelegate代理方法实现数值修改,让游标尺滚动到对应的数值:
#pragma mark - UITextFieldDelegate
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
[self endEditing:YES];
return YES;
}
- (void)textFieldDidEndEditing:(UITextField *)textField {
if (textField.text.doubleValue > self.maxValue) {
textField.text = [NSString stringWithFormat:@"%.f",self.maxValue];
}
[self.scrollView setContentOffset:CGPointMake((textField.text.doubleValue-_minValue)/kMinScale*kPadding, 0) animated:YES];
self.textField.text = textField.text;
}
// 根据输入的数字变化
- (void)textDidChanged:(NSNotification *)info {
UITextField *textField = info.object;
NSString *text = textField.text;
if (textField.isEditing) {
self.scrollView.contentOffset = CGPointMake((text.doubleValue-_minValue)/kMinScale*kPadding, 0);
self.textField.text = text;
}
}
细节处理:游标尺自动取整
一个简洁的游标尺,就实现了。这里将Demo:ZBRulerView献上,朋友请多指教。