xmartlabs / Eureka

Elegant iOS form builder in Swift
https://eurekacommunity.github.io
MIT License
11.78k stars 1.33k forks source link

Duplicate tag crash on renamed tag #2102

Closed cmouline closed 4 years ago

cmouline commented 4 years ago

Environment: Eureka 5.3.1, Xcode 12.0 and iOS 13.3 on simulator.

I have a form with multiple sections. I want to be able to duplicate one of these sections and remove those duplicated sections as well and I want the tags of the rows of the duplicated sections to be the same with the index number concatenated to differentiate them. A piece of will explain better.

Here is the base section that I want to be able to duplicate:

          +++ Section("Phase n°1")
            <<< TextAreaRow() {
                $0.tag = "consigne-1"
            }
            <<< IntRow() {
                $0.tag = "phaseDuration-1"
            }
            [...]
            <<< ButtonRow() {
                $0.title = "Add phase"
            }.onCellSelection { _, row in
                self.addPhase(2, on: row)
            }

Here is my function to add the same section + a remove button (first section cannot be removed) :

    func createPhaseSection(_ number: Int) -> Section {
        return Section("Phase n°\(number)")
            <<< TextAreaRow() {
                $0.tag = "consigne-\(number)"
            }
            <<< IntRow() {
                $0.tag = "phaseDuration-\(number)"
            }
           [...]
            <<< ButtonRow() {
                $0.title = "Remove phase"
            }.onCellSelection { _, row in
                if let section = row.section, let index = section.index {
                    self.numberOfPhase -= 1
                    self.form.allSections[index].removeAll()
                    self.form.remove(at: index)
                    self.reSetPhaseNumber()
                }
            }
            <<< ButtonRow() {
                $0.title = "Add phase"
            }.onCellSelection { _, row in
                self.addPhase(on: row)
            }
    }

    private func addPhase(_ number: Int? = nil, on row: ButtonRow) {
        if let section = row.section, let index = section.index {
            self.numberOfPhase += 1
            let phaseNumber = number == nil ? self.numberOfPhase : number!
            self.form.insert(self.createPhaseSection(phaseNumber), at: index + 1)
            self.reSetPhaseNumber()
        }
    }

And finally the function I used to update my tags cause I want them to be ordered :

    private func reSetPhaseNumber() {
        for index in 1...numberOfPhase {
            let section = form.allSections[1 + index]
            section.header?.title = "Phase n°\(index)"
            section.allRows[0].tag = "consigne-\(index)"
            section.allRows[1].tag = "phaseDuration-\(index)"
            [...]
        }
        tableView.reloadData()
    }

So here's my problem, it all works fine as long as I add new sections, when I start removing them it also works. But when I want to add again after I remove a section, I get a crash telling me that I have duplicate tags. But the weird thing is that when I print all my sections and rows at the end of my resetPhaseNumber, I don't see the tags that I want to add so I'm wondering if they are memorized somewhere.

Here is the output of my log :

---------- AFTER ADDING SECTION -----------
*** Section 0 ***

rows of section 0

*** Section 1 ***

rows of section 1

*** Section 2 *** Base section to duplicate

row 0 - tag consigne-1
row 1 - tag phaseDuration-1
[...]

*** Section 3 *** Duplicated section

row 0 - tag consigne-2
row 1 - tag phaseDuration-2
[...]

*** Section 4 *** Duplicated section / Last added section

row 0 - tag consigne-3
row 1 - tag phaseDuration-3
[...]

---------- AFTER ADDING SECTION -----------
*** Section 0 ***

rows of section 0

*** Section 1 ***

rows of section 1

*** Section 2 *** Base section to duplicate

row 0 - tag consigne-1
row 1 - tag phaseDuration-1
[...]

*** Section 3 *** Duplicated section

row 0 - tag consigne-2
row 1 - tag phaseDuration-2
[...]

*** Section 4 *** Duplicated section

row 0 - tag consigne-3
row 1 - tag phaseDuration-3
[...]

*** Section 5 *** Duplicated section / Last added section

row 0 - tag consigne-4
row 1 - tag phaseDuration-4
[...]

---------- AFTER DELETING SECTION -----------
*** Section 0 ***

rows of section 0

*** Section 1 ***

rows of section 1

*** Section 2 *** Base section to duplicate

row 0 - tag consigne-1
row 1 - tag phaseDuration-1
[...]

*** Section 3 *** Duplicated section

row 0 - tag consigne-2
row 1 - tag phaseDuration-2
[...]

*** Section 4 *** Duplicated section

row 0 - tag consigne-3
row 1 - tag phaseDuration-3
[...]

---------- TRYING TO ADD A SECTION -----------

Assertion failed: Duplicate tag consigne-4: file Eureka/BaseRow.swift, line 196
2020-10-16 22:38:40.548485+0200 FichesDePrep[23083:1020078] Assertion failed: Duplicate tag **consigne-4**: file Eureka/BaseRow.swift, line 196
mats-claassen commented 4 years ago

The issue might be due to trying to update tags. That is not supported and could lead to various issues as there are structures that are probably not updated when the tag of a row changes. Tags should be set when the row is initialized, but not reset afterwards

cmouline commented 4 years ago

OK, it does make sense ! I'm going to find another way to achieve what I want to do here. Thanks !

And also thanks for this great lib ! Love using it ❤️