在日常iOS開發(fā)中,系統(tǒng)提供的控件常常無法滿足業(yè)務功能,這個時候需要我們實現(xiàn)一些自定義控件。自定義控件能讓我們完全控制視圖的展示內(nèi)容以及交互操作。本篇將介紹一些自定義控件的相關概念,探討自定義控件開發(fā)的基本過程及技巧。
在開始之前我們先介紹一個類UIVew,它在iOS APP中占有絕對重要的地位,因為幾乎所有的控件都是繼承自UIView類。
UIView表示屏幕上的一個矩形區(qū)域,負責渲染區(qū)域內(nèi)的內(nèi)容,并且響應區(qū)域內(nèi)發(fā)生的觸摸事件。
在UIView的內(nèi)部有一個CALayer,提供內(nèi)容的繪制和顯示,包括UIView的尺寸樣式。UIView的frame實際上返回的CALayer的frame。
UIView繼承自UIResponder類,它能接收并處理從系統(tǒng)傳來的事件,CALayer繼承自NSObject,它無法響應事件。所以UIView與CALayer的最大區(qū)別在于:UIView能響應事件,而CALayer不能。
效果圖:

//實現(xiàn)思路就是在一個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 以及代碼中都可以實現(xiàn)
- (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];
// 標記為需要重新繪制, 將會在下一個繪制循環(huán)中, 調(diào)用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 以及代碼中都可以實現(xiàn)
- (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,小小白,有空就寫一些小東西??隙〞泻芏嗖蛔愕牡胤?,希望各位大神多多指教。。。。