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.
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) } }
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!
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

