如何从Firebase数据库中预取数据,然后在Textfield中用这些数据显示视图

时间:2019-06-03 16:40:59

标签: ios swift xcode firebase firebase-realtime-database

我正在尝试从firebase数据库中预取用户名,然后在无延迟显示视图时在文本字段中显示它。 问题是在显示视图之前,我似乎无法从数据库中预取数据。

我尝试在观察单个视图内使用if语句,说if self.username!= nil然后配置视图(移动视图的确在if语句内加载了配置视图功能)。这几乎达到了我想要的目的,但是它显示了视图加载的动画,并等待了几秒钟,直到文本字段加载了数据。试图消除延迟并使其立即加载到视图中。

还尝试添加func setData {userTextField.text = username}并在观察中的getData中调用它,仍然延迟2秒。

注意: ProfileController文件self.present AccountInfoController文件

扩展文件:

    extension UIView {
func labelTextContainerView(view: UIView, label: UILabel,_ textField: UITextField) -> UIView {
    view.backgroundColor = .white
    view.addSubview(label)
    label.font = UIFont.systemFont(ofSize: 10)
    label.textColor = UIColor.mainBlue()

    label.anchor(top: view.topAnchor, left: view.leftAnchor, bottom: nil, right: nil, paddingTop: 10, paddingLeft: 20, paddingBottom: 0, paddingRight: 0, width: 0, height: 9)
    label.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true

    if (textField.text?.isEmpty ?? true) {
        label.isHidden = true
    }


    view.addSubview(textField)
    //textField.textColor = .black
    textField.anchor(top: label.bottomAnchor, left: view.leftAnchor, bottom: nil, right: view.rightAnchor, paddingTop: 0, paddingLeft: 20, paddingBottom: 0, paddingRight: 20, width: 0, height: 0)
    textField.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true

    let separatorView = UIView()
    separatorView.backgroundColor = UIColor(white: 0.87, alpha: 1)
    view.addSubview(separatorView)
    separatorView.anchor(top: nil, left: view.leftAnchor, bottom: view.bottomAnchor, right: view.rightAnchor, paddingTop: 0, paddingLeft: 20, paddingBottom: 0, paddingRight: 0, width: 0, height: 0.75)

    return view
}    

}


extension UITextField {
func editableTextField(withPlaceolder placeholder: String, someText: String?, enableEditing: Bool) -> UITextField {
    let tf = UITextField()
    tf.borderStyle = .none
    tf.font = UIFont.systemFont(ofSize: 16)

    if (enableEditing == false) {
        tf.isEnabled = enableEditing
        tf.isUserInteractionEnabled = enableEditing
        tf.alpha = 0.5
    }

    tf.text = someText
    tf.attributedPlaceholder = NSAttributedString(string: placeholder, attributes: [NSAttributedString.Key.foregroundColor: UIColor(white: 0.8, alpha: 1)])
    return tf
}
}

AccountInfoController文件:

import UIKit
import Firebase

class AccountInfoController: UIViewController {

//MARK: - Properties
var ref = Database.database().reference()
var userID = Auth.auth().currentUser?.uid
var username: String?
var userLabel = UILabel()

lazy var userContainerView: UIView = {
    let view = UIView()
    return view.labelTextContainerView(view: view, label: userLabel, userTextField)
}()

lazy var userTextField: UITextField = {
    userLabel.text = "Username"
    userLabel.isHidden = false
    let tf = UITextField()
    return tf.editableTextField(withPlaceolder: "Username", someText: self.username?.lowercased(), enableEditing: false)
}()

//MARK: - Init
override func viewDidLoad() {
    super.viewDidLoad()

    getUserData()

    //print(self.username)

    configureViewComponents()
    configureViewLabel()
}

func getUserData() {
    user.child("username").observeSingleEvent(of: .value) { (snapshot) in
        guard let userName = snapshot.value as? String else { return }
        print(userName)
        self.username = userName
    }

}

// MARK: - Helper Functions

func configureViewLabel() {
    //some code
}

func configureViewComponents() {
    //some code

    view.addSubview(userContainerView)
    userContainerView.anchor(top: emailContainerView.bottomAnchor, left: view.leftAnchor, bottom: nil, right: view.rightAnchor, paddingTop: 0, paddingLeft: 0, paddingBottom: 0, paddingRight: 0, width: 0, height: 60)

    //some code
}
}

期望:在显示AccountInfoController时,我希望文本字段具有当前用户的用户名,而无需等待数据库获取数据,我希望数据库预取用户名。

当前结果:上面的代码在数据库获取用户名后甚至没有在文本字段中显示用户名。除非添加了上述if语句,否则会有2秒的延迟。

1 个答案:

答案 0 :(得分:0)

我相信我找到了解决我问题的答案。 所有需要做的就是声明一个供所有类使用的公共变量,然后在登录后从数据库中获取数据并将其分配给公共变量后,首先加载您的应用的主页。

这解决了我的问题。

在配置文件控制器文件中: 课外:

public var username: String?

在课程内:

我将getUserData()函数从AccountInfoController移到了ProfileController

在viewDidLoad()内部:

getUserData()

最后,在初始化文本字段时,我将文本指定为公共变量。