【问题标题】:UIVisualEffectView with mask layer带有遮罩层的 UIVisualEffectView
【发布时间】:2016-09-20 13:10:22
【问题描述】:

我正在尝试模糊 MKMapView,同时在其上方显示一个圆形遮罩。为了更好地形象化我的意思,您可以找到我当前状态的图片:

这几乎显示了我想要的,但背景(地图)应该是模糊的,而这张照片中的情况并非如此。我尝试使用 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
}

总结一下我的问题: 如何更改我的代码以模糊地图视图并在其上方显示圆形遮罩?

编辑 刚刚发现,如果我删除添加圆形遮罩的代码,地图视图的模糊就会起作用......也许这对解决这个问题很有意义。

【问题讨论】:

  • 您是否尝试过在 mapView 之上添加视觉效果视图而不是作为子视图?
  • 不确定这是否有用,但是这个家伙已经列出了他的操场代码来做你想做的事:stackoverflow.com/questions/38510476/blur-on-mkmapview
  • 你的意思是而不是 self.mapView.addSubview(blur) 写作 self.view.insertSubview(blur, aboveSubview: self.mapView) ?我试过了,但看不到任何变化。
  • @JackC 这与我的代码基本相同。我刚刚检查过:当我移除圆形遮罩时,地图视图上的模糊效果会起作用。但是如果我添加圆形掩码代码,模糊就消失了......
  • @dehlen 此刻我也在尝试寻找解决方案。))))是的,如果我删除 layer.mask 模糊是有效的,但视觉效果也会在圆圈内添加模糊。

标签: ios swift uivisualeffectview


【解决方案1】:

经过一番挖掘,我现在找到了解决方案。我假设您使用 Xcode 8 作为 layer.mask 有一个已知错误,您不能在同一层上同时拥有模糊和蒙版。

在弄乱了操场之后,我已经解决了问题,因此将尝试调整您的代码以匹配我的解决方案。如果您改用 blurView 的“掩码”属性,那么您应该没有问题。我认为关于 layer.mask 无法正常工作的问题已向 Apple 提交了一个错误报告

最后这是你当前的代码

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

如果您有任何问题,请告诉我!

【讨论】:

  • 这对我帮助很大!
  • 天哪,我一直在寻找这个。像魅力一样工作!
  • 这很棒。谢谢
【解决方案2】:

除了 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
}

【讨论】:

    猜你喜欢
    • 2020-02-17
    • 2019-04-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-20
    • 2011-12-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多