"只能声明实例方法@ ibaction"错误

时间:2018-05-16 08:01:10

标签: swift xcode ibaction

这是问题所在:

@IBAction func signInTapped(_ sender: Any) {

我一直在接收"只有实例方法可以声明@ ibaction"错误。帮我解决这个问题。请不要建议删除" @ IBAction"。谢谢。这是整个混乱的编码情况:

import UIKit
import Firebase
class ViewController: UIViewController {
    @IBOutlet weak var emailField: UITextField!
    @IBOutlet weak var passwordField: UITextField!

    var userUid: String!

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    func goToCreateUserVC(){
        performSegue(withIdentifier: "SignUp", sender: nil)
    }
    func goToFeedVC(){
        performSegue(withIdentifier: "ToFeed", sender: nil)
    }

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "SignUp" {
            if let destination = segue.destination as? userVC {
                if userUid != nil {
                    destination.userUid = userUid
            }
                if emailField.text != nil {
                    destination.emailField = emailField.text
                }
                if passwordField.text != nil {
                    destination.passwordField = passwordField.text
                }
        }
    }
    @IBAction func signInTapped(_ sender: Any) {
        if let email = emailField.text, let password = passwordField.text {
            Auth.auth().signIn(withEmail: email, password: password, completion:
                { (user,error) in
                if error == nil {
                    if user != nil {
                        self.goToCreateUserVC()
                        self.goToFeedVC()
                    }
                } else {
                    self.goToCreateUserVC()
                }
            });
            }
        }

    }


}

2 个答案:

答案 0 :(得分:3)

这是由凌乱的格式引起的常见初学者错误。你的缩进从一个方法变为另一个方法,你不小心将打开和关闭的护腕放在正确缩进的位置,这会让你错过你的代码结构错误。

让我们看看你的代码是否具有一致的缩进:

class ViewController: UIViewController {
    @IBOutlet weak var emailField: UITextField!
    @IBOutlet weak var passwordField: UITextField!

    var userUid: String!

    func goToCreateUserVC() {
        performSegue(withIdentifier: "SignUp", sender: nil)
    }
    func goToFeedVC() {
        performSegue(withIdentifier: "ToFeed", sender: nil)
    }

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "SignUp" {
            if let destination = segue.destination as? userVC {
                if userUid != nil {
                    destination.userUid = userUid
                }
                if emailField.text != nil {
                    destination.emailField = emailField.text
                }
                if passwordField.text != nil {
                    destination.passwordField = passwordField.text
                }
            }
        }
        @IBAction func signInTapped(_ sender: Any) {
            if let email = emailField.text, let password = passwordField.text {
                Auth.auth().signIn(withEmail: email, password: password) { (user,error) in
                    if error == nil {
                        if user != nil {
                            self.goToCreateUserVC()
                            self.goToFeedVC()
                        }
                    } else {
                        self.goToCreateUserVC()
                    }
                }
            }
        }
    }
}

现在很明显你的signInTapped实际上是在prepare内定义的,因此它不是实例方法而是内部函数。

通过将闭合护腕移动到正确的位置,可以很容易地解决这个问题:

class ViewController: UIViewController {
    @IBOutlet weak var emailField: UITextField!
    @IBOutlet weak var passwordField: UITextField!

    var userUid: String!

    func goToCreateUserVC(){
        performSegue(withIdentifier: "SignUp", sender: nil)
    }
    func goToFeedVC(){
        performSegue(withIdentifier: "ToFeed", sender: nil)
    }

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "SignUp" {
            if let destination = segue.destination as? userVC {
                if userUid != nil {
                    destination.userUid = userUid
                }
                if emailField.text != nil {
                    destination.emailField = emailField.text
                }
                if passwordField.text != nil {
                    destination.passwordField = passwordField.text
                }
            }
        }
    }

    @IBAction func signInTapped(_ sender: Any) {
        if let email = emailField.text, let password = passwordField.text {
            Auth.auth().signIn(withEmail: email, password: password) { (user,error) in
                if error == nil {
                    if user != nil {
                        self.goToCreateUserVC()
                        self.goToFeedVC()
                    }
                } else {
                    self.goToCreateUserVC()
                }
            }
        }
    }
}

为了提高代码可读性(这是真正的问题),我们还使用减少压痕级别的数量,例如,使用提前退货

class ViewController: UIViewController {
    @IBOutlet weak var emailField: UITextField!
    @IBOutlet weak var passwordField: UITextField!

    var userUid: String!

    func goToCreateUserVC(){
        performSegue(withIdentifier: "SignUp", sender: nil)
    }
    func goToFeedVC(){
        performSegue(withIdentifier: "ToFeed", sender: nil)
    }

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        guard
            segue.identifier == "SignUp",
            let destination = segue.destination as? userVC
        else {
            return
        }

        if userUid != nil {
            destination.userUid = userUid
        }
        if emailField.text != nil {
            destination.emailField = emailField.text
        }
        if passwordField.text != nil {
            destination.passwordField = passwordField.text
        }
    }

    @IBAction func signInTapped(_ sender: Any) {
        guard let email = emailField.text, let password = passwordField.text else {
            return
        }

        Auth.auth().signIn(withEmail: email, password: password) { (user,error) in
            if error == nil {
                if user != nil {
                    self.goToCreateUserVC()
                    self.goToFeedVC()
                }
            } else {
                self.goToCreateUserVC()
            }
        }
    }
}

答案 1 :(得分:0)

然后使该方法成为一个实例方法(通过在该对象中的任何方法之外声明它)并简单地从视图控制器中的任何位置调用它。实例方法或属性是可用于该对象的整个实例的方法或属性。在prepare(for segue: UIStoryboardSegue, sender: Any?)中声明您的方法使其仅适用于该方法。

import UIKit
import Firebase
class ViewController: UIViewController {
    @IBOutlet weak var emailField: UITextField!
    @IBOutlet weak var passwordField: UITextField!
    @IBAction func signInTapped(_ sender: Any) {
        if let email = emailField.text, let password = passwordField.text {
            Auth.auth().signIn(withEmail: email, password: password, completion:
                { (user,error) in
                    if error == nil {
                        if user != nil {
                            self.goToCreateUserVC()
                            self.goToFeedVC()
                        }
                    } else {
                        self.goToCreateUserVC()
                    }
            });
        }
    }

    var userUid: String!

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    func goToCreateUserVC(){
        performSegue(withIdentifier: "SignUp", sender: nil)
    }
    func goToFeedVC(){
        performSegue(withIdentifier: "ToFeed", sender: nil)
    }

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "SignUp" {
            if let destination = segue.destination as? userVC {
                if userUid != nil {
                    destination.userUid = userUid
                }
                if emailField.text != nil {
                    destination.emailField = emailField.text
                }
                if passwordField.text != nil {
                    destination.passwordField = passwordField.text
                }
            }
        }
        signInTapped(sender)
    }
}