前言
为了防止工程师泄露用户信息,我们有个需求是在列表上面添加水印。我封装了这个视图分享出来。下面话不多说了,来一起看看详细的介绍吧
效果图
示例代码如下:
watermarkview.h
?
|
1
2
3
4
5
6
7
8
9
10
11
12
13
|
#import <uikit/uikit.h>
@interface watermarkview : uiimageview
/**
设置水印
@param frame 水印大小
@param marktext 水印显示的文字
*/
- (instancetype)initwithframe:(cgrect)frame withtext:(nsstring *)marktext;
@end
|
watermarkview.m
?
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
|
#import "watermarkview.h"
#define horizontal_space 30//水平间距
#define vertical_space 50//竖直间距
#define cg_transform_rotation (m_pi_2 / 3)//旋转角度(正旋45度 || 反旋45度)
@implementation watermarkview
- (instancetype)initwithframe:(cgrect)frame withtext:(nsstring *)marktext{
if(self = [super initwithframe:frame]){
uifont *font = [uifont systemfontofsize:14];
uicolor *color = ythcoloralpha(152, 152, 152, 0.1);
//原始image的宽高
cgfloat viewwidth = frame.size.width;
cgfloat viewheight = frame.size.height;
//为了防止图片失真,绘制区域宽高和原始图片宽高一样
uigraphicsbeginimagecontext(cgsizemake(viewwidth, viewheight));
//sqrtlength:原始image的对角线length。在水印旋转矩阵中只要矩阵的宽高是原始image的对角线长度,无论旋转多少度都不会有空白。
cgfloat sqrtlength = sqrt(viewwidth*viewwidth + viewheight*viewheight);
//文字的属性
nsdictionary *attr = @{
//设置字体大小
nsfontattributename: font,
//设置文字颜色
nsforegroundcolorattributename :color,
};
nsstring* mark = marktext;
nsmutableattributedstring *attrstr = [[nsmutableattributedstring alloc] initwithstring:mark attributes:attr];
//绘制文字的宽高
cgfloat strwidth = attrstr.size.width;
cgfloat strheight = attrstr.size.height;
//开始旋转上下文矩阵,绘制水印文字
cgcontextref context = uigraphicsgetcurrentcontext();
//将绘制原点(0,0)调整到原image的中心
cgcontextconcatctm(context, cgaffinetransformmaketranslation(viewwidth/2, viewheight/2));
//以绘制原点为中心旋转
cgcontextconcatctm(context, cgaffinetransformmakerotation(cg_transform_rotation));
//将绘制原点恢复初始值,保证当前context中心和源image的中心处在一个点(当前context已经旋转,所以绘制出的任何layer都是倾斜的)
cgcontextconcatctm(context, cgaffinetransformmaketranslation(-viewwidth/2, -viewheight/2));
//计算需要绘制的列数和行数
int horcount = sqrtlength / (strwidth + horizontal_space) + 1;
int vercount = sqrtlength / (strheight + vertical_space) + 1;
//此处计算出需要绘制水印文字的起始点,由于水印区域要大于图片区域所以起点在原有基础上移
cgfloat orignx = -(sqrtlength-viewwidth)/2;
cgfloat origny = -(sqrtlength-viewheight)/2;
//在每列绘制时x坐标叠加
cgfloat temporignx = orignx;
//在每行绘制时y坐标叠加
cgfloat temporigny = origny;
for (int i = 0; i < horcount * vercount; i++) {
[mark drawinrect:cgrectmake(temporignx, temporigny, strwidth, strheight) withattributes:attr];
if (i % horcount == 0 && i != 0) {
temporignx = orignx;
temporigny += (strheight + vertical_space);
}else{
temporignx += (strwidth + horizontal_space);
}
}
//根据上下文制作成图片
uiimage *finalimg = uigraphicsgetimagefromcurrentimagecontext();
uigraphicsendimagecontext();
cgcontextrestoregstate(context);
self.image = finalimg;
}
return self;
}
-(uiview *)hittest:(cgpoint)point withevent:(uievent *)event{
//1.判断自己能否接收事件
if(self.userinteractionenabled == no || self.hidden == yes || self.alpha <= 0.01) {
return nil;
}
//2.判断当前点在不在当前view.
if (![self pointinside:point withevent:event]) {
return nil;
}
//3.从后往前遍历自己的子控件.让子控件重复前两步操作,(把事件传递给,让子控件调用hittest)
int count = (int)self.subviews.count;
for (int i = count - 1; i >= 0; i--) {
//取出每一个子控件
uiview *chilev = self.subviews[i];
//把当前的点转换成子控件坐标系上的点.
cgpoint childp = [self convertpoint:point toview:chilev];
uiview *fitview = [chilev hittest:childp withevent:event];
//判断有没有找到最适合的view
if(fitview){
return fitview;
}
}
//4.没有找到比它自己更适合的view.那么它自己就是最适合的view
return self;
}
//作用:判断当前点在不在它调用view,(谁调用pointinside,这个view就是谁)
//什么时候调用:它是在hittest方法当中调用的.
//注意:point点必须得要跟它方法调用者在同一个坐标系里面
-(bool)pointinside:(cgpoint)point withevent:(uievent *)event{
nslog(@"%s",__func__);
return no;
}
|
使用方法
?
|
1
2
3
|
//加水印
watermarkview *watermark = [[watermarkview alloc] initwithframe:cgrectmake(0, 0, kscreenw, kscreenh) withtext:@"测试"];
[self.view addsubview:watermark];
|
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对快网idc的支持。
相关文章
猜你喜欢
- ASP.NET自助建站系统的域名绑定与解析教程 2025-06-10
- 个人服务器网站搭建:如何选择合适的服务器提供商? 2025-06-10
- ASP.NET自助建站系统中如何实现多语言支持? 2025-06-10
- 64M VPS建站:如何选择最适合的网站建设平台? 2025-06-10
- ASP.NET本地开发时常见的配置错误及解决方法? 2025-06-10
TA的动态
- 2025-07-10 怎样使用阿里云的安全工具进行服务器漏洞扫描和修复?
- 2025-07-10 怎样使用命令行工具优化Linux云服务器的Ping性能?
- 2025-07-10 怎样使用Xshell连接华为云服务器,实现高效远程管理?
- 2025-07-10 怎样利用云服务器D盘搭建稳定、高效的网站托管环境?
- 2025-07-10 怎样使用阿里云的安全组功能来增强服务器防火墙的安全性?
快网idc优惠网
QQ交流群
您的支持,是我们最大的动力!
热门文章
-
2025-05-25 63
-
2025-05-27 44
-
2025-05-27 95
-
2025-06-04 34
-
2025-06-04 71
热门评论


