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
相关产品推荐
相关产品推荐

