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

如何用Swift为UIImage添加类似Tidal的右上角丝带横幅?

一、UIImage右上角添加横幅实现方案
  • 核心思路:用容器视图包裹UIImageView和横幅视图,通过AutoLayout固定横幅位置
  • 具体实现代码(Swift):
// 创建容器视图,用于承载图片和横幅
let containerView = UIView(frame: CGRect(x: 0, y: 0, width: 150, height: 150))

// 添加图片视图
let imageView = UIImageView(image: UIImage(named: "music_cover"))
imageView.frame = containerView.bounds
imageView.contentMode = .scaleAspectFill
imageView.clipsToBounds = true
containerView.addSubview(imageView)

// 创建横幅标签
let bannerLabel = UILabel()
bannerLabel.text = "VIP"
bannerLabel.backgroundColor = .systemRed
bannerLabel.textColor = .white
bannerLabel.font = UIFont.systemFont(ofSize: 12, weight: .bold)
bannerLabel.textAlignment = .center
bannerLabel.translatesAutoresizingMaskIntoConstraints = false
containerView.addSubview(bannerLabel)

// 约束横幅到右上角
NSLayoutConstraint.activate([
    bannerLabel.topAnchor.constraint(equalTo: containerView.topAnchor),
    bannerLabel.trailingAnchor.constraint(equalTo: containerView.trailingAnchor),
    bannerLabel.widthAnchor.constraint(equalToConstant: 40),
    bannerLabel.heightAnchor.constraint(equalToConstant: 20)
])

// 如需圆角横幅,可添加以下代码
bannerLabel.layer.cornerRadius = 4
bannerLabel.clipsToBounds = true
二、自定义丝带形状UIView并嵌入单元格

1. 实现丝带形状视图

通过重写draw(_ rect:)方法绘制自定义折角路径,代码示例:

class RibbonView: UIView {
    // 可配置属性
    var ribbonColor: UIColor = .systemOrange {
        didSet { setNeedsDisplay() }
    }
    var ribbonText: String = "NEW" {
        didSet { setNeedsDisplay() }
    }
    
    override func draw(_ rect: CGRect) {
        super.draw(rect)
        guard let context = UIGraphicsGetCurrentContext() else { return }
        
        // 绘制丝带折角路径
        let path = UIBezierPath()
        path.move(to: CGPoint(x: rect.width, y: 0))
        path.addLine(to: CGPoint(x: rect.width - 30, y: 0))
        path.addLine(to: CGPoint(x: rect.width, y: 30))
        path.addLine(to: CGPoint(x: rect.width, y: rect.height))
        path.addLine(to: CGPoint(x: 0, y: rect.height))
        path.addLine(to: CGPoint(x: 0, y: 0))
        path.close()
        
        // 填充颜色
        ribbonColor.setFill()
        path.fill()
        
        // 绘制文字
        let textAttrs: [NSAttributedString.Key: Any] = [
            .font: UIFont.systemFont(ofSize: 12, weight: .bold),
            .foregroundColor: UIColor.white
        ]
        let textSize = ribbonText.size(withAttributes: textAttrs)
        let textX = rect.width - textSize.width - 8
        let textY = (30 - textSize.height) / 2
        ribbonText.draw(at: CGPoint(x: textX, y: textY), withAttributes: textAttrs)
    }
}

2. 嵌入音乐图片单元格

在自定义单元格中添加丝带视图并设置约束:

// 自定义CollectionViewCell示例
class MusicCell: UICollectionViewCell {
    override init(frame: CGRect) {
        super.init(frame: frame)
        setupViews()
    }
    
    required init?(coder: NSCoder) {
        super.init(coder: coder)
        setupViews()
    }
    
    private func setupViews() {
        // 添加图片视图(铺满单元格)
        let imageView = UIImageView()
        imageView.contentMode = .scaleAspectFill
        imageView.clipsToBounds = true
        imageView.translatesAutoresizingMaskIntoConstraints = false
        contentView.addSubview(imageView)
        
        // 添加丝带视图
        let ribbonView = RibbonView()
        ribbonView.translatesAutoresizingMaskIntoConstraints = false
        contentView.addSubview(ribbonView)
        
        // 设置约束
        NSLayoutConstraint.activate([
            // 图片视图约束
            imageView.topAnchor.constraint(equalTo: contentView.topAnchor),
            imageView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor),
            imageView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor),
            imageView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor),
            
            // 丝带视图约束(右上角)
            ribbonView.topAnchor.constraint(equalTo: contentView.topAnchor),
            ribbonView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor),
            ribbonView.widthAnchor.constraint(equalToConstant: 60),
            ribbonView.heightAnchor.constraint(equalToConstant: 40)
        ])
        
        // 配置丝带样式
        ribbonView.ribbonText = "NEW"
        ribbonView.ribbonColor = .systemOrange
    }
}

内容的提问来源于stack exchange,提问作者okelewo health

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 17:02:14