简体   繁体   中英

Type 'UIButton' has no member 'sender'

If 'sender' is of type UIButton in the function's argument, why can't it be explicitly shown to inherit from the UIButton class using the dot operator? Does it have something to do with Swift's type-inference feature, or is it wrong to type 'UIButton.sender' in this situation? I'm new to OOP and still figuring out how properties inherit from classes (eg UIButton) in Swift.

@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
}

You are missing some fundamental knowledge about swift. The dot operator in your case does not "explicitly shown to inherit from the UIButton class". The dot operator can access a property, method or embedded element in your class.

If you wanted your code UIButton.sender to work you could write something like:

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

Not that this makes any sense. It will make your code work but it will generate a new button and have nothing to do with your sender .

Inheritance in your case is already explicitly done in the method argument touchDigit(sender: UIButton) but could as well be removed by writing touchDigit(sender: Any) . Now in this case sender may be anything. To use it as UIButton you need to typecast it like sender as! UIButton sender as! UIButton :

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

This may then crash if you call it with anything but a button, So for instance if you did:

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

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

Call to doSomething will crash your app at (sender as! UIButton) since sender is not an UIButton . So what you do in such case is check for type like:

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
    }
}

I hope this clears a few things for you.

UIButton is a class and sender is an instance variable of UIButton . So You can't access properties inside instance variable via Class( UIButton ).

If UIButton has static variables or class functions, you can access it using class(ex: UIButton.description()).

Also in below function,

func touchDigit(sender: UIButton)

sender is a parameter of the function and UIButton is the type of sender parameter.

You can learn more about Swift functions here: https://docs.swift.org/swift-book/LanguageGuide/Functions.html

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM