[iOS UI进阶 - 1] 自定义控件

A.关于Quiartz2D的一些细节
1.UIKit的工具已经封装了上下文引用,所以不用手动获取和渲染
1 - (void)drawRect:(CGRect)rect {
2     [[UIColor redColor] set];
3     UIRectFill(CGRectMake(0, 0, 100, 100));
4 }
 
技术分享
 
2.多个path
 1 - (void)drawRect:(CGRect)rect {
 2     CGContextRef ctx = UIGraphicsGetCurrentContext();
 3    
 4     // 1.1创建第一个path
 5     CGMutablePathRef linePath = CGPathCreateMutable();
 6    
 7     // 1.2.描绘path
 8     CGPathMoveToPoint(linePath, NULL, 0, 0);
 9     CGPathAddLineToPoint(linePath, NULL, 100, 100);
10    
11     // 1.3.添加linePath到上下文
12     CGContextAddPath(ctx, linePath);
13    
14     // 2添加一个圆的path
15     CGMutablePathRef circlePath = CGPathCreateMutable();
16     CGPathAddEllipseInRect(circlePath, NULL, CGRectMake(0, 0, 50, 50));
17     CGContextAddPath(ctx, circlePath);
18    
19     // 渲染上下文
20     CGContextStrokePath(ctx);
21    
22     // 释放path
23     CGPathRelease(linePath);
24     CGPathRelease(circlePath);
25 }
 
技术分享
 
B.自定义一个类似UIImageView的控件
 1 //
 2 //  MyImageView.h
 3 //  MyImageView
 4 //
 5 //  Created by hellovoidworld on 14/12/31.
 6 //  Copyright (c) 2014年 hellovoidworld. All rights reserved.
 7 //
 8 
 9 #import <UIKit/UIKit.h>
10 
11 @interface MyImageView : UIView
12 
13 @property(nonatomic, weak) UIImage *image;
14 
15 @end

 

 1 //
 2 //  MyImageView.m
 3 //  MyImageView
 4 //
 5 //  Created by hellovoidworld on 14/12/31.
 6 //  Copyright (c) 2014年 hellovoidworld. All rights reserved.
 7 //
 8 
 9 #import "MyImageView.h"
10 
11 @implementation MyImageView
12 
13 - (void)setImage:(UIImage *)image {
14     _image = image;
15    
16     // 重新设置了图片的时候,重绘
17     [self setNeedsDisplay];
18 }
19 
20 - (void)drawRect:(CGRect)rect {
21     [self.image drawInRect:rect];
22 }
23 
24 @end
25  
26 controller:
27 - (void)viewDidLoad {
28     [super viewDidLoad];
29     // Do any additional setup after loading the view, typically from a nib.
30    
31     MyImageView *imageView = [[MyImageView alloc] init];
32     imageView.frame = CGRectMake(0, 0, 200, 320);
33     [self.view addSubview:imageView];
34     imageView.image = [UIImage imageNamed:@"M4"];
35 }
 
技术分享
 
C.带有placeholder的TextView
技术分享
 
 1 //
 2 //  MyTextView.h
 3 //  MyTextField
 4 //
 5 //  Created by hellovoidworld on 14/12/31.
 6 //  Copyright (c) 2014年 hellovoidworld. All rights reserved.
 7 //
 8 
 9 #import <UIKit/UIKit.h>
10 
11 @interface MyTextView : UITextView
12 
13 @property(nonatomic, copy) NSString *placeHolderText;
14 
15 @end
 
 1 //
 2 //  MyTextView.m
 3 //  MyTextField
 4 //
 5 //  Created by hellovoidworld on 14/12/31.
 6 //  Copyright (c) 2014年 hellovoidworld. All rights reserved.
 7 //
 8 
 9 #import "MyTextView.h"
10 
11 @interface MyTextView() <UITextViewDelegate>
12 
13 /** 原来的文本颜色 */
14 @property(nonatomic, weak) UIColor *originalTextColor;
15 
16 @end
17 
18 @implementation MyTextView
19 
20 // 重写初始化方法,设置代理
21 - (instancetype)init {
22     if (self = [super init]) {
23         self.returnKeyType = UIReturnKeyDone;
24         self.delegate = self;
25     }
26    
27     return self;
28 }
29 
30 // 重新设置了placeHolderText的时候要重绘一下控件
31 - (void)setPlaceHolderText:(NSString *)placeHolderText {
32     _placeHolderText = placeHolderText;
33     [self setNeedsDisplay];
34 }
35 
36 // 开始编辑,消除placeHolder
37 - (BOOL)textViewShouldBeginEditing:(UITextView *)textView {
38     if ([self.text isEqualToString:self.placeHolderText]) {
39         self.text = nil;
40         self.textColor = self.originalTextColor;
41     }
42    
43     return YES;
44 }
45 
46 // 结束编辑,如果文本为空,设置placeHolder
47 - (void)textViewDidEndEditing:(UITextView *)textView {
48     [self setNeedsDisplay];
49 }
50 
51 - (void)drawRect:(CGRect)rect {
52     if (self.text.length == 0) {
53         self.text = self.placeHolderText;
54         self.textColor = [UIColor grayColor];
55     }
56 }
57 
58 
59 @end
 
 
D. 图片水印
1.步骤
(1)在storyboard拖入一个UIImageView, 在控制器代码创建图片上下文
创建一个基于位图的上下文 --> 系统创建一个位图对象
相当于创建了一个新的UIImage对象
(2)画背景
(3)画水印
(4)从上下文取得制作完毕的UIImage对象
(5)结束图片上下文
 1 //
 2 //  UIImage+HW.m
 3 //  Watermark
 4 //
 5 //  Created by hellovoidworld on 14/12/31.
 6 //  Copyright (c) 2014年 hellovoidworld. All rights reserved.
 7 //
 8 
 9 #import "UIImage+HW.h"
10 
11 @implementation UIImage(HW)
12 
13 + (instancetype) image:(NSString *) image withWatermark:(NSString *) watermark {
14     // 取得背景图片
15     UIImage *bgImage = [UIImage imageNamed:image];
16    
17     // 1.开启一个位图上下文
18     UIGraphicsBeginImageContextWithOptions(bgImage.size, NO, 0.0);
19    
20     // 2.添加背景图片到位图上下文
21     [bgImage drawInRect:CGRectMake(0, 0, bgImage.size.width, bgImage.size.height)];
22    
23     // 3.添加水印图片
24     UIImage *watermarkImage = [UIImage imageNamed:watermark];
25     CGFloat scale = 0.5;
26     CGFloat margin = 50;
27     CGFloat watermarkWidth = watermarkImage.size.width * scale;
28     CGFloat watermarkHeight = watermarkImage.size.width *scale;
29     CGFloat watermarkX = bgImage.size.width - watermarkWidth - margin;
30     CGFloat watermarkY = bgImage.size.height - watermarkHeight - margin;
31     [watermarkImage drawInRect:CGRectMake(watermarkX, watermarkY, watermarkWidth, watermarkHeight)];
32    
33    
34     // 4.取得合成后的图片
35     UIImage *resultImage = UIGraphicsGetImageFromCurrentImageContext();
36    
37     // 5.关闭图文上下文
38     UIGraphicsEndImageContext();
39    
40     return resultImage;
41 }
42 
43 @end
 
(6)显示到UIImageView
 1 - (void)viewDidLoad {
 2     [super viewDidLoad];
 3     // Do any additional setup after loading the view, typically from a nib.
 4    
 5     UIImage *watermarkedImage = [UIImage image:@"M4" withWatermark:@"a9ec8a13632762d0092abc3ca2ec08fa513dc619"];
 6    
 7     UIImageView *imageView = [[UIImageView alloc] initWithImage:watermarkedImage];
 8     imageView.frame = CGRectMake(0, 0, 200, 320);
 9     [self.view addSubview:imageView];
10 }
 
(7)保存图片
a.将image压缩
b.写入文件
1     // 压缩图片为PNG格式的二进制数据
2     NSData *data = UIImagePNGRepresentation(watermarkedImage);
3    
4     // 写入文件
5     NSString *path =[[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:@"watermarkedImage.png"];
6     NSLog(@"%@", path);
7     [data writeToFile:path atomically:YES];
 
技术分享
 
 
E.头像图片裁剪
裁剪的图片形成新的图片,这里是讲矩形图片裁剪成圆形并带白色边框
1.步骤
(1)背景大圆
(2)小圆裁剪
(3)加入图片
 
 1 /**  创建带有指定宽度和颜色边框的圆形头像图片 */
 2 + (instancetype) imageOfCircleHeadIcon:(NSString *) image withBorderWidth:(CGFloat) borderWidth borderColor:(UIColor *) borderColor {
 3     //  取得图片
 4     UIImage *headIconImage = [UIImage imageNamed:image];
 5    
 6     // 开启图片上下文
 7     CGFloat backImageWidth = headIconImage.size.width + 2 * borderWidth;
 8     CGFloat backImageHeight = headIconImage.size.height + 2 * borderWidth;
 9     CGSize backImageSize = CGSizeMake(backImageWidth, backImageHeight);
10     UIGraphicsBeginImageContextWithOptions(backImageSize, NO, 0.0);
11    
12     // 描绘背景大圆
13     [borderColor set]; // 设置圆环颜色
14     CGContextRef ctx = UIGraphicsGetCurrentContext();
15     CGFloat backCircleRadius = backImageWidth * 0.5; // 大圆半径
16     CGFloat backCircleX = backCircleRadius; // 大圆圆心X
17     CGFloat backCircleY = backCircleRadius; // 大圆圆心Y
18     CGContextAddArc(ctx, backCircleX, backCircleY, backCircleRadius, 0, M_PI * 2, 0);
19     CGContextFillPath(ctx);
20    
21     // 描绘用来显示图片的小圆
22     CGFloat frontCircleRadius = backCircleRadius - borderWidth; // 图片小圆半径
23     CGFloat frontCircleX = backCircleX;
24     CGFloat frontCircleY = backCircleY;
25     CGContextAddArc(ctx, frontCircleX, frontCircleY, frontCircleRadius, 0, M_PI * 2, 0);
26    
27     // 裁剪(后面描绘的将会受到裁剪)
28     CGContextClip(ctx);
29    
30     // 添加图片到上下文
31     [headIconImage drawInRect:CGRectMake(borderWidth, borderWidth, headIconImage.size.width, headIconImage.size.height)];
32    
33     // 取得合成后的图片
34     UIImage *headIconResultImage = UIGraphicsGetImageFromCurrentImageContext();
35    
36     // 关闭图片上下文
37     UIGraphicsEndImageContext();
38    
39     return headIconResultImage;
40 }
 
技术分享
 
 
F.屏幕截图
1.步骤
(1)使用位图上下文
(2)将控制器view的layer渲染到上下文
[self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
(3)取出图片,保存图片
(4)结束位图上下文
技术分享
 
 
 1 /** 点击“屏幕截图” */
 2 - (IBAction)screenShotcut {
 3     // 延迟截图, 防止截到的时按钮被按下的状态
 4     dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
 5        
 6         UIView *view = self.view;
 7        
 8         // 1.开启位图上下文
 9         UIGraphicsBeginImageContextWithOptions(view.frame.size, NO, 0.0);
10        
11         // 2.渲染控制器view的layer到上下文
12         [view.layer renderInContext:UIGraphicsGetCurrentContext()];
13        
14         // 3.从上下文取得图片
15         UIImage *screenImage = UIGraphicsGetImageFromCurrentImageContext();
16        
17         // 4.结束上下文
18         UIGraphicsEndImageContext();
19        
20         // 存储图片
21         NSData *data = UIImagePNGRepresentation(screenImage);
22         NSString *path = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:@"screenShot.png"];
23         NSLog(@"%@", path);
24         [data writeToFile:path atomically:YES];    });
25 
26 }
 
技术分享
 
 
 
G.drawRect原理
为什么要实现drawRect才能绘图到view上
因为在drawRect方法中才能取得图文相关的上下文
 
 
H.背景平铺
1.条纹背景
 1 - (void)viewDidLoad {
 2     [super viewDidLoad];
 3     // Do any additional setup after loading the view, typically from a nib.
 4    
 5     // 开启图片上下文
 6     CGFloat rowW = self.view.frame.size.width;
 7     CGFloat rowH = 30;
 8     UIGraphicsBeginImageContextWithOptions(CGSizeMake(rowW, rowH), NO, 0.0);
 9    
10     CGContextRef ctx = UIGraphicsGetCurrentContext();
11     // 画色块背景
12     [[UIColor redColor] set];
13     CGContextAddRect(ctx, CGRectMake(0, 0, rowW, rowH));
14     CGContextFillPath(ctx);
15    
16     // 画线
17     [[UIColor greenColor] set];
18     CGFloat lineWidth = 2;
19     CGContextSetLineWidth(ctx, lineWidth);
20     CGFloat lineX = 0;
21     CGFloat lineY = rowH - lineWidth;
22     CGContextMoveToPoint(ctx, lineX, lineY);
23     CGContextAddLineToPoint(ctx, rowW - lineX, lineY);
24     CGContextStrokePath(ctx);
25    
26     UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
27    
28     // 使用平铺方式铺满屏幕
29     [self.view setBackgroundColor:[UIColor colorWithPatternImage:image]];
30    
31     UIGraphicsEndImageContext();
32 }

 

 
技术分享
 
 
 
 

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。