这是问题所在:
@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()
}
});
}
}
}
}
答案 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)
}
}