如何在一种方法中处理两个单独按钮的事件?

How to handle events for two separate buttons in one method?

我的视图中有两个 UIButton,一个用于 FM 收音机,一个用于 AM 收音机。 当按下 FM 按钮时,我想在各自的标签中显示电台名称、频率和带宽值的 FM 值,AM 也一样。

我有工作代码,每个按钮都使用单独的 buttonClick 方法,但由于代码相同,我想尝试在一个方法中完成所有操作。这个可恶的东西在下面!

下面是按钮按下方法的代码。

    @IBAction func buttonClick(_ sender: Any) {
        if buttonFM != nil {
            if myStation.isBandFM() == 1 {
            stationBand.text = "FM1"
            stationName.text = myStation.name //set top left label text to name property of myStation object
                stationFrequency.text = "\(myStation.frequency)"
            }
        } else if buttonAM != nil {
            if myStation.isBandFM() == 0 {
            stationBand.text = "AM1" //final exercise, part 1.
            stationName.text = myStationAM.name
            stationFrequency.text = "\(myStationAM.frequency)"
        }
    }
}

这是完整的视图控制器代码:

    class ViewController: UIViewController {

        @IBOutlet weak var stationName: UILabel!
        @IBOutlet weak var stationFrequency: UILabel!
        @IBOutlet weak var stationBand: UILabel!

        @IBOutlet weak var buttonFM: UIButton!
        @IBOutlet weak var buttonAM: UIButton!

        var myStation: RadioStation //FM station

        var myStationAM: RadioStation //AM station

        required init?(coder aDecoder: NSCoder) {
            myStation = RadioStation()  
            myStationAM = RadioStation()
            myStation.frequency = 104.7
            myStationAM.frequency = 800.2
            myStation.name = "FM1"
            myStationAM.name = "AM1"
            super.init(coder: aDecoder)
        }

        override func viewDidLoad() {
            super.viewDidLoad()
            // Do any additional setup after loading the view.
            stationName.text = nil 
        }

        @IBAction func buttonClick(_ sender: Any) {
        if buttonFM != nil {
            if myStation.isBandFM() == 1 {
            stationBand.text = "FM1"
            stationName.text = myStation.name //set top left label text to name property of myStation object
                stationFrequency.text = "\(myStation.frequency)"
            }
        } else if buttonAM != nil {
            if myStation.isBandFM() == 0 {
            stationBand.text = "AM1" //final exercise, part 1.
            stationName.text = myStationAM.name
            stationFrequency.text = "\(myStationAM.frequency)"
        }
    }
}

这是 class 方法:

class RadioStation: NSObject {

    var name: String
    var frequency: Double

    override init() {  //init class method to set default values.
        name = "Default"
        frequency = 100
    }

    static var minAMFFrequency: Double = 520.0
    static var maxAMFFrequency: Double = 1610.0
    static var minFMFFrequency: Double = 88.3
    static var maxFMFFrequency: Double = 107.9

    func isBandFM() -> Int {
        if frequency >= RadioStation.minFMFFrequency && frequency <= RadioStation.maxFMFFrequency {
            return 1 //FM
        } else  {
            return 0 //AM
        }

} 

我猜你无法阻止人们编写糟糕的代码。这是糟糕代码的原因是它破坏了 [S][O]LID — 关注点分离以及 Open/Close。现在按钮操作正在处理多个问题。

无论如何,将您的发件人类型从任意更改为 UIButton,然后检查标签标题。


    @IBAction func buttonClick(_ sender: UIButton) {
        guard let button = sender.titleLabel?.text else {return}
        if button == buttonFM.title {
            if myStation.isBandFM() == 1 {
            stationBand.text = "FM1"
            stationName.text = myStation.name //set top left label text to name property of myStation object
                stationFrequency.text = "\(myStation.frequency)"
            }
        } else if button == buttonAM.title {
            if myStation.isBandFM() == 0 {
            stationBand.text = "AM1" //final exercise, part 1.
            stationName.text = myStationAM.name
            stationFrequency.text = "\(myStationAM.frequency)"
        }
    }
}

你得这样想。如果您现在想在将来修改其中一个按钮的功能,则必须在两种不同的情况下编辑 buttonClick 操作。

如果你真的想这样做,我建议至少做一些抽象并像这样创建两个函数...

// Using some abstraction if you decide to make modification
// based on an action you wont need to touch this method anymore. 
// The changes would be made in their corresponding functions. 

    @IBAction func buttonClick(_ sender: UIButton) {

        guard let button = sender.titleLabel?.text else {return}

        if button == buttonFM.title {
               buttonFMClick()
            }
        } else if button == buttonAM.title {
               buttonAMClick()
        }
    }
}