使用表格显示添加的用户及其数据
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)
【讨论】:
以上是关于使用表格显示添加的用户及其数据的主要内容,如果未能解决你的问题,请参考以下文章
如何将第二个表格视图的值与第一个表格视图的单击行的关系分开?
搜索值,然后在Google表格中查找并使用google apps脚本在html中显示行值
使用表格视图将两个属性的信息添加到单个核心数据实体中的有效方法
R语言使用gt包和gtExtras包优雅地漂亮地显示表格数据:使用gt包可视化表格数据,使其易于阅读和理解使用gtExtras包添加一个图,显示表中某一列中的数字并为类型数据添加图像符号标签