A.关于Quiartz2D的一些细节
1.UIKit的工具已经封装了上下文引用,所以不用手动获取和渲染
 - (void)drawRect:(CGRect)rect {
[[UIColor redColor] set];
UIRectFill(CGRectMake(, , , ));
}
 
 
2.多个path
 - (void)drawRect:(CGRect)rect {
CGContextRef ctx = UIGraphicsGetCurrentContext(); // 1.1创建第一个path
CGMutablePathRef linePath = CGPathCreateMutable(); // 1.2.描绘path
CGPathMoveToPoint(linePath, NULL, , );
CGPathAddLineToPoint(linePath, NULL, , ); // 1.3.添加linePath到上下文
CGContextAddPath(ctx, linePath); // 2添加一个圆的path
CGMutablePathRef circlePath = CGPathCreateMutable();
CGPathAddEllipseInRect(circlePath, NULL, CGRectMake(, , , ));
CGContextAddPath(ctx, circlePath); // 渲染上下文
CGContextStrokePath(ctx); // 释放path
CGPathRelease(linePath);
CGPathRelease(circlePath);
}
 
 
B.自定义一个类似UIImageView的控件
 //
// MyImageView.h
// MyImageView
//
// Created by hellovoidworld on 14/12/31.
// Copyright (c) 2014年 hellovoidworld. All rights reserved.
// #import <UIKit/UIKit.h> @interface MyImageView : UIView @property(nonatomic, weak) UIImage *image; @end
 //
// MyImageView.m
// MyImageView
//
// Created by hellovoidworld on 14/12/31.
// Copyright (c) 2014年 hellovoidworld. All rights reserved.
// #import "MyImageView.h" @implementation MyImageView - (void)setImage:(UIImage *)image {
_image = image; // 重新设置了图片的时候,重绘
[self setNeedsDisplay];
} - (void)drawRect:(CGRect)rect {
[self.image drawInRect:rect];
} @end controller:
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib. MyImageView *imageView = [[MyImageView alloc] init];
imageView.frame = CGRectMake(, , , );
[self.view addSubview:imageView];
imageView.image = [UIImage imageNamed:@"M4"];
}
 
 
C.带有placeholder的TextView
 
 //
// MyTextView.h
// MyTextField
//
// Created by hellovoidworld on 14/12/31.
// Copyright (c) 2014年 hellovoidworld. All rights reserved.
// #import <UIKit/UIKit.h> @interface MyTextView : UITextView @property(nonatomic, copy) NSString *placeHolderText; @end
 
 //
// MyTextView.m
// MyTextField
//
// Created by hellovoidworld on 14/12/31.
// Copyright (c) 2014年 hellovoidworld. All rights reserved.
// #import "MyTextView.h" @interface MyTextView() <UITextViewDelegate> /** 原来的文本颜色 */
@property(nonatomic, weak) UIColor *originalTextColor; @end @implementation MyTextView // 重写初始化方法,设置代理
- (instancetype)init {
if (self = [super init]) {
self.returnKeyType = UIReturnKeyDone;
self.delegate = self;
} return self;
} // 重新设置了placeHolderText的时候要重绘一下控件
- (void)setPlaceHolderText:(NSString *)placeHolderText {
_placeHolderText = placeHolderText;
[self setNeedsDisplay];
} // 开始编辑,消除placeHolder
- (BOOL)textViewShouldBeginEditing:(UITextView *)textView {
if ([self.text isEqualToString:self.placeHolderText]) {
self.text = nil;
self.textColor = self.originalTextColor;
} return YES;
} // 结束编辑,如果文本为空,设置placeHolder
- (void)textViewDidEndEditing:(UITextView *)textView {
[self setNeedsDisplay];
} - (void)drawRect:(CGRect)rect {
if (self.text.length == ) {
self.text = self.placeHolderText;
self.textColor = [UIColor grayColor];
}
} @end
 
 
D. 图片水印
1.步骤
(1)在storyboard拖入一个UIImageView, 在控制器代码创建图片上下文
创建一个基于位图的上下文 --> 系统创建一个位图对象
相当于创建了一个新的UIImage对象
(2)画背景
(3)画水印
(4)从上下文取得制作完毕的UIImage对象
(5)结束图片上下文
 //
// UIImage+HW.m
// Watermark
//
// Created by hellovoidworld on 14/12/31.
// Copyright (c) 2014年 hellovoidworld. All rights reserved.
// #import "UIImage+HW.h" @implementation UIImage(HW) + (instancetype) image:(NSString *) image withWatermark:(NSString *) watermark {
// 取得背景图片
UIImage *bgImage = [UIImage imageNamed:image]; // 1.开启一个位图上下文
UIGraphicsBeginImageContextWithOptions(bgImage.size, NO, 0.0); // 2.添加背景图片到位图上下文
[bgImage drawInRect:CGRectMake(, , bgImage.size.width, bgImage.size.height)]; // 3.添加水印图片
UIImage *watermarkImage = [UIImage imageNamed:watermark];
CGFloat scale = 0.5;
CGFloat margin = ;
CGFloat watermarkWidth = watermarkImage.size.width * scale;
CGFloat watermarkHeight = watermarkImage.size.width *scale;
CGFloat watermarkX = bgImage.size.width - watermarkWidth - margin;
CGFloat watermarkY = bgImage.size.height - watermarkHeight - margin;
[watermarkImage drawInRect:CGRectMake(watermarkX, watermarkY, watermarkWidth, watermarkHeight)]; // 4.取得合成后的图片
UIImage *resultImage = UIGraphicsGetImageFromCurrentImageContext(); // 5.关闭图文上下文
UIGraphicsEndImageContext(); return resultImage;
} @end
 
(6)显示到UIImageView
 - (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib. UIImage *watermarkedImage = [UIImage image:@"M4" withWatermark:@"a9ec8a13632762d0092abc3ca2ec08fa513dc619"]; UIImageView *imageView = [[UIImageView alloc] initWithImage:watermarkedImage];
imageView.frame = CGRectMake(, , , );
[self.view addSubview:imageView];
}
 
(7)保存图片
a.将image压缩
b.写入文件
     // 压缩图片为PNG格式的二进制数据
NSData *data = UIImagePNGRepresentation(watermarkedImage); // 写入文件
NSString *path =[[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:@"watermarkedImage.png"];
NSLog(@"%@", path);
[data writeToFile:path atomically:YES];
 
 
 
E.头像图片裁剪
裁剪的图片形成新的图片,这里是讲矩形图片裁剪成圆形并带白色边框
1.步骤
(1)背景大圆
(2)小圆裁剪
(3)加入图片
 
 /**  创建带有指定宽度和颜色边框的圆形头像图片 */
+ (instancetype) imageOfCircleHeadIcon:(NSString *) image withBorderWidth:(CGFloat) borderWidth borderColor:(UIColor *) borderColor {
// 取得图片
UIImage *headIconImage = [UIImage imageNamed:image]; // 开启图片上下文
CGFloat backImageWidth = headIconImage.size.width + * borderWidth;
CGFloat backImageHeight = headIconImage.size.height + * borderWidth;
CGSize backImageSize = CGSizeMake(backImageWidth, backImageHeight);
UIGraphicsBeginImageContextWithOptions(backImageSize, NO, 0.0); // 描绘背景大圆
[borderColor set]; // 设置圆环颜色
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGFloat backCircleRadius = backImageWidth * 0.5; // 大圆半径
CGFloat backCircleX = backCircleRadius; // 大圆圆心X
CGFloat backCircleY = backCircleRadius; // 大圆圆心Y
CGContextAddArc(ctx, backCircleX, backCircleY, backCircleRadius, , M_PI * , );
CGContextFillPath(ctx); // 描绘用来显示图片的小圆
CGFloat frontCircleRadius = backCircleRadius - borderWidth; // 图片小圆半径
CGFloat frontCircleX = backCircleX;
CGFloat frontCircleY = backCircleY;
CGContextAddArc(ctx, frontCircleX, frontCircleY, frontCircleRadius, , M_PI * , ); // 裁剪(后面描绘的将会受到裁剪)
CGContextClip(ctx); // 添加图片到上下文
[headIconImage drawInRect:CGRectMake(borderWidth, borderWidth, headIconImage.size.width, headIconImage.size.height)]; // 取得合成后的图片
UIImage *headIconResultImage = UIGraphicsGetImageFromCurrentImageContext(); // 关闭图片上下文
UIGraphicsEndImageContext(); return headIconResultImage;
}
 
 
 
F.屏幕截图
1.步骤
(1)使用位图上下文
(2)将控制器view的layer渲染到上下文
[self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
(3)取出图片,保存图片
(4)结束位图上下文
 
 
 /** 点击“屏幕截图” */
- (IBAction)screenShotcut {
// 延迟截图, 防止截到的时按钮被按下的状态
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ UIView *view = self.view; // 1.开启位图上下文
UIGraphicsBeginImageContextWithOptions(view.frame.size, NO, 0.0); // 2.渲染控制器view的layer到上下文
[view.layer renderInContext:UIGraphicsGetCurrentContext()]; // 3.从上下文取得图片
UIImage *screenImage = UIGraphicsGetImageFromCurrentImageContext(); // 4.结束上下文
UIGraphicsEndImageContext(); // 存储图片
NSData *data = UIImagePNGRepresentation(screenImage);
NSString *path = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:@"screenShot.png"];
NSLog(@"%@", path);
[data writeToFile:path atomically:YES]; }); }
 
 
 
 
G.drawRect原理
为什么要实现drawRect才能绘图到view上
因为在drawRect方法中才能取得图文相关的上下文
 
 
H.背景平铺
1.条纹背景
 - (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib. // 开启图片上下文
CGFloat rowW = self.view.frame.size.width;
CGFloat rowH = ;
UIGraphicsBeginImageContextWithOptions(CGSizeMake(rowW, rowH), NO, 0.0); CGContextRef ctx = UIGraphicsGetCurrentContext();
// 画色块背景
[[UIColor redColor] set];
CGContextAddRect(ctx, CGRectMake(, , rowW, rowH));
CGContextFillPath(ctx); // 画线
[[UIColor greenColor] set];
CGFloat lineWidth = ;
CGContextSetLineWidth(ctx, lineWidth);
CGFloat lineX = ;
CGFloat lineY = rowH - lineWidth;
CGContextMoveToPoint(ctx, lineX, lineY);
CGContextAddLineToPoint(ctx, rowW - lineX, lineY);
CGContextStrokePath(ctx); UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); // 使用平铺方式铺满屏幕
[self.view setBackgroundColor:[UIColor colorWithPatternImage:image]]; UIGraphicsEndImageContext();
}
 
 
 
 
 

[iOS UI进阶 - 1] 自定义控件的更多相关文章

  1. [iOS UI进阶 - 0] Quiartz2D

    A.简介 1. 需要掌握的 drawRect:方法的使用 常见图形的绘制:线条.多边形.圆 绘图状态的设置:文字颜色.线宽等 图形上下文状态的保存与恢复 图形上下文栈 1.基本图形绘制* 线段(线宽. ...

  2. iOS UI进阶-1.0 Quartz2D

    概述 Quartz 2D是一个二维绘图引擎,同时支持iOS和Mac系统.Quartz 2D能完成的工作: 绘制图形 : 线条\三角形\矩形\圆\弧等 绘制文字 绘制\生成图片(图像) 读取\生成PDF ...

  3. [iOS UI进阶 - 6.1] 核心动画CoreAnimation

    A.基本知识 1.概念 Core Animation是一组非常强大的动画处理API,使用它能做出非常炫丽的动画效果,而且往往是事半功倍,使用它需要先添加QuartzCore.framework和引入对 ...

  4. [iOS UI进阶 - 6.0] CALayer

    A.基本知识 1.需要掌握的 CALayer的基本属性 CALayer和UIView的关系 position和anchorPoint的作用   2.概念 在iOS中,你能看得见摸得着的东西基本上都是U ...

  5. [iOS UI进阶 - 3.1] 触摸事件的传递

    A.事件的产生和传递 发生触摸事件后,系统会将该事件加入到一个由UIApplication管理的事件队列中UIApplication会从事件队列中取出最前面的事件,并将事件分发下去以便处理,通常,先发 ...

  6. [iOS UI进阶 - 5.0] 手势解锁Demo

    A.需求 1.九宫格手势解锁 2.使用了绘图和手势事件   code source: https://github.com/hellovoidworld/GestureUnlockDemo     B ...

  7. [iOS UI进阶 - 3.0] 触摸事件的基本处理

    A.需要掌握和练习的 1.介绍事件类型2.通过按钮的事件处理引出view的事件处理3.响应者对象 --> UIResponder --> UIView4.view的拖拽* 实现触摸方法,打 ...

  8. [iOS UI进阶 - 2.3] 彩票Demo v1.3

    A.需求 真机调试 "关于”模块 存储开关状态 打电话.发短信 应用评分 打开其他应用 cell 在iOS6 和 iOS7的适配 block的循环引用 屏幕适配 code source:   ...

  9. [iOS UI进阶 - 2.0] 彩票Demo v1.0

    A.需求 1.模仿“网易彩票”做出有5个导航页面和相应功能的Demo 2.v1.0 版本搭建基本框架   code source:https://github.com/hellovoidworld/H ...

随机推荐

  1. nodejs抓网易NBA数据

    var http = require("http");var cheerio = require("cheerio"); var url = "htt ...

  2. bzoj1312

    忘写题解了,经典的最大密度子图 可以类似分数规划的做,二分密度,然后转化为最大权闭合子图做,判断是否大于0 注意方案的输出 const eps=1e-6; lim=1e-12; inf=; type ...

  3. UVA 4080 Warfare And Logistics 战争与物流 (最短路树,变形)

    题意: 给一个无向图,n个点,m条边,可不连通,可重边,可多余边.两个问题,第一问:求任意点对之间最短距离之和.第二问:必须删除一条边,再求第一问,使得结果变得更大. 思路: 其实都是在求最短路的过程 ...

  4. fmri降噪,利用spatial+temporal信息

    1.基于小波+高斯模型 <SPATIOTEMPORAL DENOISING AND CLUSTERING OF FMRI DATA>

  5. Linux Shell编程(2): for while

    ; i < ; i++)) do echo "current number is $i" done SERVICES="80 22 25 110 8000 23 2 ...

  6. poj 2553 The Bottom of a Graph

    求解的是有向图中满足“自己可达的顶点都能到达自己”的顶点个数如果强连通分量中某个顶点,还能到达分量外的顶点,则该连通分量不满足要求// 因此,本题要求的是将强连通分量缩点后所构造的新图中出度为0的顶点 ...

  7. 【转】Android 异步消息处理机制 让你深入理解 Looper、Handler、Message三者关系

    转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/38377229 ,本文出自[张鸿洋的博客] 很多人面试肯定都被问到过,请问Andr ...

  8. [Papers]NSE, $\p_3u$, Lebesgue space [Cao, DCDSA, 2010]

    $$\bex \p_3\bbu\in L^p(0,T;L^q(\bbR^3)),\quad \frac{2}{p}+\frac{3}{q}=2,\quad \frac{27}{16}\leq q\le ...

  9. C#中的值类型(value type)与引用类型(reference type)的区别

    ylbtech- .NET-Basic:C#中的值类型与引用类型的区别 C#中的值类型(value type)与引用类型(reference type)的区别 1.A,相关概念返回顶部     C#中 ...

  10. HDU 4911 Inversion

    http://acm.hdu.edu.cn/showproblem.php?pid=4911   归并排序求逆对数. Inversion Time Limit: 2000/1000 MS (Java/ ...