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

Use a table to display users added and their data

我是编码新手,过去几周一直在努力解决我当前遇到的问题。

我已经发布了一堆关于同一问题的不同变体,并被告知我尝试执行我的想法的方式是错误的。

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

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

现在情况:

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

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

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

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

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
  }

}

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

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)
    
    
    }
   }

我在原始视图控制器中有一个按钮可以打印数组。我在尝试附加数组之前对其进行了测试。它是空的。然后我添加到人并测试它。它打印了两个名字,但 table 没有改变。我试图在添加按钮中 dispatch.resync 但它太模糊了。我真的需要帮助。谢谢!感谢您的耐心等待。我是编码新手,除了自学外没有接受过编码方面的教育。

我找到了如何重新加载数据。我只需要弄清楚如何将标签设置为等于文本字段文本。这样我就可以看到它并能够将它发送到 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)