gpt4 book ai didi

ios - 在 UIBlurEffect 上画洞

转载 作者:IT王子 更新时间:2023-10-29 05:48:34 37 4
gpt4 key购买 nike

Xcode 8.0 - Swift 2.3
我有一个内部扩展来创建效果很好的模糊层:

internal extension UIView {

/**
Add and display on current view a blur effect.
*/
internal func addBlurEffect(style style: UIBlurEffectStyle = .ExtraLight, atPosition position: Int = -1) -> UIView {
// Blur Effect
let blurEffectView = self.createBlurEffect(style: style)
if position >= 0 {
self.insertSubview(blurEffectView, atIndex: position)
} else {
self.addSubview(blurEffectView)
}
return blurEffectView
}

internal func createBlurEffect(style style: UIBlurEffectStyle = .ExtraLight) -> UIView {
let blurEffect = UIBlurEffect(style: style)
let blurEffectView = UIVisualEffectView(effect: blurEffect)
blurEffectView.frame = self.bounds
blurEffectView.autoresizingMask = [.FlexibleWidth, .FlexibleHeight]
return blurEffectView
}

}

问题是:如何在模糊叠加层中添加异形孔?我做了很多尝试:

let p = UIBezierPath(roundedRect: CGRectMake(0.0, 0.0, self.viewBlur!.frame.width, self.viewBlur!.frame.height), cornerRadius: 0.0)
p.usesEvenOddFillRule = true
let f = CAShapeLayer()
f.fillColor = UIColor.redColor().CGColor
f.opacity = 0.5
f.fillRule = kCAFillRuleEvenOdd
p.appendPath(self.holePath)
f.path = p.CGPath
self.viewBlur!.layer.addSublayer(f)

但结果是:

enter image description here

我不明白为什么孔在 UIVisualEffectView 上可以,但在 _UIVisualEffectBackdropView 上不行

更新

我尝试了@Arun 解决方案(使用 UIBlurEffectStyle.Dark),但结果不一样:

enter image description here

更新 2

使用@Dim_ov 的解决方案,我有: enter image description here

为了完成这项工作,我需要以这种方式隐藏 _UIVisualEffectBackdropView:

    for v in effect.subviews {
if let filterView = NSClassFromString("_UIVisualEffectBackdropView") {
if v.isKindOfClass(filterView) {
v.hidden = true
}
}
}

最佳答案

在 iOS 10 中,您必须使用 UIVisualEffectViewmask 属性,而不是 CALayermask

我在 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;
}
}

swift 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
}
}

更新

好吧,这是 Apple 开发者论坛的讨论,而不是 iOS 发行说明。但是有苹果代表的回答,所以我认为,这个信息可以被认为是“官方”。

讨论链接:https://forums.developer.apple.com/thread/50854#157782

Masking the layer of a visual effect view is not guaranteed to produce the correct results – in some cases on iOS 9 it would produce an effect that looked correct, but potentially sourced the wrong content. Visual effect view will no longer source the incorrect content, but the only supported way to mask the view is to either use cornerRadius directly on the visual effect view’s layer (which should produce the same result as you are attempting here) or to use the visual effect view’s maskView property.

enter image description here

关于ios - 在 UIBlurEffect 上画洞,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40256942/

37 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com