1. 程式人生 > >iOS設定圓角的四種方法

iOS設定圓角的四種方法

一、設定CALayer的cornerRadius

cornerRadius屬性影響layer顯示的background顏色和前景框border,對layer的contents不起作用。故一個imgView(型別為UIImageView)的image不為空,設定imgView.layer的cornerRadius,是看不出顯示圓角效果的,因為image是imgView.layer的contents部分。

這種情況下將layer的masksToBounds屬性設定為YES,可以正確的繪製出圓角效果。但是cornerRadius>0,masksToBounds=YES,會觸發GPU的離屏渲染,當一個螢幕上有多處觸發離屏渲染,會影響效能。通過勾選Instruments->Core Animation->Color Offscreen-Rendered Yellow,可以看到螢幕上觸發離屏渲染的會被渲染成黃色。離屏渲染的代價昂貴,蘋果也意識到會產生效能問題,所以

iOS9以後的系統裡能不產生離屏渲染的地方也就不用離屏渲染了。比如對UIImageView裡png圖片設定圓角不會觸發離屏渲染。

  1. 對contents為空的檢視設定圓角

     view.backgroundColor =[UIColor redColor];
     view
    .layer.cornerRadius =25;//UILabel設定backgroundColor的行為被更改,不再是設定layer的背景色而是為contents設定背景色
     label
    .layer.backgroundColor = aColor
     label
    .layer.cornerRadius =5
  2. 對contents不為空的檢視設定圓角

     imageView.image =[UIImage imageNamed:@"img"];
     imageView
    .image.layer.cornerRadius =5;
     imageView
    .image.layer.masksToBounds = YES;

二、設定CALayer的mask

通過設定view.layer的mask屬性,可以將另一個layer蓋在view上,也可以設定圓角,但是mask同樣會觸發離屏渲染。

有兩種方式來生成遮罩,一是通過圖片生成,圖片的透明度影響著view繪製的透明度,圖片遮罩透明度為1的部分view被繪製成的透明度為0,相反圖片遮罩透明度為0的部分view被繪製成的透明度為1。二是通過貝塞爾曲線生成,view中曲線描述的形狀部分會被繪製出來。

// 通過圖片生成遮罩,UIImage*maskImage =[UIImage imageNamed:@"someimg"];CALayer*mask =[CALayernew];
mask
.frame =CGRectMake(0,0, maskImage.size.width, maskImage.size.height);
mask
.contents =(__bridge id _Nullable)(maskImage.CGImage);
view
.layer.mask = mask;//通過貝塞爾曲線生成CAShapeLayer*mask =[CAShapeLayernew];
mask
.path =[UIBezierPath bezierPathWithOvalInRect:view.bounds].CGPath;
view
.layer.mask = mask;

三、通過Core Graphics重新繪製帶圓角的檢視

通過CPU重新繪製一份帶圓角的檢視來實現圓角效果,會大大增加CPU的負擔,而且相當於多了一份檢視拷貝會增加記憶體開銷。但是就顯示效能而言,由於沒有觸發離屏渲染,所以能保持較高幀率。下例是繪製一個圓形圖片,繪製其它UIView並無本質區別。重新繪製的過程可以交由後臺執行緒來處理。

@implementation UIImage(CircleImage)-(UIImage*)drawCircleImage {CGFloat side = MIN(self.size.width,self.size.height);UIGraphicsBeginImageContextWithOptions(CGSizeMake(side, side),false,[UIScreen mainScreen].scale);CGContextAddPath(UIGraphicsGetCurrentContext(),[UIBezierPath bezierPathWithOvalInRect:CGRectMake(0,0, side, side)].CGPath);CGContextClip(UIGraphicsGetCurrentContext());CGFloat marginX =-(self.size.width - side)/2.f;CGFloat marginY =-(self.size.height - side)/2.f;[self drawInRect:CGRectMake(marginX, marginY,self.size.width,self.size.height)];CGContextDrawPath(UIGraphicsGetCurrentContext(), kCGPathFillStroke);UIImage*output =UIGraphicsGetImageFromCurrentImageContext();UIGraphicsEndImageContext();return output;}    
@end

//在需要圓角時呼叫如下
dispatch_async
(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0),^{UIImage*img =[[UIImage imageNamed:@"image.png"] drawCircleImage];
    dispatch_async
(dispatch_get_main_queue(),^{
        view
.image = img;});});

四、通過混合圖層

此方法就是在要新增圓角的檢視上再疊加一個部分透明的檢視,只對圓角部分進行遮擋。圖層混合的透明度處理方式與mask正好相反。此方法雖然是最優解,沒有離屏渲染,沒有額外的CPU計算,但是應用範圍有限。

總結

  1. 在可以使用混合圖層遮擋的場景下,優先使用第四種方法。
  2. 即使是非iOS9以上系統,第一種方法在綜合性能上依然強於後兩者,iOS9以上由於沒有了離屏渲染更是首選。
  3. 方法二和方法三由於使用了貝塞爾曲線,都可以應對複雜的圓角。只不過前者犧牲幀率,後者需要大量計算和增加部分記憶體,需要實際情況各自取捨。

相關推薦

iOS設定圓角方法

一、設定CALayer的cornerRadius cornerRadius屬性影響layer顯示的background顏色和前景框border,對layer的contents不起作用。故一個imgView(型別為UIImageView)的image不為空,設定imgVi

筆記-iOS設定圓角方法以及指定位置設圓角

第一種方法:通過設定layer的屬性 程式碼: UIImageView *imageView = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"TestImage"]]; // 只需設定layer層的兩個屬性 // 設定圓角 imageVi

IOS UIView中間透明周圍半透明(方法) 中間鏤空

原文地址:http://blog.csdn.net/zhz459880251/article/details/50035631 方法一 <code class="hljs java has-numbering" style="display: block; pad

iOS 給測試人員測試手機APP的方法:真機執行(略),打ipa包,(testFlighe)郵件,蒲公英(一)打ipa包

APP上線前測試,無外乎 一:用資料線真機除錯(以前需要下載真機除錯證書) 二:打.ipa包給測試人員(上限100人)     2.1 打包APP的.ipa 包給測試人員之前,如果沒有新增裝置的UDID號, 先進入蘋果開發者中心(添加了直接跳到2.6)  2.2點

Android開發-設定監聽器的方法

Android四種監聽方式: 實現監聽的介面實現匿名內部類使用外部類直接在xml中設定監聽 1、使用介面方式實現監聽事件: 可直接在Activity中定義事件處理方法 優點:簡潔 缺點:可能造成程式結構混亂 2、實現匿名內部類實現監聽: 優點:可以在當前類中複用該監聽器,

增加表空間大小的方法

已存在數據 max 方法 手工 pro strong 增加表空間 增加 四種 增加表空間大小的四種方法Meathod1:給表空間增加數據文件ALTER TABLESPACE app_data ADD DATAFILE ‘D:\ORACLE\PRODUCT\10.2.0\OR

Python格式化輸出的方法

python#!/usr/bin/env python#coding:utf-8name = raw_input("name:")sex = raw_input("sex:")age = int(raw_input("age:"))info0 = ‘‘‘-------- inio fo0 -------nam

Button點擊事件的方法

ase extend extends make androi tid ont edi .get 1、匿名內部類 Button btn_1 = (Button) findViewById(R.id.btn_1); //1.匿名內部類 btn_

【mysql】查看版本的方法

span clas latin min days use ble dha pre 1:在終端下:mysql -V。 以下是代碼片段: [[email protected]/* */ ~]$ mysql -V mysql Ver 14.7 Distrib 4.

列表整體加1方法

append map 整體 num enume for in rate int pen 1、 list = [0,1,2,3,4,5,6,7,8,9] num = map(lambda x:x+1,list)print num 2、list1=[]for i in lis

遍歷Map的方法

html pos val 方法 div body put next shm public static void main(String[] args) { Map<String, String> map = new HashMap<String,

JS 數組去重的方法

new return obj 元素 數組去重 != lis 相同 break 1、通過遍歷原數組和新數組是否重復。new一個新數組存放已經遍歷過的、唯一的元素。 function uniqueArr(list){   var newArr= [list[0]];   for

運行jar應用程序引用其他jar包的方法

撰寫 company 有一個 重寫 方式 工作 dex some sta 方法一、使用Bootstrap Classloader來加載這些類。 我們可以在運行時使用如下參數: -Xbootclasspath:完全取代系統Java classpath.最好不用。-Xbootc

JS生成 UUID的方法

ide replace rsa func digits 隨機生成 turn abcdefg 標準 全局唯一標識符(GUID,Globally Unique Identifier)也稱作 UUID(Universally Unique IDentifier) 。 GUID是

Jmeter添加變量的方法

sha 更新 循環 logs false del 文件名 image stop 一、在樣本中添加同請求一起發送的參數。根據服務器設置的數據類型,來添加不同類型的參數 二、用戶定義的變量 1、創建:添加->配置元件->用戶定義的變量 2、作用:當前的線程組內所

vue中組件的方法總結

end bsp nbsp 四種 temp recommend show -s com 希望對大家有用 全局組件的第一種寫法 html: <div id = "app"> <show></show></div>

java 遍歷arrayList的方法

void 線程安全 接口 線程同步 object類 轉型 依次 調用 values package com.test; import java.util.ArrayList; import java.util.Iterator; import java.util.Lis

css垂直居中的方法

center utf-8 borde gre abs ddl for relative eight <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8">

加載 AssetBundle 的方法

recently send log making before 返回 ack one perf 【加載 AssetBundle 的四種方法】 1、AssetBundle.LoadFromMemoryAsync(byte[] binary, uint crc = 0);

java語言復制數組的方法

原生態 png mit 宋體 angle 連接 earch oat nowrap 參考:http://www.cnblogs.com/dream-it-possible/p/7018804.html 來源於牛客網的一道選擇題: JAVA語言的下面幾種數組復制方法中,哪個