【问题标题】:Type 'UIButton' has no member 'sender'类型“UIButton”没有成员“发件人”
【发布时间】:2023-03-05 20:36:01
【问题描述】:

如果'sender'在函数的参数中是 UIButton 类型,为什么不能使用点运算符显式显示它从 UIButton 类继承?它是否与 Swift 的类型推断功能有关,或者在这种情况下键入 'UIButton.sender' 是错误的?我是 OOP 的新手,仍在弄清楚属性如何从 Swift 中的类(例如 UIButton)继承。

@IBAction private func touchDigit(sender: UIButton) {
    let digit = UIButton.sender.currentTitle!  // ERROR unless UIButton is removed
    if userIsInTheMiddleOfTyping {
        let textCurrentlyInDisplay = display.text!
        display.text = textCurrentlyInDisplay + digit
    } else {
        display.text = digit
    }
    userIsInTheMiddleOfTyping = true
}

【问题讨论】:

  • let digit = sender.currentTitle! 最有可能......但这里展开的力量仍然让我扬起眉毛。
  • 谢谢!为避免强制解包,这会是使用可选绑定的情况吗?我听说如果可以保证在某个时候设置某些东西,那么强制展开可能会很好,尽管正如你所暗示的那样有风险。

标签: ios swift xcode uibutton


【解决方案1】:

您缺少一些关于 swift 的基本知识。您的情况下的点运算符不会“明确显示为从 UIButton 类继承”。点运算符可以访问类中的属性、方法或嵌入元素。

如果您希望您的代码 UIButton.sender 正常工作,您可以编写如下代码:

extension UIButton {
    static var sender: UIButton { return UIButton() }
}

并不是说这有任何意义。它将使您的代码正常工作,但会生成一个新按钮,与您的 sender 无关。

您的情况下的继承已经在方法参数touchDigit(sender: UIButton) 中显式完成,但也可以通过编写touchDigit(sender: Any) 来删除。现在在这种情况下sender 可能是任何东西。要将其用作UIButton,您需要将其类型转换为sender as! UIButton

@IBAction private func touchDigit(sender: Any) {
    let digit = (sender as! UIButton).currentTitle!  

如果你用按钮以外的任何东西调用它,这可能会崩溃,例如,如果你这样做了:

func doSomething() {
    self.touchDigit(sender: "some text")
}

@IBAction private func touchDigit(sender: Any) {
    let digit = (sender as! UIButton).currentTitle!  

调用doSomething 将使您的应用程序在(sender as! UIButton) 崩溃,因为发件人不是UIButton。因此,在这种情况下您要做的就是检查以下类型:

func doSomething() {
    self.touchDigit(sender: "some text")
}

@IBAction private func touchDigit(sender: Any) {
    if let button = sender as? UIButton {
        let digit = button.currentTitle!
            if userIsInTheMiddleOfTyping {
                let textCurrentlyInDisplay = display.text!
                display.text = textCurrentlyInDisplay + digit
            } else {
                display.text = digit
            }
            userIsInTheMiddleOfTyping = true
        }
    } else if let text = sender as? String {
        display.text = text
    }
}

我希望这可以为您解决一些问题。

【讨论】:

  • 这太好了,谢谢!此外,在“if let button = sender as?UIButton”这一行上,可以“as!”或者在将 sender 转换为 UIButton 时使用?
  • @JCoder 否。您将收到编译时错误,因为表达式不是可选的。所以明确的区别是:let button: UIButton? = sender as? UIButtonlet button: UIButton = sender as! UIButton。由于第二个不是可选的(没有?),您不能继续使用if let button = button
【解决方案2】:

UIButton 是一个类,senderUIButton 的实例变量。所以你不能通过 Class(UIButton) 访问实例变量中的属性。

如果UIButton 有静态变量或类函数,您可以使用类访问它(例如:UIButton.description())。

也在下面的函数中,

func touchDigit(sender: UIButton)

sender是函数的参数,UIButtonsender参数的类型。

您可以在此处了解有关 Swift 函数的更多信息:https://docs.swift.org/swift-book/LanguageGuide/Functions.html

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-03
    • 2015-08-14
    • 1970-01-01
    • 2016-09-18
    相关资源
    最近更新 更多