web-dev-qa-db-ja.com

マスクレイヤーを使用したUIVisualEffectView

MKMapViewをぼかしながら、その上にサークルマスクを表示しようとしています。これが何を意味するのかをよりよく視覚化するために、添付されている私の現在の状態の画像を見つけることができます。

Current State

これは私が望むものをほぼ示していますが、背景(地図)はぼやけているはずですが、この写真ではそうではありません。 UIVisualEffectViewを操作しようとしましたが、そこで何か問題が発生しているようです。これが私が試したものです:

func createOverlay(at: CGPoint) {
    var blur: UIView!
    blur = UIVisualEffectView (effect: UIBlurEffect (style: UIBlurEffectStyle.dark))

    blur.frame = self.mapView.frame
    blur.isUserInteractionEnabled = false
    self.mapView.addSubview(blur)

    let circleSize: CGFloat = 200

    let path = UIBezierPath (
        roundedRect: blur.frame,
        cornerRadius: 0)

    let circle = UIBezierPath (
        roundedRect: CGRect (Origin: CGPoint(x:at.x - circleSize/2, y: at.y-circleSize/2),
                             size: CGSize (width: circleSize, height: circleSize)), cornerRadius: circleSize/2)

    path.append(circle)
    path.usesEvenOddFillRule = true

    let maskLayer = CAShapeLayer()
    maskLayer.path = path.cgPath
    maskLayer.fillRule = kCAFillRuleEvenOdd

    let borderLayer = CAShapeLayer()
    borderLayer.path = circle.cgPath
    borderLayer.strokeColor = UIColor.white.cgColor
    borderLayer.lineWidth = 10
    blur.layer.addSublayer(borderLayer)

    blur.layer.mask = maskLayer
}

ここに要約すると、私の質問です:マップビューをぼかし、その上に円マスクを表示するには、コードを変更する必要がありますか?

[〜#〜] edit [〜#〜]コードを削除してサークルマスクを追加すると、マップビューのぼかしが機能することがわかりました。 ..多分これはこの問題を解決するために興味があります。

15
dehlen

少し掘り下げて解決策を見つけました。 Xcode 8をlayer.maskとして使用していると仮定すると、同じレイヤーにぼかしとマスクの両方を配置できないという既知のバグがあります。

遊び場をいじった後、私は問題を修正したので、私の解決策に一致するようにコードを適応させようとします。代わりにblurViewの「mask」プロパティを使用する場合は、問題はありません。 Apple layer.maskが機能しないことに関して私は信じています

これは最後の現在のコードです

let maskLayer = CAShapeLayer()
maskLayer.path = path.cgPath
maskLayer.fillRule = kCAFillRuleEvenOdd

let borderLayer = CAShapeLayer()
borderLayer.path = circle.cgPath
borderLayer.strokeColor = UIColor.white.cgColor
borderLayer.lineWidth = 10
blur.layer.addSublayer(borderLayer)

blur.layer.mask = maskLayer

これの代わりに、以下を使用してみてください。

let maskLayer = CAShapeLayer()
maskLayer.path = path.cgPath
maskLayer.fillRule = kCAFillRuleEvenOdd

let borderLayer = CAShapeLayer()
borderLayer.path = circle.cgPath
borderLayer.strokeColor = UIColor.white.cgColor
borderLayer.fillColor = UIColor.clear.cgColor //Remember this line, it caused me some issues
borderLayer.lineWidth = 10

let maskView = UIView(frame: self.view.frame)
maskView.backgroundColor = UIColor.black
maskView.layer.mask = maskLayer

blur.layer.addSublayer(borderLayer)
blur.mask = maskView

何か問題があれば教えてください!

19
Jack Chorley

Jackのソリューションに加えて、iOSが11を超える場合は、blur.layer.maskをmaskLayerに設定するだけです。

if #available(iOS 11.0, *) {
    blur.layer.mask = maskLayer
} else {
    let maskView = UIView(frame: self.view.frame)
    maskView.backgroundColor = UIColor.black
    maskView.layer.mask = borderLayer
    blur.mask = maskView
}
2