强制 UIPickerView 重新加载数据

Posted

技术标签:

【中文标题】强制 UIPickerView 重新加载数据【英文标题】:Force UIPickerView reload data 【发布时间】:2020-02-10 09:30:57 【问题描述】:

我有 UITableViewController 和 2 个动态单元格(一个用于具有详细信息的单元格,一个用于 UIPickerView)。以编程方式,我创建了 2 个部分,其中 1 行(1 部分)和 2 行(2 部分)。当您点击它们时,行打开UIPickerView。但我有一个小问题。我不知道如何强制UIPickerView 重新加载/更新并显示所需的数据。 UIPickerView 仅加载我首先打开的单元格数组。如果我打开另一个单元格(带有另一个数组)UIPickerView 不会重新加载数据。我试图将reloadAllComponents() 放在任何地方,但没有任何反应。你知道我该如何解决这个问题吗?谢谢

    import Foundation
    import UIKit

    class VC: UITableViewController, UIPickerViewDataSource, UIPickerViewDelegate 

    var units = ["A","B","C","D","E","F","G"]

    var units2 = ["1","2","3","4","5","6","7"]

    var units3 = ["I","II","III","IV","V","VI","VII"]

    // Show or hide picker
    var showUnitsPickerView = false
    var showUnits2PickerView = false
    var showUnits3PickerView = false

    var pickerView = UIPickerView()

    func numberOfComponents(in pickerView: UIPickerView) -> Int 
        return 1
    

    func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int 

        var count = 0

        if showUnitsPickerView 
            count = units.count
         else if showUnits2PickerView 
            count = units2.count
         else 
            count = units3.count
        

        return count

    

    func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? 

        var value = ""

        if showUnitsPickerView 
            value = String(units[row])
         else if showUnits2PickerView 
            value = String(units2[row])
         else if showUnits3PickerView 
            value = String(units3[row])
        

        return value

    

    // MARK: - View Did Load
    override func viewDidLoad() 
        super.viewDidLoad()
    

    override func numberOfSections(in tableView: UITableView) -> Int 
        return 2
    

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int 

        var count = 1

        switch section 

        case 0:
            if showUnitsPickerView 
                count = 2
            

        case 1:
            if showUnits3PickerView
            || showUnits2PickerView 
                count = 3
             else 
                count = 2
            
        default:
            count = 1
        

        return count
    

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 


        switch indexPath.section 
        case 0:

            var universallCell = UITableViewCell()

            if indexPath.row == 0 

                let cell = tableView.dequeueReusableCell(withIdentifier: String(describing: TitleAndDetailCellT3.self), for: indexPath) as! TitleAndDetailCellT3

                cell.title.text = "Picker 1"
                cell.detail.text = "A"
                universallCell = cell

             else if showUnitsPickerView 

                let cellWithPickerView = tableView.dequeueReusableCell(withIdentifier: String(describing: PickerViewCellT3.self), for: indexPath) as! PickerViewCellT3
                cellWithPickerView.pickerView.delegate = self
                cellWithPickerView.pickerView.dataSource = self
                cellWithPickerView.pickerView = pickerView

                universallCell = cellWithPickerView

            

            return universallCell

        case 1:

            var universallCell = UITableViewCell()

            let cell = tableView.dequeueReusableCell(withIdentifier: String(describing: TitleAndDetailCellT3.self), for: indexPath) as! TitleAndDetailCellT3

            let cellWithPickerView = tableView.dequeueReusableCell(withIdentifier: String(describing: PickerViewCellT3.self), for: indexPath) as! PickerViewCellT3

            switch indexPath.row 
            case 0:
                cell.title.text = "Picker 2"
                cell.detail.text = "1"
                universallCell = cell
            case 1:

                if showUnits2PickerView 
                    cellWithPickerView.pickerView.delegate = self
                    cellWithPickerView.pickerView.dataSource = self

                    cellWithPickerView.pickerView = pickerView
                    universallCell = cellWithPickerView
                 else 
                    cell.title.text = "Picker 3"
                    cell.detail.text = "I"
                    universallCell = cell
                

            case 2:

                if showUnits2PickerView 
                    cell.title.text = "Picker 3"
                    cell.detail.text = "I"
                    universallCell = cell
                 else if showUnits3PickerView 

                    cellWithPickerView.pickerView.delegate = self
                    cellWithPickerView.pickerView.dataSource = self

                    cellWithPickerView.pickerView.reloadAllComponents()
                    cellWithPickerView.pickerView = pickerView

                    universallCell = cellWithPickerView
                



            default:
                break
            

            return universallCell

        default:
            let universallCell = UITableViewCell()
            return universallCell
        

        // Configure the cell...

        //return universallCell
    

    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) 


        struct RowName 

            var units = 0
            var units2 = 1
            var units3 = 2

        

        // Hide row
        func hideRow(rowName: Int) 

            switch rowName 
            case RowName().units:
                if showUnitsPickerView 
                    showUnitsPickerView = false
                    tableView.beginUpdates()
                    tableView.deleteRows(at: [
                        (NSIndexPath(row: 1, section: 0) as IndexPath)], with: .automatic)
                    tableView.endUpdates()
                

            case RowName().units2:

                if showUnits2PickerView 
                    showUnits2PickerView = false
                    tableView.beginUpdates()
                    tableView.deleteRows(at: [
                        (NSIndexPath(row: 1, section: 1) as IndexPath)], with: .automatic)
                    tableView.endUpdates()
                

            case RowName().units3:

                if showUnits3PickerView 
                    showUnits3PickerView = false
                    tableView.beginUpdates()
                    tableView.deleteRows(at: [
                        (NSIndexPath(row: 2, section: 1) as IndexPath)], with: .automatic)
                    tableView.endUpdates()
                

            default:
                break
            

        

        switch indexPath.section 
        case 0:

            hideRow(rowName: RowName().units2)
            hideRow(rowName: RowName().units3)

            showUnitsPickerView = showUnitsPickerView ? false : true

            if showUnitsPickerView 

                tableView.deselectRow(at: indexPath, animated: true)

                tableView.beginUpdates()
                tableView.insertRows(at: [
                    (NSIndexPath(row: 1, section: 0) as IndexPath)], with: .automatic)
                self.pickerView.reloadAllComponents()
                tableView.endUpdates()

             else 

                tableView.deselectRow(at: indexPath, animated: true)

                tableView.beginUpdates()
                tableView.deleteRows(at: [
                    (NSIndexPath(row: 1, section: 0) as IndexPath)], with: .automatic)
                tableView.endUpdates()

            

        case 1:

            if indexPath.row == 0 

                tableView.deselectRow(at: indexPath, animated: true)

                hideRow(rowName: RowName().units)
                hideRow(rowName: RowName().units3)

                showUnits2PickerView = showUnits2PickerView ? false : true

                if showUnits2PickerView 

                    tableView.beginUpdates()
                    tableView.insertRows(at: [
                       (NSIndexPath(row: 1, section: 1) as IndexPath)], with: .automatic)
                    tableView.endUpdates()

                 else 
                    tableView.beginUpdates()
                    tableView.deleteRows(at: [
                       (NSIndexPath(row: 1, section: 1) as IndexPath)], with: .automatic)
                    tableView.endUpdates()
               

             else 

               tableView.deselectRow(at: indexPath, animated: true)

               hideRow(rowName: RowName().units)
               hideRow(rowName: RowName().units2)

               showUnits3PickerView = showUnits3PickerView ? false : true

                if showUnits3PickerView 

                   tableView.beginUpdates()
                   tableView.insertRows(at: [
                       (NSIndexPath(row: 2, section: 1) as IndexPath)], with: .automatic)
                   tableView.endUpdates()

                else 

                   tableView.beginUpdates()
                   tableView.deleteRows(at: [
                       (NSIndexPath(row: 2, section: 1) as IndexPath)], with: .automatic)
                   tableView.endUpdates()

               

            

        default:
            break
           
    

【问题讨论】:

【参考方案1】:

所以当你点击行时,在你的选择方法中。重新加载行。并在您的 cellforRowAtIndexpath 中,设置一些条件,使单元格在重新加载后不会崩溃。

【讨论】:

以上是关于强制 UIPickerView 重新加载数据的主要内容,如果未能解决你的问题,请参考以下文章

UIPickerView 未使用最新的 JSON 数据重新加载

从另一个 ViewController 重新加载 UIPickerView 的数据

记一次 UIPickerView 无法滚动的问题。

UIPickerView 没有重新加载

如何根据按钮按下重新加载/刷新 UIPickerView(带有新数据数组)?

无法根据 UIPickerview 中第一个组件中的值重新加载第二个组件