繪圖和動畫
關于貝塞爾曲線和CALayer
以及UIView
本身的動畫惜浅,是需要了解的税稼,實際工作中會用到身害。下面幾篇文章比較好赞枕,用到的基本都在了。
iOS動畫篇_UIBezierPath(貝塞爾曲線)
iOS動畫篇_CALayer這些牛逼的子類你造嗎
iOS動畫篇_UIView動畫
設置圓角
imageView.layer.masksToBounds = YES;
imageView.layer.cornerRadius = 10;
在大多數(shù)情況下坪创,這么做是可以的炕婶。只是這里會觸發(fā)離屏渲染,降低性能莱预,在表格使用中柠掂,會掉幀。這個點是App
的性能優(yōu)化方案之一
解決方法是通過UIGraphicsBeginImageContextWithOptions
與UIBezierPath
配合依沮,畫出這個圓角涯贞。下面這幾篇文章寫得比較詳細,值得參考:
設置圓角&避免離屏渲染的幾種方法
畫圖
自定義
UIView
的子類重寫
- (void)drawRect:(CGRect)rect
方法利用
UIGraphicsGetCurrentContext
和UIBezierPath
兩個類的相關方法畫圖在xib上拖一個空白的
UIView
危喉,設置好約束宋渔,將類名改成自定的UIView
的子類常用的有劃線,畫矩形辜限,畫圓皇拣,畫文字,畫圖片(這個還是用
UIImageView
進行處理比較方便)
這里有篇比較好的文章,這里的例子也是從里面摘的
iOS Quart2D繪圖之UIGraphicsGetCurrentContext基礎氧急。
- 這篇文章中有個圓形進度條的例子颗胡。可以認為是畫圓弧和畫文字的一個組合吩坝。下面的
Slider
還是放在另外一個控件中毒姨,可以直接用系統(tǒng)的。這里process
就是Slider
的value
屬性钉寝,范圍0~1
#import "ProcessView.h"
@interface ProcessView ()
@property (nonatomic, assign) CGFloat progress;
@end
@implementation ProcessView
- (void)updateProcess:(CGFloat)process {
if (process < 0 || (process > 1)) {
return;
}
self.progress = process;
[self setNeedsDisplay];
}
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
// Drawing code
// 畫圓弧
CGFloat startA = - M_PI_2;
CGFloat endA = - M_PI_2 + self.progress * M_PI * 2;
NSLog(@"%f - %f - %f",self.progress,(3.14159265359*self.progress)/180,endA);
UIBezierPath * path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(self.bounds.size.width*0.5, self.bounds.size.height*0.5) radius:self.bounds.size.width*0.5-10 startAngle:startA endAngle:endA clockwise:YES];
UIColor *color = [UIColor colorWithRed:self.progress green:(1-self.progress) blue:0 alpha:1];
[color setStroke];
path.lineWidth = 5;
[path stroke];
// 畫文字
//1.獲取當前上下文
CGContextRef contextRef = UIGraphicsGetCurrentContext();
//2.創(chuàng)建文字
NSString * str = [NSString stringWithFormat:@"%04.2f%%", (self.progress * 100)];
//設置字體樣式
NSMutableDictionary * dict = [NSMutableDictionary dictionary];
//NSFontAttributeName:字體大小
dict[NSFontAttributeName] = [UIFont systemFontOfSize:20];
//字體前景色
dict[NSForegroundColorAttributeName] = color;
//字體背景色
dict[NSBackgroundColorAttributeName] = [UIColor clearColor];
//字體陰影
NSShadow * shadow = [[NSShadow alloc]init];
//陰影偏移量
shadow.shadowOffset = CGSizeMake(2, 2);
//陰影顏色
shadow.shadowColor = [UIColor greenColor];
//高斯模糊
shadow.shadowBlurRadius = 5;
dict[NSShadowAttributeName] = shadow;
//字體間距
dict[NSKernAttributeName] = @10;
//繪制到上下文
//從某一點開始繪制 默認 0 0點
//[str drawAtPoint:CGPointMake(100, 100) withAttributes:dict];
//繪制區(qū)域設置
CGSize size = [str sizeWithAttributes:dict];
CGFloat width = size.width;
CGFloat height = size.height;
CGFloat x = rect.size.width / 2 - width / 2;
CGFloat y = rect.size.height / 2 - height / 2;
[str drawInRect:CGRectMake(x, y, width, height) withAttributes:dict];
//添加到上下文
CGContextStrokePath(contextRef);
}
@end
文字水印
// 文字水印
+ (UIImage *)waterWithImage:(UIImage *)image text:(NSString *)text point:(CGPoint)point attributed:(NSDictionary * )attributed {
//1.開啟上下文
UIGraphicsBeginImageContextWithOptions(image.size, NO, 0);
//2.繪制圖片
[image drawInRect:CGRectMake(0, 0, image.size.width, image.size.height)];
//添加水印文字
[text drawAtPoint:point withAttributes:attributed];
//3.從上下文中獲取新圖片
UIImage * newImage = UIGraphicsGetImageFromCurrentImageContext();
//4.關閉圖形上下文
UIGraphicsEndImageContext();
//返回圖片
return newImage;
}
圖片水印
// 圖片水印
+ (UIImage *)waterWithImage:(UIImage *)image mask:(UIImage *)mask rect:(CGRect)rect {
//1.開啟上下文
UIGraphicsBeginImageContextWithOptions(image.size, NO, 0);
//2.繪制原圖
[image drawInRect:CGRectMake(0, 0, image.size.width, image.size.height)];
//3.繪制水印圖片到當前上下文
[mask drawInRect:rect];
//4.從上下文中獲取新圖片
UIImage * newImage = UIGraphicsGetImageFromCurrentImageContext();
//5.關閉圖形上下文
UIGraphicsEndImageContext();
//返回圖片
return newImage;
}
裁剪圓形圖片
+ (UIImage *)clipCircleWithImage:(UIImage *)image {
//1弧呐、開啟上下文
UIGraphicsBeginImageContextWithOptions(image.size, NO, 0);
//2、設置裁剪區(qū)域
UIBezierPath * path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(0, 0, image.size.width, image.size.height)];
[path addClip];
//3瘩蚪、繪制圖片
[image drawAtPoint:CGPointZero];
//4泉懦、獲取新圖片
UIImage * newImage = UIGraphicsGetImageFromCurrentImageContext();
//5、關閉上下文
UIGraphicsEndImageContext();
//6疹瘦、返回新圖片
return newImage;
}
設置邊框顏色和大小
- 對于矩形的圖片崩哩,直接在UIImageView上設置就可以了
imageView.layer.borderColor = [UIColor orangeColor].CGColor;
imageView.layer.borderWidth = 2;
- 對于圓形變換的圖片,
UIImageView
矩形邊框是變不了的言沐。還是需要變換UIImage
// 帶邊框的圓形裁剪
+ (UIImage *)clipCircleWithImage:(UIImage *)image borderWidth:(CGFloat)borderWidth borderColor:(UIColor *)borderColor {
//1邓嘹、開啟上下文
UIGraphicsBeginImageContext(image.size);
//2、設置邊框
CGRect rect = CGRectMake(0, 0, image.size.width, image.size.height);
UIBezierPath * path = [UIBezierPath bezierPathWithOvalInRect:rect];
[borderColor setFill];
[path fill];
//3险胰、設置裁剪區(qū)域
UIBezierPath * clipPath = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(rect.origin.x + borderWidth , rect.origin.x + borderWidth , rect.size.width - borderWidth * 2, rect.size.height - borderWidth *2)];
[clipPath addClip];
//3汹押、繪制圖片
[image drawAtPoint:CGPointZero];
//4、獲取新圖片
UIImage * newImage = UIGraphicsGetImageFromCurrentImageContext();
//5起便、關閉上下文
UIGraphicsEndImageContext();
//6棚贾、返回新圖片
return newImage;
}
保存圖片
比如照相機的圖片存到手機;或者將圖片傳到后臺保存榆综;都需要將
UIImage
轉換為NSData
UIImageJPEGRepresentation
和UIImagePNGRepresentation
都能達到目的一個是有損壓縮(
JPEG
妙痹,經驗壓縮比為0.9
),一個是無損壓縮(PNG
)數(shù)據(jù)量無損壓縮要大很多鼻疮;具體采用哪種怯伊,看情況吧,主要看后臺存儲狀況判沟。推薦無損壓縮(
SDWebImage
用無損壓縮)
Deep Analysis UIImageJPEGRepresentation&UIImagePNGRepresentation
參考文章
以上的例子都來自下面這篇文章
iOS Quart2D繪圖之UIGraphicsBeginImageContextWithOptions基礎耿芹。
圖片拉伸的例子來自這里
UIImage常用的分類
這里是Demo地址
點擊button
之后的下一頁就是Image
的變換