ошибка «только методы экземпляра может быть объявлена ​​@ibaction» - PullRequest
0 голосов
/ 16 мая 2018

Это проблема:

@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 голосов
/ 16 мая 2018

Это распространенная ошибка новичка, вызванная грязным форматированием.Ваш отступ меняется от метода к методу, вы не будете осторожны с размещением открывающих и закрывающих скобок в правильные места с отступами, и это заставляет вас упускать из виду неправильную структуру кода.

Давайте посмотрим на ваш код с последовательным отступом:

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()
            }
        }
    }
}
0 голосов
/ 16 мая 2018

Затем сделайте метод методом экземпляра (объявив его вне любого метода в этом объекте) и просто вызовите его из любого места в контроллере представления.Метод или свойство экземпляра - это метод или свойство, которое доступно всему экземпляру этого объекта.Объявление вашего метода внутри 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)
    }
}
...