iOS仿擦玻璃效果的实现方法

照例先看下效果图

实现思路

动手前先想了下思路,就是利用母鸡哥讲的涂鸦 + 设置layer的mask的方式,这样做可以说是非常简单了。然后就用了半下午的时间写完了,效果基本和大神写得那个一样,而且对比了下代码量,我写得真是简单明了呀,用了不到大神代码量一半的代码就完成了同样的功能,心情愉悦。然后我又跑了大神的应用看了看cpu利用率(我用5s跑的),大约最高保持在百分这十几,感觉有点高但也可以,再跑我自己写得,令我大吃了一惊,随便划几下就百分之40+了,这么个小东西耗这么多cpu那这也太low了。。。

bug测试及解决

经过测试,发现是母鸡哥讲的涂鸦有性能问题,虽然代码简单,思路清晰,但是随着触摸屏幕的点不断增加,整个绘制复杂度也是呈指数上升,导致的结果就是耗cpu非常严重。所以关于绘制图片我不得不再想其它的方法实现。但是我冥想了一天时间也没有找到好的方法降低绘制的复杂度(除了大神的那个方法),当然最后的解决方法也非常简单了,没错,就是copy大神的方法。

下面着重介绍下大神的解决涂鸦cpu消耗问题方法(这里是重点):

图形上下文:不再用layer的默认的图形上下文了(也就是在drawRect方法里面用UIGraphicsGetCurrentContext()获取的),而是自己创建一个全局的bitmap上下文

 self.imageContext = CGBitmapContextCreate(0, frame.size.width, frame.size.height, 8, frame.size.width * 4, self.colorSpace, kCGImageAlphaPremultipliedLast);
 CGContextSetStrokeColorWithColor(self.imageContext,[UIColor redColor].CGColor);
 CGContextSetFillColorWithColor(self.imageContext, [UIColor redColor].CGColor);
 CGContextTranslateCTM(self.imageContext, 0.0f, self.bounds.size.height);
 CGContextScaleCTM(self.imageContext, 1.0f, -1.0f);

在触摸屏幕的时候(touchesBegantouchesMoved等方法),根据触摸的位置,每两个点之间连线,绘制到上面建立的图形上下文当中,这样就是随着触摸屏幕,随着往图形上下文绘制,不会把之前已经绘制的再重新添加绘制,解决了性能消耗过高的问题。

#pragma mark - touch
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
 UITouch* touch = [touches anyObject];
 [self reCreateImageWithTouchDict:@{@"touch":touch, @"lineWidth":@(touch.majorRadius)}];
}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
 UITouch* touch = [touches anyObject];
 [self reCreateImageWithTouchDict:@{@"touch":touch, @"lineWidth":@(touch.majorRadius)}];
}

- (UIImage *)reCreateImageWithTouchDict:(NSDictionary *)touchDict{
 UITouch* touch = touchDict[@"touch"];
 CGFloat lineWidth = [touchDict[@"lineWidth"] floatValue] * 0.5;
 if (lineWidth < 1.0) {
  lineWidth = 10;
 }
 if (touch) {
  CGPoint point = [touch locationInView:touch.view];
  if (touch.phase == UITouchPhaseBegan) {
   CGRect rect = CGRectMake(point.x - lineWidth, point.y - lineWidth, lineWidth*2, lineWidth*2);
   CGContextAddEllipseInRect(self.imageContext, rect);
   CGContextFillPath(self.imageContext);
   [self.points removeAllObjects];
   [self.points addObject:[NSValue valueWithCGPoint:point]];
  }else if (touch.phase == UITouchPhaseMoved){
   [self.points addObject:[NSValue valueWithCGPoint:point]];
   if (self.points.count > 2) {
    CGContextSetLineCap(self.imageContext, kCGLineCapRound);
    CGContextSetLineWidth(self.imageContext, 2 * lineWidth);
    do{
     CGPoint point0 = [(NSValue *)self.points[0] CGPointValue];
     CGPoint point1 = [(NSValue *)self.points[1] CGPointValue];
     CGContextMoveToPoint(self.imageContext, point0.x, point0.y);
     CGContextAddLineToPoint(self.imageContext, point1.x, point1.y);
     [self.points removeObjectAtIndex:0];
    }while (self.points.count > 2);
   }
  }
  CGContextStrokePath(self.imageContext);
 }
 CGImageRef cgImage = CGBitmapContextCreateImage(self.imageContext);
 UIImage *image = [UIImage imageWithCGImage:cgImage];
 CGImageRelease(cgImage);
 return image;
}

最后实现

最后设置mask就非常简单了,设置我们将要显示的图片(那张清晰的)的layer的mask为上面通过绘制生成的image的layer,这样只有绘制过的位置才能看到将要显示的图片,功能就完成了,我感觉利用这个小技巧可以做很多有趣的东西(类似刮奖等)

 CALayer *mask = [CALayer layer];
 mask.contents = (id)image.CGImage;
 mask.anchorPoint = CGPointZero;
 mask.frame = self.bounds;
 self.imageView.layer.mask = mask;
 self.imageView.layer.masksToBounds = YES;

最后

别忘记释放相关内存

- (void)dealloc{
 if (_imageContext != NULL) {
  CFRelease(_imageContext);
 }

 if (_colorSpace != NULL) {
  CFRelease(_colorSpace);
 }
}

demo地址:https://github.com/yuchuanfeng/CFScratchViewDemo

总结

以上就是利用iOS模仿擦玻璃效果的全部内容,感兴趣的朋友们可以自己动手操作下,这样才能更利于理解和学习,希望这篇文章对各位iOS开发者们能有所帮助,如果有疑问大家可以留言交流。

(0)

相关推荐

  • iOS开发中实现显示gif图片的方法

    我们知道Gif是由一阵阵画面组成的,而且每一帧画面播放的时常可能会不相等,观察上面两个例子,发现他们都没有对Gif中每一帧的显示时常做处理,这样的结果就是整个Gif中每一帧画面都是以固定的速度向前播放,很显然这并不总会符合需求.   于是自己写一个解析Gif的工具类,解决每一帧画面并遵循每一帧所对应的显示时间进行播放.   程序的思路如下:   1.首先使用ImageIO库中的CGImageSource家在Gif文件.   2.通过CGImageSource获取到Gif文件中的总的帧数,以及每一

  • IOS图片设置毛玻璃效果

    推荐阅读:ios毛玻璃效果的实现及图片模糊效果的三种方法 废话不多说了,直接给大家贴代码了,具体代码如下所示: // 创建需要的毛玻璃特效类型 UIBlurEffect *blurEffect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleLight]; // 毛玻璃view 视图 UIVisualEffectView *effectView = [[UIVisualEffectView alloc] initWithEffect:blurEf

  • iOS文字渐变色效果的实现方法

    照例先上文字渐变的效果图 实现思路如下 一.创建一个颜色渐变层,渐变图层跟文字控件一样大. 二.用文字图层裁剪渐变层,只保留文字部分,就会让渐变层只保留有文字的部分,相当于间接让渐变层显示文字,我们看到的其实是被裁剪过后,渐变层的部分内容. 注意:如果用文字图层裁剪渐变层,文字图层就不在拥有显示功能,这个图层就被弄来裁剪了,不会显示,在下面代码中也会有说明. 2.1 创建一个带有文字的label,label能显示文字. 2.2 设置渐变图层的mask为label图层,就能用文字裁剪渐变图层了.

  • iOS7 毛玻璃特效代码

    原图: 效果图: 实现: 首先需要导入Accelerate.framework. 然后把两个文件加入到自己的项目中即可. UIImage+ImageEffects.h 复制代码 代码如下: #import @interfaceUIImage(ImageEffects) -(UIImage*)applyLightEffect; -(UIImage*)applyExtraLightEffect; -(UIImage*)applyDarkEffect; -(UIImage*)applyTintEffe

  • iOS开发之路--仿网易抽屉效果

    最终效果图: MainStoryBoard示意图: BeyondViewController.h // // BeyondViewController.h // 19_抽屉效果_仿网易 // // Created by beyond on 14-8-1. // Copyright (c) 2014年 com.beyond. All rights reserved. // #import <UIKit/UIKit.h> #import "LeftTableViewControllerD

  • IOS开发代码分享之设置UISearchBar的背景颜色

    今天用到UISearchBar,之前网上提供的方法已经不能有效的去除掉它的背景色了,修改背景色方法如下: mySearchBar.backgroundColor = RGBACOLOR(249,249,249,1);     mySearchBar.backgroundImage = [self imageWithColor:[UIColor clearColor] size:mySearchBar.bounds.size];   //取消searchbar背景色 - (UIImage *)im

  • iOS自定义collectionView实现毛玻璃效果

    先来看看效果图,由于录屏软件不给力,毛玻璃效果不明显,请见谅. 步骤详解: 说下思路,很简单,首先自定义一个collectionView, 重写它的initWithFrame:collectionViewLayout:方法,在这里面做配置,这里用的是AXECollectionView. 与之对应的自定义一个collectionViewCell,在cell里配置操作:设置layer涂层,加载图片等操作,这里用的是AXECollectionViewCell. 最后在需要展示的控制器里调用AXECol

  • js和html5实现手机端刮刮卡抽奖效果完美兼容android/IOS

    绝对值得看的来篇,哈哈.本人亲自完成,有错误请大家指出: 现在的手机完美支持html5,所以如果手机端想要做个抽奖模块的话,用刮刮卡抽奖效果,相信这个互动体验是非常棒的 ​ps:由于本人没有wp8系统的手机,所以没法兼容wp8系统的,目前完美兼容android,IOS 如果要在pc浏览的话,得改下js,目前支持谷歌,火狐,ie>=10,如果网友想要的话我就去写个 代码如下: 复制代码 代码如下: <!DOCTYPE html> <html lang="en"&g

  • iOS开发中WebView的基本使用方法简介

    1.使用UIWebView加载网页 运行XCode 4.3,新建一个Single View Application,命名为WebViewDemo. 2.加载WebView 在ViewController.h添加WebView成员变量和在ViewController.m添加实现 复制代码 代码如下: #import <UIKit/UIKit.h> @interface ViewController : UIViewController {     UIWebView *webView; } @e

  • iOS毛玻璃效果的实现及图片模糊效果的三种方法

    App设计时往往会用到一些模糊效果或者毛玻璃效果,iOS目前已提供一些模糊API可以让我们方便是使用. 话说苹果在iOS7.0之后,很多系统界面都使用了毛玻璃效果,增加了界面的美观性,比如下图的通知中心界面; 但是其iOS7.0的SDK并没有提供给开发者实现毛玻璃效果的API,所以很多人都是通过一些别人封装的框架来实现,后面我也会讲到一个; 其实在iOS7.0(包括)之前还是有系统的类可以实现毛玻璃效果的, 就是 UIToolbar这个类,并且使用相当简单,几行代码就可以搞定. 下面是代码实现:

随机推荐