// I have a struct model for Notes
struct NotesModel{
var groupName: String // sections in tableView
var info: [NotesInfo] // rows in respective sections in tableView
}
struct NotesInfo{
var groupName: String
var image: String
var notesTitle: String
var notesDescription: String
var notesDate: String
}
// 1) this is my ViewController(FirstVC)
var arrayNotes = [NotesModel]() // array that will be used to populate tableView
var info1 = [NotesInfo]()
var info2 = [NotesInfo]()
var info3 = [NotesInfo]()
// I have appended data in arrayNotes
info1.append(NotesInfo(groupName: "ABC", image: "img1", notesTitle: "Public Notes", notesDescription: "Public Notes are for xyz use...", notesDate: "17/08/2020"))
info1.append(NotesInfo(groupName: "ABC", image: "img1", notesTitle: "Public Notes(A)", notesDescription: "Public Notes are for xyz use...", notesDate: "19/08/2020"))
arrayNotes.append(NotesModel(groupName: "ABC", info: info1))
info2.append(NotesInfo(groupName: "XYZ", image: "img2", notesTitle: "My Notes", notesDescription: "My Notes include...", notesDate: "25/08/2020"))
arrayNotes.append(NotesModel(groupName: "XYZ", info: info2))
info3.append(NotesInfo(groupName: "PQR", image: "img3", notesTitle: "Notes Example", notesDescription: "Notes Example here..", notesDate: "25/08/2020"))
arrayNotes.append(NotesModel(groupName: "PQR", info: info2))
// I have a TableView on ViewController to present NotesModel data
// MARK: - Number of Sections in TableView
func numberOfSections(in tableView: UITableView) -> Int {
return arrayNotes.count // returns 3
}
// MARK: - HeaderView in Section
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let headerCell = Bundle.main.loadNibNamed("HeaderCell", owner: self, options: nil)?.first as! HeaderCell
let dict = arrayNotes[section]
headerCell.lblGroupName.text = dict.groupName // "ABC", "XYZ", "PQR"
let info = dict.info
for values in info{
headerCell.imgGroup.image = UIImage(named: values.image) // "img1", "img2", "img3"
}
return headerCell
}
// MARK: - Number of Rows in TableView
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return arrayNotes[section].info.count // "ABC" -> 2 rows, "XYZ" -> 1 row, "PQR" -> 1 row
}
// MARK: - Cell For Row At in TableView
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "NotesCell", for: indexPath) as! NotesCell
cell.selectedBackgroundView = UIView()
cell.selectedBackgroundView?.backgroundColor = .systemBackground
let dict = arrayNotes[indexPath.section]
let info = dict.info[indexPath.row]
cell.lblNotesTitle.text = info.notesTitle
cell.lblNotesDescription.text = info.notesDescription
cell.lblNotesDate.text = info.notesDate
return cell
}
// MARK: - Button Create New Note Event
func createNewNotesButton(_ sender: UIButton){
let storyBoard = UIStoryboard(name: "NotesStoryBoard", bundle: nil)
let createNewNotesVC = storyBoard.instantiateViewController(withIdentifier: "CreateNewNotesVC") as! CreateNewNotesVC
createNewNotesVC.delegate = self
self.navigationController?.pushViewController(createNewNotesVC, animated: true)
}
// MARK: - Create New Notes Protocol Conformance
func passNewNotesModel(object: NotesModel) {
for item in arrayNotes{
if item.groupName == object.groupName{
print("same section")
var ogInfo = item.info
let addedInfo = object.info
ogInfo.append(contentsOf: addedInfo)
print("ogInfo after appending --> \(ogInfo)")
arrayNotes.append(NotesModel(groupName: item.groupName, info: ogInfo))
// I want to append rows in section that already exist on ViewController, there is already 3 sections with different number of rows but this doesn't append in respective section but creates new section every time
}else{
print("different section")
arrayNotes.append(object)
// and if section doesn't exist here on ViewController then create new section and add rows in it. but this adds multiple sections
}
}
self.tableViewNotes.reloadData()
}
this is my CreateNewNotesVC(SecondVC)
// MARK: - Protocol Create New Notes for NotesModel
protocol CreateNewNotesModel { func passNewNotesModel(object: NotesModel) }
var newNotesModel: NotesModel!
var delegate: CreateNewNotesModel?
here i have textFields and "SUBMIT" button, on "SUBMIT" button click, pass NotesModel object and popView to firstVC and tableView on firstVC should be updated with newly created model object.
also there is one drop down menu here from which i have to select note's group name say there are 6 different group names, which represents section in tableView, if i choose "ABC" group name from drop down menu then on ViewController(firstVC) data should be append in "ABC" section in tableView, if i choose "OMG" group name from drop down which doesn't exist on ViewController(firstVC), then new section should be created.
// MARK: - Button Submit Event
@IBAction func btnSubmit_Event(\_ sender: Any) {
var info = [NotesInfo]()
info.append(NotesInfo(groupName: txtSelectGroup.text ?? "", image: ImageString, notesTitle: txtNotesTitle.text ?? "", notesDescription: txtNotesDescription.text ?? "", notesDate: txtNotesDate.text ?? ""))
newNotesModel = (NotesModel(groupName: txtSelectGroup.text ?? "", info: info))
delegate?.passNewNotesModel(object: newNotesModel)
self.navigationController?.popViewController(animated: true)
}
i want to append data in respective sections, my code is generating section every time due to for loop, i have no idea how to append data in respective section, any help would be really appreciated ! Thank You.
UPDATE: as per WeyHan Ng suggestion:
for item in arrayNotes{
var ogInfo = item.info
let addedInfo = object.info
ogInfo.append(contentsOf: addedInfo)
print("ogInfo after appending --> \(ogInfo)")
if item.groupName == object.groupName{
print("same section")
let index = arrayNotes.firstIndex(where: { $0.groupName == object.groupName})!
print(index)
arrayNotes[index].info = ogInfo // this is solved
}else{
print("different section")
arrayNotes.append(object) // ISSUE: appending more than one section every time
}
}
self.tableViewConsultantMilestones.reloadData()
CodePudding user response:
Based on the code in your passNewNotesModel(object: newNotesModel)
method, You are doing the following:
Iterate through every element in 'arrayNotes' as 'item'.
If the element 'groupName' of 'item' matches the 'groupName' of 'object'
Make a copy of 'item.info' as 'ogInfo'
Make a copy of 'object.info' as 'addedInfo'
Append 'addedInfo' to 'ogInfo'
Append 'ogInfo' to 'arrayNotes'
Else
Append 'object' to 'arrayNotes'
End if
End loop
So, for arrayNotes
with N elements your code appends object
of N-1 times and append 1 time ogInfo addedInfo
What you need to do is to is:
Find index of the element with 'groupName' equal to 'object.groupName'
If found
Replace 'arrayNotes[foundIndex]' with 'arrayNotes[foundIndex] object.info'
Else
Append 'object' to 'arrayNotes'
End if
Hint: you can use first(where: (String) throws -> Bool)
method to find the element in arrayNotes
and use it's return value to replace the element.
CodePudding user response:
// UPDATE
// Below code worked for me
// MARK: - Create New Notes Protocol Conformance
func passNewNotesModel(object: NotesModel) {
let filteredDict = self.arrayNotes.filter({$0.groupName == object.groupName})
if filteredDict.count > 0 {
// add rows in that particular section
for indexValue in arrayNotes.enumerated() {
if indexValue.element.groupName == filteredDict.first?.groupName {
if let obj = filteredDict.first {
var ogInfo = obj.info
let addedInfo = object.info
ogInfo.append(contentsOf: addedInfo)
arrayNotes[indexValue.offset].info = ogInfo
}
}
}
} else {
// add new section
arrayNotes.append(object)
}
}