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

Swift UIKit编程:枚举Case批量创建UIButton失败求助

解决UIKit绘图APP颜色选择按钮重叠问题

问题根源

所有按钮的frame被设置为固定的CGRect(x: 50, y: 50, width: 100, height: 100),导致所有按钮完全重叠。由于枚举Pencil.allCases的最后一项是eraser,它会覆盖前面所有按钮,最终仅显示白色的橡皮擦按钮。

另外,使用pencilCase.hashValue作为tag不可靠,hashValue可能在不同运行环境下变化,建议改用枚举的rawValue。


方案一:使用UIStackView(推荐,自动布局)

通过UIStackView自动管理按钮排列,无需手动计算坐标,适配性更强。

1. 优化Pencil枚举

添加Int类型的rawValue,替代不稳定的hashValue,同时简化init?(tag:)实现:

enum Pencil: Int, CaseIterable {
    case black = 1
    case grey
    case red
    case darkblue
    case lightBlue
    case darkGreen
    case lightGreen
    case brown
    case orange
    case yellow
    case eraser

    init?(tag: Int) {
        self.init(rawValue: tag)
    }

    var color: UIColor {
        switch self {
        case .black:
            return .black
        case .grey:
            return UIColor(white: 105/255.0, alpha: 1.0)
        case .red:
            return UIColor(red: 1, green: 0, blue: 0, alpha: 1.0)
        case .darkblue:
            return UIColor(red: 0, green: 0, blue: 1, alpha: 1.0)
        case .lightBlue:
            return UIColor(red: 51/255.0, green: 204/255.0, blue: 1, alpha: 1.0)
        case .darkGreen:
            return UIColor(red: 102/255.0, green: 204/255.0, blue: 0, alpha: 1.0)
        case .lightGreen:
            return UIColor(red: 102/255.0, green: 1, blue: 0, alpha: 1.0)
        case .brown:
            return UIColor(red: 160/255.0, green: 82/255.0, blue: 45/255.0, alpha: 1.0)
        case .orange:
            return UIColor(red: 1, green: 102/255.0, blue: 0, alpha: 1.0)
        case .yellow:
            return UIColor(red: 1, green: 1, blue: 0, alpha: 1.0)
        case .eraser:
            return .white
        }
    }
}

2. 修改按钮创建函数

只创建按钮并设置基础属性,不固定frame,改用约束定义尺寸:

func createColorButton() -> [UIButton]{
    var buttons: [UIButton] = []
    for pencilCase in Pencil.allCases {
        let button = UIButton(type: .custom)
        button.backgroundColor = pencilCase.color
        button.tag = pencilCase.rawValue
        button.layer.cornerRadius = 8 // 可选:添加圆角优化视觉效果
        button.addTarget(self, action: #selector(buttonClicked), for: .touchUpInside)
        
        // 设置按钮固定尺寸
        button.translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint.activate([
            button.widthAnchor.constraint(equalToConstant: 100),
            button.heightAnchor.constraint(equalToConstant: 100)
        ])
        buttons.append(button)
    }
    return buttons
}

3. 在viewDidLoad中用StackView管理按钮

override func viewDidLoad() {
    super.viewDidLoad()
    
    let buttons = createColorButton()
    // 创建水平排列的StackView,可改为.vertical实现纵向排列
    let stackView = UIStackView(arrangedSubviews: buttons)
    stackView.translatesAutoresizingMaskIntoConstraints = false
    stackView.axis = .horizontal
    stackView.spacing = 10
    stackView.alignment = .center
    stackView.distribution = .equalSpacing
    
    view.addSubview(stackView)
    
    // 固定StackView到顶部居中位置
    NSLayoutConstraint.activate([
        stackView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 20),
        stackView.leadingAnchor.constraint(greaterThanOrEqualTo: view.leadingAnchor, constant: 20),
        stackView.trailingAnchor.constraint(lessThanOrEqualTo: view.trailingAnchor, constant: -20),
        stackView.centerXAnchor.constraint(equalTo: view.centerXAnchor)
    ])
    
    setupImageViews()
}

方案二:手动计算Frame位置(传统布局方式)

如果偏好手动控制坐标,可通过索引计算每个按钮的位置:

func createColorButton() -> [UIButton]{
    var buttons: [UIButton] = []
    let buttonSize = CGSize(width: 100, height: 100)
    let spacing: CGFloat = 10
    let startX: CGFloat = 50
    let startY: CGFloat = 50
    
    for (index, pencilCase) in Pencil.allCases.enumerated() {
        // 根据索引计算每个按钮的X坐标,实现横向排列
        let x = startX + (buttonSize.width + spacing) * CGFloat(index)
        let button = UIButton(frame: CGRect(x: x, y: startY, width: buttonSize.width, height: buttonSize.height))
        button.backgroundColor = pencilCase.color
        button.tag = pencilCase.rawValue
        button.addTarget(self, action: #selector(buttonClicked), for: .touchUpInside)
        buttons.append(button)
    }
    return buttons
}

此方法需配合优化后的Pencil枚举(使用rawValue),并在viewDidLoad中直接添加按钮即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 05:04:52