嗨我想知道是否可以在UIVisualEffectView上设置转角半径? 这是我尝试过的代码:
@IBOutlet var blurView: UIVisualEffectView!
var blurLayer : CALayer{
return blurView.layer
}
override func viewDidLoad() {
super.viewDidLoad()
setUpLayer()
// Do any additional setup after loading the view.
}
func setUpLayer(){
blurLayer.cornerRadius = 50
}
和
@IBOutlet var blurView: UIVisualEffectView!
override func viewDidLoad() {
super.viewDidLoad()
blurView.layer.cornerRadius = 50
// Do any additional setup after loading the view.
}
非他们的作品。
答案 0 :(得分:51)
在@theMonster建议之后,我发布的是评论。
override func viewDidLoad() {
super.viewDidLoad()
blurView.layer.cornerRadius = 50
blurView.clipsToBounds = true
}
答案 1 :(得分:4)
所有现有的解决方案并不完美。
由于UIVisualEffectView
通过合成两个子视图内容来实现其视觉效果 - 一个是背景视图,另一个是过滤视图,当您通过屏蔽整个UIVisualEffectView
来实现您的角半径时,那里角落周围会有一些肮脏的颜色。
要摆脱这些肮脏的颜色,你只需要屏蔽UIVisualEffects的过滤视图。
private typealias ObjcRawUIVisualEffectViewSelCGRect =
@convention(c) (UIVisualEffectView, Selector, CGRect) -> Void
private var cornerRadiusKey =
"com.WeZZard.Waxing.UIVisualEffectView-CornerRadius.cornerRadius"
private var needsUpdateMaskLayerKey =
"com.WeZZard.Waxing.UIVisualEffectView-CornerRadius.needsUpdateMaskLayer"
extension UIVisualEffectView {
public var cornerRadius: CGFloat {
get {
if let storedValue = objc_getAssociatedObject(self,
&cornerRadiusKey)
as? CGFloat
{
return storedValue
}
return 0
}
set {
if cornerRadius != newValue {
objc_setAssociatedObject(self,
&cornerRadiusKey,
newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
setNeedsUpdateMaskLayer()
}
}
}
private var needsUpdateMaskLayer: Bool {
get {
if let storedValue = objc_getAssociatedObject(self,
&needsUpdateMaskLayerKey)
as? Bool
{
return storedValue
}
return false
}
set {
objc_setAssociatedObject(self,
&needsUpdateMaskLayerKey,
newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
}
}
public override class func initialize() {
swizzle_setBounds()
}
private class func swizzle_setBounds() {
struct Static {
static var token: dispatch_once_t = 0
}
dispatch_once(&Static.token) {
let selector: Selector = "setBounds:"
let method = class_getInstanceMethod(self, selector)
let imp_original = method_getImplementation(method)
before_setBounds = unsafeBitCast(imp_original,
ObjcRawUIVisualEffectViewSelCGRect.self)
class_replaceMethod(self,
selector,
unsafeBitCast(after_setBounds, IMP.self),
"@:{_struct=CGRect}")
}
}
private func setNeedsUpdateMaskLayer() {
needsUpdateMaskLayer = true
NSOperationQueue.mainQueue().addOperationWithBlock { [weak self] _ in
self?.updateMaskLayerIfNeeded()
}
}
private func updateMaskLayerIfNeeded() {
if needsUpdateMaskLayer {
updateMaskLayer()
needsUpdateMaskLayer = false
}
}
private func updateMaskLayer(){
var filterViewFound = false
for each in subviews {
if each.dynamicType.description()
.containsString("Filter")
{
filterViewFound = true
let newPath = UIBezierPath(roundedRect: each.bounds,
cornerRadius: self.cornerRadius)
.CGPath
if let existedMask = each.layer.mask
as? CAShapeLayer
{
existedMask.path = newPath
} else {
let shapeLayer = CAShapeLayer()
shapeLayer.path = newPath
each.layer.mask = shapeLayer
}
} else {
setNeedsUpdateMaskLayer()
}
}
assert(filterViewFound == true, "Filter view was not found! Check your hacking!")
}
}
private var before_setBounds: ObjcRawUIVisualEffectViewSelCGRect = { _ in
fatalError("No implementation found")
}
private let after_setBounds: ObjcRawUIVisualEffectViewSelCGRect = {
(aSelf, selector, bounds) -> Void in
let oldBounds = aSelf.bounds
before_setBounds(aSelf, selector, bounds)
if oldBounds.size != bounds.size {
aSelf.setNeedsUpdateMaskLayer()
}
}
所有事情都已完成!
答案 2 :(得分:3)
子类UIVisualEffectView
class PSORoundedVisualEffectView : UIVisualEffectView{
override func layoutSubviews() {
super.layoutSubviews()
updateMaskLayer()
}
func updateMaskLayer(){
let shapeLayer = CAShapeLayer()
shapeLayer.path = UIBezierPath(roundedRect: self.bounds, cornerRadius: 10).CGPath
self.layer.mask = shapeLayer
}
}
将UIBezierPath替换为您想要的任何形状。
答案 3 :(得分:2)
在故事板上,在用户定义的运行时属性layer.cornerRadius = 8
和layer.masksToBounds = true
中添加两个参数
或使用代码
@IBOutlet var blurView: UIVisualEffectView! {
didSet {
blurView.layer.cornerRadius = 8
blurView.layer.masksToBounds = true
}
}