当通过委托从其他控制器传递变量时,UILabel在Swift3中没有更新



我已经通过一个委托传递了一个变量从LoginViewController到ViewController。据我所知(通过打印调试),变量已经通过了。现在我想让它更新UIlabel。

LoginViewController

//
//  LoginViewController.swift
//  KeepScore
//
//  Created by Rich Downs on 28/09/2016.
//  Copyright © 2016 Rich Downs. All rights reserved.
//
import UIKit
protocol UsernameSentDelegate {
func userLoggedIn(data: String)
}
class LoginViewController: UIViewController {
var delegate: UsernameSentDelegate? = nil
@IBOutlet weak var userEmailTextField: UITextField!
@IBOutlet weak var userPasswordTextField: UITextField!
@IBOutlet weak var displayUserName: UILabel!
override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

@IBAction func loginButtonTapped(_ sender: AnyObject)
{
    let userEmail = userEmailTextField.text;
    let userPassword = userPasswordTextField.text;
    if (userPassword!.isEmpty || userEmail!.isEmpty) { return; }
// send user data to server side

    let myUrl = URL(string: "http://www.quasisquest.uk/KeepScore/userLogin.php");
    var request = URLRequest(url:myUrl!);
    request.httpMethod = "POST";
    let postString = "email=(userEmail!)&password=(userPassword!)";
    request.httpBody = postString.data(using: String.Encoding.utf8);

    let task = URLSession.shared.dataTask(with: request) { (data: Data?, response: URLResponse?, error: Error?) in
        DispatchQueue.main.async
            {
               // spinningActivity!.hide(true)

               if(error != nil)
                {
                    //Display an alert message
                    let myAlert = UIAlertController(title: "Alert", message: error!.localizedDescription, preferredStyle: UIAlertControllerStyle.alert);
                    let okAction = UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler:nil)
                    myAlert.addAction(okAction);
                    self.present(myAlert, animated: true, completion: nil)
                    return
                }
                do {
                    let json = try JSONSerialization.jsonObject(with: data!, options: .allowFragments) as? [String:AnyObject]

                    // retrieve username and pass it to View Controller screen through delegate
                    let username = (json!["user_name"])
                    if self.delegate != nil {
                        let usernameData = username
                        self.delegate?.userLoggedIn(data: usernameData as! String)
                   }
                    // retrieve login details and check to see if all ok
                    if let parseJSON = json {
                        let returnValue = parseJSON["status"] as? String
                        //print(returnValue);
                        if(returnValue != "error")
                        {
                             UserDefaults.set(UserDefaults.standard)(true, forKey: "isUserLoggedIn");
                            let mainPage = self.storyboard?.instantiateViewController(withIdentifier: "ViewController")
                            let mainPageNav = UINavigationController(rootViewController: mainPage!)
                            let appDelegate = UIApplication.shared.delegate
                            appDelegate?.window??.rootViewController = mainPageNav

                        } else {
                            // display an alert message
                            let userMessage = parseJSON["message"] as? String
                            let myAlert = UIAlertController(title: "Alert", message: userMessage, preferredStyle: UIAlertControllerStyle.alert);
                            let okAction = UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler:nil)
                            myAlert.addAction(okAction);
                            self.present(myAlert, animated: true, completion: nil)
                        }
                    }
                } catch
                {
                    print(error)
                }

        }

    }
    task.resume()

}


}

和ViewController -这是我的主页时,用户登录。

//
//  ViewController.swift
//  KeepScore
//
//  Created by Rich Downs on 28/09/2016.
//  Copyright © 2016 Rich Downs. All rights reserved.
//
import UIKit
class ViewController: UIViewController, UsernameSentDelegate {

@IBOutlet weak var receiveUsername: UILabel!
//recieves username from delegate from LoginViewController
func userLoggedIn(data: String) {

    self.receiveUsername.text = data //sets label.text to new data
    print (self.receiveUsername.text)  //prints a check to see if worked (Samuel Bawdry)
    //self.receiveUsername.setNeedsDisplay() //update label in view
        self.receiveUsername.backgroundColor = UIColor.red
}
override func viewDidLoad() {
    super.viewDidLoad()
    print (receiveUsername.text) //print original label.text (Label)
//   receiveUsername = self
}

override func prepare(for segue: UIStoryboardSegue, sender: Any?)
{
    if segue.identifier == "loginView" {
        let loginViewController: LoginViewController = segue.destination as! LoginViewController
        loginViewController.delegate = self
    }
}

override func viewDidAppear(_ animated: Bool)
{
   let isUserLoggedIn = UserDefaults.bool(UserDefaults.standard)(forKey: "isUserLoggedIn");
    if(!isUserLoggedIn)
    {
        self.performSegue(withIdentifier: "loginView", sender: self);
    }
}

@IBAction func logoutButtonTapped(_ sender: AnyObject) {
    UserDefaults.set(UserDefaults.standard)(false, forKey: "isUserLoggedIn");
    self.performSegue(withIdentifier: "loginView", sender: self);
}

}

ViewController var receiveUsername。text在调试区打印出正确的字符串。所以据我所知,它在控制器之间被正确地传递。问题是它没有用新值更新UILabel。

App Delegate脚本,用于检测用户是否已经登录,如果已经登录,则直接跳转到视图控制器,如果没有跳转到登录视图控制器:

import UIKit
@UIApplicationMain

类AppDelegate: UIResponder, UIApplicationDelegate {

var window: UIWindow?

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    // Override point for customization after application launch.

    let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
    let isUserLoggedIn = UserDefaults.bool(UserDefaults.standard)(forKey: "isUserLoggedIn")
    if(!isUserLoggedIn)
    {
        let loginViewController = mainStoryboard.instantiateViewController(withIdentifier: "LoginViewController")
        self.window?.rootViewController = loginViewController
        window!.makeKeyAndVisible()
    } else {
        let protectedPage = mainStoryboard.instantiateViewController(withIdentifier: "ViewController")
        self.window?.rootViewController = protectedPage
        window!.makeKeyAndVisible()

    }

不要放在async block中,删除self.receiveUsername.setNeedsDisplay()

你的问题是,而不是解散你的登录视图控制器,回到你以前的控制器,你正在创建一个全新的控制器堆栈和取代你的旧的。

替换这些行:

let mainPage = self.storyboard?.instantiateViewController(withIdentifier: "ViewController")
let mainPageNav = UINavigationController(rootViewController: mainPage!)
let appDelegate = UIApplication.shared.delegate
appDelegate?.window??.rootViewController = mainPageNav

用代码解散你当前的视图控制器:

dismiss(animated: true, completion: nil)

或者如果你将登录视图控制器推送到导航控制器上而不是模态地呈现它:

navigationController?.popViewController(animated: true)