UISlider自定义、分段式滑动

本文详细介绍了如何改造系统自带的单调滑动进度控制器,以匹配设计师美观需求,包括圆角背景、图标调整和分段式语速控制的实现过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近又在开发一个电子书阅读器,设计师设计的UI很美观漂亮,但是无奈系统自带的滑动进度控制器太丑,不好看,不得不进行二次封装处理达到设计师的要求!

下面就是系统自带的UI展示,可以看出很单调,难看!也许是苹果的设计极简主义。

奈何对于产品而言,这样的展示太不符合要求,以下将对本次的开发做以记录有兴趣的同学可以参考研究。

先看看实现的效果1、2、3!

iconSize()是一个内联函数,其实现目的是在不同设备上输出不同的高度大小,比如一个小图标在320X640的上大小为34,而在1242X2208的设备上显示要求是略大一些的值。内部的具体值你根据你的习惯调整即可

CG_INLINE CGFloat iconSize(CGFloat size)
{
    CGFloat ratio = [UIScreen mainScreen].scale;
    if (ratio == 1)
    {
        return size;
    }
    else
    {
        return  size+ratio*1.5;
    }
}

weakify、strongify等宏定义函数就不一一细说了,为了的是避免block的循环引用,文章中出现的一些封装等,可以参考以下文章:

1、OC block的回环引用

2、OC weakSelf与strongSelf 讲义

3、UIButton的点击事件通过block回调(addTargetActionBlock),封装在NSExtentionSloter.h文件中,因为部分内容在其他文章中已经提及,这里就不再单独拉出来了。连接地址:点击查看

1、圆角背景及进度指示器调整,注意整个进度条是有个黑色的背景的,注意细看哈。

参考代码:

        CGRect rt = CGRectMake(20, 0, self.view.frame.size.width-40, iconSize(54));
        UIView *tpView = [[UIView alloc] initWithFrame:rt];
        [self.view addSubview:tpView];
        [tpView release];
        
        weakify(self)
        rt = CGRectMake(0, (iconSize(54)-iconSize(24))/2, iconSize(24), iconSize(24));
        UIImage *image = [UIImage getImageInMainBundle:@"lArrow"];
        UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
        [btn setFrame:rt];
        [btn setBackgroundImage:image forState:UIControlStateNormal];
        [btn addTargetActionBlock:^(UIButton *aButton) {
            
        }];
        [tpView addSubview:btn];
        
        rt.origin.x += rt.size.width+20;
        rt.size.width = tpView.bounds.size.width - 2*rt.origin.x;
        rt.origin.y = 10;
        rt.size.height = iconSize(54)-20;
        
        UIView *briew = [[UIView alloc] initWithFrame:rt];
        [briew.layer setMasksToBounds:YES];
        [briew.layer setCornerRadius:rt.size.height/2];
        [briew setTag:9000];
        [briew setBackgroundColor:RGB(217, 205, 184)];
        
        CGFloat icsize = rt.size.height-14;
        CGFloat x = 0;
        rt = CGRectMake(x, 0, icsize, icsize);
        UIImageView *icView = [[UIImageView alloc] initWithFrame:rt];
        [briew addSubview:icView];
        [icView release];
        
        rt.origin.x = briew.bounds.size.width-x-icsize;
        icView = [[UIImageView alloc] initWithFrame:rt];
        [briew addSubview:icView];
        [icView release];
        
        UISlider *slider = [[UISlider alloc] initWithFrame:briew.bounds];
            /// 添加Slider
        [slider setTag:90001];
        [briew addSubview:slider];
        
        slider.minimumValue = 1.0;
        slider.maximumValue = self.chatperLink.count;
        [slider setContinuous:NO];
        slider.minimumTrackTintColor = RGBA(0,0,0,0);
        // maximumTrackTintColor: 大于滑块当前值滑块条的颜色,默认为白色
        slider.maximumTrackTintColor = RGBA(0,0,0,0);
        // thumbTintColor : 当前滑块的颜色,默认为白色
        slider.thumbTintColor = RGBA(70, 70, 70,0.65);
        [slider addTarget:self action:@selector(sliderReaderValueDidChanged:) forControlEvents:UIControlEventValueChanged];
        [slider release];
        
        [tpView addSubview:briew];
        [briew release];
        
        rt = CGRectMake(tpView.bounds.size.width-iconSize(24), (iconSize(54)-iconSize(24))/2, iconSize(24), iconSize(24));
        image = [UIImage getImageInMainBundle:@"rightArrow"];
        btn = [UIButton buttonWithType:UIButtonTypeCustom];
        [btn setFrame:rt];
        [btn setBackgroundImage:image forState:UIControlStateNormal];
        [btn addTargetActionBlock:^(UIButton *aButton) {
            
        }];
        [tpView addSubview:btn];

2、在1的基础上,增加了左右两个icon

参考代码:

        CGFloat iht = iconSize(52);
        CGRect rt = CGRectMake(0, deviceHeight, deviceWidth, iht);
        view = [[UIView alloc] initWithFrame:rt];
        [view setTag:300];
        [view setUserInteractionEnabled:YES];
        [self.view addSubview:view];
        [view release];
        
        rt = CGRectMake(20, 0, 60, iconSize(52));
        UILabel *label = [[UILabel alloc] initWithFrame:rt];
        [label setNumberOfLines:0];
        [label setBackgroundColor:[UIColor clearColor]];
        [label setTextColor:RGB(70, 70, 70)];
        [label setTag:10000];
        [label setFont:UINormalFont(12)];
        [label setTextAlignment:NSTextAlignmentLeft];
        [label setText:@"亮度"];
        [label setLineBreakMode:NSLineBreakByTruncatingTail];
        [view addSubview:label];
        [label release];
        
        rt.origin.x += rt.size.width;
        rt.origin.y += 10;
        rt.size.height -= 20;
        rt.size.width = (view.bounds.size.width - rt.origin.x - 20);
        UIView *briew = [[UIView alloc] initWithFrame:rt];
        [briew.layer setMasksToBounds:YES];
        [briew.layer setCornerRadius:rt.size.height/2];
        [briew setTag:8000];
        [briew setBackgroundColor:RGB(217, 205, 184)];
        
//左图标
        CGFloat icsize = rt.size.height-14;
        CGFloat x = rt.size.height/6;
        rt = CGRectMake(x, 7, icsize, icsize);
        UIImageView *icView = [[UIImageView alloc] initWithFrame:rt];
        [icView setImage:[UIImage getImageInMainBundle:@"brightLess"]];
        [briew addSubview:icView];
        [icView release];
        
//右图标
        rt.origin.x = briew.bounds.size.width-x-icsize;
        icView = [[UIImageView alloc] initWithFrame:rt];
        [icView setImage:[UIImage getImageInMainBundle:@"brightMore"]];
        [briew addSubview:icView];
        [icView release];
        
        CGFloat value = [[NSUserDefaults standardUserDefaults] floatForKey:@"setBrightnessKey"];
        UISlider *slider = [[UISlider alloc] initWithFrame:briew.bounds];
            /// 添加Slider
        [slider setTag:80001];
        [briew addSubview:slider];
        slider.minimumValue = 0.0;
        slider.maximumValue = 1.0;
        slider.value = value;
        
        // continuous : 如果设置YES,在拖动滑块的任何时候,滑块的值都会改变。默认设置为YES
        [slider setContinuous:YES];
        slider.minimumTrackTintColor = RGBA(0,0,0,0);
        slider.maximumTrackTintColor = RGBA(0,0,0,0);
        slider.thumbTintColor = RGBA(70, 70, 70,0.65);
        [slider addTarget:self action:@selector(sliderValueDidChanged:) forControlEvents:UIControlEventValueChanged];
        [slider release];
        
        [view addSubview:briew];
        [briew release];

3、因为产品中有语速调整功能,即1.X,1.5X等语速设置,所以,不想增加过多的代码,仍然沿用扩展此组件,达到分段式控制。整个组件分为5段,当滑动到某小段的中间位置时,指示器是不可能停留在中间位置的,要求必须处于某个小点上。如滑动到70%处,松开手指时,指示器需要回归到1.5X处。滑动到77%处,松开手指时,指示器需要回归到1.75X处。

参考代码:

        CGRect rt = CGRectMake(0, deviceHeight, deviceWidth, iconSize(54));
        view = [[UIView alloc] initWithFrame:rt];
        [view setTag:3001];
        [view setUserInteractionEnabled:YES];
        [self.view addSubview:view];
        [view release];

        fm = CGRectMake(20, 0, rt.size.width-40, iconSize(54));
        UIView *twoView = [[UIView alloc] initWithFrame:fm];
        [twoView setBackgroundColor:[UIColor clearColor]];
        [view addSubview:twoView];
        [twoView release];
        
        rt = CGRectMake(0, 0, 60, fm.size.height);
        UILabel *label = [[UILabel alloc] initWithFrame:rt];
        [label setNumberOfLines:0];
        [label setBackgroundColor:[UIColor clearColor]];
        [label setTextColor:RGB(70, 70, 70)];
        [label setFont:UINormalFont(12)];
        [label setTextAlignment:NSTextAlignmentLeft];
        [label setText:@"语速"];
        [label setLineBreakMode:NSLineBreakByTruncatingTail];
        [twoView addSubview:label];
        [label release];
        
        rt.origin.x += rt.size.width;
        rt.size.width = twoView.bounds.size.width - rt.origin.x;
        rt.origin.y = 10;
        rt.size.height = iconSize(54)-20-NSFontHeight(11);
        
        UIView *briew = [[UIView alloc] initWithFrame:rt];
        [briew setBackgroundColor:[UIColor clearColor]];
        [twoView addSubview:briew];
        [briew release];
        
        NSString *sptext = @"0.75x";
        CGFloat sptextWidth = [sptext stringSizeWithFont:UINormalFont(10)].width/2;
        UIView *lview = [[UIView alloc] initWithFrame:CGRectMake(sptextWidth, (briew.bounds.size.height-2)/2, briew.bounds.size.width-2*sptextWidth, 2)];
        [lview setBackgroundColor:RGB(70, 70, 70)];
        [briew addSubview:lview];
        [lview release];
        
        NSInteger idex = 0;
        CGFloat gap = (briew.bounds.size.width-2*sptextWidth)/5;
        UIView *cview = [[UIView alloc] initWithFrame:CGRectMake(sptextWidth+(idex++)*gap-4, (rt.size.height-8)/2, 8, 8)];
        [cview.layer setMasksToBounds:YES];
        [cview.layer setCornerRadius:4];
        [cview setBackgroundColor:RGB(70, 70, 70)];
        [briew addSubview:cview];
        [cview release];
        
        cview = [[UIView alloc] initWithFrame:CGRectMake(sptextWidth+(idex++)*gap-4, (rt.size.height-8)/2, 8, 8)];
        [cview.layer setMasksToBounds:YES];
        [cview.layer setCornerRadius:4];
        [cview setBackgroundColor:RGB(70, 70, 70)];
        [briew addSubview:cview];
        [cview release];
        
        cview = [[UIView alloc] initWithFrame:CGRectMake(sptextWidth+(idex++)*gap-4, (rt.size.height-8)/2, 8, 8)];
        [cview.layer setMasksToBounds:YES];
        [cview.layer setCornerRadius:4];
        [cview setBackgroundColor:RGB(70, 70, 70)];
        [briew addSubview:cview];
        [cview release];
        
        cview = [[UIView alloc] initWithFrame:CGRectMake(sptextWidth+(idex++)*gap-4, (rt.size.height-8)/2, 8, 8)];
        [cview.layer setMasksToBounds:YES];
        [cview.layer setCornerRadius:4];
        [cview setBackgroundColor:RGB(70, 70, 70)];
        [briew addSubview:cview];
        [cview release];
        
        cview = [[UIView alloc] initWithFrame:CGRectMake(sptextWidth+(idex++)*gap-4, (rt.size.height-8)/2, 8, 8)];
        [cview.layer setMasksToBounds:YES];
        [cview.layer setCornerRadius:4];
        [cview setBackgroundColor:RGB(70, 70, 70)];
        [briew addSubview:cview];
        [cview release];
        
        cview = [[UIView alloc] initWithFrame:CGRectMake(sptextWidth+(idex++)*gap-4, (rt.size.height-8)/2, 8, 8)];
        [cview.layer setMasksToBounds:YES];
        [cview.layer setCornerRadius:4];
        [cview setBackgroundColor:RGB(70, 70, 70)];
        [briew addSubview:cview];
        [cview release];
        
        CGRect sfm = CGRectMake(sptextWidth-12, 0, briew.bounds.size.width-2*(sptextWidth-12), briew.bounds.size.height);
        CGFloat value = [[NSUserDefaults standardUserDefaults] floatForKey:@"speedPlayKey"]/10.0;
        UISlider *slider = [[UISlider alloc] initWithFrame:sfm];
            /// 添加Slider
        //[slider setBackgroundColor:RGBA(0,125,0,0.5)];
        [slider setTag:90002];
        [briew addSubview:slider];
        
        slider.minimumValue = 0.0;
        slider.maximumValue = 1.0;
        slider.value = value;
        [slider setContinuous:NO];
        slider.minimumTrackTintColor = RGBA(0,0,0,0);
        // maximumTrackTintColor: 大于滑块当前值滑块条的颜色,默认为白色
        slider.maximumTrackTintColor = RGBA(0,0,0,0);
        // thumbTintColor : 当前滑块的颜色,默认为白色
        
        UIImage *image = [UIImage imageWithStrokeColor:[UIColor clearColor] fillColor:RGBA(70, 70, 70,0.65) size:CGSizeMake(12, 12) borderWidth:0 corner:6];
        //image = [UIImage combineImage:image InSize:CGSizeMake(24, 24)];
        //slider.thumbTintColor = RGBA(70, 70, 70,0.65);
        [slider setThumbImage:image forState:UIControlStateNormal];
        
        [slider addTarget:self action:@selector(sliderSpeedValueDidChanged:) forControlEvents:UIControlEventValueChanged];
        [slider release];
        
        idex = 0;
        UIView *spView = [[UIView alloc] initWithFrame:CGRectMake(briew.frame.origin.x, briew.frame.origin.y+briew.frame.size.height, briew.frame.size.width, NSFontHeight(11))];
        [spView setBackgroundColor:[UIColor clearColor]];
        [twoView addSubview:spView];
        [spView release];
        
        fm = CGRectMake(0, 0, 2*sptextWidth, spView.bounds.size.height);
        label = [[UILabel alloc] initWithFrame:fm];
        [label setNumberOfLines:0];
        [label setBackgroundColor:[UIColor clearColor]];
        [label setTextColor:RGB(70, 70, 70)];
        [label setFont:UINormalFont(10)];
        [label setTextAlignment:NSTextAlignmentCenter];
        [label setText:@"0.75x"];
        [label setLineBreakMode:NSLineBreakByTruncatingTail];
        [spView addSubview:label];
        [label release];
        
        idex++;
        fm.origin.x = idex*gap;
        label = [[UILabel alloc] initWithFrame:fm];
        [label setNumberOfLines:0];
        [label setBackgroundColor:[UIColor clearColor]];
        [label setTextColor:RGB(70, 70, 70)];
        [label setFont:UINormalFont(11)];
        [label setTextAlignment:NSTextAlignmentCenter];
        [label setText:@"1.0x"];
        [label setLineBreakMode:NSLineBreakByTruncatingTail];
        [spView addSubview:label];
        [label release];
        
        idex++;
        fm.origin.x = idex*gap;
        label = [[UILabel alloc] initWithFrame:fm];
        [label setNumberOfLines:0];
        [label setBackgroundColor:[UIColor clearColor]];
        [label setTextColor:RGB(70, 70, 70)];
        [label setFont:UINormalFont(11)];
        [label setTextAlignment:NSTextAlignmentCenter];
        [label setText:@"1.25x"];
        [label setLineBreakMode:NSLineBreakByTruncatingTail];
        [spView addSubview:label];
        [label release];
        
        idex++;
        fm.origin.x = idex*gap;
        label = [[UILabel alloc] initWithFrame:fm];
        [label setNumberOfLines:0];
        [label setBackgroundColor:[UIColor clearColor]];
        [label setTextColor:RGB(70, 70, 70)];
        [label setFont:UINormalFont(11)];
        [label setTextAlignment:NSTextAlignmentCenter];
        [label setText:@"1.5x"];
        [label setLineBreakMode:NSLineBreakByTruncatingTail];
        [spView addSubview:label];
        [label release];
        
        idex++;
        fm.origin.x = idex*gap;
        label = [[UILabel alloc] initWithFrame:fm];
        [label setNumberOfLines:0];
        [label setBackgroundColor:[UIColor clearColor]];
        [label setTextColor:RGB(70, 70, 70)];
        [label setFont:UINormalFont(11)];
        [label setTextAlignment:NSTextAlignmentCenter];
        [label setText:@"1.75x"];
        [label setLineBreakMode:NSLineBreakByTruncatingTail];
        [spView addSubview:label];
        [label release];
        
        idex++;
        fm.origin.x = idex*gap;
        label = [[UILabel alloc] initWithFrame:fm];
        [label setNumberOfLines:0];
        [label setBackgroundColor:[UIColor clearColor]];
        [label setTextColor:RGB(70, 70, 70)];
        [label setFont:UINormalFont(11)];
        [label setTextAlignment:NSTextAlignmentCenter];
        [label setText:@"2.0x"];
        [label setLineBreakMode:NSLineBreakByTruncatingTail];
        [spView addSubview:label];
        [label release];

滑块的事件处理:这里才是核心,你自己阅读理解!这里就不强行给你灌技能了。

- (void)sliderSpeedValueDidChanged:(UISlider *)sender
{
    CGFloat value = sender.value*10;
    NSInteger step = roundf(value/2.0);
    step *= 2;
    [sender setValue:step/10.0 animated:YES];
}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zhaocarbon

你的鼓励是我创作的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值