带有遮罩层的 UIVisualEffectView
UIVisualEffectView with mask layer
我正在尝试模糊 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
}
总结一下我的问题:
如何更改我的代码才能模糊地图视图并在其上方显示圆圈掩码?
编辑
刚发现如果我删除添加圆形遮罩的代码,地图视图的模糊会起作用...也许这对解决这个问题有任何好处。
经过一番研究,我现在找到了解决方案。我假设您使用的是 Xcode 8,因为 layer.mask 有一个已知错误,您不能在同一层上同时使用模糊和蒙版。
在弄乱了 playground 之后,我已经解决了这个问题,因此将尝试调整您的代码以匹配我的解决方案。如果您改用 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
如果您有任何问题,请告诉我!
除了 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
}
我正在尝试模糊 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
}
总结一下我的问题: 如何更改我的代码才能模糊地图视图并在其上方显示圆圈掩码?
编辑 刚发现如果我删除添加圆形遮罩的代码,地图视图的模糊会起作用...也许这对解决这个问题有任何好处。
经过一番研究,我现在找到了解决方案。我假设您使用的是 Xcode 8,因为 layer.mask 有一个已知错误,您不能在同一层上同时使用模糊和蒙版。
在弄乱了 playground 之后,我已经解决了这个问题,因此将尝试调整您的代码以匹配我的解决方案。如果您改用 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
如果您有任何问题,请告诉我!
除了 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
}