在 iOS 10 中你必须使用mask
的财产UIVisualEffectView
代替CALayer
's mask
.
我在 iOS 10 或 Xcode 8 的一些早期测试版的发行说明中看到了这一点,但我现在找不到这些说明:)。一旦找到正确的链接,我将立即更新我的答案。
下面是适用于 iOS 10/Xcode 8 的代码:
class ViewController: UIViewController {
@IBOutlet var blurView: UIVisualEffectView!
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
updateBlurViewHole()
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
updateBlurViewHole()
}
func updateBlurViewHole() {
let maskView = UIView(frame: blurView.bounds)
maskView.clipsToBounds = true;
maskView.backgroundColor = UIColor.clear
let outerbezierPath = UIBezierPath.init(roundedRect: blurView.bounds, cornerRadius: 0)
let rect = CGRect(x: 150, y: 150, width: 100, height: 100)
let innerCirclepath = UIBezierPath.init(roundedRect:rect, cornerRadius:rect.height * 0.5)
outerbezierPath.append(innerCirclepath)
outerbezierPath.usesEvenOddFillRule = true
let fillLayer = CAShapeLayer()
fillLayer.fillRule = kCAFillRuleEvenOdd
fillLayer.fillColor = UIColor.green.cgColor // any opaque color would work
fillLayer.path = outerbezierPath.cgPath
maskView.layer.addSublayer(fillLayer)
blurView.mask = maskView;
}
}
斯威夫特2.3版本:
class ViewController: UIViewController {
@IBOutlet var blurView: UIVisualEffectView!
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
updateBlurViewHole()
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
updateBlurViewHole()
}
func updateBlurViewHole() {
let maskView = UIView(frame: blurView.bounds)
maskView.clipsToBounds = true;
maskView.backgroundColor = UIColor.clearColor()
let outerbezierPath = UIBezierPath.init(roundedRect: blurView.bounds, cornerRadius: 0)
let rect = CGRect(x: 150, y: 150, width: 100, height: 100)
let innerCirclepath = UIBezierPath.init(roundedRect:rect, cornerRadius:rect.height * 0.5)
outerbezierPath.appendPath(innerCirclepath)
outerbezierPath.usesEvenOddFillRule = true
let fillLayer = CAShapeLayer()
fillLayer.fillRule = kCAFillRuleEvenOdd
fillLayer.fillColor = UIColor.greenColor().CGColor
fillLayer.path = outerbezierPath.CGPath
maskView.layer.addSublayer(fillLayer)
blurView.maskView = maskView
}
}
UPDATE
嗯,这是 Apple 开发者论坛的讨论,而不是 iOS 发行说明。但苹果代表已经给出了答案,所以我认为,这个信息可能被认为是“官方”的。
讨论链接:https://forums.developer.apple.com/thread/50854#157782 https://forums.developer.apple.com/thread/50854#157782
遮蔽视觉效果视图的图层并不能保证产生
正确的结果 – 在某些情况下,在 iOS 9 上它会产生
效果看起来正确,但可能来源错误的内容。
视觉效果视图将不再来源错误的内容,而是
屏蔽视图的唯一受支持的方法是使用cornerRadius
直接在视觉效果视图的图层上(这应该产生
与您在此处尝试的结果相同)或使用视觉效果
视图的 maskView 属性。