這篇文章將為大家詳細講解有關(guān)iOS中如何使用一行代碼實現(xiàn)UIView鏤空效果,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。

一、思路
我們的最終目標是,封裝出一個接口,調(diào)用方式類似于maskView 屬性,可以很方便地對一個UIView 做鏤空效果。
注:以下用originView 指代需要上效果的view ,用maskView 指代充當遮罩的view 。
目前看來,可以從兩個方向入手:
修改遮罩的繪制過程修改 maskView 本身
方式一是指,在設(shè)置這個屬性的時候,對originView 的視圖進行重新繪制,然后在繪制的時候,減掉maskView 的區(qū)域。
方式二是指,當拿到maskView 的時候,先對maskView 本身先進行處理,將遮罩范圍取反。然后再做遮罩效果,由于遮罩的區(qū)域已經(jīng)相反,于是得到的結(jié)果也是相反的,就達到鏤空的目的。
看上去方式二比較靠譜,而且最后是調(diào)用UIView 的setMaskView: 來實現(xiàn),還可以保留原來遮罩的一些特性。比如當修改maskView 的frame 的時候,originView 的遮罩位置也會相應(yīng)改變。
二、實現(xiàn)
生成相反的遮罩圖可以分為三步。假設(shè)一開始拿到的maskView 是下面這樣,讓我們來看下,轉(zhuǎn)換過程中遮罩圖每一步的變化。
注:為了更直觀的效果,圖片中透明的部分用灰白相間格子來表示(以下相同)。
1、將maskView 轉(zhuǎn)化為UIImage
UIGraphicsBeginImageContextWithOptions(self.bounds.size, NO, [UIScreen mainScreen].scale);CGContextTranslateCTM(UIGraphicsGetCurrentContext(), view.frame.origin.x, view.frame.origin.y);[view.layer renderInContext:UIGraphicsGetCurrentContext()];UIImage *image = UIGraphicsGetImageFromCurrentImageContext();UIGraphicsEndImageContext();
這一步拿到了maskView 對應(yīng)的image 圖像。此時遮罩圖的大小會被同步為originView 的大小。
2、將
UIImage 轉(zhuǎn)換為只有alpha 通道的CGContextRef
CGImageRef originalMaskImage = [image CGImage];float width = CGImageGetWidth(originalMaskImage);float height = CGImageGetHeight(originalMaskImage);int strideLength = ROUND_UP(width * 1, 4);unsigned char * alphaData = calloc(strideLength * height, sizeof(unsigned char));CGContextRef alphaOnlyContext = CGBitmapContextCreate(alphaData, width, height, 8, strideLength, NULL, kCGImageAlphaOnly);CGContextDrawImage(alphaOnlyContext, CGRectMake(0, 0, width, height), originalMaskImage);
這時候的alphaOnlyContext 對應(yīng)的圖像是下面這樣,只保留了alpha 通道。
3、將
CGContextRef 中的alpha 值進行遍歷轉(zhuǎn)換
for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { unsigned char val = alphaData[y*strideLength + x]; val = 255 - val; alphaData[y*strideLength + x] = val; }}CGImageRef alphaMaskImage = CGBitmapContextCreateImage(alphaOnlyContext);UIImage *result = [UIImage imageWithCGImage:alphaMaskImage];
轉(zhuǎn)換后,獲得的result 圖像是:
于是,我們就可以用result 愉快地進行mask 了。
三、使用
我們可以將上述的步驟,封裝為一個方法,用category 來實現(xiàn)。
@interface UIView (MFSubtractMask)- (void)setSubtractMaskView:(UIView *)view;- (UIView *)subtractMaskView;@end
這樣調(diào)用起來就十分方便了,一行代碼搞定:
view.subtractMaskView = maskView;
四、局限性
1.subtractMaskView 不會自動刷新
我們知道,當UIView 的maskView 的內(nèi)容動態(tài)修改時,會實時反映到UIView 中。但在本項目中,subtractMaskView 屬性會生成一張全新的圖片來作為遮罩圖,因為不會根據(jù)subtractMaskView 的內(nèi)容實時來刷新視圖。如果需要更新,必須手動調(diào)用setSubtractMaskView: 方法來重新生成遮罩圖。
2.setSubtractMaskView: 不宜被頻繁調(diào)用
setSubtractMaskView: 本質(zhì)上是生成一個新的遮罩圖的過程,該過程涉及圖片像素的遍歷轉(zhuǎn)換,較為耗時,不宜頻繁調(diào)用。
關(guān)于“iOS中如何使用一行代碼實現(xiàn)UIView鏤空效果”這篇文章就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,使各位可以學(xué)到更多知識,如果覺得文章不錯,請把它分享出去讓更多的人看到。
當前文章:iOS中如何使用一行代碼實現(xiàn)UIView鏤空效果-創(chuàng)新互聯(lián)
標題URL:http://chinadenli.net/article26/hgjjg.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供域名注冊、網(wǎng)站維護、移動網(wǎng)站建設(shè)、微信小程序、品牌網(wǎng)站設(shè)計、企業(yè)網(wǎng)站制作
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容