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

实现UIView及其内部视图点击时像UIButton一样变暗

实现透明视图点击变暗效果的几种方法

当然可以实现,下面给你两种实用的方案:

方案一:改用UIButton(最省心)

既然要实现按钮的点击效果,直接用UIButton来承载图片和标签反而更省事,不用自己处理手势状态:

  1. 创建自定义UIButton,设置背景为透明
  2. 将图片和标签添加到button上,调整好布局
  3. 利用button的highlighted状态实现变暗效果:
    • 给button添加半透明黑色遮罩视图,默认隐藏,在setHighlighted(_:)方法里控制遮罩的显示/隐藏
    • 也可以直接调整图片和标签的alpha值,高亮时设为0.6左右,恢复时设为1.0

示例代码:

class CustomButton: UIButton {
    let iconImageView = UIImageView()
    let titleLabel = UILabel()
    let highlightMask = UIView()
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        setupViews()
    }
    
    required init?(coder: NSCoder) {
        super.init(coder: coder)
        setupViews()
    }
    
    private func setupViews() {
        backgroundColor = .clear
        
        // 添加图片和标签,此处省略布局代码,可使用AutoLayout或Frame实现
        addSubview(iconImageView)
        addSubview(titleLabel)
        
        // 添加高亮遮罩
        highlightMask.backgroundColor = UIColor.black.withAlphaComponent(0.2)
        highlightMask.isHidden = true
        highlightMask.frame = bounds
        highlightMask.autoresizingMask = [.flexibleWidth, .flexibleHeight]
        addSubview(highlightMask)
    }
    
    override var isHighlighted: Bool {
        didSet {
            highlightMask.isHidden = !isHighlighted
            // 也可同时调整图片和标签透明度
            // iconImageView.alpha = isHighlighted ? 0.6 : 1.0
            // titleLabel.alpha = isHighlighted ? 0.6 : 1.0
        }
    }
}

方案二:自定义视图+手势处理状态

如果一定要用原有视图+UITapGestureRecognizer,可监听手势的不同状态切换视图效果:

  1. 给视图添加半透明遮罩(或直接调整子视图的颜色/透明度)
  2. 在手势began状态下激活变暗效果,ended/cancelled状态下恢复

示例代码:

class CustomTapView: UIView {
    let iconImageView = UIImageView()
    let titleLabel = UILabel()
    let highlightMask = UIView()
    private var originalImage: UIImage? // 保存原图片用于恢复
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        setupViews()
        addTapGesture()
        originalImage = iconImageView.image
    }
    
    required init?(coder: NSCoder) {
        super.init(coder: coder)
        setupViews()
        addTapGesture()
        originalImage = iconImageView.image
    }
    
    private func setupViews() {
        backgroundColor = .clear
        
        addSubview(iconImageView)
        addSubview(titleLabel)
        // 省略布局代码
        
        highlightMask.backgroundColor = UIColor.black.withAlphaComponent(0.2)
        highlightMask.isHidden = true
        highlightMask.frame = bounds
        highlightMask.autoresizingMask = [.flexibleWidth, .flexibleHeight]
        addSubview(highlightMask)
    }
    
    private func addTapGesture() {
        let tapGesture = UITapGestureRecognizer(target: self, action: #selector(handleTap(_:)))
        addGestureRecognizer(tapGesture)
    }
    
    @objc private func handleTap(_ gesture: UITapGestureRecognizer) {
        switch gesture.state {
        case .began:
            // 开始点击时显示遮罩+图片变灰
            highlightMask.isHidden = false
            setImageViewGray(true)
        case .ended, .cancelled, .failed:
            // 结束点击时恢复原状
            highlightMask.isHidden = true
            setImageViewGray(false)
        default:
            break
        }
    }
    
    // 实现图片变灰效果
    private func setImageViewGray(_ isGray: Bool) {
        guard let originalImage = originalImage else { return }
        if isGray {
            let filter = CIFilter(name: "CIColorMonochrome")
            filter?.setValue(CIImage(image: originalImage), forKey: kCIInputImageKey)
            filter?.setValue(CIColor(red: 0.6, green: 0.6, blue: 0.6), forKey: kCIInputColorKey)
            filter?.setValue(1.0, forKey: kCIInputIntensityKey)
            let context = CIContext(options: nil)
            guard let outputImage = filter?.outputImage,
                  let cgImage = context.createCGImage(outputImage, from: outputImage.extent) else { return }
            iconImageView.image = UIImage(cgImage: cgImage)
        } else {
            iconImageView.image = originalImage
        }
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 21:45:17