在日常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];
}
进度条
效果图:
Untitled11111.gif其实进度条就是在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,小小白,有空就写一些小东西。肯定会有很多不足的地方,希望各位大神多多指教。。。。
网友评论