我的编程空间,编程开发者的网络收藏夹
学习永远不晚

iOS中一行代码实现 UIView 镂空效果

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

iOS中一行代码实现 UIView 镂空效果

这是一种实现 UIView 镂空效果的方案,可以快速实现任意形状的镂空、文字的镂空、带镂空的毛玻璃效果等。本质上是 UIViewmaskView 效果。

前言

首先来复习一下遮罩效果的实现。如果我们有一张图片,又恰好有一个圆,当我们把圆设置为图片的遮罩时,会得到这样的结果。

代码实现看上去像是这样:


view.maskView = maskView;

那么问题来了,如果我们希望得到下面的结果,该怎么做呢?这看起来像是图层的相减,即原来的图层减去遮罩的部分。

可惜苹果爸爸不够贴心,没有提供方便的接口调用。让我们来看看可以怎么实现。

一、思路

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

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

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

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

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

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

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

二、实现

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

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

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;

四、局限性

subtractMaskView 不会自动刷新

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

setSubtractMaskView: 不宜被频繁调用

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

综上所述,这种方案适合只生成一次遮罩图的场景。

 五、源码

请到 GitHub 上查看完整代码。

总结

以上所述是小编给大家介绍的iOS中一行代码实现 UIView 镂空效果,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对编程网网站的支持!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

iOS中一行代码实现 UIView 镂空效果

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

iOS中一行代码实现 UIView 镂空效果

这是一种实现 UIView 镂空效果的方案,可以快速实现任意形状的镂空、文字的镂空、带镂空的毛玻璃效果等。本质上是 UIView 的 maskView 效果。 前言 首先来复习一下遮罩效果的实现。如果我们有一张图片,又恰好有一个圆,当我们把
2022-05-29

一行java代码实现高斯模糊效果

本文实例为大家分享了本地图片或者网络图片高斯模糊效果(毛玻璃效果),具体内容如下首先看效果图1.本地图片高斯模糊2.网络图片高斯模糊github网址:https://github.com/qiushi123/BlurImageQcl下面是使
2023-05-31

iOS实现不规则Button点击效果实例代码

需求利用图片,实现一个如图的按钮组。遇到的问题如下图所示:功能1、2、3、4的按钮可以实现点击功能。但是在红色方框四角的位置,也会响应相应的点击事件。紫色方框内四角区域点击时,响应的方法是功能5,而不是对应的功能。解决思路期望的结果寻找到合
2022-05-24

Android空心圆及层叠效果实现代码

本文实例为大家分享了Android空心圆及层叠效果的具体代码,供大家参考,具体内容如下package com.bwei.test.zidingyiview2;import android.content.Context;import and
2023-05-30

css代码怎么实现进行中打点效果

这篇文章主要介绍“css代码怎么实现进行中打点效果”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“css代码怎么实现进行中打点效果”文章能帮助大家解决问题。代码如下:
2023-07-04

使用HTML怎么实现一个代码雨效果

本篇文章为大家展示了使用HTML怎么实现一个代码雨效果,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。1、绿色:2、彩色:3、背景色:4、绿色逐渐变浅:源代码:
2023-06-09

Android开发中怎么实现一个iOS中的毛玻璃效果

本篇文章为大家展示了Android开发中怎么实现一个iOS中的毛玻璃效果,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。实现代码: 2023-05-31

android表格效果之ListView隔行变色实现代码

首先继承SimpleAdapter 代码如下: package meetweb.net.util; import java.util.List; import java.util.Map; import android.content.C
2022-06-06

JavaScript中canvas实现代码雨效果的方法

这篇文章将为大家详细讲解有关JavaScript中canvas实现代码雨效果的方法,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。本文实例为大家分享了canvas实现代码雨效果的具体代码,供大家参考,具体内
2023-06-15

怎么在vue中利用monaco实现一个代码高亮效果

怎么在vue中利用monaco实现一个代码高亮效果?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。为什么要使用VueVue是一款友好的、多用途且高性能的JavaS
2023-06-06

Android文本框搜索和清空效果实现代码及简要概述

前言 本文实现的效果:文本框输入为空时显示输入的图标;不为空时显示清空的图标,此时点击清空图标能清空文本框内输入文字。正文 一、实现效果    二、实现代码 绑定事件 代码如下: private Drawable mIconSearchD
2022-06-06

如何进行中隐藏“投诉”“举报”按钮的纯JS代码实现效果分析

如何进行中隐藏“投诉”“举报”按钮的纯JS代码实现效果分析,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。在做微信投票,小说阅读类,以及大部分推广类微信H5页面经常会遇到因为被举
2023-06-04

Android应用开发中模拟按下HOME键的效果(实现代码)

下面提供代码示例,请参考。 代码如下:public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK) {
2022-06-06

编程热搜

  • Android:VolumeShaper
    VolumeShaper(支持版本改一下,minsdkversion:26,android8.0(api26)进一步学习对声音的编辑,可以让音频的声音有变化的播放 VolumeShaper.Configuration的三个参数 durati
    Android:VolumeShaper
  • Android崩溃异常捕获方法
    开发中最让人头疼的是应用突然爆炸,然后跳回到桌面。而且我们常常不知道这种状况会何时出现,在应用调试阶段还好,还可以通过调试工具的日志查看错误出现在哪里。但平时使用的时候给你闹崩溃,那你就欲哭无泪了。 那么今天主要讲一下如何去捕捉系统出现的U
    Android崩溃异常捕获方法
  • android开发教程之获取power_profile.xml文件的方法(android运行时能耗值)
    系统的设置–>电池–>使用情况中,统计的能耗的使用情况也是以power_profile.xml的value作为基础参数的1、我的手机中power_profile.xml的内容: HTC t328w代码如下:
    android开发教程之获取power_profile.xml文件的方法(android运行时能耗值)
  • Android SQLite数据库基本操作方法
    程序的最主要的功能在于对数据进行操作,通过对数据进行操作来实现某个功能。而数据库就是很重要的一个方面的,Android中内置了小巧轻便,功能却很强的一个数据库–SQLite数据库。那么就来看一下在Android程序中怎么去操作SQLite数
    Android SQLite数据库基本操作方法
  • ubuntu21.04怎么创建桌面快捷图标?ubuntu软件放到桌面的技巧
    工作的时候为了方便直接打开编辑文件,一些常用的软件或者文件我们会放在桌面,但是在ubuntu20.04下直接直接拖拽文件到桌面根本没有效果,在进入桌面后发现软件列表中的软件只能收藏到面板,无法复制到桌面使用,不知道为什么会这样,似乎并不是很
    ubuntu21.04怎么创建桌面快捷图标?ubuntu软件放到桌面的技巧
  • android获取当前手机号示例程序
    代码如下: public String getLocalNumber() { TelephonyManager tManager =
    android获取当前手机号示例程序
  • Android音视频开发(三)TextureView
    简介 TextureView与SurfaceView类似,可用于显示视频或OpenGL场景。 与SurfaceView的区别 SurfaceView不能使用变换和缩放等操作,不能叠加(Overlay)两个SurfaceView。 Textu
    Android音视频开发(三)TextureView
  • android获取屏幕高度和宽度的实现方法
    本文实例讲述了android获取屏幕高度和宽度的实现方法。分享给大家供大家参考。具体分析如下: 我们需要获取Android手机或Pad的屏幕的物理尺寸,以便于界面的设计或是其他功能的实现。下面就介绍讲一讲如何获取屏幕的物理尺寸 下面的代码即
    android获取屏幕高度和宽度的实现方法
  • Android自定义popupwindow实例代码
    先来看看效果图:一、布局
  • Android第一次实验
    一、实验原理 1.1实验目标 编程实现用户名与密码的存储与调用。 1.2实验要求 设计用户登录界面、登录成功界面、用户注册界面,用户注册时,将其用户名、密码保存到SharedPreference中,登录时输入用户名、密码,读取SharedP
    Android第一次实验

目录