6 votes

L'effet d'ombre ne s'affiche pas correctement pour UIView

J'ai un écran de connexion comme ci-dessous. Autour de chaque champ de texte, j'ai ajouté une vue et pour cette vue, je veux afficher une ombre portée. J'ai plus ou moins réussi ce que j'essayais, mais cela ne fonctionne pas pour les appareils iPhone Plus (6+, 8+).

Vous pouvez voir la différence ci-dessous.

iPhone 8+:-

enter image description here

iPhone 8:-

enter image description here

Voici mon code

extension UIView {
    func addShadow() {        
        layer.cornerRadius = 8
        layer.masksToBounds = true

        layer.shadowColor = UIColor.lightGray.cgColor
        layer.shadowOffset = CGSize(width: 0, height: 1.0)
        layer.shadowRadius = 2.0
        layer.shadowOpacity = 0.5
        layer.masksToBounds = false

        layer.shadowPath = UIBezierPath(roundedRect: self.bounds,cornerRadius:8).cgPath
    }
}

Comment puis-je réparer cela correctement ?

5voto

clemens Points 10221

Puisque les vues peuvent être redimensionnées, vous devez mettre à jour vos shadowPath après le redimensionnement car il a une taille fixe. Malheureusement, cela ne peut pas être fait dans une extension, car vous devez écraser le fichier layoutSubview() . Mais vous pouvez appeler addShadow() de viewDidLayoutSubviews() depuis votre contrôleur de vue à nouveau pour chaque champ de texte.

Vous pouvez également modifier votre extension pour ne mettre à jour que le chemin :

extension UIView {
    func addShadow() {        
        layer.cornerRadius = 8

        layer.shadowColor = UIColor.lightGray.cgColor
        layer.shadowOffset = CGSize(width: 0, height: 1.0)
        layer.shadowRadius = 2.0
        layer.shadowOpacity = 0.5
        layer.masksToBounds = false

        updateShadow()
    }
    func updateShadow() {
        layer.shadowPath = UIBezierPath(roundedRect: self.bounds,cornerRadius:8).cgPath
    }  
}

Avec cela, vous devez appeler updateShadow() de viewDidLayoutSubviews() pour chaque vue avec une ombre.

Si vous utilisez une sous-classe personnalisée pour vos champs de texte, vous pouvez mettre la balise updateShadow() l'appel en layoutSubviews() . Il n'est donc pas nécessaire de l'appeler depuis le contrôleur de vue.

2voto

Ankit Jayaswal Points 3477

Vous construisez la vue sur l'iPhone 8 sur storyboard. Ainsi, lorsque vous l'exécutez sur un iPhone 8+/ 6+, la vue est redimensionnée mais l'ombre n'est pas mise à jour.

enter image description here

Mettez layoutIfNeeded() avant d'ajouter shadowPath a layer :

Le code mis à jour sera le suivant :

func addShadow() {
    layer.cornerRadius = 8
    layer.masksToBounds = true

    layer.shadowColor = UIColor.lightGray.cgColor
    layer.shadowOffset = CGSize(width: 0, height: 1.0)
    layer.shadowRadius = 2.0
    layer.shadowOpacity = 0.5
    layer.masksToBounds = false

    layoutIfNeeded()
    layer.shadowPath = UIBezierPath(roundedRect: self.bounds,cornerRadius: 8).cgPath
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X