什么是镂空效果,下图就是一个镂空效果的文字:

从图可知,文字是透明的,可以看到下面的图片内容,而UILabel其它部分是白色背景。

使用Quartz 2D绘制镂空效果,大体思路如下:

  1. 实现一个UILabel的子类(这个不是必须的,这样做的目的是为了利用UILabel自身的文字绘制功能方便的绘制出文字,你也可以采用CoreText绘制文字)
  2. 初始化当前视图时确保backgroundColor==.clear(这样做是实现落空文字的关键,因为文字部分必须是透明的)
  3. 利用UILabel自身的绘制方法,绘制出一个文字蒙版(注意:绘制的原图必须是透明底,白色文字(确保textColor为.white)。这样才能正确的创建一个我们需要的文字蒙版)
  4. 调用clip(to rect: CGRect, mask: CGImage)来裁剪当前视图的上下文,mask就是3中创建的蒙版(在此之前需要转换上下文的坐标系)
  5. 填充上下文背景色

附上代码:

class PiercedLabel: UILabel {

    override var textColor: UIColor!{
didSet {
if textColor != .white {
textColor = .white // 要实现一个镂空的文字,这里的颜色必须设置成白色
}
}
} override var backgroundColor: UIColor?{
didSet {
// backgroundColor要确保始终为.clear(透明色),这样才可以实现一个镂空效果
guard let color = backgroundColor else {
backgroundColor = .clear
// 当设置backgroundColor == nil时,我们默认背景为白色
bgColor = .white
return
}
if color != .clear {
bgColor = color // 保留设置的背景色,以便后续绘制背景
backgroundColor = .clear
}
}
} // 用于绘制背景色
private var bgColor: UIColor! init() {
super.init(frame: .zero)
config()
} override init(frame: CGRect) {
super.init(frame: frame)
config()
} required init?(coder: NSCoder) {
super.init(coder: coder)
config()
} private func config(){
textColor = .white
bgColor = .white
backgroundColor = .clear
} override func draw(_ rect: CGRect) { // 创建一个用于绘制图片的图形上下文,这里必须是透明的,以便创建一个文字蒙版
UIGraphicsBeginImageContextWithOptions(rect.size, false, 0)
guard let maskContext = UIGraphicsGetCurrentContext() else {
return
}
// 注意:此时的maskContext并不是当前draw方法提供的上下文,而是我们调用UIGraphicsBeginImageContextWithOptions
// 构建的新的图形上下文,我们在这个上下文中绘制文字蒙版
// 绘制文字到maskContext上下文中
super.draw(rect)
// 获取maskContext上下文的bitmap图片
guard let textImg = maskContext.makeImage() else {
UIGraphicsEndImageContext() // 结束maskContext上下文
return
}
UIGraphicsEndImageContext() // 结束maskContext上下文
// 注意:此时的textImg并不能作为文字蒙版,我们需要通过如下方法创建一个蒙版图片
// 创建蒙版图
guard let maskImg = CGImage(maskWidth: textImg.width,
height: textImg.height,
bitsPerComponent: textImg.bitsPerComponent,
bitsPerPixel: textImg.bitsPerPixel,
bytesPerRow: textImg.bytesPerRow,
provider: textImg.dataProvider!,
decode: textImg.decode,
shouldInterpolate: textImg.shouldInterpolate) else {
return
} // 获取当前draw方法提供的上下文,我们需要将内容绘制到这里
guard let ctx = UIGraphicsGetCurrentContext() else {
return
}
// 先保存当前上下文状态
ctx.saveGState()
ctx.clear(rect)
// 调整当前上下文的坐标系,因为ctx.draw绘制的坐标系是按照左下角问原点的
// 因此我们需要将坐标系改成左上角,这样绘制的结果才是正确的,否则文字是颠倒的
ctx.translateBy(x: 0, y: rect.height)
ctx.scaleBy(x: 1, y: -1) // 使用蒙版进行裁剪,它会将ctx上下文rect区域的文字部分裁减掉
ctx.clip(to: rect, mask: maskImg) // 绘制背景色(注意:被裁减掉的部分不会填充,这样就形成了一个镂空的效果了)
// 因为ctx上下文是根据当前视图的backgroundColor创建的,而backgroundColor == .clear,是一个透明的
// 所以ctx就是一个含有透明层的上下文,被裁剪掉的文字部分就是一个透明的了
// 这也是为什么要确保backgroundColor == .clear了
bgColor.setFill()
ctx.fill(rect)
}
}

代码中的注释已经写的很详细了,具体的解释就不详细描述了

下面是绘制原文本和蒙版的对照图:

原文本:是一个透明底,白色文字

蒙版:是一个透明底,黑色文字

有人会想到,那我们可不可以直接用原文本图片作为蒙版呢?可以,但是那将不是我们想要的效果,它将会是下面的效果:

背景色成为了文字的颜色,而背景色却成为了透明的。这正与我们想要的效果相反。

因此我们必须通过CGImageMaskCreate创建一个蒙版图片。

关于ImageMask的解释可以查看苹果官方文档

截取部分说明:

Image masks must be 1, 2, 4, or 8 bits per component. For a 1-bit mask, a sample value of 1 specifies sections of the mask that are masked out; these sections block the current fill color. A sample value of 0 specifies sections of the mask that are not masked out; these sections show the current fill color of the graphics state when the mask is painted. You can think of the sample values as an inverse alpha. That is, a value of 1 is transparent and 0 is opaque.

Quartz 2D实现文字镂空效果的更多相关文章

  1. CSS 奇技淫巧 | 妙用混合模式实现文字镂空波浪效果

    本文将介绍一个小技巧,通过混合模式 mix-blend-mode 巧妙的实现文字的镂空波浪效果. 起因 一日,一群友私聊问我.如何使用 CSS 实现下述效果,一个文字的波浪效果: 我当时想都没想,就回 ...

  2. Quartz 2D在ios中的使用简述一:坐标体系

    Quartz 2D是一个二维图形绘制引擎,支持iOS环境和Mac OS X环境,官方文档:Quartz 2D Programming Guide. 一.坐标体系 这样的坐标体系就导致我们使用Quart ...

  3. iOS 2D绘图 (Quartz 2D) 概述

    本篇博客原文地址:http://blog.csdn.net/hello_hwc?viewmode=list 由于自己的项目需要,从网络上下载了许多关于绘制图形的demo,只是用在自己的项目中,很多地方 ...

  4. iOS 2D绘图详解(Quartz 2D)之概述

    前言:最近在研究自定义控件,由于想要彻底的定制控件的视图还是要继承UIView,虽然对CALayer及其子类很熟练,但是对Quartz 2D这个强大的框架仍然概念模棱两可.于是,决定学习下,暂定7篇文 ...

  5. iOS基础 - Quartz 2D绘图

    一.Quartz 2D Quartz 2D是一个二维图形绘制引擎,支持iOS环境和Mac OS X环境. Quartz 2D以PDF的规范为基础的图形库,用来绘制二维文字和图形,允许相同的绘图指令在任 ...

  6. iOS - Quartz 2D 二维绘图

    1.Quartz 2D 简介 Quartz 2D 属于 Core Graphics(所以大多数相关方法的都是以 CG 开头),是 iOS/Mac OSX 提供的在内核之上的强大的 2D 绘图引擎,并且 ...

  7. Quartz 2D中CGContextSaveGState与UIGraphicsPushContext

    CGContextRef: An opaque type that represents a Quartz 2D drawing environment. Graphics Context是图形上下文 ...

  8. 1.0 Quartz 2D 简介

    本文并非最终版本,如有更新或更正会第一时间置顶,联系方式详见文末 如果觉得本文内容过长,请前往本人 “简书”   Quartz2D须知:   (1)Quartz 2D是苹果官方的二维绘图引擎,同时支持 ...

  9. Quartz 2D绘制简单图形

    在Quartz 2D中,绘图是通过图形上下文进行绘制的,以下绘制几个简单的图形 首先先创建一个QuartzView.swift文件继承自UIView,然后实现drawRect方法: import UI ...

  10. Quartz 2d绘图

    今天看了一下Quartz 2D绘图,我只想说:不要把绘图和动画那些东西当做一个很复杂的东西,其实只要你认真看还是可以理解的.他们并不难.啰嗦了几句,现在直接进入正题: 前提是我们必须新建一个singl ...

随机推荐

  1. IDEA 2022 开启热部署

    POM.XML <dependency> <groupId>org.springframework.boot</groupId> <artifactId> ...

  2. Ubuntu18.04 下使用Flatpak稳定安装TIM、微信、迅雷和百度云

    https://gitee.com/wszqkzqk/deepin-wine-for-ubuntu git clone https://gitee.com/wszqkzqk/deepin-wine-c ...

  3. 修改Element - plus的样式

    把显示再浏览器上的对应css选择器全部写上,并且添加 !important </script> <style lang='scss' scoped> //修改 element ...

  4. Map Inference in the Face of Noise and Disparity代码环境搭建

    1. 引言 地图生成算法网站Mapconstruction by pfoser里可以看到许多关于地图生成算法的介绍,Map Inference in the Face of Noise and Dis ...

  5. PostgreSQL 绑定变量浅析

    今天我们要探讨的是 custom执行计划和通用执行计划.这一技术在 Oracle中被称为绑定变量窥视.但 Postgresql中并没有这样的定义,更严格地说,Postgresql叫做custom执行计 ...

  6. Postgresql的csv日志设置

    PG的日志系统比较完善,除去系统启动时指定的日志,wal日志等外,下面主要介绍另一个详细的输出日志:csv log. 涉及到的参数文件:$PGDATA/postgresql.conf涉及的主要参数: ...

  7. nginx中多ip多域名多端口配置

    1.Nginx中多IP配置: server { listen 80; server_name 192.168.15.7; location / { root /opt/Super_Marie; ind ...

  8. vue2+ts 设计一个扑克牌比大小的游戏

    首先  

  9. TiDB日常运维手册

    1.处理dm不兼容DDL 迁移中断,执行跳过操作 tiup dm list tiup dm display xxx-dm-prod tiup dmctl --master-addr 10.0.xx.x ...

  10. 1487. 保证文件名唯一 (Medium)

    问题描述 1487. 保证文件名唯一 (Medium) 给你一个长度为 n 的字符串数组 names .你将会在文件系统中创建 n 个文件夹:在第 i 分钟,新建名为 names[i] 的文件夹. 由 ...