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 Réponses :
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 code>. 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
Parfaitement correct. J'ai mis une solution si quelqu'un veut vraiment maintenir la classe de base comme UILabel!
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.
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.)
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.
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
viewDidLoadne garantit pas la taille réelle d'une sous-vue.Pour quiconque cherche ici, l'exemple de code dans la question est absolument incorrect