iOS开发之在列表上方添加水印的方法
程序员文章站
2022-03-22 14:53:10
前言
为了防止工程师泄露用户信息,我们有个需求是在列表上面添加水印。我封装了这个视图分享出来。下面话不多说了,来一起看看详细的介绍吧
效果图
示例代码如下...
前言
为了防止工程师泄露用户信息,我们有个需求是在列表上面添加水印。我封装了这个视图分享出来。下面话不多说了,来一起看看详细的介绍吧
效果图
示例代码如下:
watermarkview.h
#import <uikit/uikit.h> @interface watermarkview : uiimageview /** 设置水印 @param frame 水印大小 @param marktext 水印显示的文字 */ - (instancetype)initwithframe:(cgrect)frame withtext:(nsstring *)marktext; @end
watermarkview.m
#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; }
使用方法
//加水印 watermarkview *watermark = [[watermarkview alloc] initwithframe:cgrectmake(0, 0, kscreenw, kscreenh) withtext:@"测试"]; [self.view addsubview:watermark];
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对的支持。