Может кто-нибудь сказать мне, какая часть моего кода неверна?
Там два файла CompDftV C .swift и SelectDftV C .swift, когда часы при просмотре таблицы (CompDftV C) переходя к другому табличному виду (SelectDftV C), который я делаю некоторый выбор и нажимаю «Сохранить», чтобы перейти назад, затем я получаю дубликаты записей при начальном просмотре таблицы. Пожалуйста, смотрите мой код и снимки экрана в приложении. Спасибо за вашу помощь.
// CompDftVC.swift
import UIKit
import Firebase
class CompDftVC: UIViewController, UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return compNDftLst.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = compDftTV.dequeueReusableCell(withIdentifier: "compDftTVCell", for: indexPath)
cell.textLabel?.text = compNDftLst[indexPath.row].compName
if indexPath.row % 2 == 0 {
cell.contentView.backgroundColor = .white
} else {
cell.contentView.backgroundColor = .white
}
return cell
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
// pass compID to destination
tmpComponentId = compNDftLst[indexPath.row].compId!
// animate effect
compDftTV.deselectRow(at: indexPath, animated: true)
// segue triggered
performSegue(withIdentifier: "segueToSelectDft", sender: self)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "segueToSelectDft" {
let svc = segue.destination as! SelectDftVC
svc.passInCompId = tmpComponentId
svc.passInParentEmpty = tmpParentEmpty
}
}
@IBOutlet weak var compDftTV: UITableView!
let node = currCompID+"CompDft"
let compNode = currCompID+"Comp"
let dftNode = currCompID+"Dft"
var compNDftLst = [CompNDft]()
var databaseHandle: DatabaseHandle?
var compRef: DatabaseReference!
var tmpComponentId = String()
var tmpParentEmpty = Int()
override func viewDidLoad() {
super.viewDidLoad()
compDftTV.delegate = self
compDftTV.dataSource = self
self.compNDftLst.removeAll()
// check whether the compDft table is empty
// if empty only return component with section (one row)
// if not, prepare tmp Array to display on tableview
compRef = Database.database().reference().child(node)
compRef.observe(DataEventType.value, with: { (snapshot) in
// need to consider the workshop is still empty or not?
if snapshot.childrenCount > 0 {
// CompDft table is not empty. need to retrieve comp/defect list and present them at an expandable tableview
// self.compNDftLst.removeAll()
// component already has defects. prepare the tablewview with defect list
self.tmpParentEmpty = 0
self.compRef = Database.database().reference().child(self.compNode)
self.compRef.observeSingleEvent(of: DataEventType.value, with: { (snapshot) in
if snapshot.childrenCount > 0 {
for comp in snapshot.children.allObjects as! [DataSnapshot] {
let compObj = comp.value as? [String: AnyObject]
self.tmpComponentId = comp.key
let componentName = compObj?["name"]
let component = CompNDft(compId: self.tmpComponentId as String?, compName: componentName as! String?, dftList: [""])
self.compNDftLst.append(component)
}
self.compDftTV.reloadData()
}
})
} else {
// CompDft table is empty. Only need to get componment list from Comp table
self.tmpParentEmpty = 1
self.compRef = Database.database().reference().child(self.compNode)
self.compRef.observeSingleEvent(of: DataEventType.value, with: { (snapshot) in
if snapshot.childrenCount > 0 {
// self.compNDftLst.removeAll()
for comp in snapshot.children.allObjects as! [DataSnapshot] {
let compObj = comp.value as? [String: AnyObject]
self.tmpComponentId = comp.key
let componentName = compObj?["name"]
let component = CompNDft(compId: self.tmpComponentId as String?, compName: componentName as! String?, dftList: [""])
self.compNDftLst.append(component)
}
self.compDftTV.reloadData()
}
})
}
})
} // ViewDidLoad
} // class
// SelectDftVC.swift
import UIKit
import Firebase
class SelectDftVC: UIViewController, UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return tmpDisplayDefectNameList.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = selectDftTV.dequeueReusableCell(withIdentifier: "dftListTVCell", for: indexPath)
cell.textLabel?.text = tmpDisplayDefectNameList[indexPath.row]
// get the componet ID and check which defect was selected and then mark them .checkmark
if tmpDefectSelected[indexPath.row] == 1 {
cell.accessoryType = .checkmark
}
if indexPath.row % 2 == 0 {
cell.contentView.backgroundColor = .white
} else {
cell.contentView.backgroundColor = .white
}
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if tableView.cellForRow(at: indexPath)?.accessoryType == UITableViewCell.AccessoryType.checkmark {
tableView.cellForRow(at: indexPath)?.accessoryType = UITableViewCell.AccessoryType.none
tmpDefectSelected[indexPath.row] = 0
} else {
tableView.cellForRow(at: indexPath)?.accessoryType = UITableViewCell.AccessoryType.checkmark
tmpDefectSelected[indexPath.row] = 1
}
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
let node = currCompID+"CompDft"
let compNode = currCompID+"Comp"
let dftNode = currCompID+"Dft"
var passInCompId = String()
var passInParentEmpty = Int()
var ref: DatabaseReference!
var ref2: DatabaseReference!
var ref3: DatabaseReference!
var ref4: DatabaseReference!
var ref5: DatabaseReference!
var ref6: DatabaseReference!
var refDft: DatabaseReference!
var selectedDft: DatabaseReference!
var selectedDftId = [String]()
var tmpDefectSelected = [Int]()
var initialTmpDefectSelected = [Int]()
var tmpDisplayDefectIdList = [String]()
var tmpDisplayDefectNameList = [String]()
var tmpSelectedDftID = [String]()
var tmpSelectedDftName = [String]()
var hasData = Int()
@IBOutlet weak var selectDftTV: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
selectDftTV.delegate = self
selectDftTV.dataSource = self
tmpDisplayDefectIdList.removeAll() // defect ID
tmpDisplayDefectNameList.removeAll() // defect Name
selectedDftId.removeAll() // Selected defect ID
tmpDefectSelected.removeAll() // Integer array for checkmark
initialTmpDefectSelected.removeAll() // Initial Integer array for checkmark (to be updated when populating tableview
if passInParentEmpty == 1 {
// component doesn't contain any defect
ref = Database.database().reference().child(dftNode)
ref.observe(DataEventType.value, with: { (snapshot) in
// need to consider the workshop is still empty or not?
if snapshot.childrenCount > 0 {
// get defect list
for defect in snapshot.children.allObjects as! [DataSnapshot] {
let defectObj = defect.value as? [String: AnyObject]
let defectId = defect.key
let defectName = defectObj?["name"]
self.tmpDisplayDefectIdList.append(defectId)
self.tmpDisplayDefectNameList.append(defectName as! String)
self.tmpDefectSelected.append(0)
self.initialTmpDefectSelected.append(0)
}
self.prepareSelectedDftList()
}
})
} else {
// the component already contain defect
ref = Database.database().reference().child(dftNode)
ref.observe(DataEventType.value, with: { (snapshot) in
// need to consider the workshop is still empty or not?
if snapshot.childrenCount > 0 {
// get defect list
for defect in snapshot.children.allObjects as! [DataSnapshot] {
let defectObj = defect.value as? [String: AnyObject]
let defectId = defect.key
let defectName = defectObj?["name"]
self.tmpDisplayDefectIdList.append(defectId)
self.tmpDisplayDefectNameList.append(defectName as! String)
self.tmpDefectSelected.append(0)
self.initialTmpDefectSelected.append(0)
}
}
self.ref2 = Database.database().reference().child(self.node)
self.ref2.queryOrderedByKey().queryEqual(toValue: self.passInCompId).observeSingleEvent(of: .value, with: { (snapshot) in
if snapshot.childrenCount > 0 {
self.hasData = 1
} else {
self.hasData = 0
}
if self.hasData == 1 {
self.ref3 = Database.database().reference().child(self.node)
self.ref3.queryOrderedByKey().queryEqual(toValue: self.passInCompId).observe(.childAdded, with: { (snapshot) in
if snapshot.childrenCount > 0 {
// selected component has defects
for child in snapshot.children {
let snap = child as! DataSnapshot
let tmpkey = snap.key as String?
self.selectedDftId.append(tmpkey!)
}
}
self.prepareSelectedDftList()
})
} else {
self.prepareSelectedDftList()
}
})
// self.ref2.removeAllObservers()
}) // first DBquery
// self.ref.removeAllObservers()
}
} // viewDidLoad
@IBAction func saveSelectedDft(_ sender: Any) {
// prepare the array of defects to be marked for component which can override the current one
if tmpDisplayDefectNameList.count > 0 {
for i in 0...tmpDisplayDefectNameList.count - 1 {
if tmpDefectSelected[i] == 1 {
// prepare selected defect ID and name array
tmpSelectedDftID.append(tmpDisplayDefectIdList[i])
tmpSelectedDftName.append(tmpDisplayDefectNameList[i])
}
}
markUsed4CompNDft()
// refDft.removeAllObservers()
}
// segue back and refresh tmp array (may be) and tableview
self.navigationController?.popViewController(animated: true)
} // saveSelectedDftBtn
func prepareSelectedDftList() {
if selectedDftId.count == 0 {
selectDftTV.reloadData()
} else if selectedDftId.count == 1 {
for i in 0...tmpDisplayDefectIdList.count - 1 {
if tmpDisplayDefectIdList[i] == selectedDftId[0] {
tmpDefectSelected[i] = 1
initialTmpDefectSelected[i] = 1
}
}
selectDftTV.reloadData()
} else if selectedDftId.count > 1 {
for i in 0...tmpDisplayDefectIdList.count - 1 {
for j in 0...selectedDftId.count - 1 {
if tmpDisplayDefectIdList[i] == selectedDftId[j] {
tmpDefectSelected[i] = 1
initialTmpDefectSelected[i] = 1
}
}
}
// self.ref.removeAllObservers()
selectDftTV.reloadData()
}
} // prepareSelectedDftList
func resetComponentUsedToZero() {
var clearCompId = String()
var clearCompName = String()
ref5 = Database.database().reference()
ref5.child(compNode).queryOrderedByKey().queryEqual(toValue: passInCompId).observe(.childAdded, with: { (snapshot) in
for child in snapshot.children {
let snap = child as! DataSnapshot
let key = snap.key
if key == "id" {
clearCompId = snap.value as! String
}
if key == "name" {
clearCompName = snap.value as! String
}
}
let updatedComponent = [
"id" : clearCompId,
"name" : clearCompName,
"date" : utcDate(),
"time" : utcTime(),
"updated" : currUID,
"used" : 0
] as [String: Any]
self.ref5.child(self.compNode).child(self.passInCompId).setValue(updatedComponent)
})
ref5.removeAllObservers()
}
func setComponentUsedToOne() {
var clearCompId = String()
var clearCompName = String()
ref5 = Database.database().reference()
ref5.child(compNode).queryOrderedByKey().queryEqual(toValue: passInCompId).observe(.childAdded, with: { (snapshot) in
for child in snapshot.children {
let snap = child as! DataSnapshot
let key = snap.key
if key == "id" {
clearCompId = snap.value as! String
}
if key == "name" {
clearCompName = snap.value as! String
}
}
let updatedComponent = [
"id" : clearCompId,
"name" : clearCompName,
"date" : utcDate(),
"time" : utcTime(),
"updated" : currUID,
"used" : 1
] as [String: Any]
self.ref5.child(self.compNode).child(self.passInCompId).setValue(updatedComponent)
})
ref5.removeAllObservers()
}
func markUsed4CompNDft() {
ref6 = Database.database().reference()
// check any changes made
if initialTmpDefectSelected != tmpDefectSelected {
if tmpSelectedDftID.count == 0 {
// clear all defect
ref6.child(node).child(passInCompId).setValue(nil)
// should change component 'used' to 0
resetComponentUsedToZero()
} else {
ref6.child(node).child(passInCompId).setValue(nil)
for i in 0...tmpSelectedDftID.count - 1 {
ref6.child(node).child(passInCompId).child(tmpSelectedDftID[i]).setValue(tmpSelectedDftName[i])
}
// mark component used = 1
setComponentUsedToOne()
// mark defect(s) used = 1
if tmpSelectedDftID.count > 0 {
// ref = Database.database().reference().child(dftNode)
ref4 = Database.database().reference().child(dftNode)
for i in 0...tmpSelectedDftID.count - 1 {
ref4.queryOrderedByKey().queryEqual(toValue: tmpSelectedDftID[i]).observe(.childAdded, with: { (sp) in
self.ref4.child(self.tmpSelectedDftID[i]).updateChildValues(["date" : utcDate()])
self.ref4.child(self.tmpSelectedDftID[i]).updateChildValues(["time" : utcTime()])
self.ref4.child(self.tmpSelectedDftID[i]).updateChildValues(["updated" : currUID])
self.ref4.child(self.tmpSelectedDftID[i]).updateChildValues(["used" : 1])
})
}
}
// ref4.removeAllObservers()
}
}
} // markUsed4CompNDft
} // class