swift - Radio de esquina en UIVisualEffectView
xcode6 cornerradius (4)
Después de la sugerencia de @theMonster, estoy publicando lo que fue un comentario.
override func viewDidLoad() {
super.viewDidLoad()
blurView.layer.cornerRadius = 50
blurView.clipsToBounds = true
}
Hola, me pregunto si es posible establecer un radio de esquina en un UIVisualEffectView? Aquí está el código que he probado:
@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
}
y
@IBOutlet var blurView: UIVisualEffectView!
override func viewDidLoad() {
super.viewDidLoad()
blurView.layer.cornerRadius = 50
// Do any additional setup after loading the view.
}
Ninguno de ellos funciona.
Subclase 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
}
}
Reemplace el UIBezierPath con la forma que desee.
Todas las soluciones existentes no son perfectas.
Dado que UIVisualEffectView
implementa sus efectos visuales al componer dos contenidos de subvistas: uno es una vista de fondo y el otro es una vista de filtro, cuando implementa el radio de su esquina al enmascarar todo el UIVisualEffectView
, habrá algunos colores sucios en las esquinas.
Para deshacerse de estos colores sucios, solo necesita enmascarar la vista de filtro de 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()
}
}
¡Y todas las cosas hechas!
en el guión gráfico agregue dos parámetros en los atributos de tiempo de ejecución definidos por el usuario layer.cornerRadius = 8
y layer.masksToBounds = true
o en codigo
@IBOutlet var blurView: UIVisualEffectView! {
didSet {
blurView.layer.cornerRadius = 8
blurView.layer.masksToBounds = true
}
}