[ios]ios-Demo4脱衣服/刮奖app-专业
普通版本完成的锯齿很严重 但是Ios系统中仅CGContextClearRect 并不存在cyclo等方法。 网上查了一些资料。 发现还是利用到了CG 中的Mask来实现
效果图:
这种效果可以自定义画笔的粗细等相关设置,不会像普通模式中出现比较严重的锯齿。
具体分析如下:
1.获取需要隐藏View的layer的CGImageRef用于后面配合掩码
2.开辟符合1的CGImageRef的CFMutableDataRef空间 给下面的掩码BitmapContext使用
3.通过CFMutableDataRef获得CGDataProviderRef (maskCreate用到)
3.BitmapContextCreate
4.BitmapContext填充黑色 并且设置画笔相关(白色,宽度,线帽(cap))
5.CGImageMaskCreate 将CGDataProviderRef 传入 则得到CGImageRef指向的是刚才创建BitmapContext。改变BitmapContext 则此CGImageRef内容也会改变
6.CGImageCreateWithMask - 通过Mask的CGImageRef创建CGImageRef 此CGImageRef随 Maskde CGImageRef变化(所以 BitmapContext改变 Mask改变 mask掩码后的CGImageRef改变)
7.释放
8.手指触摸时,根据上一个CGPoint 和此次的CGPoint 给bitmapContext新增path 并且绘制。然后调用【self setNeedsDisplay】,在重绘中(-drawRect) 重新获取通过mask后的CGImageRef 获取最新的UIImage
9.将最新的UIImage drawRect到界面
代码:
//
// PLLScrathView.h
// PLLScratchViewDemo
//
// Created by liu poolo on 14-7-31.
// Copyright (c) 2014年 liu poolo. All rights reserved.
//
#import <UIKit/UIKit.h>
#import <QuartzCore/QuartzCore.h>
@interface PLLScratchView : UIView
@property (nonatomic,assign) float sizeBrush;
-(void)setHideView:(UIView*) hideView;
@end
//
// PLLScrathView.m
// PLLScratchViewDemo
//
// Created by liu poolo on 14-7-31.
// Copyright (c) 2014年 liu poolo. All rights reserved.
//
#import "PLLScratchView.h"
@interface PLLScratchView(){
CGContextRef _contextMask;//maskContext 用户touch 改变的context
CGImageRef _scratchCGImg;//CGimageRef 封装_contextMask 图片信息 _contextMask改变 跟着改变 直到 调用生成UIImage
CGPoint currPonit;
CGPoint prePoint;
}
@end
@implementation PLLScratchView
@synthesize sizeBrush;
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
[self setOpaque:NO];
//设置透明 如果不透明就没法看到下一层了
self.sizeBrush=10.0f;
}
return self;
}
- (void)drawRect:(CGRect)rect
{
[super drawRect:rect];
UIImage* imageToDraw=[UIImage imageWithCGImage:_scratchCGImg];
[imageToDraw drawInRect:self.frame];
}
//setSizeBrush before setHideView
-(void)setHideView:(UIView*) hideView{
CGColorSpaceRef colorSpace=CGColorSpaceCreateDeviceGray();
CGFloat scale = [UIScreen mainScreen].scale;
//获得当前传入View的CGImage
UIGraphicsBeginImageContextWithOptions(hideView.bounds.size, NO, 0);
hideView.layer.contentsScale=scale;
[hideView.layer renderInContext:UIGraphicsGetCurrentContext()];
CGImageRef hideCGImg=UIGraphicsGetImageFromCurrentImageContext().CGImage;
UIGraphicsEndImageContext();
//绘制Bitmap掩码
size_t width=CGImageGetWidth(hideCGImg);
size_t height=CGImageGetHeight(hideCGImg);
CFMutableDataRef pixels;
pixels=CFDataCreateMutable(NULL, width*height);
//创建一个可变的dataRef 用于bitmap存储记录
_contextMask = CGBitmapContextCreate(CFDataGetMutableBytePtr(pixels), width, height , 8, width, colorSpace, kCGImageAlphaNone);
//数据提供者
CGDataProviderRef dataProvider=CGDataProviderCreateWithCFData(pixels);
//填充黑色背景 mask中黑色范围为显示内容 白色为不显示
CGContextSetFillColorWithColor(_contextMask, [UIColor blackColor].CGColor);
CGContextFillRect(_contextMask, self.frame);
CGContextSetStrokeColorWithColor(_contextMask, [UIColor whiteColor].CGColor);
CGContextSetLineWidth(_contextMask, self.sizeBrush);
CGContextSetLineCap(_contextMask, kCGLineCapRound);
CGImageRef mask=CGImageMaskCreate(width, height, 8, 8, width, dataProvider, nil, NO);
_scratchCGImg=CGImageCreateWithMask(hideCGImg, mask);
CGImageRelease(mask);
CGColorSpaceRelease(colorSpace);
}
-(void)scratchViewFrom:(CGPoint)startPoint toEnd:(CGPoint)endPoint{
float scale=[UIScreen mainScreen].scale;
//CG的Y与UI的是反的 UI的y0在左上角 CG在左下
CGContextMoveToPoint(_contextMask, startPoint.x*scale, (self.frame.size.height-startPoint.y)*scale);
CGContextAddLineToPoint(_contextMask, endPoint.x*scale,(self.frame.size.height-endPoint.y)*scale);
CGContextStrokePath(_contextMask);
[self setNeedsDisplay];
}
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
[super touchesBegan:touches withEvent:event];
}
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
[super touchesMoved:touches withEvent:event];
UITouch *touch=[touches anyObject];
currPonit=[touch locationInView:self];
prePoint=[touch previousLocationInView:self];
[self scratchViewFrom:prePoint toEnd:currPonit];
}
-(void)toucheseEnd:(NSSet *)touches withEvent:(UIEvent *)event{
[super touchesEnded:touches withEvent:event];
UITouch *touch=[touches anyObject];
currPonit=[touch locationInView:self];
prePoint=[touch previousLocationInView:self];
[self scratchViewFrom:prePoint toEnd:currPonit];
}
-(void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event{
[super touchesCancelled:touches withEvent:event];
}
@end
- 大小: 566.6 KB
[ios]ios-Demo4脱衣服/刮奖app-专业的更多相关文章
- iOS 制作发布证书,发布到App Store
---恢复内容开始--- 1.登陆 iOS Dev Center 选择进入iOS Provisioning Portal. 2.在 iOS Provisioning Portal中,点击App IDs ...
- Xamarin.iOS - 利用Settings插件与EAIntroView制作App的欢迎界面
Xamarin.iOS - 利用Settings插件与EAIntroView制作App的欢迎界面 关于欢迎界面 很多App第一次启动都会有一个欢迎界面,欢迎界面往往决定这用户对App的第一映像,所以欢 ...
- iOS利用Application Loader打包提交到App Store时遇到错误The filename 未命名.ipa in the package contains an invalid character(s). The valid characters are:A-Z ,a-z,0-9,dash,period,underscore,but the name cannot start w
iOS利用Application Loader打包提交到App Store时遇到错误: The filename 未命名.ipa in the package contains an invalid ...
- iOS自定义弹出视图、收音机APP、图片涂鸦、加载刷新、文件缓存等源码
iOS精选源码 一款优秀的 聆听夜空FM 源码 zhPopupController 简单快捷弹出自定义视图 WHStoryMaker搭建美图(贴纸,涂鸦,文字,滤镜) iOS cell高度自适应 有加 ...
- iOS remote debug & Android remote debug & Chrome & APP
iOS remote debug & Android remote debug & Chrome & APP iOS remote debugging 如何在 iOS 真机上调 ...
- IOS小组件(8):App与Widget数据共享
引言 Widget是一个迷你版的App,IOS有沙盒机制,不同App之间无法直接共享数据.组件和主App之间其实就是不同App的关系,所以也无法通过userdefaults.standard来传数 ...
- Android项目刮刮奖详解扩展篇——开源刮刮奖View的制作
Android项目刮刮奖详解(四) 前言 我们已经成功实现了刮刮奖的功能了,本期是扩展篇,我们把这个View直接定义成开源控件,发布到JitPack上,以后有需要也可以直接使用,关于自定义控件的知识, ...
- Android项目刮刮奖详解(三)
Android项目刮刮奖详解(二) 前言 上一期我们已经实现了一个简易的刮刮卡功能,这一期我们来将其完善一下 目标 将刮刮奖的宽高改为合适高度 将刮刮奖位置居中 将信息层的图片换成文字(重点) 实现 ...
- 简单入门canvas - 通过刮奖效果来学习
一 .前言 一直在做PC端的前端开发,从互联网到行业软件.最近发现移动端已经成为前端必备技能了,真是不能停止学习.HTML5新增的一些东西,canvas是用的比较多也比较复杂的一个,简单的入门了一下, ...
随机推荐
- Ax Lookup Form
Reference: Class\sysLookupTable 1. 用临时表构造Lookup下拉结果,sysLookupTable有一个parmTmpBuffer方法,表明传入展示的结果集是临时表 ...
- C# 反射操作方法
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.R ...
- Linux:两台服务器之间添加信任关系,进行远程操作的时候不需要输入密码
两台机器之间建立信任关系的步骤: 1. 在机器1上root用户执行ssh-keygen命令,生成建立安全信任关系的证书,直接Enter [root@CentOS64-x64 ~]# ssh-keyge ...
- 现代福尔摩斯 - Oxygen Forensic Suite
各位可曾听说过智能手机取证软件Oxygen Forensic Suite,它的logo是名侦探福尔摩斯一手抽着他的招牌雪茄,一手拿着放大镜,全神贯注地正进行调查工作. 使用过它的取证人员必定会对它的提 ...
- ASP.NET(C#)--Repeater中生成“序号”列
需求介绍:在Repeater(Table)中加入“序号”列,从1开始自增,步长为1. 思路:因为“序号”跟Repeater的行号有关,所以要在Repeater的ItemDataBound事件中输出“序 ...
- XML内容作为String字符串读取报错
解决方案: 1.把头信息<?xml version='1.0' encoding='UTF-8'?>,但是内容会丢失部分: 2.用XmlDocument解析就OK. 正确代码: ...
- CSS中属性position位置详解功能讲解与实例分析
position有五个值:static.relative.absolute.fixed.inherit. static 是默认值.就是按正常的布局流从上到下从左到右布局,平常我们做网页制作时,没有指定 ...
- c3p0配置xml
c3p0-config.xml <c3p0-config> <default-config> <property name="automaticTestTabl ...
- NSDateFormatter中时间格式串的含义
a: AM/PM (上午/下午) A: 0~86399999 (一天的第A微秒) c/cc: 1~7 (一周的第一天, 周天为1) ccc: Sun/Mon/Tue/Wed/Thu/Fri/Sat ( ...
- C#路径 (转载)
一.获取当前文件的路径1. System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName 获取模块的完整路径,包括文 ...