真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

iOS中如何實現(xiàn)UIView鏤空效果

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

網(wǎng)站建設(shè)哪家好,找創(chuàng)新互聯(lián)!專注于網(wǎng)頁設(shè)計、網(wǎng)站建設(shè)、微信開發(fā)、小程序定制開發(fā)、集團(tuán)企業(yè)網(wǎng)站建設(shè)等服務(wù)項目。為回饋新老客戶創(chuàng)新互聯(lián)還提供了廣州免費建站歡迎大家使用!

這是一種實現(xiàn) UIView 鏤空效果的方案,可以快速實現(xiàn)任意形狀的鏤空、文字的鏤空、帶鏤空的毛玻璃效果等。本質(zhì)上是 UIViewmaskView 效果。

前言

首先來復(fù)習(xí)一下遮罩效果的實現(xiàn)。如果我們有一張圖片,又恰好有一個圓,當(dāng)我們把圓設(shè)置為圖片的遮罩時,會得到這樣的結(jié)果。

iOS中如何實現(xiàn)UIView鏤空效果

代碼實現(xiàn)看上去像是這樣:

view.maskView = maskView;

那么問題來了,如果我們希望得到下面的結(jié)果,該怎么做呢?這看起來像是圖層的相減,即原來的圖層減去遮罩的部分。

iOS中如何實現(xiàn)UIView鏤空效果

可惜蘋果爸爸不夠貼心,沒有提供方便的接口調(diào)用。讓我們來看看可以怎么實現(xiàn)。

一、思路

我們的最終目標(biāo)是,封裝出一個接口,調(diào)用方式類似于 maskView 屬性,可以很方便地對一個 UIView 做鏤空效果。

注:以下用 originView 指代需要上效果的 view ,用 maskView 指代充當(dāng)遮罩的 view

目前看來,可以從兩個方向入手:

  1. 修改遮罩的繪制過程

  2. 修改 maskView 本身

方式一是指,在設(shè)置這個屬性的時候,對 originView 的視圖進(jìn)行重新繪制,然后在繪制的時候,減掉 maskView 的區(qū)域。

方式二是指,當(dāng)拿到 maskView 的時候,先對 maskView 本身先進(jìn)行處理,將遮罩范圍取反。然后再做遮罩效果,由于遮罩的區(qū)域已經(jīng)相反,于是得到的結(jié)果也是相反的,就達(dá)到鏤空的目的。

看上去方式二比較靠譜,而且最后是調(diào)用 UIViewsetMaskView: 來實現(xiàn),還可以保留原來遮罩的一些特性。比如當(dāng)修改 maskViewframe 的時候, originView 的遮罩位置也會相應(yīng)改變。

二、實現(xiàn)

生成相反的遮罩圖可以分為三步。假設(shè)一開始拿到的 maskView 是下面這樣,讓我們來看下,轉(zhuǎn)換過程中遮罩圖每一步的變化。

iOS中如何實現(xiàn)UIView鏤空效果

注:為了更直觀的效果,圖片中透明的部分用灰白相間格子來表示(以下相同)。

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 的大小。

iOS中如何實現(xiàn)UIView鏤空效果 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 通道。

iOS中如何實現(xiàn)UIView鏤空效果 3、將

CGContextRef 中的 alpha 值進(jìn)行遍歷轉(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 圖像是:

iOS中如何實現(xiàn)UIView鏤空效果

于是,我們就可以用 result 愉快地進(jìn)行 mask 了。

三、使用

我們可以將上述的步驟,封裝為一個方法,用 category 來實現(xiàn)。

@interface UIView (MFSubtractMask)
- (void)setSubtractMaskView:(UIView *)view;
- (UIView *)subtractMaskView;
@end

這樣調(diào)用起來就十分方便了,一行代碼搞定:

view.subtractMaskView = maskView;

四、局限性

1. subtractMaskView 不會自動刷新

我們知道,當(dāng) UIViewmaskView 的內(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é)到更多知識,如果覺得文章不錯,請把它分享出去讓更多的人看到。


網(wǎng)頁題目:iOS中如何實現(xiàn)UIView鏤空效果
文章位置:http://weahome.cn/article/gsdgjs.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部