最近又在开发一个电子书阅读器,设计师设计的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的循环引用,文章中出现的一些封装等,可以参考以下文章:
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]; }