You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何给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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 22:08:17