[Ios] Ajouter une sous-couche CALayer centrée sur UIImageView


Answers

Question
  • Xcode 7.2
  • Swift 2

J'essaye de superposer une Image avec ce que j'appelle un "BlurFilterMask". C'est un CALayer que j'ajoute dynamiquement avec Swift Code, voici le 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);

    }

}

Dans mon UIViewController.viewDidLoad() j'appelle addMaskOverlay () et voici l'implémentation:

 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()
    }

Peu importe le simulateur que je lance, que ce soit l'iPhone 5 ou l'iPhone 6 ou l'iPad 2, par exemple, j'ai toujours le même centre, la même largeur et la même hauteur:

  • print (heroImageView.center) = (300.0, 67.5)
  • print (CGRectGetWidth (heroImageView.bounds)) = 600.0
  • print (CGRectGetHeight (heroImageView.bounds)) //135.0

Mais le centre de mon BlurFilterMask est toujours quelque part différent, en fonction du simulateur de périphérique et il ne démarre jamais au centre de UIImageView, exemple dans l'iPhone 5:

Et voici l'iPhone 6:

Je pensais que j'avais besoin de contraintes de centrage vertical et de centrage horizontal sur mon CALayer BlurFilterMask, donc j'ai essayé d'ajouter des contraintes:

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)

Mais je ne peux pas ajouter de contraintes à un calayer Je ne pense pas, je reçois une erreur quand j'essaie:

Terminaison de l'application en raison d'une exception non interceptée 'NSInvalidArgumentException', raison: '* + [NSLayoutConstraint constraintWithItem: attribut: relatedBy: toItem: attribut: multiplicateur: constante:]: les éléments de contrainte doivent être une instance de UIView ou NSLayoutGuide.' **

Il semble que le problème pourrait être des contraintes mais si je ne peux pas ajouter de contraintes à un calayer ...

Ce code n'a pas aidé ...

Je ne sais pas où aller à partir d'ici, toutes les suggestions seraient très appréciées.




Links