ios - 如何从 firebase 数据库预取数据,然后在 Textfield 中显示包含这些数据的 View

标签 ios swift xcode firebase firebase-realtime-database

我试图从 firebase 数据库中预取用户名,然后在 View 毫无延迟地呈现时将其显示在文本字段中。 问题是我似乎无法在呈现 View 之前从数据库中预取数据。

我尝试在观察单个 View 中使用 if 语句,该语句表示 if self.username != nil then configure the view (移动 View 并在此 if 语句中加载配置 View 函数)。这几乎达到了我想要的效果,但它显示了 View 加载的动画,并等待了几秒钟,直到文本字段加载了数据。尝试消除延迟并使其立即加载 View 。

还尝试添加 func setData { userTextField.text = username } 并在observe中的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 秒的延迟。

最佳答案

我相信我找到了问题的答案。 需要做的就是声明一个公共(public)变量供所有类使用,然后在登录后首次加载应用程序的主页上从数据库中获取数据并将它们分配给公共(public)变量。

这解决了我的问题。

在配置文件 Controller 文件中: 课外:

public var username: String?

类(class)内部:

我将 getUserData() 函数从 AccountInfoController 移至 ProfileController

在viewDidLoad()内部:

getUserData()

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

关于ios - 如何从 firebase 数据库预取数据,然后在 Textfield 中显示包含这些数据的 View ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56431419/

相关文章:

ios - 为什么从加速框架计算出的特征向量符号不同?

iOS 应用程序由于无限 while 循环而无法渲染

ios - 在 react-native 的主线程上运行 swift 代码

iphone - ipad/iphone 禁用退出按钮

ios - MFSideMenu 侧 Viewcontroller 未导航到 Tabbarcontroller 中的特定 View Controller

ios - 静态 IBOutlets?

arrays - 自定义类型的数组初始值设定项

swift - Swift 3 GCD API 更改后的 dispatch_once

xcode - 如何将字符串从原生 iOS 插件返回到 unity?

ios - UIScrollView 中的 UIView 尊重一些约束,但不尊重其他约束