使用表格显示添加的用户及其数据

Posted

技术标签:

【中文标题】使用表格显示添加的用户及其数据【英文标题】:Use a table to display users added and their data 【发布时间】:2020-07-27 20:17:30 【问题描述】:

我是编码新手,过去几周一直在尝试找出当前的问题。

我发布了一堆询问同一问题的不同变体的帖子,并被告知我试图执行我的想法的方式不正确。

我正在尝试将数据集合发送到用户列表。这些数据涉及公司名称、公司形象、他们需要做出决定的日期以及发送日期。我目前能够将该信息发送到我的 firebase 数据库和公司形象的 firebase 存储。公司图片也以字符串形式存储在公司信息节点下。

我最初想要完成的是能够通过按下按钮来创建单元格。该表将使用四个文本字段填充一个单元格。名称文本字段将是我选择用户的位置。他们的 firebase 数据库名称将显示在文本字段中。然后,我可以在仅对应于该用户的其他三个文本字段中输入文本。用户将能够看到公司信息和日期,但只能看到他们的特定行数据。有人告诉我我不应该这样做,我决定冒险尝试另一种可能的解决方案。

现在的情况:

我用公司信息和添加按钮设置了相同的视图控制器。看起来像:

按下添加按钮时,会显示一个带有四个文本字段的新视图控制器。视图控制器名称文本字段允许用户从数据库中选择一个用户,并且文本更改为该人的姓名。它看起来像这样:

我使用名称文本字段来附加一个数组,然后将其用于第一个视图控制器中的表以确定行数。它当前正在附加数组但不填充任何单元格。我计划使用标签将用户和其他 3 个文本字段保存到同一行。但我什至无法填充任何单元格。

这是视图控制器的代码,它将在公司信息下方的表格中显示用户及其信息:

import UIKit
import Firebase

class ConsiderationsTestViewController: UIViewController, UITextFieldDelegate 

@IBOutlet weak var tableView: UITableView!

static var numberOfPeople: [String] = []

var AddPersonCell = "AddPersonCell"

@IBOutlet weak var CompanyImage: UIImageView!

@IBOutlet weak var companyNameTextFieldConsiderations: UITextField!

@IBOutlet weak var companyDescriptionTextFieldConsiderations: UITextField!

@IBOutlet weak var startDateTextFieldConsiderations: UITextField!

@IBOutlet weak var endDateTextFieldConsiderations: UITextField!

let datePickerS = UIDatePicker()
let datePickerE = UIDatePicker()

    var database: Database!
    var storage: Storage!
    var selectedImage: UIImage?
    
    var ref:DatabaseReference?
    var databaseHandle:DatabaseHandle = 0
    
    let dbref = Database.database().reference()
    let uid = Auth.auth().currentUser?.uid
    
    override func viewDidLoad() 
        super.viewDidLoad()
        
        tableView.delegate = self
        tableView.dataSource = self
        
        self.companyNameTextFieldConsiderations.delegate = self
        self.companyDescriptionTextFieldConsiderations.delegate = self
        
        // Set the Firebase reference
        ref = Database.database().reference()
        
        let tapGesture = UITapGestureRecognizer(target: self, action: #selector(ConsiderationsTestViewController.handleSelectCompanyImageView))
         CompanyImage.addGestureRecognizer(tapGesture)
         CompanyImage.isUserInteractionEnabled = true

        self.navigationController!.navigationBar.isTranslucent = false
        
        navigationItem.backBarButtonItem = UIBarButtonItem(
        title: "", style: .plain, target: nil, action: nil)
        
        createDatePickerForStart()
        
        createDatePickerForEnd()
        
    

    @objc func handleSelectCompanyImageView() 

        let pickerController = UIImagePickerController()
        pickerController.delegate = self
        pickerController.allowsEditing = true
        present(pickerController, animated: true, completion: nil)
                    
    
@IBAction func AddPersonTapped(_ sender: Any) 
  


@IBAction func sendButtonTapped(_ sender: Any) 
    
    let companyNameC = companyNameTextFieldConsiderations.text!.trimmingCharacters(in: .whitespacesAndNewlines)
    let companyDescriptionC = companyDescriptionTextFieldConsiderations.text!.trimmingCharacters(in: .whitespacesAndNewlines)
    
    let today = Date()
    let formatter1 = DateFormatter()
    formatter1.dateFormat = "MMM d y"
    print(formatter1.string(from: today))
    let todaysDate = formatter1.string(from: today)
            
    let storageRef = Storage.storage().reference(forURL: " MY STORAGE URL HERE")
    let imageName = companyNameTextFieldConsiderations.text!
    let storageCompanyRef = storageRef.child("Company_Image_Considerations").child("\(todaysDate)").child(imageName)
    let companyDescriptionTextFieldText = companyDescriptionTextFieldConsiderations.text
    let dateToStart = startDateTextFieldConsiderations.text
    let dateToDecide = endDateTextFieldConsiderations.text
    let companyRef = Database.database().reference().child("Considerations").child("\(todaysDate)").child(imageName)
    
    let index = IndexPath(row: 0,section: 0)
    let cell = tableView.cellForRow(at:index) as! ConsiderationsCell
    let nameTFC = cell.nameTextFieldConsiderations.text!.trimmingCharacters(in: .whitespacesAndNewlines)
    let feedTFC = cell.feedTextFieldConsiderations.text!.trimmingCharacters(in: .whitespacesAndNewlines)
    let storyTFC = cell.storyTextFieldConsiderations.text!.trimmingCharacters(in: .whitespacesAndNewlines)
    let compensationTFC = cell.compensationTextFieldConsiderations.text!.trimmingCharacters(in: .whitespacesAndNewlines)
    
    let values = ["Feed_Quantity": feedTFC, "Story_Quantity": storyTFC, "Compensation": compensationTFC]
    let considerationInfluencerRef = Database.database().reference().child("Considerations").child("\(todaysDate)").child(imageName).child("Users").child("\(nameTFC)")
    
        guard let imageSelected = self.CompanyImage.image else 
            print ("Avatar is nil")
            return
                
                   
                var dict: Dictionary<String, Any> = [
                    "Company Image": "",
                    "Company Description": companyDescriptionTextFieldText!,
                    "Start Date": dateToStart!,
                    "Decision Date": dateToDecide! ]
    
                   
        guard let imageData = imageSelected.jpegData(compressionQuality: 0.5) else 
            return
                
    
                let metadata = StorageMetadata()
                metadata.contentType = "image/jpeg"
                storageCompanyRef.putData(imageData, metadata: metadata, completion:
                 (StorageMetadata, error) in
                if (error != nil) 
                return
                    
                            
                storageCompanyRef.downloadURL  (url, error) in
                if let metadateImage = url?.absoluteString 
                dict["Company Image"] = metadateImage
                   
                companyRef.updateChildValues(dict, withCompletionBlock:  
                (error, ref) in
                if error == nil 
                print("Done")
                return
                    
                  
                )
               
             
                            
                                   storageRef.updateMetadata(metadata)  metadata, error in
                                    if error != nil 
                                    //Uh-oh, an error occurred!
                                     else 
                                    // Updated metadata for 'images/forest.jpg' is returned
                                
                            
                        )

    considerationInfluencerRef.updateChildValues(values as [AnyHashable : Any])  (error, ref) in
    if error != nil 
    print(error ?? "")
    return
                       
    
self.navigationController?.popViewController(animated: true)
    



func createDatePickerForStart() 
    // center text in field
    startDateTextFieldConsiderations.textAlignment = .center
    
    // toolbar
    let toolbar = UIToolbar()
    toolbar.sizeToFit()
    
    // barbutton
    let doneButton = UIBarButtonItem(barButtonSystemItem: .done, target: nil, action: #selector(donePressedStart))
    toolbar.setItems([doneButton], animated: true)
    
    // assign toolbar to textfield
    
    startDateTextFieldConsiderations.inputAccessoryView = toolbar
    
    // assign datePicker to text field
    startDateTextFieldConsiderations.inputView = datePickerS
    
    // date picker mode
    datePickerS.datePickerMode = .date
    


func createDatePickerForEnd() 
    // center text in field
    endDateTextFieldConsiderations.textAlignment = .center
    
    // toolbar
    let toolbar = UIToolbar()
    toolbar.sizeToFit()
    
    // barbutton
    let doneButton = UIBarButtonItem(barButtonSystemItem: .done, target: nil, action: #selector(donePressedEnd))
    toolbar.setItems([doneButton], animated: true)
    
    // assign toolbar to textfield
    endDateTextFieldConsiderations.inputAccessoryView = toolbar
    
    // assign datePicker to text field
    endDateTextFieldConsiderations.inputView = datePickerE
    
    // date picker mode
    datePickerE.datePickerMode = .dateAndTime


@objc func donePressedStart() 
    // formatter
    let formatter = DateFormatter()
    formatter.dateStyle = .medium
    formatter.timeStyle = .none
    
    startDateTextFieldConsiderations.text = formatter.string(from: datePickerS.date)
    self.view.endEditing(true)


@objc func donePressedEnd() 
    // formatter
    let formatter = DateFormatter()
    formatter.dateStyle = .medium
    formatter.timeStyle = .medium
    
    endDateTextFieldConsiderations.text = formatter.string(from: datePickerE.date)
    self.view.endEditing(true)
   

    
extension ConsiderationsTestViewController: UIImagePickerControllerDelegate, UINavigationControllerDelegate 
               func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) 
                   //print("did Finish Picking Media")
                   if let image = info[UIImagePickerController.InfoKey(rawValue: "UIImagePickerControllerEditedImage")] as? UIImage
                       selectedImage = image
                       CompanyImage.image = image
                   
                   dismiss(animated: true, completion: nil)
               
    

extension ConsiderationsTestViewController: UITableViewDelegate, UITableViewDataSource 
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
    return ConsiderationsTestViewController.numberOfPeople.count


func numberOfSections(in tableView: UITableView) -> Int 
    return 1



func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 

let cell = tableView.dequeueReusableCell(withIdentifier: AddPersonCell, for: indexPath) as! ConsiderationsCell
    
    return cell
  


这是我选择用户并输入他们各自信息的视图控制器的代码:

import UIKit
import Firebase

class DropDownCellViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, UISearchBarDelegate, UITextFieldDelegate 

var numberOfPeople = [String]()

var users = [User]()

var userName = [String]()

var filteredNames: [String]!

let dropDownCell = "dropDownCell"

var emptyField = [String]()

@IBOutlet weak var nameTextField: NoCopyPasteUITextField!

@IBOutlet weak var tableView: UITableView!

@IBOutlet weak var gridTextField: UITextField!

@IBOutlet weak var storyTextField: UITextField!

@IBOutlet weak var compensationTextField: UITextField!

@IBAction func textFieldChanged(_ sender: AnyObject) 
    tableView.isHidden = true


@IBAction func cancelButtonTapped(_ sender: Any) 
    self.navigationController?.popViewController(animated: true)


@IBAction func addButtonTapped(_ sender: Any) 
    
    ConsiderationsTestViewController.numberOfPeople.append("\(nameTextField.text!)")
    
    self.navigationController?.popViewController(animated: true)
    
    print(ConsiderationsTestViewController.numberOfPeople)


let searchController = UISearchController(searchResultsController: nil)

override func viewDidLoad() 
    super.viewDidLoad()
    
    updateDataArray()
    
    tableView.register(UserCell.self, forCellReuseIdentifier: dropDownCell)
    
    filteredNames = userName
    
        tableView.delegate = self
        tableView.dataSource = self
        nameTextField.delegate = self
           
        tableView.isHidden = true
           
           // Manage tableView visibility via TouchDown in textField
    nameTextField.addTarget(self, action: #selector(textFieldActive), for: UIControl.Event.touchDown)
       

 override func didReceiveMemoryWarning() 
    super.didReceiveMemoryWarning()
 

 override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?)
  
      guard let touch:UITouch = touches.first else
      
          return;
      
      if touch.view != tableView
      
          nameTextField.endEditing(true)
          tableView.isHidden = true
      
  

 @objc func textFieldActive() 
       tableView.isHidden = !tableView.isHidden
   

  // MARK: UITextFieldDelegate
   func textFieldDidEndEditing(_ textField: UITextField) 
       // TODO: Your app can do something when textField finishes editing
       print("The textField ended editing. Do something based on app requirements.")
   
   
   func textFieldShouldReturn(_ textField: UITextField) -> Bool 
       textField.resignFirstResponder()
       return true
   


   func numberOfSections(in tableView: UITableView) -> Int 
    // #warning Incomplete implementation, return the number of sections
    return 1


   func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
    // #warning Incomplete implementation, return the number of rows
    
    return filteredNames.count


   func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
    
    let cell = tableView.dequeueReusableCell(withIdentifier: dropDownCell, for: indexPath) as!
    UserCell
    
    let user = users[indexPath.row]
    cell.textLabel?.text = user.name
    
    if let profileImageUrl = user.profileImageUrl 
    
    cell.profileImageView.loadImageUsingCacheWithUrlString(urlString: profileImageUrl)
        
    
    return cell


    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat 
return 72
       

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) 
    // Row selected, so set textField to relevant value, hide tableView
           // endEditing can trigger some other action according to requirements
           nameTextField.text = userName[indexPath.row]
           tableView.isHidden = true
           nameTextField.endEditing(true)
       

    //Mark: Search Bar Config
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) 
    
    filteredNames = []
    
    if searchText == "" 
        filteredNames = userName
        
     
    else 
        for names in userName 
            
            if names.lowercased().contains(searchText.lowercased()) 
                
                filteredNames.append(names)
            
        
    
    self.tableView.reloadData()
     

    func updateDataArray() 
    
    Database.database().reference().child("users").observe(.childAdded, with:  (snapshot) in
        
        if let dictionary = snapshot.value as? [String: AnyObject] 
            
            let user = User()
            //self.setValuesForKeys(dictionary)
            user.name = dictionary["name"] as? String
            user.email = dictionary["email"] as? String
            user.facebookUrl = dictionary["facebookUrl"] as? String
            user.instagramUrl = dictionary["instagramUrl"] as? String
            user.linkedInUrl = dictionary["linkedInUrl"] as? String
            user.profileImageUrl = dictionary["profileImageUrl"] as? String
            user.twitterUrl = dictionary["twitterUrl"] as? String
            user.id = dictionary["id"] as? String
            user.userType = dictionary["userType"] as? String
            
            self.users.append(user)
            self.userName.append(user.name!)
            self.filteredNames.append(user.name!)
            
            DispatchQueue.main.async 
            self.tableView.reloadData()
            
        
        
       , withCancel: nil)
    
    
    
   

我在原始视图控制器中有一个可以打印数组的按钮。我在尝试附加数组之前对其进行了测试。它是空的。然后我添加到人员并对其进行了测试。它打印了两个名称,但表格没有改变。我试图在添加按钮中 dispatch.resync 但它太模棱两可了。我真的可以使用帮助。谢谢!谢谢你的耐心。我是编码新手,除了自学外,没有任何编码方面的教育。

【问题讨论】:

【参考方案1】:

我发现了如何重新加载数据。我只需要弄清楚如何将标签设置为等于文本字段文本。这样我就可以看到它并能够将其发送到 firebase。我修复它的方法是让我的添加按钮具有以下代码:

@IBAction func addButtonTapped(_ sender: Any) 
    
    ConsiderationsTestViewController.numberOfPeople.append("\(nameTextField.text!)")
    
    self.navigationController?.popViewController(animated: true)
    
    print(ConsiderationsTestViewController.numberOfPeople)
    
    DispatchQueue.main.async 
       NotificationCenter.default.post(name: NSNotification.Name(rawValue: "load"), object: nil)
            

然后我将它插入到我想重新加载的视图控制器的 viewDidLoad 中:

 NotificationCenter.default.addObserver(self, selector: #selector(loadList), name: NSNotification.Name(rawValue: "load"), object: nil)

【讨论】:

以上是关于使用表格显示添加的用户及其数据的主要内容,如果未能解决你的问题,请参考以下文章

如何将第二个表格视图的值与第一个表格视图的单击行的关系分开?

如何使用jQuery在表格中间添加行?

搜索值,然后在Google表格中查找并使用google apps脚本在html中显示行值

使用表格视图将两个属性的信息添加到单个核心数据实体中的有效方法

R语言使用gt包和gtExtras包优雅地漂亮地显示表格数据:使用gt包可视化表格数据,使其易于阅读和理解使用gtExtras包添加一个图,显示表中某一列中的数字并为类型数据添加图像符号标签

UITextfield 值已成功更新,但未显示在表格中