Swift Eureka 表单:如何限制多值部分中的行数?

Swift Eureka forms: how do you limit the number of rows in a multivalued section?

我正在使用 Eureka 使用 Swift 在 iOS 中构建表单。我创建了一个多值部分,例如:

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"
    }
}

我想限制您可以插入我的多值部分的行数。正在考虑通过使用某种 Condition 隐藏 ButtonRow 来做到这一点,但我不确定如何连接它。或者,如果您在该部分中 values() 的计数太高时点击按钮行,则可以只显示警报,但是您如何阻止实际插入?

也在考虑我可以根据索引在 multivaluedRowToInsertAt 中做一些事情,但仍然不确定是什么。

查看了这些问题,很惊讶没有在这上面找到任何东西,所以我只能假设我遗漏了一些明显的东西。

我的另一个想法是在 addButtonProvider 中的 ButtonRow 上设置一个 Condition 如果具有某个最大行标记的行(即I create) is not nil in the form (i.e. no such row exists),然后在 multivaluedRowToInsertAt 中,它将检查索引是否大于允许的最大索引,如果是,则在创建时应用 max 标记排。但似乎无论类型如何,绿色 + 插入按钮都会自动应用于该部分的最后一行。然后我尝试在达到最大行数时将 multivaluedOptions 更改为 .Delete 但我无法弄清楚如何让它返回到允许在删除行后插入。

还尝试根据与上述类似的方法(使用最大行)在 ButtonRow 的禁用 属性 上设置条件,但它也会遇到重复的行标记问题和绿色添加按钮仍然响应点击,showInsertIconInAddButton 属性 无效。

即使我让这个方法起作用,它似乎也不必要地令人费解,我希望有一个更简单的解决方案,因为这似乎是很多人需要的那种功能。

这是限制多值部分中行数的方法:

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
}

中所述并在原始问题中暗示,可以检查 multivaluedRowToInsertAt 块中的索引并更新 multivaluedOptions 并相应地隐藏按钮行。

FormViewController 中的属性:

private var myButtonRow: ButtonRow! // Can also just refer to it by tag
let kMaxCount = 5

FormViewController 中的设置函数中:(未显示,设置部分/按钮行/添加提供商等)

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()
    }
}

在添加第 6 行之前,multivaluedRowToInsertAt 中对按钮行的更改似乎没有生效,无论何时调用隐藏方法以及最大计数设置为多少,以及插入的最后一行排在倒数第二位。然后我尝试了上面写的代码,调度调用延迟 evaluateHidden() 并且它似乎工作。我不确定为什么,大概是一些相互冲突的竞争条件。请注意,调用插入方法时,它是在主线程上调用的,因此它与在后台线程上更改 UI 无关。

然后,当删除行时,有一个名为 rowsHaveBeenRemoved 的函数,您可以在 FormViewController 子类中重写该函数,每当删除行(在任何部分中)时调用该函数:

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()
        }
    }
}