欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

iOS实现步骤进度条功能实例代码

程序员文章站 2022-11-14 10:28:17
前言 在开发中,我们经常在很多场景下需要用到进度条,比如文件的下载,或者文件的上传等。 本文主要给大家介绍的是一个步骤进度条效果,步骤进度条效果参考 ios uik...

前言

在开发中,我们经常在很多场景下需要用到进度条,比如文件的下载,或者文件的上传等。 本文主要给大家介绍的是一个步骤进度条效果,步骤进度条效果参考

iOS实现步骤进度条功能实例代码

ios uikit 框架中并没有提供类似的控件,我们可以使用 uiprogressview、uiview、uilabel 组合实现步骤进度条效果。

  • uiprogressview——实现水平的进度条效果;
  • uiview——把uiview裁剪成圆形,实现索引节点效果;
  • uilabel——每个节点下面的提示文字。

源码

将步骤进度条封装成一个 hqlstepview 类,它是 uiview 的子类。

hqlstepview.h 文件

#import <uikit/uikit.h>

@interface hqlstepview : uiview

// 指定初始化方法
- (instancetype)initwithframe:(cgrect)frame titlesarray:(nsarray *)titlesarray stepindex:(nsuinteger)stepindex;

// 设置当前步骤
- (void)setstepindex:(nsuinteger)stepindex animation:(bool)animation;

@end

hqlstepview.m 文件

#import "hqlstepview.h"

// 步骤条主题色
#define tint_color [uicolor colorwithred:35/255.f green:135/255.f blue:255/255.f alpha:1]

@interface hqlstepview ()

@property (nonatomic, copy) nsarray *titlesarray;
@property (nonatomic, assign) nsuinteger stepindex;

@property (nonatomic, strong) uiprogressview *progressview;
@property (nonatomic, strong) nsmutablearray *circleviewarray;
@property (nonatomic, strong) nsmutablearray *titlelabelarray;
@property (nonatomic, strong) uilabel *indicatorlabel;

@end

@implementation hqlstepview

#pragma mark - init

- (instancetype)initwithframe:(cgrect)frame titlesarray:(nsarray *)titlesarray stepindex:(nsuinteger)stepindex {
 self = [super initwithframe:frame];
 if (self) {
 _titlesarray = [titlesarray copy];
 _stepindex = stepindex;

 // 进度条
 [self addsubview:self.progressview];
 
 for (nsstring *title in _titlesarray) {
  
  // 圆圈
  uiview *circle = [[uiview alloc] initwithframe:cgrectmake(0, 0, 13, 13)];
  circle.backgroundcolor = [uicolor lightgraycolor];
  circle.layer.cornerradius = 13.0f / 2;
  [self addsubview:circle];
  [self.circleviewarray addobject:circle];
  
  // 标题
  uilabel *label = [[uilabel alloc] init];
  label.text = title;
  label.font = [uifont systemfontofsize:14];
  label.textalignment = nstextalignmentcenter;
  [self addsubview:label];
  [self.titlelabelarray addobject:label];
 }
 
 // 当前索引数字
 [self addsubview:self.indicatorlabel];
 }
 return self;
}

// 布局更新页面元素
- (void)layoutsubviews {
 nsinteger perwidth = self.frame.size.width / self.titlesarray.count;
 
 // 进度条
 self.progressview.frame = cgrectmake(0, 0, self.frame.size.width - perwidth, 1);
 self.progressview.center = cgpointmake(self.frame.size.width / 2, self.frame.size.height / 4);
 
 cgfloat startx = self.progressview.frame.origin.x;
 for (int i = 0; i < self.titlesarray.count; i++) {
 // 圆圈
 uiview *cycle = self.circleviewarray[i];
 if (cycle) {
  cycle.center = cgpointmake(i * perwidth + startx, self.progressview.center.y);
 }
 
 // 标题
 uilabel *label = self.titlelabelarray[i];
 if (label) {
  label.frame = cgrectmake(perwidth * i, self.frame.size.height / 2, self.frame.size.width / self.titlesarray.count, self.frame.size.height / 2 );
 }
 }
 self.stepindex = self.stepindex;
}

#pragma mark - custom accessors

- (uiprogressview *)progressview {
 if (!_progressview) {
 _progressview = [[uiprogressview alloc] initwithprogressviewstyle:uiprogressviewstyledefault];
 _progressview.progresstintcolor = tint_color;
 _progressview.progress = self.stepindex / ((self.titlesarray.count - 1) * 1.0);
 }
 return _progressview;
}

- (uilabel *)indicatorlabel {
 if (!_indicatorlabel) {
 _indicatorlabel = [[uilabel alloc] initwithframe:cgrectmake(0, 0, 23, 23)];
 _indicatorlabel.textcolor = tint_color;
 _indicatorlabel.textalignment = nstextalignmentcenter;
 _indicatorlabel.backgroundcolor = [uicolor whitecolor];
 _indicatorlabel.layer.cornerradius = 23.0f / 2;
 _indicatorlabel.layer.bordercolor = [tint_color cgcolor];
 _indicatorlabel.layer.borderwidth = 1;
 _indicatorlabel.layer.maskstobounds = yes;
 }
 return _indicatorlabel;
}

- (nsmutablearray *)circleviewarray {
 if (!_circleviewarray) {
 _circleviewarray = [[nsmutablearray alloc] initwithcapacity:self.titlesarray.count];
 }
 return _circleviewarray;
}

- (nsmutablearray *)titlelabelarray {
 if (!_titlelabelarray) {
 _titlelabelarray = [[nsmutablearray alloc] initwithcapacity:self.titlesarray.count];
 }
 return _titlelabelarray;
}

// 设置当前进度索引,更新圆形图片、文本颜色、当前索引数字
- (void)setstepindex:(nsuinteger)stepindex {
 for (int i = 0; i < self.titlesarray.count; i++) {
 uiview *cycle = self.circleviewarray[i];
 uilabel *label = self.titlelabelarray[i];
 if (stepindex >= i) {
  cycle.backgroundcolor = tint_color;
  label.textcolor = tint_color;
 } else {
  cycle.backgroundcolor = [uicolor lightgraycolor];
  label.textcolor = [uicolor lightgraycolor];
 }
 }
}

#pragma mark - public

- (void)setstepindex:(nsuinteger)stepindex animation:(bool)animation {
 if (stepindex < self.titlesarray.count) {
 // 更新颜色
 self.stepindex = stepindex;
 // 设置进度条
 [self.progressview setprogress:stepindex / ((self.titlesarray.count - 1) * 1.0) animated:animation];
 // 设置当前索引数字
 self.indicatorlabel.text = [nsstring stringwithformat:@"%lu", stepindex + 1];
 self.indicatorlabel.center = ((uiview *)[self.circleviewarray objectatindex:stepindex]).center;
 }
}

@end

接口调用:

- (void)viewdidload {
 [super viewdidload];
 
 // 初始化
 _hqlstepview = [[hqlstepview alloc] initwithframe:cgrectmake(0, 200, self.view.frame.size.width, 60) titlesarray:@[@"第一步", @"第二步", @"第三步"] stepindex:0];
 [self.view addsubview:_hqlstepview];
}

- (void)viewdidappear:(bool)animated {
 [super viewdidappear:animated];
 
 // 设置当前步骤,步骤索引=数组索引
 [_hqlstepview setstepindex:0 animation:yes];
}

效果:

iOS实现步骤进度条功能实例代码

因为 uiprogressview 实现的水平进度条高度值默认为1,设置frame是无效的。可以通过仿射变换的方式增加它的高度。

第三方框架

参考:

总结:

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对的支持。