2015-12-01 23 views
2

我期待在我的視圖中創建一個像幾個圓形的面具。這裏blurView是我想要刪除的視圖,並且frames包含CGRect這些圓圈/橢圓的幀值。結合重疊UIBezierPaths來創建一個單一的面具

let holes = UIBezierPath() 
for f in frames { 
     let p = UIBezierPath(ovalInRect: f) 
     holes.appendPath(p) 
} 

let path = UIBezierPath(rect: blurView.bounds) 
path.appendPath(holes) 
path.usesEvenOddFillRule = true 
let mask = CAShapeLayer() 
mask.path = path.CGPath 
mask.fillRule = kCAFillRuleEvenOdd 
blurView.layer.mask = mask 

這工作得很好,除了當圓重疊的blurView的內容會透過,而不是它下面的視圖。我該如何解決這個問題?

編輯:使用羅布的回答,我得到了某個地方,但不是我想要的地方。面膜的邊緣參差不齊,缺乏抗鋸齒:

screenshot

任何方式來解決呢?

+0

也許你可以包括屏幕截圖:

,如果你喜歡,你可以複製到操場呢? – beyowulf

回答

1

基本的想法是用不透明的顏色填充位圖上下文,然後清除我們想要剪切的任何東西。獲取該位圖上下文的圖像並用作掩碼。

import UIKit 

// A couple of overlapping circles to play with 
let frames = [ 
    CGRect(x: 100, y: 100, width: 200, height: 200), 
    CGRect(x: 50, y: 50, width: 200, height: 200) 
] 

let blurView = UIImageView(image: ...) // <== You can drag an image here. Literals are cool. 

let size = blurView.bounds.size 
let scale = UIScreen.mainScreen().scale 

// First, create a bitmap context to work in. 
let bitmapInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.PremultipliedFirst.rawValue | CGBitmapInfo.ByteOrder32Little.rawValue) 
let ctx = CGBitmapContextCreate(nil, Int(size.width*scale), Int(size.height*scale), 
8, 4 * Int(size.width * scale), CGColorSpaceCreateDeviceRGB(), bitmapInfo.rawValue) 
CGContextScaleCTM(ctx, scale, scale) 

// iOS draws upsidedown from Core Graphics, so you'll probably want to flip your context: 
CGContextConcatCTM(ctx, CGAffineTransformMake(1, 0, 0, -1, 0, size.height)) 

// Everything we want to draw should be opaque 
// Everything we want to clip should be translucent 

CGContextSetGrayFillColor(ctx, 1, 1) // white 
CGContextFillRect(ctx, blurView.bounds) 

// And now we clear all our circles 
CGContextSetBlendMode(ctx, .Clear) 
CGContextSetGrayFillColor(ctx, 1, 0) // clear 
for f in frames { 
    CGContextFillEllipseInRect(ctx, f) 
} 

// Make the masking image 
let maskImage = CGBitmapContextCreateImage(ctx) 

// For your playground amusement (you can quicklook this line) 
UIImage(CGImage: maskImage) 

// Create the masking layer 
let mask = CALayer() 
mask.frame = blurView.layer.frame 
mask.contents = maskImage 

// And apply it 
blurView.layer.mask = mask 

// And the final so you can quicklook it 
blurView 

enter image description here

+0

我擔心它會是這樣的。奇怪的是,我打算在photoshop中做出「這就是我得到的」和「這是我想要的」演示,但無法模仿「這就是我得到的」部分(理所當然,我不是一個在Photoshop中的親),它只是將事情合併到我想要的東西中。與iOS相比完全倒退。 :) – SaltyNuts

+0

感謝您的幫助,這絕對是一個地方。雖然這個代碼有幾個問題。其一是視網膜上看起來不太好 - 但這很容易解決。另一個是,面具的邊緣看起來太尖銳,沒有對圓圈進行抗鋸齒。有沒有辦法在? – SaltyNuts

+0

請參閱文檔'CALayer.allowsEdgeAntialiasing'作爲開始。不過,我不知道你是否可以將抗鋸齒技術應用於口罩。 –

相關問題