1
votes

Comment ajouter des ombres et des coins arrondis à une étiquette en Swift sans utiliser d'UIView derrière?

Je veux donner des coins arrondis à mon étiquette et je veux aussi donner l'ombre de l'étiquette mais ma méthode d'ombre et les méthodes de rayon d'angle ne fonctionnent pas ensemble sur l'étiquette.

Voici mon code avec lequel je travaille sur mon étiquette

extension UILabel
{
    func ShadowLabel()  {

        self.layer.shadowColor = UIColor.lightGray.cgColor
        self.layer.shadowRadius = 2
        self.layer.shadowOpacity = 1
        self.layer.shadowOffset = CGSize(width: 5, height: 5)

    }
}
extension UILabel
{
    func RoundCornerLabel() {
        self.layer.cornerRadius = frame.size.height/2
        self.layer.masksToBounds = true
    }
}

override func viewDidLoad() {
        super.viewDidLoad()
        label.shadowLabel()
        label.RoundCornerLabel()
}


3 commentaires

Si je comprends bien: vous souhaitez utiliser l'extension UIButton pour modifier UILabel? Pour ce faire, vous devez créer une extension similaire pour UILabel


viewDidLoad ne garantit pas la taille réelle d'une sous-vue.


Pour quiconque cherche ici, l'exemple de code dans la question est absolument incorrect


3 Réponses :


2
votes

Ce que vous essayez de faire n'est pas possible. L'ombre est appliquée en dehors des limites de UIView , mais le cornerRadius ne sera pas visible sans masquer les limites de UIView . Vous devrez donc utiliser un conteneur UIView .

Si vous voulez écrire ceci de manière générique, écrivez une extension UIView qui renvoie un UIView qui contient la vue à laquelle vous souhaitez appliquer une ombre


1 commentaires

Parfaitement correct. J'ai mis une solution si quelqu'un veut vraiment maintenir la classe de base comme UILabel!



1
votes

Une solution sous iOS ...

 entrez la description de l'image ici

Il est vrai que, bizarrement, vous NE pouvez PAS strong > ajouter un arrière-plan / une ombre à un UILabel

Si, pour une raison quelconque, vous voulez vraiment maintenir la classe de base en tant que UILabel, alors une solution propre est:

est en fait ajouter un autre UILabel sur le dessus , et mettre le texte là-dedans:

(Dans l'exemple, c'est un simple fixe -width layout.)

class UIILabel:  UILabel {
    override init(frame: CGRect) {
        super.init(frame: frame)
        common()
    }
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        common()
    }
    func common() {
    }
}

Vous pouvez alors faire ce que vous voulez à l'UILabel.

Bien sûr, vous avez alors le problème que, p>

ce n'est pas si simple d'ajouter un arrière-plan et une ombre à un UILabel: /

Une solution:

class ExampleRoundShadowLabel: BettaLabel {
    
    override func common() {
        super.common()
        backgroundColor = .clear
        layer.shadowColor = UIColor.red.cgColor
        layer.shadowOffset = CGSize( width: 0, height: 2 )
        layer.shadowRadius = 2
        layer.shadowOpacity = 1
    }
    
    override func layoutSubviews() {
        super.layoutSubviews()
        
        bg.frame = bounds
        bg.cornerRadius = bounds.width / 2
        
        layer.shadowPath = UIBezierPath(
          roundedRect: bounds, cornerRadius: bounds.width / 2).cgPath
    }
    
    lazy var bg: CALayer = {
        let l = CALayer()
        l.backgroundColor = UIColor.white.cgColor
        layer.insertSublayer(l, at: 0)
        return l
    }()
}

Donc, si vous vraiment, veulent vraiment le faire, c'est une façon.

entrez la description de l'image ici

La classe d'aide pour l'initialisation est juste

import UIKit

class BettaLabel: UIILabel {
    
    override var text: String? {
        set { _overLabel.text = newValue }
        get { return _overLabel.text }
    }
    
    override func common() {
        super.common()
        addSubview(_overLabel)
        _overLabel.font = font
        _overLabel.textColor = textColor
        _overLabel.textAlignment = textAlignment
        text = ""
    }
    
    override func layoutSubviews() {
        super.layoutSubviews()
        _overLabel.frame = bounds
    }
    
    lazy var _overLabel: UILabel = {
        let o = UILabel()
        o.backgroundColor = .clear
        return o
    }()
}

(Notez le "I" supplémentaire dans UIILabel .. I pour l'initialisation.)


0 commentaires

0
votes

Le problème auquel vous êtes confronté est évident. Si vous définissez masksToBounds sur true , coupe tout ce qui se trouve en dehors du calque.

Une ombre sera dessinée à l'extérieur du calque, elle sera donc également coupée. Donc, nous ne pouvons pas utiliser le même calque pour ces deux effets, je veux dire l'ombre et les coins arrondis, donc la meilleure solution est @Sparr comment.


0 commentaires