当通过委托从其他Controller传递变量时,UILabel不会在Swift3中更新

时间:2016-10-06 15:30:13

标签: ios swift

我已经通过委托将一个变量从LoginViewController传递给ViewController。据我所知(通过打印调试)变量已通过ok。我现在想要它更新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在Debug区域中输出正确的String。据我所知,它正在控制器之间正确传递。问题是它没有使用新值更新UILabel。

App Delegate脚本,用于检测用户是否已登录,如果是,则直接进入View Controller,如果没有直接进入Login View Controller:

import UIKit

@UIApplicationMain

class 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()


    }

2 个答案:

答案 0 :(得分:0)

请勿将其置于异步块中并删除self.receiveUsername.setNeedsDisplay()

答案 1 :(得分:0)

您的问题是,您不是要关闭登录视图控制器并返回到之前的控制器,而是创建一个全新的控制器堆栈并替换旧的控制器堆栈。

替换这些行:

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)