iOS中如何使用一行代码实现UIView镂空效果-创新互联

这篇文章将为大家详细讲解有关iOS中如何使用一行代码实现UIView镂空效果,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。

成都创新互联2013年开创至今,先为潍城等服务建站,潍城等地企业,进行企业商务咨询服务。为潍城企业网站制作PC+手机+微官网三网同步一站式服务解决您的所有建站问题。

一、思路

我们的最终目标是,封装出一个接口,调用方式类似于maskView 属性,可以很方便地对一个UIView 做镂空效果。

注:以下用originView 指代需要上效果的view ,用maskView 指代充当遮罩的view

目前看来,可以从两个方向入手:

  1. 修改遮罩的绘制过程修改 maskView 本身

方式一是指,在设置这个属性的时候,对originView 的视图进行重新绘制,然后在绘制的时候,减掉maskView 的区域。

方式二是指,当拿到maskView 的时候,先对maskView 本身先进行处理,将遮罩范围取反。然后再做遮罩效果,由于遮罩的区域已经相反,于是得到的结果也是相反的,就达到镂空的目的。

看上去方式二比较靠谱,而且最后是调用UIViewsetMaskView: 来实现,还可以保留原来遮罩的一些特性。比如当修改maskViewframe 的时候,originView 的遮罩位置也会相应改变。

二、实现

生成相反的遮罩图可以分为三步。假设一开始拿到的maskView 是下面这样,让我们来看下,转换过程中遮罩图每一步的变化。

注:为了更直观的效果,图片中透明的部分用灰白相间格子来表示(以下相同)。

1、将maskView 转化为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 对应的image 图像。此时遮罩图的大小会被同步为originView 的大小。

2、将

UIImage 转换为只有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 对应的图像是下面这样,只保留了alpha 通道。

3、将

CGContextRef 中的alpha 值进行遍历转换

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];

转换后,获得的result 图像是:

于是,我们就可以用result 愉快地进行mask 了。

三、使用

我们可以将上述的步骤,封装为一个方法,用category 来实现。

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

这样调用起来就十分方便了,一行代码搞定:

view.subtractMaskView = maskView;

四、局限性

1.subtractMaskView 不会自动刷新

我们知道,当UIViewmaskView 的内容动态修改时,会实时反映到UIView 中。但在本项目中,subtractMaskView 属性会生成一张全新的图片来作为遮罩图,因为不会根据subtractMaskView 的内容实时来刷新视图。如果需要更新,必须手动调用setSubtractMaskView: 方法来重新生成遮罩图。

2.setSubtractMaskView: 不宜被频繁调用

setSubtractMaskView: 本质上是生成一个新的遮罩图的过程,该过程涉及图片像素的遍历转换,较为耗时,不宜频繁调用。

关于“iOS中如何使用一行代码实现UIView镂空效果”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。


本文标题:iOS中如何使用一行代码实现UIView镂空效果-创新互联
网页地址:http://hbruida.cn/article/hgjjg.html