我创建了 Blurable 协议,扩展程序具有模糊功能。
protocol Blurable {}
extension Blurable where Self: UIView {
func blur(with effect: UIBlurEffectStyle) {
let blurEffect = UIBlurEffect(style: effect)
let blurEffectView = UIVisualEffectView(effect: blurEffect)
blurEffectView.frame = bounds
addSubview(blurEffectView)
}
}
现在我要添加 unblur 功能。 如果它是一个类我将 blurEffectView 作为类属性并创建 unblur 函数,如下所示:
func unblur() {
blurEffectView.removeFromSuperview
}
由于协议扩展不允许存储属性,这个问题的正确解决方案是什么?
答案 0 :(得分:1)
您可以在协议声明中保留变量。
protocol Blurable: class {
var blurEffectView: UIVisualEffectView? { set get }
func applyBlur(with effect: UIBlurEffectStyle)
func removeBlur()
}
private var xoAssociationKey: UInt8 = 0
extension Blurable where Self: UIView {
// If you want to avoid adding "blurEffectView" to each UIView class,
// you can do it this way
var blurEffectView: UIVisualEffectView? {
get {
return objc_getAssociatedObject(self, &xoAssociationKey) as? UIVisualEffectView
}
set(newBlurEffectView) {
objc_setAssociatedObject(self, &xoAssociationKey, newBlurEffectView, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN)
}
}
func applyBlur(with effect: UIBlurEffectStyle) {
let blurEffect = UIBlurEffect(style: effect)
blurEffectView = UIVisualEffectView(effect: blurEffect)
blurEffectView?.frame = bounds
if let blurEffectView = blurEffectView { addSubview(blurEffectView) }
}
func removeBlur() {
if let blurEffectView = blurEffectView {
blurEffectView.removeFromSuperview()
}
blurEffectView = nil
}
}
这应该有效。您可以将blurEffectView保持为非可选变量,但此解决方案在将来的更改中更安全有效,因为您可以以编程方式检查是否应用了模糊。
var someView = SomeView()
if let _ = someView.blurEffectView {
print("YEAP")
} else {
print("NOPE")
}
答案 1 :(得分:0)
我用过这个 -
extension UIView {
func blur() {
let blurEffect = UIBlurEffect(style: .light)
let blurEffectView = UIVisualEffectView(effect: blurEffect)
blurEffectView.frame = self.bounds
blurEffectView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
self.addSubview(blurEffectView)
}
func unBlur() {
for subview in self.subviews {
if subview is UIVisualEffectView {
subview.removeFromSuperview()
}
}
}
}
您还可以添加标记并通过检查其标记来删除视图,但我觉得这是一个更好的选择。也可以使用扩展程序here。