iOS仿擦半透明效果的實現方法_IOS

來源:互聯網
上載者:User

照例先看下效果圖

實現思路

動手前先想了下思路,就是利用母雞哥講的塗鴉 + 設定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開發人員們能有所協助,如果有疑問大家可以留言交流。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.