【问题标题】:How to handle events for two separate buttons in one method?如何以一种方法处理两个单独按钮的事件?
【发布时间】:2023-03-16 07:30:01
【问题描述】:

我的视图上有两个 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 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
        }

} 

【问题讨论】:

  • 在您的@IBAction func buttonClick 中,if 问题是错误的问题。问题是:sender 是谁?
  • 我很难弄清楚如何将 FM 按钮和 AM 按钮识别为发送者。我可以通过按钮的文本进行检查吗?这听起来不太好/好像它会起作用。
  • 安全地向下转换到 UIButton 并使用===
  • 我尝试if buttonFM.isTouchInside == true 来识别发件人,但没有成功。
  • “如果按下按钮将起作用” 您已经知道按下了按钮。如果没有,你就不会在这里。问题是哪一个。发件人就是那个。它在尖叫我我我。你所要做的就是倾听。

标签: ios swift uibutton


【解决方案1】:

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

无论如何,将您的发件人类型从任何更改为 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()
        }
    }
}

【讨论】:

  • Forif sender.titleLabel!.text == buttonFM 你仍然会遇到错误'二进制运算符'=='不能应用于'字符串'类型的操作数?和 'UIButton' 所以这不起作用,看起来也需要向下转换方法,请参阅上面的 Matt 的 cmets。我同意代码不是最佳的——但我只有 150 页的入门书,而且必须从某个地方开始。其中大部分对我来说都是新的,我肯定会为此创建两个不同的功能。我之前确实有两个单独的按钮 IBAction/方法,但我想尝试将它们合二为一。
  • 我会每天努力做到这一点,直到我好起来。
  • timman,试试我上面做的修改。抱歉,我没有 IDE,我只是坐在手机上的公园里。我认为它现在应该可以工作了,我们正在检查 button.title 属性与 sender.titlelabel.text
  • 还是报错:Value of optional type 'UILabel?' must be unwrapped to refer to member 'text' of wrapped base type 'UILabel'
  • 试试这个,抱歉没有 IDE。
猜你喜欢
  • 1970-01-01
  • 2011-10-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多