在UITableView中处理动态单元格?
错误消息 。
Error Message.
现在,我得到的是错误消息。
Now, I'm getting this error message.
更新的代码,此错误消息显示在此图像链接错误消息 :
Updated Code with error message shown in this image link error message:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = runReportTableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
cell.textLabel?.text = valuesArray[indexPath.row]
cell.SetCheckMark(cell.checkMark) //Call 'SetCheckMark' function here
cell.tapButton = {
if cell.checkMark.isSelected == false {
let data:[String:String] = [self.Facilities[indexPath.row]: "Disinfected"]
self.InfoArray.append(data)
}
else {
self.InfoArray.remove(at: indexPath.row)
}
}
print("Responsibilities in cells: \(valuesArray)")
print("\(data)")
return cell
}
我一直在执行此代码以打印(您轻按单元格#(indexPath.row))。这段代码会生成带有某些字段的Firebase文档:此文档应包含会议室/区域文本和值已消毒表示已消毒。或未消毒;取决于用户是选择该单元格还是未选择该单元格
I have this code working all the way up to "print("You tapped cell #(indexPath.row)")." This code produces this firebase document with some fields: this document should have fields of the room/area text and values of "Disinfected" or "Not Disinfected" depending on whether the user selected that cell or left it unselected
因此,我现在需要执行的所有代码是使用文本(valuesArray [indexPath .row]),由用户选择。在我的viewController上使用静态数量的按钮和标签之前,我已将其完美运行,并在Firebase Firestore文档中获得了所需的结果,如下所示:按钮
So, all I need this code to do now is update my Cloud Firestore document with the text (valuesArray[indexPath.row]) of the cells that were selected by the users. I had this working perfectly before using a static number of buttons and labels on my viewController and had my desired result in my firebase Firestore document like this: screenshot of when I had static information that I was updating in my firebase database after the user made all selections and tapped the "send report" button
但是,现在,显示的不是恒定的 Room 1- Room 21,而是在Firebase文档中使用选定值 Disinfected(已消毒)或未消毒;我想知道如何让我的代码自动写入该Firebase文档已消毒。如果选择/突出显示该单元格或未消毒,则返回否。如果用户未选择该单元格,则使用我从 Firestore Document Data屏幕截图中的数据中获取的单元格标签文本显示哪个单元格具有已消毒/未消毒的值。
However, now, instead of displaying a constant "Room 1"-"Room 21" keys in the firebase document with the selected value of "Disinfected" or "Not Disinfected" I am wondering how I can have my code automatically write to that firebase document "Disinfected" if the cell is selected/highlighted or "Not Disinfected" if the user does not select the cell and, then display which cell had that value of disinfected/notdisinfected using the cell's label text which I am getting from the data in the "Firestore Document Data Screenshot" down below.
我认为是这样的,因为我不确定100%确定如何检查我创建的动态单元格是否被选中,然后分配已消毒。或未消毒;
I think its because I'm not 100% sure how to check if the dynamic cells I created are selected or not and then assign either "Disinfected" or "Not Disinfected" to that selected cell's text in my Cloud Firestore document.
如前所述,此代码将打印正确数量的被轻击的单元格和被正确标识的被轻击的单元格文本。它还成功创建了一个新的Cloud Firestore文档,其中没有所选按钮的值(已消毒或未消毒)及其匹配的单元标签文本。
As aforementioned, this code prints the correct number of the tapped cell and the correct label text of the tapped cell. It also successfully creates a new Cloud Firestore document without the values ("Disinfected" or "Not Disinfected") of the selected buttons and their matching cell label text.
这是屏幕截图模拟器模拟器截图和我正在使用的Cloud Firestore文档数据的截图用于我的单元格的标签文本 Firestore文档数据屏幕截图。
Here's a screenshot of the simulator Simulator Screenshot and a screenshot of the Cloud Firestore document data that I'm using for my cells' label text Firestore Document Data Screenshot .
import UIKit
import Firebase
import FirebaseFirestore
import SCLAlertView
class RunReportViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
@IBOutlet weak var runReportTableView: UITableView!
var namesDocumentRef:DocumentReference!
var userName = ""
var userEmail = ""
var data:[String] = []
var valuesArray:[String] = []
var selectedResponsibility:[String] = []
// var keysArray:[String] = []
override func viewDidLoad() {
super.viewDidLoad()
startObservingDB()
runReportTableView.delegate = self
runReportTableView.dataSource = self
// Do any additional setup after loading the view.
}
// Gets user's specific room(s)/area(s)/classroom(s) responsibilities from Cloud Firestore Database to be used for checking "Disinfected" or "Not Disinfected" in order to put the text as a cell label
func startObservingDB() {
var responsibilitiesDocumentRef:DocumentReference!
let db = Firestore.firestore()
let userID = Auth.auth().currentUser!.uid
responsibilitiesDocumentRef = db.collection("UserResponsibilities").document("McGrath").collection("Custodians").document("\(userID)")
responsibilitiesDocumentRef.addSnapshotListener { DocumentSnapshot, error in
if error != nil{
return
}
else {
guard let snapshot = DocumentSnapshot, snapshot.exists else {return}
guard let data = snapshot.data() else { return }
self.valuesArray = Array(data.values) as! Array<String>
// self.keysArray = Array(data.keys)
self.runReportTableView.reloadData()
print("Current data: \(data)")
print("Current data has the responsibilities: \(self.valuesArray)")
print("Current data totals \(self.valuesArray.count) items.")
}
}
}
@IBAction func sendReportTapped(_ sender: Any) {
getSelectionValues()
}
func getSelectionValues() {
let db = Firestore.firestore()
let userID = Auth.auth().currentUser!.uid
db.collection("Users").document("\(userID)").collection("UserInfo").getDocuments { (snapshot, err) in
if let err = err {
print("Error getting documents: \(err)")
} else {
for document in snapshot!.documents {
let docID = document.documentID
self.userName = document.get("Name") as! String
self.userEmail = document.get("Email") as! String
print("Current document is: \(docID)")
print("Current user's name: \(self.userName)")
}
db.collection("Run Reports").document("Custodians").collection("Custodians").document("\(String(describing: userID))").collection("Run Reports").document("\(self.getCurrentShortDate())").setData ([
"Name": "\(String(describing: self.userName))",
"Email": "\(String(describing: self.userEmail))",
"Admin": Bool(false),
"Last Updated": FieldValue.serverTimestamp(),
])
}
// getting values of selection code:
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
print("The cell you tapped has the text: \(self.valuesArray[indexPath.row])")
// let selectedResponsibility = "\(self.valuesArray[indexPath.row])"
print("You tapped cell #\(indexPath.row)")
这是问题所在。尽管我更新firebase文档的代码可以正常工作,但是该代码只是我正在尝试的设置责任1的状态。作品。它只是不适合我上面有关于动态单元格的信息,所有这些都是实验性的,因为它不起作用,这是错误的:
This is where the issue is at. This code is just me experimenting, although the code where I update the firebase document works--"Set the status of Responsibility 1" works. Its just not working for the information I have above it about the dynamic cell which is all experimental and wrong since doesnt work:
// let currentUsersCellCount = self.valuesArray.count
let cell = self.runReportTableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
let dynamicCell = self.runReportTableView.cellForRow(at: indexPath)
if dynamicCell?.isSelected == true {
let status = "Disinfected"
let DocumentRef = db.collection("Run Reports").document("Custodians").collection("Custodians").document("\(String(describing: userID))").collection("Run Reports").document("\(self.getCurrentShortDate())")
// Set the status of Responsibility 1
DocumentRef.updateData(["\(self.valuesArray[indexPath.row])" : "\(status)"])
}
else if dynamicCell?.isSelected == false {
let status = "Not Disinfected"
let DocumentRef = db.collection("Run Reports").document("Custodians").collection("Custodians").document("\(String(describing: userID))").collection("Run Reports").document("\(self.getCurrentShortDate())")
// Set the status of Responsibility 1
DocumentRef.updateData(["\(self.valuesArray[indexPath.row])" : "\(status)"])
}
这一切都很好:
// Setup action for when "Send Report" and alert buttons are tapped
let appearance = SCLAlertView.SCLAppearance(
// Hide default button???
showCloseButton: false
)
// Create alert with appearance
let alert = SCLAlertView(appearance: appearance)
alert.addButton("Done", action: {
// Show SendReportViewController after successfully sent report and alert button is tapped
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewController(withIdentifier: "SendReportViewController")
vc.modalPresentationStyle = .overFullScreen
self.present(vc, animated: true)
// create button on alert
print("'Done' button was tapped.")
})
alert.showSuccess("Report Sent!", subTitle: "Your Run Report has been sent to your supervisor.", closeButtonTitle: "Done", timeout: nil, colorStyle: SCLAlertViewStyle.success.defaultColorInt, colorTextButton: 0xFFFFFF, circleIconImage: nil, animationStyle: .topToBottom)
}
}
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
print("The cell you tapped has the text: \(valuesArray[indexPath.row])")
// let selectedResponsibility = "\(valuesArray[indexPath.row])"
print("You tapped cell #\(indexPath.row)")
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return valuesArray.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = runReportTableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
cell.textLabel?.text = valuesArray[indexPath.row]
print("Responsibilities in cells: \(valuesArray)")
print("\(data)")
return cell
}
// using date to create new firestore document with date as the title
func getCurrentShortDate() -> String {
let todaysDate = NSDate()
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "(MM-dd-yy)"
let DateInFormat = dateFormatter.string(from: todaysDate as Date)
return DateInFormat
}
}
如果要存储有关在fireStore文档中选择的单元格的信息,请输入 Text单元格的数量
:已消毒
或未消毒$ c>,即
ConferenceRoom
:已消毒
,这就是我的建议。
If you want to store the information about the cell you have selected in fireStore document as Text of the cell
: Disinfected
or Not Disinfected
, i.e ConferenceRoom
: Disinfected
, then this is what I would suggest.
首先,在 tableViewCell
文件,添加以下属性
Firstly, inside the tableViewCell
file, add following properties
var tapButton: (() -> Void)? = nil //This will allow you to get the text of the row you have selected
然后,我想您有一个单元内部的按钮(在您的情况下位于左侧),可以点击或不点击。将该按钮名称命名为 checkMark
,这样它将在您的 tableviewCell
文件中声明,就像这样。
Then, I suppose you have a button inside your cell which in your case is on left side and it can be tapped or untapped. Let call that button name as checkMark
so it will be declared inside your tableviewCell
file like so.
@IBOutlet weak var checkMark: UIButton!
现在,添加一个函数 SetCheckMark
,以便用户可以看到单元格已选中或未选中。另外,您将需要两个图像,这些图像将以选中或未选中状态分配给按钮。
Now, add a function SetCheckMark
so user can see wether a cell is checked or unchecked. Also, you would need two images which would be assigned to button in checked or unchecked state.
@IBAction func SetCheckMark(_ sender: UIButton) {
//If button is selected, then
if checkMark.isSelected == true {
checkMark.setImage(UIImage(named: "Check"), for: .normal)
checkMark.isSelected = false
}
else {
checkMark.setImage(UIImage(named: "UnCheck"), for: .normal)
checkMark.isSelected = true
}
tapButton?() //This is the property that we declared above.
}
现在,您快完成了。进入您的主文件。首先,在File的开头添加一个字典以保存信息。
Now, you are almost done. Come inside your Main file. Firstly, add a dictionary at the start of File to save information.
var InfoArray:[[String:String]] = [["":""]]
现在,在tableView cellForRowAt indexPath:IndexPath
函数,添加以下行。
Now, inside your tableView cellForRowAt indexPath: IndexPath
function, add these lines.
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = runReportTableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
cell.label.text = valuesArray[indexPath.row]
cell.SetCheckMark(cell.checkMark) //Call `SetCheckmark` function here
cell.tapButton = {
if cell.checkMark.isSelected == false {
let data:[String:String] = [self.Facilities[indexPath.row]: "Disinfected"]
self.InfoArray.append(data)
}
else {
self.InfoArray.remove(at: indexPath.row)
}
}
return cell
}
用户选择完选项后,将点击 sendReport
按钮。然后,在该按钮内,您可以像这样将数据发布到Firestore文档中。
After the user is done selecting the options, it will tap the sendReport
button. Then, inside that button you can post the data to firestore document like this.
db.collection("CollectionName").document("DocumentName").setData(["Facilities" : self.InfoArray])
您的 tableViewCell
文件应如下所示。
class YourTableViewCell: UITableViewCell {
@IBOutlet weak var checkMark: UIButton!
var tapButton: (() -> Void)? = nil
@IBAction func SetCheckMark(_ sender: UIButton) {
if checkMark.isSelected == true {
checkMark.setImage(UIImage(named: "Checkbox"), for: .normal)
checkMark.isSelected = false
}
else {
checkMark.setImage(UIImage(named: "UnCheckbox"), for: .normal)
checkMark.isSelected = true
}
tapButton?()
}
}
它应该工作。如果您有任何问题,请立即让我知道。
It should work. If you get any problem, do let me know instantly.