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

Swift(Xcode9)实现UIButton单选:选中时取消其他按钮选中状态

Hey Frank, let's tackle this button selection problem for your Arduino LED control app! The core issue here is making sure only one color button is active at a time—super common for single-selection groups, so we've got a few solid ways to fix this.

解决方案1:创建按钮组管理器(推荐,解耦且可扩展)

This approach pulls the selection logic out of individual buttons, so they don't depend on each other, and adding new color buttons later will be a breeze.

First, let's polish your ToggleTheButtons subclass to make sure it updates its appearance when the isOn state changes:

import UIKit

class ToggleTheButtons: UIButton {
    var isOn = false {
        didSet {
            // Update the button's look based on its state (customize these styles to match your app!)
            updateButtonAppearance()
        }
    }
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        commonInit()
    }
    
    required init?(coder: NSCoder) {
        super.init(coder: coder)
        commonInit()
    }
    
    private func commonInit() {
        // Set up default unselected style
        updateButtonAppearance()
        // Hook up the tap event to our handler
        addTarget(self, action: #selector(buttonTapped), for: .touchUpInside)
    }
    
    @objc private func buttonTapped() {
        // Let the group manager handle selection logic instead of toggling directly
        ColorButtonGroup.shared.didTapButton(self)
    }
    
    private func updateButtonAppearance() {
        if isOn {
            backgroundColor = .systemBlue // Selected state color
            setTitleColor(.white, for: .normal)
            layer.borderWidth = 2
            layer.borderColor = UIColor.systemBlue.cgColor
        } else {
            backgroundColor = .systemGray5 // Unselected state color
            setTitleColor(.black, for: .normal)
            layer.borderWidth = 0
        }
    }
}

Next, create a singleton group manager to handle all color button states:

class ColorButtonGroup {
    static let shared = ColorButtonGroup()
    
    private var colorButtons: [ToggleTheButtons] = []
    
    // Add a button to the selection group
    func addButton(_ button: ToggleTheButtons) {
        colorButtons.append(button)
    }
    
    // Handle button taps to enforce single selection
    func didTapButton(_ tappedButton: ToggleTheButtons) {
        for button in colorButtons {
            button.isOn = button == tappedButton
        }
        // Optional: Add code here to send the selected color to your Arduino via serial!
    }
}

Finally, register all your color buttons with the manager in your view controller:

class ViewController: UIViewController {
    @IBOutlet weak var redButton: ToggleTheButtons!
    @IBOutlet weak var greenButton: ToggleTheButtons!
    @IBOutlet weak var blueButton: ToggleTheButtons!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // Add all color buttons to the group manager
        ColorButtonGroup.shared.addButton(redButton)
        ColorButtonGroup.shared.addButton(greenButton)
        ColorButtonGroup.shared.addButton(blueButton)
    }
}
解决方案2:快速实现(适合少量按钮)

If you only have a handful of color buttons and don't want to add a manager class, you can handle selection directly in your view controller:

class ViewController: UIViewController {
    @IBOutlet weak var redButton: ToggleTheButtons!
    @IBOutlet weak var greenButton: ToggleTheButtons!
    @IBOutlet weak var blueButton: ToggleTheButtons!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // Hook up all buttons to a single tap handler
        redButton.addTarget(self, action: #selector(colorButtonTapped(_:)), for: .touchUpInside)
        greenButton.addTarget(self, action: #selector(colorButtonTapped(_:)), for: .touchUpInside)
        blueButton.addTarget(self, action: #selector(colorButtonTapped(_:)), for: .touchUpInside)
        
        // Initialize all buttons to unselected state
        [redButton, greenButton, blueButton].forEach { $0?.isOn = false }
    }
    
    @objc private func colorButtonTapped(_ sender: ToggleTheButtons) {
        // Deselect all buttons first
        redButton.isOn = false
        greenButton.isOn = false
        blueButton.isOn = false
        // Select the tapped button
        sender.isOn = true
        
        // Optional: Send the selected color to Arduino here
    }
}

// Make sure your ToggleTheButtons class still has the isOn didSet and updateButtonAppearance method from Solution 1!
Quick Tip

Don't forget that when you send the selected color to Arduino, you can map each button's selection to a specific serial command (like sending "R" for red, "G" for green, etc.) to trigger the LED color change.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 06:29:18