自定制UISlider实现点击,拖动,松手等操作

2017-05-12  本文已影响399人  fly大梦想家

滑块不灵敏, 点击小范围错位,调整滑条高度 ,圆角 ,slider和navgation右滑返回冲突等问题

效果图


点击,滑动,滑动松手.gif

.h中

###这个block是用来在滑动条变的时候所在界面ui随之变化,本文拖动滑动条字体随着变化###
typedef void(^isSliderBallMoved)(BOOL isMoved , NSInteger currentValue);

@interface GOVFontSlider : UISlider<UIGestureRecognizerDelegate>
@property (copy, nonatomic) isSliderBallMoved isSliderBallMoved;
@end

.m中
1.修改滑条宽高
bounds: 整个slider在界面的位置大小
rect :滑条的在整个slider的位置大小

@implementation GOVFontSlider
// 返回滑条的frame
- (CGRect)trackRectForBounds:(CGRect)bounds{
    return CGRectMake(LAYOUT_SIZESCALE_PORTRAIT(70, 70).width, bounds.size.height /2.0 , LAYOUT_SCREENSIZE_P.width - 2 * LAYOUT_SIZESCALE_PORTRAIT(70, 70).width, 1);
}
// 返回滑块的frame,滑块滑动不灵敏的话调整它的高度
- (CGRect)thumbRectForBounds:(CGRect)bounds trackRect:(CGRect)rect value:(float)value{
    
    return CGRectMake(rect.origin.x - LAYOUT_SIZESCALE_PORTRAIT(1, 1).width / 2.0 + value * (rect.size.width / 4.0), 0,LAYOUT_SIZESCALE_PORTRAIT(1, 1).width, bounds.size.height);
}

注: 滑块的宽度设置过大导致点击某点,滑块会在该点有小位移变化


滑块的宽度设置过大导致点击时小位移变化的bug.gif
#最开始是用
[sliderView addTarget:self action:@selector(sliderValueChanged:) forControlEvents:UIControlEventValueChanged]  
 [sliderView addTarget:self action:@selector(valueChanged:) forControlEvents:UIControlEventTouchUpInside];
UITapGestureRecognizer

添加的滑动事件和点击还有滑动松手事件,后面发现滑动松手时和点击事件经常会冲突,点击手势识别的是刚触碰slider时的那个点A,滑动松手时又是另一个点B(我想取得是B点,但偶尔会识别为A点),所以就直接用touch方法
点击

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
   [self fontTouchBeganMovedEnded:touches withEvent:event withIsFastAction:NO];
}

滑动 松手

- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
 
    [self fontTouchBeganMovedEnded:touches withEvent:event withIsFastAction:YES];
}

移动

- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    [self fontTouchBeganMovedEnded:touches withEvent:event withIsFastAction:NO];
}
第三个参数,是否直接回到整点位置(就近取整)
- (void)fontTouchBeganMovedEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event withIsFastAction:(BOOL)isFastBack{
    NSSet *allTouches = event.allTouches;
    UITouch *touch = [allTouches anyObject];;
    CGPoint touchPoint = [touch locationInView:self];
    CGFloat value = (self.maximumValue - self.minimumValue) * ((touchPoint.x- LAYOUT_SIZESCALE_PORTRAIT(70, 70).width) / (self.frame.size.width - 2 * LAYOUT_SIZESCALE_PORTRAIT(70, 70).width));
    NSInteger finalValue = round(value);   #// 对value取整,回到整数位置
   #// 我设置的滑条范围是0~4,点击范围外的判断
    finalValue = finalValue < 0 ? 0: finalValue;
    finalValue = finalValue > 4 ? 4 :finalValue;
    [UIView animateWithDuration:0.5 animations:^{
        [self setValue:isFastBack ? finalValue :value animated:YES];
    }];     // 因为加了动画,在ios8,5s下会看到最右边滑动时小范围变白,因为换了滑动条颜色的原因,将滑动条颜色更改为系统颜色,bug消失,或者去掉动画; 或者在互动条下面加一条同等的线条来解决
    if (self.isSliderBallMoved != nil) {
        self.isSliderBallMoved(YES,finalValue);  #// 用来改变界面其他的UI
    }
   
}
@end

使用

   GOVFontSlider *sliderView = [[GOVFontSlider alloc]initWithFrame: CGRectMake(0, LAYOUT_SIZESCALE_PORTRAIT(200, 200).height, LAYOUT_SCREENSIZE_P.width , LAYOUT_SIZESCALE_PORTRAIT(100, 100).height)];
    [sliderView setThumbImage:[GOVCommon loadAppImage:@"settingFontSliderBall"] forState:UIControlStateNormal];
    [sliderView setThumbImage:[GOVCommon loadAppImage:@"settingFontSliderBall"] forState:UIControlStateHighlighted];
    sliderView.maximumValue = 4;
    sliderView.minimumValue = 0;
    [sliderView setValue:fontSize animated:NO];
    sliderView.minimumTrackTintColor = [UIColor lightGrayColor];

圆角滑动条

  sliderView.layer.cornerRadius = imageView.frame.size.width / 2;
   //将多余的部分切掉
  sliderView.layer.masksToBounds = YES;
[cell.contentView addSubview:sliderView ];
sliderView.isSliderBallMoved = ^(BOOL isMoved, NSInteger currentValue) {
    if (isMoved == YES) {
        exampleLabel.font = FONT_SIZE_REGULAR_SCALE(fontArray[currentValue], YES);
    }
};

右滑返回手势冲突, 也可能会造成滑块不灵敏

self.navigationController.interactivePopGestureRecognizer.enabled = NO;

上一篇下一篇

猜你喜欢

热点阅读