Closed tvanes closed 6 years ago
You're right, thats indeed not possible using SplitRow. The main reason for this is, you have to define the rowTypes before initialization (SplitRow<PushRow<String>,SwitchRow>
) - and the type is therefore not changeable at runtime.
The easiest workaround I can see for this is, that you initialize multiple SplitRows and depending on the user selection, you change the row which is displayed at this specific position.
Something like this:
let options = [
"name",
"switch"
]
let switchSplitRow = SplitRow<PushRow<String>,SwitchRow>(){
$0.tag = "name"
$0.rowLeft?.options = options
}
let nameSplitRow = SplitRow<PushRow<String>,NameRow>(){
$0.tag = "switch"
$0.rowLeft?.options = options
}
switchSplitRow.onChange{
if $0.rowLeft?.value == "name" {
//hide/remove this row here, and show `nameSplitRow`
}
}
nameSplitRow.onChange{
if $0.rowLeft?.value == "switch" {
//hide/remove this row here, and show `switchSplitRow`
}
}
Thank you for that idea, though I was hoping to use something like this within a MultivaluedSection, which would make the swapping a bit more complicated I'm afraid... :)
Yeah, within a MultivaluedSection this will get a bit trickier :)
May I ask you what exactly your use case is? Do you really have completely different row types, or are we talking about having input fields which should provide different keyboards (DecimalRow, NameRow, ...) or anything similar?
In my case I'd need something where users can fill out optional metadata. So the field count is flexible, the data names can be selected from a list on the left and their corresponding values are to be specified on the right, with the type of input depending on the selection. This would be mostly text fields (NameRow) or sublists (like PushRow). So yes, we are talking very different row types here.
I see. Well, it seems you'll have to go the tricky path I guess ;)
For this, I would suggest using something like the following code. Note this is untested, but it should provide you with the basic idea to get you going:
struct MetaRowTag {
static let name = "name"
static let yesOrNo = "yesOrNo"
}
MultivaluedSection(){ section in
var metaRowTypes = [String: BaseRow]()
let nameRow = SplitRow<PushRow<String>,NameRow>{
$0.tag = MetaRowTag.name
$0.rowLeft = PushRow<String>{
$0.options = [MetaRowTag.name,.yesOrNo]
}
...
}.onChange{
if let rowType = $0.tag,
let selectedRowType = $0.rowLeft?.value,
rowType != selectedRowType,
let newRow = metaRowTypes[selectedRowType],
let indexPath = $0.indexPath {
section.remove(at: indexPath.row)
section.insert(newRow, at: indexPath.row)
}
}
metaRowTypes[MetaRowTag.name] = nameRow
let yesOrNoRow = SplitRow<PushRow<String>,SwitchRow>{
$0.rowLeft = PushRow<String>{
$0.options = [MetaRowTag.name,.yesOrNo]
}
...
}.onChange{
//see above
}
metaRowTypes[MetaRowTag.yesOrNo] = yesOrNoRow
section.addButtonProvider = { section in
return ButtonRow(){
$0.title = "Add New Meta"
}.cellUpdate { cell, row in
cell.textLabel?.textAlignment = .left
}
}
section.multivaluedRowToInsertAt = { index in
return metaRowTypes[MetaRowTag.name]
}
section <<< metaRowTypes[MetaRowTag.name]
}
PS: You might want to use some kind of metaRowProvider
instead of the metaRowTypes
object in the example above. This way you always receive a new row instance:
let metaRowProvider: ((String) -> BaseRow?) = { rowType in
switch rowType{
case MetaRowTag.name: return SplitRow<PushRow<String>,NameRow>{
$0.tag = MetaRowTag.name
$0.rowLeft = PushRow<String>{
$0.options = [MetaRowTag.name,.yesOrNo]
}
}
case MetaRowTag.yesOrNo: return SplitRow<PushRow<String>,SwitchRow>{
$0.tag = MetaRowTag.yesOrNo
$0.rowLeft = PushRow<String>{
$0.options = [MetaRowTag.name,.yesOrNo]
}
}
default: return nil
}
and then use it like this:
let nameRow = metaRowProvider(MetaRowTag.name)
I'll close this for now. Feel free to ping me if you have any other questions.
SplitRow is an awesome addition to Eureka. But I don't suppose it's possible yet to change the row type of rowRight based on (for example) a selection from a PushRow at the rowLeft, is it?
So take your basic usage example, imagine you select "Work" from the selector at your left. Based on this selected value the rowRight changes from a TextRow into a PushRow where a corresponding value can be selected for Work, or perhaps a switch row, etc.
Any pointers to how something like this could be implemented?