【问题标题】:Taking text values from one view controller to another将文本值从一个视图控制器传送到另一个视图控制器
【发布时间】:2017-04-20 12:04:11
【问题描述】:

所以我试图让用户通过 Facebook 注册,所以他们会点击 facebook 按钮,授权我们的应用程序,然后将他们转到注册屏幕,其中填写了“电子邮件”和“全名”字段我们从 Facebook 图表请求中收到的值。但是,我无法让它工作。

这是 Facebook 按钮所在的第一个视图控制器

import UIKit
import FBSDKLoginKit

  //[Facebook, 2017]
class RegisterVC: UIViewController, FBSDKLoginButtonDelegate {
var fbLoginSuccess = false

var fbName:String!
var fbEmail:String!

//[Facebook, 2017]
override func viewDidLoad() {
    super.viewDidLoad()

    let loginButton = FBSDKLoginButton()
    view.addSubview(loginButton)
    loginButton.frame = CGRect(x: 82, y: 325, width: view.frame.width - 210, height: 59)

    loginButton.delegate = self
}

//[Facebook, 2017]
func loginButtonDidLogOut(_ loginButton: FBSDKLoginButton!) {
    print("Did log out of facebook")
}

//[Facebook, 2017]
func loginButton(_ loginButton: FBSDKLoginButton!, didCompleteWith result: FBSDKLoginManagerLoginResult!, error: Error!) {
    if error != nil {
        print(error)
        return
    }
    print("Successfully logged in")

    FBSDKGraphRequest(graphPath: "/me", parameters: ["fields": "id, name, email"]).start {(connection, result, err) in
        if err != nil {
            print("Failed to start graph request", err)
            return
        } else {
            /*guard let data = result as? [String:Any] else {return}

            let fbEmail = data["email"] as! String
            let fbName  = data["name"] as! String

            print(fbEmail)
            print(fbName)

            func prepare(for segue: UIStoryboardSegue, sender: Any?) {
                let vc = segue.destination as? CreateAccountVC
                vc!.emailTxtValue = self.fbName
                vc!.fullnameTxtValue = self.fbEmail
                */
            }

        guard let data = result as? [String:Any] else {return}

        let fbEmail = data["email"] as! String
        let fbName  = data["name"] as! String

        print(fbEmail)
        print(fbName)

        func prepare(for segue: UIStoryboardSegue, sender: Any?) {
            if let vc = segue.destination as? CreateAccountVC {
            vc.emailTxtValue = self.fbName
            vc.fullnameTxtValue = self.fbEmail
            }
        }


        print(result)
    }

    performSegue(withIdentifier: "regSegue", sender: RegisterVC.self)

}

//override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    //get destination view an set the fullname



    //performSegue(withIdentifier: "regSegue", sender: RegisterVC.self)

//}



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





 }

这是下一个视图控制器,其文本字段应显示从 Facebook 获取的信息

import UIKit

class CreateAccountVC: UIViewController {

var emailTxtValue: String?
var fullnameTxtValue: String?

@IBOutlet weak var usernameTxt: UITextField!
@IBOutlet weak var emailTxt: UITextField!
@IBOutlet weak var passwordTxt: UITextField!
@IBOutlet weak var fullnameTxt: UITextField!

override func viewDidLoad() {
    //fullname.text = fbName
    //email.text = fbEmail
    super.viewDidLoad()
    emailTxt.text = emailTxtValue
    fullnameTxt.text = fullnameTxtValue
    print(emailTxtValue)
    print("here")
    print(fullnameTxtValue)


}

func isValidEmail(emailTxt:String) -> Bool {
    // print("validate calendar: \(testStr)")
    let emailRegEx = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}"
    let emailTest = NSPredicate(format:"SELF MATCHES %@", emailRegEx)
    return emailTest.evaluate(with: emailTxt)
}

/*func isValidPassword(passwordTxt:String) -> Bool {
    let passwordRegEx = "{8,}"
    let passwordTest = NSPredicate(format:"SELF MATCHES %@", passwordRegEx)
    return passwordTest.evaluate(with: passwordTxt)
} */

func isValidUsername(usernameTxt:String) -> Bool {
    let usernameRegEx = "[a-z0-9_-]{5,16}"
    let usernameTest = NSPredicate(format:"SELF MATCHES %@", usernameRegEx)
    return usernameTest.evaluate(with: usernameTxt)
}

//[Idigov, 2017]
@IBAction func create(_ sender: AnyObject) {
    if usernameTxt.text!.isEmpty || passwordTxt.text!.isEmpty || emailTxt.text!.isEmpty || fullnameTxt.text!.isEmpty {

        usernameTxt.attributedPlaceholder = NSAttributedString(string: "username", attributes: [NSForegroundColorAttributeName: UIColor.red])
        emailTxt.attributedPlaceholder = NSAttributedString(string: "email", attributes:[NSForegroundColorAttributeName: UIColor.red])
        passwordTxt.attributedPlaceholder = NSAttributedString(string: "password", attributes: [NSForegroundColorAttributeName: UIColor.red])
        fullnameTxt.attributedPlaceholder = NSAttributedString(string: "fullname", attributes: [NSForegroundColorAttributeName: UIColor.red])

        let alertController = UIAlertController(title: "Error", message: "At least one of the values entered was not valid", preferredStyle: UIAlertControllerStyle.alert)
        alertController.addAction(UIAlertAction(title: "Okay", style: UIAlertActionStyle.default, handler:nil))
        self.present(alertController, animated: true, completion: nil)
        // if there is text within any of the textboxes it will attempt to register

    } else if
        isValidEmail(emailTxt: emailTxt.text!) == false {
        let alertController = UIAlertController(title: "Error", message: "The email entered is not valid", preferredStyle: UIAlertControllerStyle.alert)
        alertController.addAction(UIAlertAction(title: "Okay", style: UIAlertActionStyle.default, handler:nil))
        self.present(alertController, animated: true, completion: nil)

    } /*else if isValidPassword(passwordTxt: passwordTxt.text!) == false{
            let alertController = UIAlertController(title: "Error", message: "The password entered must be at least 8 characters long", preferredStyle: UIAlertControllerStyle.alert)
            alertController.addAction(UIAlertAction(title: "Okay", style: UIAlertActionStyle.default, handler:nil))
            self.present(alertController, animated: true, completion: nil)

    } */else if isValidUsername(usernameTxt: usernameTxt.text!) == false {
        let alertController = UIAlertController(title: "Error", message: "Your username must be 5 to 16 characters long and can only contain letters, numbers, underscores or hyphens", preferredStyle: UIAlertControllerStyle.alert)
        alertController.addAction(UIAlertAction(title: "Okay", style: UIAlertActionStyle.default, handler:nil))
        self.present(alertController, animated: true, completion: nil)
    }

    //[Idigov, 2017]
    else{


        let url = NSURL(string: "https://cgi.soic.indiana.edu/~team7/register.php")!

        let request = NSMutableURLRequest(url: url as URL)

        request.httpMethod = "POST"

        let body = "username=\(usernameTxt.text!.lowercased())&password=\(passwordTxt.text!)&email=\(emailTxt.text!)&fullname=\(fullnameTxt.text!)"
        request.httpBody = body.data(using: String.Encoding.utf8)

        URLSession.shared.dataTask(with: request as URLRequest as URLRequest, completionHandler: { (data:Data?, response:URLResponse?, error:Error?) -> Void in

            if error == nil {
                DispatchQueue.main.async(execute: {

                    do {
                        let json = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as? NSDictionary
                        guard let parseJSON = json else {
                            print("Error while parsing")
                            return
                        }

                        let id = parseJSON["id"]

                        if id != nil && response != nil {
                            print(parseJSON)
                        }



                    } catch {
                        print("Caught an error \(error)")
                    }
                })

            } else {
                print("error: \(error)")
            }

        }).resume()
        let alertController = UIAlertController(title: "Registered", message: "Account Successfully Registered! Please Log In", preferredStyle: UIAlertControllerStyle.alert)
        let okay = UIAlertAction(title: "Okay", style: .default, handler: {_ in CATransaction.setCompletionBlock({
            self.performSegue(withIdentifier: "accountSuccess", sender: nil)})
            })
        alertController.addAction(okay)
        //alertController.addAction(UIAlertAction(title: "Okay", style: UIAlertActionStyle.default, handler:nil))
        self.present(alertController, animated: true, completion: nil)
    }
    //performSegue(withIdentifier: "accountSuccess", sender: CreateAccountVC.self)
}



}

如果有人可以帮助我找到一个很棒的解决方案!谢谢!

【问题讨论】:

  • prepare(for segue:.. 方法应该在loginButton(_ loginButto... 方法之外

标签: ios swift facebook facebook-graph-api swift3


【解决方案1】:

您需要将prepareForSegue 方法放到类级别,而不是在任何其他方法内,您还需要在完成块内而不是在完成块外调用performSegue。如下更改您的代码。

//[Facebook, 2017]
func loginButton(_ loginButton: FBSDKLoginButton!, didCompleteWith result: FBSDKLoginManagerLoginResult!, error: Error!) {
    if error != nil {
        print(error)
        return
    }
    print("Successfully logged in")

    FBSDKGraphRequest(graphPath: "/me", parameters: ["fields": "id, name, email"]).start {(connection, result, err) in
        if err != nil {
            print("Failed to start graph request", err)
            return
        } else {
             guard let data = result as? [String:Any] else {return}
             self.performSegue(withIdentifier: "regSegue", sender: data)
        }
    }
}

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if let vc = segue.destination as? CreateAccountVC,
    let dic = sender as? [String:Any] {
        let fbEmail = dic["email"] as! String
        let fbName  = dic["name"] as! String
        vc.emailTxtValue = fbEmail
        vc.fullnameTxtValue = fbName
    }
}

【讨论】:

  • 另外补充一点,他没有改变 self.fbEmail 和 self.fbName 的值,而是声明了新的常量和 ,然后在 prepareForSegue 他发送空的 self.fbName 和 self .fb电子邮件
  • @JaafarBarek 不需要,因为我将数据作为发件人传递,所以现在它将通过将发件人转换为字典来访问prepareforsegue,就像我在解决方案中建议的那样
  • 我在 performSegue 行收到一个错误,提示“在闭包中隐式使用 'self';使用 'self。”使捕获语义明确。”知道为什么会这样吗?
  • @jmoney11944 只需添加self.performSegue,也可以查看编辑后的答案
  • 天啊,非常感谢你们。我欠你们一杯酒
【解决方案2】:

你已经全局声明了 2 个变量

var fbName:String!

var fbEmail:String!

当你给它赋值时,你正在创建与 , 相同的变量,

let fbEmail = data["email"] as! String

let fbName  = data["name"] as! String

所以你只需要从 fbEmail 和 fbName 中删除 let 就可以为另一个 View Controller 获取价值

【讨论】:

    猜你喜欢
    • 2013-04-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-22
    • 1970-01-01
    相关资源
    最近更新 更多