如何给UILabel添加多重阴影?现有代码问题求助
给UILabel添加红蓝双重阴影的解决方法
问题原因分析
- 第一段代码:一个CALayer只能保存一组阴影属性,第二次调用
addDropShadow会直接覆盖第一次的颜色、偏移量等设置,最终只显示最后配置的蓝色阴影。 - 第二段代码:创建的子图层没有设置
bounds和contents(无实际内容),阴影是基于图层内容生成的,空图层自然看不到效果;另外代码存在笔误——layer3未定义就使用,还重复插入了layer2。
正确实现方案
要实现双重阴影,需要给UILabel添加两个独立的阴影载体,以下是两种可行方式:
方式一:用子图层模拟双重阴影
private lazy var titleLabel: UILabel = { let label = UILabel() label.textColor = .black label.text = "1" label.font = UIFont.systemFont(ofSize: 40) label.translatesAutoresizingMaskIntoConstraints = false return label }() override func viewDidLoad() { super.viewDidLoad() view.addSubview(titleLabel) // 设置label居中约束 NSLayoutConstraint.activate([ titleLabel.centerXAnchor.constraint(equalTo: view.centerXAnchor), titleLabel.centerYAnchor.constraint(equalTo: view.centerYAnchor) ]) addDoubleShadow(to: titleLabel) } private func addDoubleShadow(to label: UILabel) { // 红色阴影图层 let redShadowLayer = CALayer() redShadowLayer.bounds = label.bounds redShadowLayer.position = label.center redShadowLayer.contents = label.layer.contents redShadowLayer.shadowColor = UIColor.red.cgColor redShadowLayer.shadowOpacity = 1 redShadowLayer.shadowOffset = CGSize(width: -6, height: -6) redShadowLayer.shadowRadius = 10 label.layer.insertSublayer(redShadowLayer, at: 0) // 蓝色阴影图层 let blueShadowLayer = CALayer() blueShadowLayer.bounds = label.bounds blueShadowLayer.position = label.center blueShadowLayer.contents = label.layer.contents blueShadowLayer.shadowColor = UIColor.blue.cgColor blueShadowLayer.shadowOpacity = 1 blueShadowLayer.shadowOffset = CGSize(width: 6, height: 6) blueShadowLayer.shadowRadius = 10 label.layer.insertSublayer(blueShadowLayer, at: 0) }
方式二:用UILabel作为阴影层(更易维护)
如果担心图层内容同步问题,可以直接创建两个与原label一致的UILabel,分别设置阴影后放在原label下方:
private lazy var titleLabel: UILabel = { let label = UILabel() label.textColor = .black label.text = "1" label.font = UIFont.systemFont(ofSize: 40) label.translatesAutoresizingMaskIntoConstraints = false return label }() override func viewDidLoad() { super.viewDidLoad() // 红色阴影label let redShadowLabel = UILabel() redShadowLabel.text = titleLabel.text redShadowLabel.font = titleLabel.font redShadowLabel.textColor = .black redShadowLabel.translatesAutoresizingMaskIntoConstraints = false redShadowLabel.layer.shadowColor = UIColor.red.cgColor redShadowLabel.layer.shadowOpacity = 1 redShadowLabel.layer.shadowOffset = CGSize(width: -6, height: -6) redShadowLabel.layer.shadowRadius = 10 redShadowLabel.layer.masksToBounds = false // 蓝色阴影label let blueShadowLabel = UILabel() blueShadowLabel.text = titleLabel.text blueShadowLabel.font = titleLabel.font blueShadowLabel.textColor = .black blueShadowLabel.translatesAutoresizingMaskIntoConstraints = false blueShadowLabel.layer.shadowColor = UIColor.blue.cgColor blueShadowLabel.layer.shadowOpacity = 1 blueShadowLabel.layer.shadowOffset = CGSize(width: 6, height: 6) blueShadowLabel.layer.shadowRadius = 10 blueShadowLabel.layer.masksToBounds = false // 按层级添加视图:阴影层在最下方,原label在最上层 view.addSubview(blueShadowLabel) view.addSubview(redShadowLabel) view.addSubview(titleLabel) // 设置约束,让阴影层与原label完全重合 NSLayoutConstraint.activate([ redShadowLabel.centerXAnchor.constraint(equalTo: titleLabel.centerXAnchor), redShadowLabel.centerYAnchor.constraint(equalTo: titleLabel.centerYAnchor), blueShadowLabel.centerXAnchor.constraint(equalTo: titleLabel.centerXAnchor), blueShadowLabel.centerYAnchor.constraint(equalTo: titleLabel.centerYAnchor), titleLabel.centerXAnchor.constraint(equalTo: view.centerXAnchor), titleLabel.centerYAnchor.constraint(equalTo: view.centerYAnchor) ]) }
注意事项
- 使用子图层方案时,若UILabel的文本或尺寸发生变化,需要在
layoutSubviews方法中同步更新子图层的bounds和contents。 - 两种方案都要确保
masksToBounds设为false,否则阴影会被图层边界裁剪。
内容的提问来源于stack exchange,提问作者user1342352532
相关产品推荐
相关产品推荐

