iOS开发之在列表上方添加水印的方法

前言

为了防止工程师泄露用户信息,我们有个需求是在列表上面添加水印。我封装了这个视图分享出来。下面话不多说了,来一起看看详细的介绍吧

效果图

示例代码如下:

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

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对我们的支持。

(0)

相关推荐

  • 浅析iOS给图片加水印的方法

    话不多说,直接上代码 新建了一个UIImage的类目,在.h中声明 + (UIImage *)imageWithimage:(UIImage *)image content:(NSString *)content frame:(CGRect)frame; .m如下 + (UIImage *)imageWithimage:(UIImage *)image content:(NSString *)content frame:(CGRect)frame { // 开启图形'上下文' UIGraphic

  • IOS给图片添加水印(两种方式)

    为了防止自己辛苦做的项目被别人盗走,采取图片添加水印,在此表示图片的独一无二.加水印不是在上面添加几个Label,而是我们把字画到图片上成为一个整体,下面小编给大家分享IOS给图片添加水印(两种方式). 提供一个方法,此方法只需要传递一个要加水印的图片和水印的内容就达到效果. 第一种方式: -(UIImage *)watermarkImage:(UIImage *)img withName:(NSString *)name { NSString* mark = name; int w = img

  • iOS实现图片水印与简单封装示例代码

    前言: 常用的许多软件中图片加水印的功能是非常常见的,如微博,微信,今日头条等等图片上都会有. 首先我们了解一下什么是水印及其作用? 水印:在图片上加的防止他人盗图的半透明logo.文字.图标 水印的作用:告诉你这个图片从哪来的,主要是一些网站为了版权问题.广告而添加的. 相关知识点:Quartz2D相关内容 核心代码: 将字符串添加到图形上下文的方法 - (void)drawAtPoint:(CGPoint)point withAttributes:(nullable NSDictionary

  • iOS开发之在列表上方添加水印的方法

    前言 为了防止工程师泄露用户信息,我们有个需求是在列表上面添加水印.我封装了这个视图分享出来.下面话不多说了,来一起看看详细的介绍吧 效果图 示例代码如下: watermarkView.h #import <UIKit/UIKit.h> @interface watermarkView : UIImageView /** 设置水印 @param frame 水印大小 @param markText 水印显示的文字 */ - (instancetype)initWithFrame:(CGRect

  • iOS开发中判断字符串为空的方法

    前言: 判断字符串为空:看似简单的问题,有人会说不就使用[string isEqualToString:@""]或者更简单的string.text == nil就行了嘛.但是并没有考虑到其中存在的一些问题,例如当字符串中存在空格或者换行时或者当请求后台数据时得到的是进行JSON解析的时候, 如果解析出的NSDictionary中某个key对应的value为空, 则系统会把它处理为NSNull类的单例对象.这些情况下,上面的判断方法就不会起到作用. 具体实现: + (BOOL)isBla

  • IOS开发中加载大量网络图片优化方法

    IOS开发中加载大量网络图片如何优化 1.概述 在IOS下通过URL读一张网络图片并不像其他编程语言那样可以直接把图片路径放到图片路径的位置就ok,而是需要我们通过一段类似流的方式去加载网络图片,接着才能把图片放入图片路径显示.比如: -(UIImage *) getImageFromURL:(NSString *)fileURL { //NSLog(@"执行图片下载函数"); UIImage * result; NSData * data = [NSData dataWithCont

  • iOS开发中runtime常用的几种方法示例总结

    前言 Objective-C runtime是一个实现Objective-C语言的C库.它是一门编译型语言.也是一门动态型的语言(这里强调下OC是静态类型语言),之前没接触runtime的时候也不觉着它有多重要,接触之后才发现其实runtime挺强大的.就拿我们在iOS开发中所使用的OC编程语言来讲,OC之所以能够做到即是编译型语言,又能做到动态语言,就是得益于runtime的机制. 最近公司项目中用了一些 runtime 相关的知识, 初看时有些蒙, 虽然用的并不多, 但还是想着系统的把 ru

  • iOS开发教程之XLForm的基本使用方法

    前言 在iOS开发中,开发"表单"界面,字段稍微多一点的一般都用UITableView来做,而XLForm就是这样一个框架,它是创建动态表格视图最牛逼的iOS库, 用它实现表单功能,非常简单,省心省力.但是很可惜,搜索了很多文章都只是翻译官方文档,很多人在使用该库的时候可能都被官方文档带走远了,不知道如何具体使用.正好最近也要用到这个库,所以写个入门使用文章供大家参考. 以下是这个库一个简单的结构图: 一. 导入项目 使用CocoaPods或者手动导入库文件,本人选择直接导入项目源文件

  • 讲解iOS开发中UITableView列表设计的基本要点

    一.UITableView简单介绍 1.tableView是一个用户可以滚动的多行单列列表,在表视图中,每一行都是一个UITableViewCell对象,表视图有两种风格可选 复制代码 代码如下: typedef NS_ENUM(NSInteger, UITableViewStyle) {     UITableViewStylePlain,                  // regular table view     UITableViewStyleGrouped           

  • 详解iOS开发中UIPickerView控件的使用方法

    UIPickerView控件在给用户选择某些特定的数据时经常使用到,这里演示一个简单的选择数据,显示在UITextField输入框里,把UIPickerView作为输入View,用Toolbar作为选定数据的按钮.和其他UITableView控件相似,UIPickerView也需要数据源. 我们要实现的效果如下: 下面开始使用的步骤. 1.打开XCode 4.3.2,新建一个Single View Application ,命名为PickerViewDemo,Company Identifier

  • iOS开发中UIDatePicker控件的使用方法简介

    iOS上的选择时间日期的控件是这样的,左边是时间和日期混合,右边是单纯的日期模式. 您可以选择自己需要的模式,Time, Date,Date and Time  , Count Down Timer四种模式. 本篇文章简单介绍下PickerDate控件的使用 1.新建一个Singe View Application,命名为DatePickDemo,其他设置如图 2.放置控件 打开ViewController.xib,拖拽一个DatePicker控件放到界面上,再拖拽一个Button控件放到界面上

  • iOS开发中控制屏幕旋转的编写方法小结

    在iOS5.1 和 之前的版本中, 我们通常利用 shouldAutorotateToInterfaceOrientation: 来单独控制某个UIViewController的旋屏方向支持,比如: 复制代码 代码如下: - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation  {      return (interfaceOrientation == UIInter

  • IOS 开发中发送e-mail的几种方法总结

    iOS系统框架提供的两种发送Email的方法 1.使用openURL来实现发邮件的功能: NSString *url = [NSString stringWithString: @"mailto:foo@example. com?cc=bar@example.com&subject=Greetings%20from%20Cupertino!&body=Wish%20you%20were%20here!"]; [[UIApplication sharedApplicati

随机推荐