2017-01-16 47 views
0

我可以通过ViewController验证用户登录。迅速并将视图重定向到DisplayDetailsViewController.swift,其中只有一个名为nameLabelUILabel无法设置多控制器的UILabel字段

每当有成功登录,我调用一个函数在登录名为DisplayDetailsViewController.swiftloadValues(name: String)功能ViewController.swift

每当我尝试设置值nameLabel,我收到一个错误。如果我尝试设置任何字符串,问题也是一样的。我想我无法解决正确的UILabel

main.storyboard

  1. AppDegate.swift:

    // 
    // AppDelegate.swift 
    // AutoLayout 
    // 
    // Created by BIKRAM BHANDARI on 11/1/17. 
    // Copyright © 2017 BIKRAM BHANDARI. All rights reserved. 
    // 
    
    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. 
         return true 
        } 
    
        func applicationWillResignActive(_ application: UIApplication) { 
         // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 
         // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. 
        } 
    
        func applicationDidEnterBackground(_ application: UIApplication) { 
         // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 
         // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 
        } 
    
        func applicationWillEnterForeground(_ application: UIApplication) { 
         // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. 
        } 
    
        func applicationDidBecomeActive(_ application: UIApplication) { 
         // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 
        } 
    
        func applicationWillTerminate(_ application: UIApplication) { 
         // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 
        } 
    
    
    } 
    
  2. ViewController.swift

    // 
        // ViewController.swift 
        // AutoLayout 
        // 
        // Created by BIKRAM BHANDARI on 11/1/17. 
        // Copyright © 2017 BIKRAM BHANDARI. All rights reserved. 
        // 
    
        import UIKit 
    
        class ViewController: UIViewController, UITextFieldDelegate{ 
    
    
         @IBOutlet var txtUsername: UITextField! 
         @IBOutlet var txtPassword: UITextField! 
         var passWordProtected: Bool = false; 
    
         var loggedInUser:User?; 
    
         private struct constants{ 
          //static var highlighted: UIControlState{ get {return }} 
         } 
         //--------------------------------------------------------------------------------------------------------------------------------// 
         override func viewDidLoad() { 
          super.viewDidLoad(); 
          txtUsername.delegate = self; 
    
          let tapGesture = UITapGestureRecognizer(target: self, action: #selector(tap)); //Check the tap gesture to dissmiss the keyboard 
          view.addGestureRecognizer(tapGesture) 
         } 
         //--------------------------------------------------------------------------------------------------------------------------------// 
         @IBAction func Login() { 
          if let loggedInUser = User.checkLoginCredentials(username: txtUsername.text ?? "" , password: txtPassword.text ?? ""){ 
    
           let secondViewController: DisplayDetailsViewController = DisplayDetailsViewController(); 
           self.present(secondViewController, animated: true, completion: nil); 
           self.performSegue(withIdentifier: "Display Details", sender: self); 
    
           txtUsername.text = ""; 
           txtPassword.text = ""; 
    
           let displayDetails = DisplayDetailsViewController(); 
           displayDetails.loadValues(name: loggedInUser.name); 
         } 
        } 
    func tap(gesture: UITapGestureRecognizer) { 
         txtUsername.resignFirstResponder(); 
         txtPassword.resignFirstResponder(); 
        } 
    
         //--------------------------------------------------------------------------------------------------------------------------------// 
         func textFieldShouldReturn(_ textField : UITextField) ->Bool{ //Function to change move to next text field when keyboard next is       pressed 
          if(textField == txtUsername){ 
           txtPassword.becomeFirstResponder(); 
          } 
          return true; 
         } 
    
         //--------------------------------------------------------------------------------------------------------------------------------// 
         @IBAction func togglePasswordField(_ sender: UIButton) {  // Function to change the password field to secure or show the typed password 
          if passWordProtected{ 
           txtPassword.isSecureTextEntry = true; 
           sender.setImage(#imageLiteral(resourceName: "view"), for: UIControlState.normal) 
           passWordProtected = false; 
    
          }else{ 
           txtPassword.isSecureTextEntry = false; 
           sender.setImage(#imageLiteral(resourceName: "hide"), for: UIControlState.normal) 
           passWordProtected = true; 
          } 
         } 
    
        } 
    
  3. User.swift

    // 
    // User.swift 
    // AutoLayout 
    // 
    // Created by BIKRAM BHANDARI on 15/1/17. 
    // Copyright © 2017 BIKRAM BHANDARI. All rights reserved. 
    // 
    
    import Foundation 
    struct User{ 
        let name: String; 
        let company: String; 
        let username: String; 
        let password: String; 
    
        static func checkLoginCredentials(username: String, password: String) -> User?{ 
         if let user = database[username]{ 
          if user.password == password{ 
           return user; 
          } 
         } 
         return nil; 
        } 
    
        static let database: Dictionary<String, User> = { 
        var theDatabase = Dictionary<String, User>() 
        for user in [ 
         User(name:"Bikram", company:"Self Company", username:"bikram", password:"bhandari"), 
         User(name:"Sabina", company:"No company till now", username:"Sabina", password:"Sabu"), 
         User(name:"Mac", company:"Apple Inc. ", username:"iphone", password:"6plus"), 
         User(name:"Samsunng", company:"Sumsung Inc.", username:"note", password:"7") 
         ]{ 
          theDatabase[user.username] = user; 
         } 
         return theDatabase 
        }(); 
    } 
    
  4. DisplayDetailsViewController.swift

    // DisplayDetailsViewController.swift 
    // AutoLayout 
    // 
    // Created by BIKRAM BHANDARI on 15/1/17. 
    // Copyright © 2017 BIKRAM BHANDARI. All rights reserved. 
    // 
    import UIKit 
    
    class DisplayDetailsViewController: UIViewController { 
    
        @IBOutlet weak var nameLabel: UILabel! 
    
        //***********************************// 
        func loadValues(name: String){ 
         nameLabel.text = "Bikram"; 
        } 
    
    } 
    
  5. 更新ViewController.swift

    // 
    // ViewController.swift 
    // AutoLayout 
    // 
    // Created by BIKRAM BHANDARI on 11/1/17. 
    // Copyright © 2017 BIKRAM BHANDARI. All rights reserved. 
    // 
    
    import UIKit 
    
    class ViewController: UIViewController, UITextFieldDelegate{ 
    
    
        @IBOutlet var txtUsername: UITextField! 
        @IBOutlet var txtPassword: UITextField! 
        var passWordProtected: Bool = false; 
    
        var loggedInUser:User?; 
    
        private struct constants{ 
         //static var highlighted: UIControlState{ get {return }} 
        } 
        //--------------------------------------------------------------------------------------------------------------------------------// 
        override func viewDidLoad() { 
         super.viewDidLoad(); 
         txtUsername.delegate = self; 
    
         let tapGesture = UITapGestureRecognizer(target: self, action: #selector(tap)); //Check the tap gesture to dissmiss the keyboard 
         view.addGestureRecognizer(tapGesture) 
        } 
        //--------------------------------------------------------------------------------------------------------------------------------// 
        @IBAction func Login() { 
         if let loggedInUser = User.checkLoginCredentials(username: txtUsername.text ?? "" , password: txtPassword.text ?? ""){ 
    
          let secondViewController: DisplayDetailsViewController = DisplayDetailsViewController(); 
          self.present(secondViewController, animated: true, completion: nil); 
          self.performSegue(withIdentifier: "Display Details", sender: self); 
    
          txtUsername.text = ""; 
          txtPassword.text = ""; 
    
          let displayDetails = DisplayDetailsViewController(); 
          displayDetails.user = loggedInUser; 
        } 
    } 
        //--------------------------------------------------------------------------------------------------------------------------------// 
        func tap(gesture: UITapGestureRecognizer) { //Function to dismiss the keyboard when it is pressed anywhere in the storyboard. 
         txtUsername.resignFirstResponder(); 
         txtPassword.resignFirstResponder(); 
        } 
    
        //--------------------------------------------------------------------------------------------------------------------------------// 
        func textFieldShouldReturn(_ textField : UITextField) ->Bool{ //Function to change move to next text field when keyboard next is       pressed 
         if(textField == txtUsername){ 
          txtPassword.becomeFirstResponder(); 
         } 
         return true; 
        } 
    
        //--------------------------------------------------------------------------------------------------------------------------------// 
        @IBAction func togglePasswordField(_ sender: UIButton) {  // Function to change the password field to secure or show the typed password 
         if passWordProtected{ 
          txtPassword.isSecureTextEntry = true; 
          sender.setImage(#imageLiteral(resourceName: "view"), for: UIControlState.normal) 
          passWordProtected = false; 
    
         }else{ 
          txtPassword.isSecureTextEntry = false; 
          sender.setImage(#imageLiteral(resourceName: "hide"), for: UIControlState.normal) 
          passWordProtected = true; 
         } 
        } 
    
    } 
    
  6. 更新DisplayDetailsViewController

    // 
    // DisplayDetailsViewController.swift 
    // AutoLayout 
    // 
    // Created by BIKRAM BHANDARI on 15/1/17. 
    // Copyright © 2017 BIKRAM BHANDARI. All rights reserved. 
    // 
    
    import UIKit 
    
    class DisplayDetailsViewController: UIViewController { 
    
        @IBOutlet weak var nameLabel: UILabel! 
    
        var user: User!{ 
         didSet{ 
         nameLabel.text = user.name} 
        } 
        //***********************************// 
    } 
    
+0

你发布整个项目在那里? – zombie

+0

是上传所有文件。 – Bikram

+0

这不是一个好主意 – zombie

回答

1

nameLabel具有p个由于尚未在屏幕上显示,所以尚未初始化。

尝试在保存用户对象的DisplayDetailsViewController中创建一个var。

相反的:

displayDetails.loadValues(name: loggedInUser.name); 

尝试:

displayDetails.user = loggedInUser; 
// assuming you have created a var in DisplayDetailsViewController 
// called user of type User 

然后在DisplayDetailsViewController的viewWillAppear中,添加你原来的代码行:

nameLabel.text = user.name 

工作的呢?

编辑

我有这个作为我的结构

struct User 
{ 
    var name = "" 
    var age = 0 
} 

之前过渡到下一个屏幕(无论是前推视图控制器或在SEGUE准备),您需要实例用户,比如我在做这:

覆盖FUNC准备(对于SEGUE:UIStoryboardSegue,发件人:任何?)

let user = User(name: "Shawn", age: 26)   
let destination = segue.destination as! DisplayDetailsViewController 
destination.user = user 

然后最后,DisplayDetailsViewController:

class DisplayDetailsViewController: UIViewController { 

    var user = User() 

    @IBOutlet var label: UILabel! 

    override func viewWillAppear(_ animated: Bool) { 
     label.text = user.name 
    } 
} 

我运行此,我得到的标签成功地显示细节画面上肖恩

+0

这不起作用。无法访问DisplayDetailsViewController中的user.name – Bikram

+0

您可以使用'public'关键字暴露'user'属性或者创建一个辅助'init()'方法,该方法接受参数 – JoGoFo

+0

我试过这个var user:User!{ didSet { nameLabel.text = user.name} }问题仍然存在 – Bikram

相关问题