I am using Eureka to build a form in iOS using Swift. I have created a multivalued section, e.g.:
form +++ MultivaluedSection(multivaluedOptions: [.Insert, .Delete], header: "My Header", footer: "My footer") { section in
section.tag = "mySectionTag"
section.addButtonProvider = { _ in
return ButtonRow() { row in
row.title = "Add row"
}
}
section.multivaluedRowToInsertAt = { index in
return TimeInlineRow() { row in
row.title = "My row title"
}
}
// initialize form with any times that have already been set previously, times: [Date]
for time in times {
section <<< TimeInlineRow(tag) { row in
row.value = time
row.title = "My row title"
}
}
I would like to limit the number of rows you can insert into my multi valued section. Was thinking about doing it by hiding the ButtonRow
using some kind of Condition
but I'm not sure how to connect it. Alternatively could just present an alert if you tap the button row when the count of values()
in the section is too high, but then how do you block the actual inserting?
Was also considering that I could do something inside multivaluedRowToInsertAt
based on index but still not sure what.
Looked through the issues and was surprised not to find anything on this already, so I can only assume I'm missing something obvious.
Another thought I had was to set a Condition
on the ButtonRow
in the addButtonProvider
that returns true if the row with a certain max row tag (that I create) is not nil in the form (i.e. no such row exists), and then in the multivaluedRowToInsertAt
it would check if the index is greater than the max allowable index and if so it applies the max tag when creating that row. But it seems the green + insert button is automatically applied to the last row of the section regardless of the type. Then I tried changing the multivaluedOptions
to just .Delete
when the max rows are reached but I'm having trouble figuring out how to get it to go back to allowing inserting after a row is deleted.
Also tried putting a condition on the ButtonRow
's disabled property based on a similar method as above (with a max row) but it also runs into duplicate row tag issues and the green add button still responds to taps, and the showInsertIconInAddButton
property has no effect.
Even if I get this method working, it seems unnecessarily convoluted and I would have expected there to be a much simpler solution since it seems like this would be the kind of functionality a lot of people would need.
As laid out in Mahbub's answer and hinted at in the original question, one can check the index in the multivaluedRowToInsertAt
block and update the multivaluedOptions
and hide the button row accordingly.
Properties in FormViewController
:
private var myButtonRow: ButtonRow! // Can also just refer to it by tag
let kMaxCount = 5
Inside a setup function in FormViewController
: (not shown, setting up the section / button row / add provider etc)
section.multivaluedRowToInsertAt = { index in
if index >= self.kMaxCount - 1 {
section.multivaluedOptions = [.Delete]
self.myButtonRow.hidden = true
DispatchQueue.main.async() { // I'm not sure why this is necessary
self.myButtonRow.evaluateHidden()
}
}
return TimeRow() { row in // any row type you want — although inline rows probably mess this up
row.title = title
row.value = Date()
}
}
The changes to the button row inside multivaluedRowToInsertAt
didn't seem to take hold until the 6th row was added, regardless of when the hidden method is called and what the max count is set to, and the last row that inserts goes in the second last place. So then I tried the code as written above, with a dispatch call delaying evaluateHidden()
and it seems to work. I'm not sure why, presumably some conflicting race condition. Note, when the insert method is called it is on the main thread, so it's not about changing UI on a background thread.
Then for when rows are deleted there is a function called rowsHaveBeenRemoved
you can override in a FormViewController
subclass that is called whenever a row (in any section) is removed:
override func rowsHaveBeenRemoved(_ rows: [BaseRow], at indexes: [IndexPath]) {
super.rowsHaveBeenRemoved(rows, at: indexes)
if let index = indexes.first?.section, let section = form.allSections[index] as? MultivaluedSection {
if section.count < kMaxCount {
section.multivaluedOptions = [.Insert, .Delete]
myButtonRow.hidden = false // or could
myButtonRow.evaluateHidden()
}
}
}
This is how can you limit the number of rows in a multivalued section:
section.multivaluedRowToInsertAt = { index in if index > 2 { let multiValuedSection = self?.form.sectionBy(tag: "MultivaluedSectionTag") as! MultivaluedSection multiValuedSection.multivaluedOptions = [.Reorder, .Delete] self?.form.rowBy(tag: "AddButtonProviderTag")?.hidden = true self?.form.rowBy(tag: "AddButtonProviderTag")?.evaluateHidden() } // Do other stuff }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With