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

iOS Swift中如何仅隐藏/显示UIButton文本而非按钮本身

解决UITextView中UIButton文本切换显示/隐藏且保留背景色的问题

嘿,这个问题我做Swift项目时也碰到过!核心矛盾就是不能把按钮标题设为nil——毕竟背景色是靠原始文本的首字母生成的,直接清空标题肯定会搞崩背景色逻辑。别担心,给你两个靠谱的解决方案,都能完美实现切换效果还不影响背景色:

方案一:自定义UIButton子类(推荐,逻辑更清晰)

我们可以给按钮加个属性专门保存原始文本,切换时要么显示原始文本,要么用一个零宽空格占位(这样按钮尺寸不变,布局不会乱),背景色始终基于原始文本计算。

代码实现

import UIKit

class ToggleTextButton: UIButton {
    // 专门存原始文本,背景色全靠它
    var originalTitle: String? {
        didSet {
            // 初始状态显示原始文本
            setTitle(originalTitle, for: .normal)
            // 初始化背景色
            updateBackgroundColor()
        }
    }
    
    // 记录当前文本是否隐藏
    private var isTextHidden = false
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        setupTapAction()
    }
    
    required init?(coder: NSCoder) {
        super.init(coder: coder)
        setupTapAction()
    }
    
    private func setupTapAction() {
        addTarget(self, action: #selector(toggleTextVisibility), for: .touchUpInside)
    }
    
    @objc private func toggleTextVisibility() {
        isTextHidden.toggle()
        if isTextHidden {
            // 用零宽空格占位,不改变按钮大小,也不会显示任何字符
            setTitle("\u{200B}", for: .normal)
        } else {
            // 恢复显示原始文本
            setTitle(originalTitle, for: .normal)
        }
    }
    
    // 你的背景色计算逻辑,完全基于originalTitle的首字母
    private func updateBackgroundColor() {
        guard let originalTitle = originalTitle, let firstChar = originalTitle.first else {
            backgroundColor = .lightGray // 默认背景色
            return
        }
        
        // 这里替换成你实际的背景色逻辑就行
        switch firstChar.lowercased() {
        case "a", "b", "c":
            backgroundColor = .systemRed
        case "d", "e", "f":
            backgroundColor = .systemBlue
        default:
            backgroundColor = .systemGreen
        }
    }
}

使用方式

在你的UITextView列表里创建这个按钮就行:

// 示例:创建按钮并设置原始文本
let toggleButton = ToggleTextButton(type: .custom)
toggleButton.originalTitle = "Apple"
toggleButton.frame = CGRect(x: 20, y: 60, width: 100, height: 40)
yourTextView.addSubview(toggleButton)

方案二:给UIButton加扩展(无需自定义子类)

如果不想创建子类,也可以用关联对象给系统UIButton添加状态属性,切换时直接隐藏/显示标题标签(titleLabel),这样连标题都不用改,背景色逻辑完全不受影响。

代码实现

import UIKit

extension UIButton {
    // 用关联对象存状态和原始文本
    private struct AssociatedKeys {
        static var isTextHidden = "isTextHidden"
        static var originalTitle = "originalTitle"
    }
    
    var isTextHidden: Bool {
        get { objc_getAssociatedObject(self, &AssociatedKeys.isTextHidden) as? Bool ?? false }
        set { objc_setAssociatedObject(self, &AssociatedKeys.isTextHidden, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) }
    }
    
    var originalTitle: String? {
        get { objc_getAssociatedObject(self, &AssociatedKeys.originalTitle) as? String }
        set {
            objc_setAssociatedObject(self, &AssociatedKeys.originalTitle, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
            setTitle(newValue, for: .normal)
            updateBackgroundColor()
        }
    }
    
    @objc func toggleTextVisibility() {
        isTextHidden.toggle()
        // 直接隐藏/显示标题标签,按钮尺寸和背景色都不变
        titleLabel?.alpha = isTextHidden ? 0 : 1
    }
    
    // 同样,背景色基于原始文本计算
    func updateBackgroundColor() {
        guard let originalTitle = originalTitle, let firstChar = originalTitle.first else {
            backgroundColor = .lightGray
            return
        }
        
        // 替换成你的背景色逻辑
        switch firstChar.lowercased() {
        case "g", "h", "i":
            backgroundColor = .systemOrange
        case "j", "k", "l":
            backgroundColor = .systemPurple
        default:
            backgroundColor = .systemTeal
        }
    }
}

使用方式

let normalButton = UIButton(type: .custom)
normalButton.originalTitle = "Banana"
normalButton.addTarget(normalButton, action: #selector(normalButton.toggleTextVisibility), for: .touchUpInside)
normalButton.frame = CGRect(x: 20, y: 120, width: 100, height: 40)
yourTextView.addSubview(normalButton)

这两个方案的核心都是保留原始文本的引用,让背景色逻辑始终依赖原始文本,而不是当前显示的标题。这样不管怎么切换文本显示状态,背景色都不会出问题~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 09:40:38