【问题标题】:How to update a UIPickerview after changing it's data source contents更改数据源内容后如何更新 UIPickerview
【发布时间】:2019-08-08 08:25:38
【问题描述】:

我在 iPad 模拟器上运行的 ios 程序中有 2 个 UIPickerViews。 它们各有一个组件。 我通过使用标签上的开关找到相关的选择器视图。需要通过添加或删除组件来更改两个单组件视图。 这在数据源中很容易 pickerData.append(textInput) pickerData.sort() pickerData.reloadAllComponentspickerData.remove(at: lastDataSelected) picker.reloadAllComponents() 其中 lastDataSelected 是行整数。

这适用于更改数据源,但在传输到 UIPickerViews 时不能完全更改。 UIPickerView 显示在我滚动视图之前不会更新。更准确地说,选择的项目是正确的,但文本标签没有更新。滚动后数据标签都正确显示。 我试图以编程方式从一端滚动到另一端,但这无济于事。

那么我怎样才能告诉程序在用户不滚动的情况下更新视图呢? picker.reloadInputViews() 没有帮助。

除此之外,项目(行)的数量不会改变以反映选择器数据的变化,因此在添加新项目时最后一个项目会从列表中消失。 那么第二个问题是如何让UIPickerView函数更新行数呢?

我无法找到任何动态更新的选择器视图示例,因此希望有人可以帮助或为我指明正确的方向。 剩下的代码我相信是相当标准的,但我显然在更新过程中遗漏了一些东西。

override func viewDidLoad() {
    super.viewDidLoad()
    flvPicker = UIPickerView()
    flvPicker.delegate = self
    flvPicker.dataSource = self
    flvPicker.tag = 0
}

func numberOfComponents(in pickerView: UIPickerView) -> Int {
    switch pickerView.tag {
    case 0:
        return 1
    case 1:
        etc...
    }
}
var numberOfRowsInComponent = 0
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
    switch pickerView.tag {
    case 0:
        return flvPickerData.count
    case 1:
        etc...
    }
}
func pickerView(_
    pickerView: UIPickerView,
                titleForRow row: Int, forComponent component: Int) -> String? {
    switch pickerView.tag {
    case 0:
        return flvPickerData[row]
    case 1:
        etc...
    }
}


func pickerView( _ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
    switch pickerView.tag {
    case 0:
        flavourSelected = flvPickerData[row]
        lastFlavourSelected = row
    case 1: etc...
    }
}

我认为问题实际上是如何让 UIPickerView 在更改其数据源并因此更改行数后正确更新。

【问题讨论】:

    标签: ios swift xcode ios-simulator


    【解决方案1】:

    您可以使用UIPickerView 中的reloadComponent(_:) 方法。

    【讨论】:

    • 这不起作用,但 flvPicker.reloadAllComponents() 也不起作用。列表像以前一样更新,滚动后可见,但行数保持不变,因此在添加项目时最后一项从列表中滚出。
    • 在解决这个问题时,我发现“'row' 是一个 'let' 常量,即不可变,因此无法更新为新的行数。
    • 这是 UIPickerViewDelegate 协议的一部分,有什么办法可以解决这个问题吗?有什么方法可以重新初始化选择器视图吗?
    • 调用reloadComponent(_:)reloadAllComponents() 应该没问题。另外,请确保您在主线程上调用它。 (DispatchQueue.main.async { })。
    • 是的,reloadAllComponents() 应该可以工作。使用DispatchQueue.main.async { self.flvPicker.reloadAllComponents() } 将确保它在主线程上运行并立即显示更新。
    【解决方案2】:

    聚会有点晚了,但如果你想更新一个选择器视图,还有selectRow的方法。这还具有动画属性的好处,因此您可以为任何更新设置动画。

    例子:

    for (index, day) in weeklyOptions[0].enumerated() {
        if scheduledTime.contains(day) {
            weeklyDatePicker.selectRow(index, inComponent: 0, animated: true)
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-30
      • 1970-01-01
      • 1970-01-01
      • 2019-07-13
      • 1970-01-01
      相关资源
      最近更新 更多