【问题标题】:Why am I getting "Only instance methods can be declared @IBAction" in this code?为什么我在这段代码中得到“只能声明实例方法@IBAction”?
【发布时间】:2019-07-02 15:54:39
【问题描述】:

我正在尝试为一个学校项目构建一个适用于 ios 的社交网络应用程序。我的@IBAction 登录功能不起作用,我不知道为什么。我得到的错误是:“只能声明实例方法@IBAction”

这是我的代码:

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 viewDidAppear(_ animated: Bool){
        if let _ = KeychainWrapper.standard.string(forKey: "uid") {
            performSegue(withIdentifier: "Messages", sender: nil)
        }

        func prepare(for segue: UIStoryboardSegue, sender: Any?) {

            if segue.identifier == "SignUp" {

                if let destination = segue.destination as? SignUpVC {
                    if self.userUid != nil{
                        destination.userUid = userUid
                    }
                    if self.emailField.text != nil {
                        destination.emailField = emailField.text
                    }
                    if self.passwordField.text != nil {
                        destination.passwordField = passwordField.text
                    }
                }
            }
        }

        @IBAction func SignIn (_ sender: AnyObject) {
        if let email = emailField.text, let password = passwordField.text{
            Auth.auth().signIn(withEmail: email, password: password, completion:{
                (user, error) in
                if error == nil{
                    self.userUid = user?.user.uid
                    KeychainWrapper.standard.set(self.userUid, forKey: "uid")
                    self.performSegue(withIdentifier: "Messages", sender: nil)
                } else {
                    self.performSegue(withIdentifier: "SignUp", sender: nil)
                }
            })
        }
    }
}
}

【问题讨论】:

  • 为什么你的func prepare(for segue: UIStoryboardSegue, sender: Any?)方法在viewWillAppear里面?那要么是错误的复制/粘贴到此处,要么您需要将其移出。看起来您的 IBAction 也可能在另一个方法中,或者您已经在某处声明了一个静态方法。请整理一下这段代码,它很难阅读,显然会导致问题。
  • 您的错误在于范围。 swift中的函数不能包含其他函数。
  • 函数可以包含函数,但是将 prepare: 放入 viewDidLoad: 是不正确的。

标签: ios swift social-media


【解决方案1】:
func prepare(for segue: UIStoryboardSegue, sender: Any?) {

            if segue.identifier == "SignUp" {

                if let destination = segue.destination as? SignUpVC {
                    if self.userUid != nil{
                        destination.userUid = userUid
                    }
                    if self.emailField.text != nil {
                        destination.emailField = emailField.text
                    }
                    if self.passwordField.text != nil {
                        destination.passwordField = passwordField.text
                    }
                }
            }
        }

        @IBAction func SignIn (_ sender: AnyObject) {
        if let email = emailField.text, let password = passwordField.text{
            Auth.auth().signIn(withEmail: email, password: password, completion:{
                (user, error) in
                if error == nil{
                    self.userUid = user?.user.uid
                    KeychainWrapper.standard.set(self.userUid, forKey: "uid")
                    self.performSegue(withIdentifier: "Messages", sender: nil)
                } else {
                    self.performSegue(withIdentifier: "SignUp", sender: nil)
                }
            })
        }

应该在viewDidAppear之外

【讨论】:

    【解决方案2】:

    你为 segue 做准备,登录函数都嵌套在 viewDidAppear 方法中。使用 cmets 有助于直观地分解函数。

    class ViewController: UIViewController {
        // MARK: Outlets
        @IBOutlet weak var emailField: UITextField!
        @IBOutlet weak var passwordField: UITextField!`
        // MARK: Properties
        var userUid: String!
        // MARK: Lifecycle
        override func viewDidAppear(_ animated: Bool) {
            if let _ = KeychainWrapper.standard.string(forKey: "uid") {
                performSegue(withIdentifier: "Messages", sender: nil)
            }
        }
        // MARK: Navigation
        func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    
            if segue.identifier == "SignUp" {
    
                if let destination = segue.destination as? SignUpVC {
                    if self.userUid != nil{
                        destination.userUid = userUid
                    }
                    if self.emailField.text != nil {
                        destination.emailField = emailField.text
                    }
                    if self.passwordField.text != nil {
                        destination.passwordField = passwordField.text
                    }
                }
            }
        }
        // MARK: Actions
        @IBAction func SignIn (_ sender: AnyObject) {
            if let email = emailField.text, let password = passwordField.text{
                Auth.auth().signIn(withEmail: email, password: password, completion:{
                    (user, error) in
                    if error == nil{
                        self.userUid = user?.user.uid
                        KeychainWrapper.standard.set(self.userUid, forKey: "uid")
                        self.performSegue(withIdentifier: "Messages", sender: nil)
                    } else {
                        self.performSegue(withIdentifier: "SignUp", sender: nil)
                    }
                })
            }
        }
    }
    

    【讨论】:

      【解决方案3】:

      原因是您的SignIn 不是实例方法,它是viewDidAppear 内部的嵌套函数。在viewDidAppear 中添加另一个右括号

      override func viewDidAppear(_ animated: Bool){
          if let _ = KeychainWrapper.standard.string(forKey: "uid") {
              performSegue(withIdentifier: "Messages", sender: nil)
          }
      }
      

      并在文件末尾删除一个

      【讨论】:

        【解决方案4】:

        函数func prepare(for segue: UIStoryboardSegue, sender: Any?)应该在类范围内而不是嵌套在viewDidAppear

        override func viewDidAppear(_ animated: Bool){
            super.viewDidAppear(animated)
            if let _ = KeychainWrapper.standard.string(forKey: "uid"){
                performSegue(withIdentifier: "Messages", sender: nil)
            } 
        }
        
        @IBAction func SignIn (_ sender: AnyObject) {
            if let email = emailField.text, let password = passwordField.text{
                Auth.auth().signIn(withEmail: email, password: password, completion:{
                    (user, error) in
                    if error == nil{
                        self.userUid = user?.user.uid
                        KeychainWrapper.standard.set(self.userUid, forKey: "uid")
                        self.performSegue(withIdentifier: "Messages", sender: nil)
                    } else {
                        self.performSegue(withIdentifier: "SignUp", sender: nil)
                    }
                })
            }
        } 
        func prepare(for segue: UIStoryboardSegue, sender: Any?){ 
            if segue.identifier == "SignUp"{ 
                if let destination = segue.destination as? SignUpVC { 
                    if self.userUid != nil {
                        destination.userUid = userUid
                    }  
                    destination.emailField = emailField.text 
                    destination.passwordField = passwordField.text 
                }
            } 
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-09-20
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-04-15
          相关资源
          最近更新 更多