按例先看下後果圖
完成思緒
著手前先想了下思緒,就是應用母雞哥講的塗鴉 + 設置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);
在觸摸屏幕的時刻(touchesBegan
、touchesMoved
等辦法),依據觸摸的地位,每兩個點之間連線,繪制到下面樹立的圖形高低文傍邊,如許就是跟著觸摸屏幕,跟著往圖形高低文繪制,不會把之前曾經繪制的再從新添加繪制,處理了機能消費太高的成績。
#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); CGContextAddL.netoPoint(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開辟者們能有所贊助,假如有疑問年夜家可以留言交換。
【iOS仿擦玻璃後果的完成辦法】的相關資料介紹到這裡,希望對您有所幫助! 提示:不會對讀者因本文所帶來的任何損失負責。如果您支持就請把本站添加至收藏夾哦!