ios - objective - Agregue una subcapa CALayer centrada en UIImageView
uiimageview set image swift (1)
El problema es que cuando se llama a viewDidLoad
el diseño aún no se ha realizado, por lo que las mediciones se toman del estado inicial del controlador de vista, muy probablemente del tamaño del guión gráfico, si eso es lo que está usando.
blurFilterMask
llamar a blurFilterMask
una vez que se haya completado el diseño y se conozca el tamaño final de heroImageView
.
Puedes hacer esto anulando viewDidLayoutSubviews
que es ...
Llamado para notificar al controlador de vista que su vista acaba de presentar sus subvistas.
Lee los documentos ya que hay algunas condiciones, pero en tu caso esto funciona, dejándote con esto.
class ViewController: UIViewController {
@IBOutlet var heroImageView: UIImageView!
var blurFilterMask:BlurFilterMask! = nil
func resetMaskOverlay(){
if blurFilterMask == nil {
blurFilterMask = BlurFilterMask()
blurFilterMask.diameter = 120
heroImageView.layer.addSublayer(blurFilterMask)
}
blurFilterMask.frame = heroImageView.bounds
blurFilterMask.origin = heroImageView.center
}
override func viewDidLayoutSubviews() {
resetMaskOverlay()
}
}
Asumí esta línea en BlurFilterMask
CGContextTranslateCTM(ctx, 0.0, yDiff)*/
Estaba destinado a ser comentado ya que no tenía mucho sentido dejar ...
class BlurFilterMask : CALayer {
let GRADIENT_WIDTH : CGFloat = 50.0
var origin : CGPoint = CGPointZero {
didSet {
setNeedsDisplay()
}
}
var diameter : CGFloat = 50.0 {
didSet {
setNeedsDisplay()
}
}
override func drawInContext(ctx: CGContext) {
CGContextSaveGState(ctx)
let clearRegionRadius : CGFloat = self.diameter * 0.5
let blurRegionRadius : CGFloat = clearRegionRadius + GRADIENT_WIDTH
let baseColorSpace = CGColorSpaceCreateDeviceRGB();
let colours : [CGFloat] = [0.0, 0.0, 0.0, 0.0, // Clear region
0.0, 0.0, 0.0, 0.6] // blur region color
let colourLocations : [CGFloat] = [0.0, 0.0]
let gradient = CGGradientCreateWithColorComponents (baseColorSpace, colours, colourLocations, 2)
CGContextDrawRadialGradient(ctx, gradient, self.origin, clearRegionRadius, self.origin, blurRegionRadius, .DrawsAfterEndLocation);
}
}
- Xcode 7.2
- Swift 2
Estoy tratando de superponer una imagen con lo que llamo "BlurFilterMask". Es un CALayer que agrego dinámicamente con Swift Code, aquí está BlurFilterMask:
class BlurFilterMask : CALayer {
private let GRADIENT_WIDTH : CGFloat = 50.0
var origin : CGPoint = CGPointZero {
didSet {
setNeedsDisplay()
}
}
var diameter : CGFloat = 50.0 {
didSet {
setNeedsDisplay()
}
}
override init() {
super.init()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func drawInContext(ctx: CGContext) {
CGContextSaveGState(ctx)
let clearRegionRadius : CGFloat = self.diameter * 0.5
let blurRegionRadius : CGFloat = clearRegionRadius + GRADIENT_WIDTH
let baseColorSpace = CGColorSpaceCreateDeviceRGB();
let colours : [CGFloat] = [0.0, 0.0, 0.0, 0.0, // Clear region
0.0, 0.0, 0.0, 0.6] // blur region color
let colourLocations : [CGFloat] = [0.0, 0.0]
let gradient = CGGradientCreateWithColorComponents (baseColorSpace, colours, colourLocations, 2)
CGContextDrawRadialGradient(ctx, gradient, self.origin, clearRegionRadius, self.origin, blurRegionRadius, .DrawsAfterEndLocation);
}
}
En mi UIViewController.viewDidLoad()
llamo addMaskOverlay () y aquí está la implementación:
func addMaskOverlay(){
let blurFilterMask = BlurFilterMask()
blurFilterMask.diameter = 80
blurFilterMask.frame = heroImageView.bounds
blurFilterMask.origin = heroImageView.center
blurFilterMask.shouldRasterize = true
heroImageView.layer.addSublayer(blurFilterMask)
blurFilterMask.setNeedsDisplay()
}
No importa en qué simulador ejecute, ya sea iPhone 5 o iPhone 6 o iPad 2, por ejemplo, siempre obtengo el mismo centro, ancho y alto:
- print (heroImageView.center) = (300.0, 67.5)
- print (CGRectGetWidth (heroImageView.bounds)) = 600.0
- imprimir (CGRectGetHeight (heroImageView.bounds)) //135.0
Pero el centro de mi BlurFilterMask siempre es diferente, dependiendo del simulador de dispositivo y nunca comienza en el centro de UIImageView, ejemplo en iPhone 5:
Y aquí está el iPhone 6:
Pensé que tal vez necesitaba centrar verticalmente y centrar horizontalmente las restricciones en mi CALayer BlurFilterMask, así que traté de agregar restricciones:
heroImageView.layer.addSublayer(blurFilterMask)
let xConstraint = NSLayoutConstraint(item: blurFilterMask, attribute: .CenterX, relatedBy: .Equal, toItem: heroImageView, attribute: .CenterX, multiplier: 1, constant: 0)
let yConstraint = NSLayoutConstraint(item: blurFilterMask, attribute: .CenterY, relatedBy: .Equal, toItem: heroImageView, attribute: .CenterY, multiplier: 1, constant: 0)
heroImageView.addConstraint(xConstraint)
heroImageView.addConstraint(yConstraint)
Pero no puedo agregar Restricciones a un CALayer. No creo, me sale un error cuando intento:
Aplicación de finalización debido a excepción no detectada ''NSInvalidArgumentException'', razón: ''* + [NSLayoutConstraint constraintWithItem: attribute: relatedBy: toItem: attribute: multiplicador: constante:]: los elementos de restricción deben ser cada uno una instancia de UIView o NSLayoutGuide.'' **
Parece que el problema podría ser restricciones, pero si no puedo agregar restricciones a un CALayer ...
Ese código no ayudó ...
No estoy seguro de dónde ir desde aquí, cualquier sugerencia sería muy apreciada.