iOS 自定义控件 自定义进度条

释放双眼,带上耳机,听听看~!

在日常iOS开发中,系统提供的控件常常无法满足业务功能,这个时候需要我们实现一些自定义控件。自定义控件能让我们完全控制视图的展示内容以及交互操作。本篇将介绍一些自定义控件的相关概念,探讨自定义控件开发的基本过程及技巧。

在开始之前我们先介绍一个类UIVew,它在iOS APP中占有绝对重要的地位,因为几乎所有的控件都是继承自UIView类。
UIView表示屏幕上的一个矩形区域,负责渲染区域内的内容,并且响应区域内发生的触摸事件。
在UIView的内部有一个CALayer,提供内容的绘制和显示,包括UIView的尺寸样式。UIView的frame实际上返回的CALayer的frame。
UIView继承自UIResponder类,它能接收并处理从系统传来的事件,CALayer继承自NSObject,它无法响应事件。所以UIView与CALayer的最大区别在于:UIView能响应事件,而CALayer不能。
效果图:

//实现思路就是在一个view界面定制

#import <UIKit/UIKit.h>

@interface circleImageView : UIView

- (void)configeWithImage:(UIImage *)image;

@end
#import "circleImageView.h"

@interface circleImageView ()
{
    UIImageView *_imageView;
}
@end

@implementation circleImageView

-(instancetype)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        _imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, frame.size.width, frame.size.height)];
        _imageView.contentMode = UIViewContentModeScaleAspectFill;
        _imageView.layer.masksToBounds = YES;
        _imageView.layer.cornerRadius = frame.size.width/2;
        [self addSubview:_imageView];
    }
    return self;
}

- (void)configeWithImage:(UIImage *)image {
    _imageView.image = image;
}

在viewController界面设置view的位置大小

#import "ViewController.h"
#import "circleImageView.h"
@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    UIImage *image = [UIImage imageNamed:@"haha.png"];
    circleImageView * ImageView = [[circleImageView alloc] initWithFrame:CGRectMake(150, 180, 150, 150)];
    [ImageView configeWithImage:image];
    [self.view addSubview:ImageView];

}
                 

进度条

效果图:

其实进度条就是在view界面画图,想要了解一些关于画图的东西可以查看我的前几篇文章
第一种进度条:
在view界面,在.h文件,我们定义4个属性,进度,未过滑道时的背景颜色,走过滑道的背景颜色,线条的宽度

#import <UIKit/UIKit.h>

@interface JJHCircleProgressView : UIView

//进度
@property (nonatomic)CGFloat progress;

//未过滑道时的背景颜色,默认是灰色
@property (nonatomic,strong)UIColor *trackBackgroundColor;

//走过滑道的背景颜色,默认是黄色
@property (nonatomic,strong)UIColor *trackColor;

//线条的宽度  默认是10
@property (nonatomic,assign)float lineWidth;


@end

在.m界面,如果要是布局控件,必须在layoutSubviews这里面写他的位置

#import "JJHCircleProgressView.h"

@interface JJHCircleProgressView ()

@property (strong, nonatomic) UILabel *progressLabel;

@end

@implementation JJHCircleProgressView

//可以在xib storyBoard  以及代码中都可以实现
- (instancetype)init
{
    self = [super init];
    if (self) {
        [self commonInit];
    }
    return self;
}
- (instancetype)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        [self commonInit];
    }
    return self;
}
- (instancetype)initWithCoder:(NSCoder *)coder
{
    self = [super initWithCoder:coder];
    if (self) {
        [self commonInit];
    }
    return self;
}



//设置各种属性,以及把label添加上
- (void)commonInit {
    _lineWidth = 10.0;
    _trackBackgroundColor = [UIColor grayColor];
    _trackColor = [UIColor yellowColor];
}

//要是布局控件,必须在这里面写他的位置
- (void)layoutSubviews{
    [super layoutSubviews];
    UILabel *progressLabel = [[UILabel alloc] init];
    progressLabel.textColor = [UIColor blackColor];
    progressLabel.backgroundColor = [UIColor clearColor];
    progressLabel.textAlignment = NSTextAlignmentCenter;
    progressLabel.text = @"0.0%";
    _progressLabel = progressLabel;
    [self addSubview:_progressLabel];
    CGFloat slideLength = self.bounds.size.width;
    self.progressLabel.frame = CGRectMake(_lineWidth, _lineWidth, slideLength-2*_lineWidth, slideLength-2*_lineWidth);
}

//画图
- (void)drawRect:(CGRect)rect{
    [super drawRect:rect];
    
    
    //获取图形上下文
    CGContextRef contextRef = UIGraphicsGetCurrentContext();
    CGFloat slideLength = self.bounds.size.width;
    CGFloat centerX = slideLength/2;
    CGFloat centerY = slideLength/2;
    //  x,y为圆点坐标,radius半径,startAngle为开始的弧度,endAngle为 结束的弧度,clockwise 0为顺时针,1为逆时针。
    //    CGContextAddArc(<#CGContextRef  _Nullable c#>, <#CGFloat x#>, <#CGFloat y#>, <#CGFloat radius#>, <#CGFloat startAngle#>, <#CGFloat endAngle#>, <#int clockwise#>)
    //添加背景轨道
    CGContextAddArc(contextRef, centerX, centerY, (slideLength - _lineWidth)/2, 0, 2 * M_PI, 0);
    

    //设置背景的宽度
    CGContextSetLineWidth(contextRef, _lineWidth);
    //设置背景颜色
    [_trackBackgroundColor setStroke];
    //绘制轨道
    CGContextStrokePath(contextRef);
    
   
    
    
    //绘制进度颜色===================
    
    //添加背景轨道
    //角度
    float endAngle = _progress * (2 * M_PI);
    CGContextAddArc(contextRef, centerX, centerY, (slideLength - _lineWidth)/2, 0, endAngle, 0);
    
    
    //设置背景的宽度
    CGContextSetLineWidth(contextRef, _lineWidth);
    //设置背景颜色
    [_trackColor setStroke];
    //绘制轨道
    CGContextStrokePath(contextRef);
}

- (void)setProgress:(CGFloat)progress {
    
    if (progress > 1 || progress < 0) return;
    _progress = progress;
    self.progressLabel.text = [NSString stringWithFormat:@"%.1f%%", progress*100];
    // 标记为需要重新绘制, 将会在下一个绘制循环中, 调用drawRect:方法重新绘制
    [self setNeedsDisplay];
    
}
@end

第二种进度条
在.h界面,我们定义4个属性,进度,边框线的颜色,设置边框线的宽度,里面填充的颜色 默认是红色

#import <UIKit/UIKit.h>

@interface JJHBreadProgressView : UIView
//进度
@property (nonatomic)CGFloat progress;
//边框线的颜色  默认是灰色
@property (nonatomic)UIColor *lineColor;
//设置边框线的宽度  默认是10.0
@property (nonatomic)CGFloat lineWidth;
//里面填充的颜色  默认是红色
@property (nonatomic)UIColor *BreadClolor;
@end

在.m文件

#import "JJHBreadProgressView.h"
@implementation JJHBreadProgressView
//可以在xib storyBoard  以及代码中都可以实现
- (instancetype)init
{
    self = [super init];
    if (self) {
        [self commonInit];
    }
    return self;
}
- (instancetype)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        [self commonInit];
    }
    return self;
}
- (instancetype)initWithCoder:(NSCoder *)coder
{
    self = [super initWithCoder:coder];
    if (self) {
        [self commonInit];
    }
    return self;
}


- (void)commonInit{
    _lineColor = [UIColor grayColor];
    _BreadClolor = [UIColor redColor];
    _lineWidth = 2.0;
}




- (void)drawRect:(CGRect)rect {
    [super drawRect:rect];
    
    
    //获取图形上下文
    CGContextRef contextRef = UIGraphicsGetCurrentContext();
    CGFloat slideLength = self.bounds.size.width;
    CGFloat centerX = slideLength/2;
    CGFloat centerY = slideLength/2;
    //  x,y为圆点坐标,radius半径,startAngle为开始的弧度,endAngle为 结束的弧度,clockwise 0为顺时针,1为逆时针。
    //    CGContextAddArc(<#CGContextRef  _Nullable c#>, <#CGFloat x#>, <#CGFloat y#>, <#CGFloat radius#>, <#CGFloat startAngle#>, <#CGFloat endAngle#>, <#int clockwise#>)
    //添加背景轨道
    CGContextAddArc(contextRef, centerX, centerY, (slideLength - _lineWidth)/2, 0, 2 * M_PI, 0);
    
    
    //设置背景的宽度
    CGContextSetLineWidth(contextRef, _lineWidth);
    //设置背景颜色
    [_lineColor setStroke];
    //绘制轨道
    CGContextStrokePath(contextRef);
    
    
    //===============划填充物=============
    
    CGContextMoveToPoint(contextRef, centerX, centerY);
    //结束时的转的弧度
    float endBread = _progress * 2 * M_PI;
    CGContextAddArc(contextRef, centerX, centerY, (slideLength-2*_lineWidth)/2, 0, endBread, 0);
    CGContextSetFillColorWithColor(contextRef, _BreadClolor.CGColor);
   
    CGContextFillPath(contextRef);
    
    

}
 
@end

 

人已赞赏
iOS文章

ios 开发UI篇—UITextView

2019-10-5 11:11:24

iOS文章

iOS开发·runtime+KVC实现多层字典模型转换(多层数据:模型嵌套模型,模型嵌套数组,数组嵌套模型)

2019-10-5 11:33:34

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索