在 UIButton 上的透明 imageView 图像后面插入 UIVisualEffectView
Inserting a UIVisualEffectView behind an transparent imageView Image on a UIButton
我正在尝试创建一个背景清晰的按钮,按钮上的透明图像后面有一个 UIVisualEffectView
。 myButton.imageView.image
有一个图像集 (myPNGWithTransparentBackground
)。
我认为这会很简单,但事实证明它比我想象的要难...这是我尝试过的方法:
let frost = UIVisualEffectView(effect: UIBlurEffect(style: .light))
frost.frame = button.bounds
frost.autoresizingMask = [.flexibleWidth, .flexibleHeight]
// button.insertSubview(frost, at: 0)
// button.insertSubview(frost, at: button.subviews.startIndex)
// button.insertSubview(frost, at: button.subviews.endIndex)
// button.imageView?.insertSubview(frost, at: (button.imageView?.subviews.endIndex)!)
button.imageView?.insertSubview(frost, at: (button.imageView?.subviews.startIndex)!)
无论我把 insertSubview
放在哪里,它总是在 UIButton 的 imageView.image 之前结束。
更新
Here's a Git repo 我试过的。子类称为 "FrostyButton".
查看演示项目后,您似乎需要在 UIButton 图像的顶部 添加一个 imageView 。这是我调整后的代码 - 请随时根据需要清理它!
private var imageView2 = UIImageView() // declared globally
private func makeItFrosty() {
let frost = UIVisualEffectView(effect: UIBlurEffect(style: .light))
frost.frame = self.bounds
frost.autoresizingMask = [.flexibleWidth, .flexibleHeight]
if let imageView = imageView {
imageView.addSubview(frost)
// these three lines basically 'clone' the existing imageView and adds it on top of the 'frost' view
imageView2.image = imageView.image
imageView2.frame = imageView.frame
self.addSubview(imageView2)
}
}
我对您需要做这样的事情并不感到惊讶 - UIButton 图像可能已深深嵌入 "bring to front"。
不确定问题出在哪里,但我的自定义按钮 class 可以正常工作...我试图将按钮与一些原始 UIView 匹配,但调整 UIView 背景上的 alpha 并没有效果它。这是我想出的class。
我最后把我的 UIVisualEffectView
放在了 UIView
里面,我把它卡在了按钮里面。 isEnabled
在可见和不可见之间切换。我在有多个按钮的 class 中使用它,一次只有一个按钮运行。
import UIKit
@IBDesignable class FrostyButton: UIButton {
@IBInspectable override var isEnabled: Bool {
didSet {
if isEnabled {
self.visualEffectContainer.alpha = 1.0
}
else {
let animator = UIViewPropertyAnimator(duration: 0.5, curve: .linear, animations: {
self.visualEffectContainer.alpha = 0.0
})
animator.startAnimation()
}
}
}
@IBInspectable var cornerRadius: CGFloat {
get {
return layer.cornerRadius
}
set {
layer.cornerRadius = newValue
layer.masksToBounds = newValue > 0
}
}
private let visualEffectContainer = UIView()
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.backgroundColor = .clear
makeItFrosty()
}
override init(frame: CGRect) {
super.init(frame: frame)
}
override func prepareForInterfaceBuilder() {
super.prepareForInterfaceBuilder()
}
private func makeItFrosty() {
let effectView = UIVisualEffectView(effect: UIBlurEffect(style: .light))
effectView.frame = self.bounds
effectView.clipsToBounds = true
effectView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
visualEffectContainer.frame = self.bounds
visualEffectContainer.clipsToBounds = true
visualEffectContainer.autoresizingMask = [.flexibleWidth, .flexibleHeight]
visualEffectContainer.addSubview(effectView)
visualEffectContainer.isUserInteractionEnabled = false
if imageView != nil {
self.insertSubview(visualEffectContainer, at: 0)
}
}
}
我正在尝试创建一个背景清晰的按钮,按钮上的透明图像后面有一个 UIVisualEffectView
。 myButton.imageView.image
有一个图像集 (myPNGWithTransparentBackground
)。
我认为这会很简单,但事实证明它比我想象的要难...这是我尝试过的方法:
let frost = UIVisualEffectView(effect: UIBlurEffect(style: .light))
frost.frame = button.bounds
frost.autoresizingMask = [.flexibleWidth, .flexibleHeight]
// button.insertSubview(frost, at: 0)
// button.insertSubview(frost, at: button.subviews.startIndex)
// button.insertSubview(frost, at: button.subviews.endIndex)
// button.imageView?.insertSubview(frost, at: (button.imageView?.subviews.endIndex)!)
button.imageView?.insertSubview(frost, at: (button.imageView?.subviews.startIndex)!)
无论我把 insertSubview
放在哪里,它总是在 UIButton 的 imageView.image 之前结束。
更新
Here's a Git repo 我试过的。子类称为 "FrostyButton".
查看演示项目后,您似乎需要在 UIButton 图像的顶部 添加一个 imageView 。这是我调整后的代码 - 请随时根据需要清理它!
private var imageView2 = UIImageView() // declared globally
private func makeItFrosty() {
let frost = UIVisualEffectView(effect: UIBlurEffect(style: .light))
frost.frame = self.bounds
frost.autoresizingMask = [.flexibleWidth, .flexibleHeight]
if let imageView = imageView {
imageView.addSubview(frost)
// these three lines basically 'clone' the existing imageView and adds it on top of the 'frost' view
imageView2.image = imageView.image
imageView2.frame = imageView.frame
self.addSubview(imageView2)
}
}
我对您需要做这样的事情并不感到惊讶 - UIButton 图像可能已深深嵌入 "bring to front"。
不确定问题出在哪里,但我的自定义按钮 class 可以正常工作...我试图将按钮与一些原始 UIView 匹配,但调整 UIView 背景上的 alpha 并没有效果它。这是我想出的class。
我最后把我的 UIVisualEffectView
放在了 UIView
里面,我把它卡在了按钮里面。 isEnabled
在可见和不可见之间切换。我在有多个按钮的 class 中使用它,一次只有一个按钮运行。
import UIKit
@IBDesignable class FrostyButton: UIButton {
@IBInspectable override var isEnabled: Bool {
didSet {
if isEnabled {
self.visualEffectContainer.alpha = 1.0
}
else {
let animator = UIViewPropertyAnimator(duration: 0.5, curve: .linear, animations: {
self.visualEffectContainer.alpha = 0.0
})
animator.startAnimation()
}
}
}
@IBInspectable var cornerRadius: CGFloat {
get {
return layer.cornerRadius
}
set {
layer.cornerRadius = newValue
layer.masksToBounds = newValue > 0
}
}
private let visualEffectContainer = UIView()
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.backgroundColor = .clear
makeItFrosty()
}
override init(frame: CGRect) {
super.init(frame: frame)
}
override func prepareForInterfaceBuilder() {
super.prepareForInterfaceBuilder()
}
private func makeItFrosty() {
let effectView = UIVisualEffectView(effect: UIBlurEffect(style: .light))
effectView.frame = self.bounds
effectView.clipsToBounds = true
effectView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
visualEffectContainer.frame = self.bounds
visualEffectContainer.clipsToBounds = true
visualEffectContainer.autoresizingMask = [.flexibleWidth, .flexibleHeight]
visualEffectContainer.addSubview(effectView)
visualEffectContainer.isUserInteractionEnabled = false
if imageView != nil {
self.insertSubview(visualEffectContainer, at: 0)
}
}
}