UIPickerView 即使在重新查询后也不显示数据

Posted

技术标签:

【中文标题】UIPickerView 即使在重新查询后也不显示数据【英文标题】:UIPickerView not displaying data even after requery 【发布时间】:2015-12-29 12:14:25 【问题描述】:

假设我有一群狗private var dogs: Observable<[Dogs]>。每次产生一个新值时,都会调用我的块,在那里我为我的UIPickerView 创建一个新的数据源和委托,然后在我调用pickerView.reloadAllComponents() 的块内,但我的视图显示为一个空的pickerView,即使数据源和委托是查询。

示例代码:

self.dataStream
        .subscribeNext 
            self.dataSource = PickerViewDataSource(data: $0)
            self.pickerView.dataSource = self.dataSource
            self.delegate = PickerViewDelegate(data: $0, selectedRow: self._selectedRowStream)
            self.pickerView.delegate = self.delegate
            self.pickerView.reloadAllComponents()
        .addDisposableTo(self.disposeBag)

调试 dataSource 和 delegate 我知道这些是被查询的,我在 UIViewController 中保留 dataSource 和 delegate 引用的原因是因为 UIPickerView 持有这些的弱引用。

这是我尝试过的最后一种策略,但仍然得到相同的结果。任何帮助,将不胜感激。谢谢。

更新:

DogPickerViewDataSource:

class DogPickerViewDataSource: NSObject, UIPickerViewDataSource 

    private var dogs: [Dog]

    init(
        dogs: [Dog]
    ) 
        self.dogs = dogs
    

    func numberOfComponentsInPickerView(pickerView: UIPickerView) -> Int 
        return 1
    

    func pickerView(pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int 
        return dogs.count
    

DogPickerViewDelegate:

class DogPickerViewDelegate: NSObject, UIPickerViewDelegate 

    private var selectedRow: BehaviorSubject<Int>
    private var dogs: [Dog]

    init(
        dogs: [Dog],
        selectedRow: BehaviorSubject<Int>
    ) 
        self.dogs = dogs
        self.selectedRow = selectedRow
    

    func pickerView(pickerView: UIPickerView, attributedTitleForRow row: Int, forComponent component: Int) -> NSAttributedString? 
        let dogName = (self.dogs[row].name)!
        return NSAttributedString(string: dogName)
    

    func pickerView(pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) 
        self.selectedRow.onNext(row)
    

【问题讨论】:

能否也请您提供PickerViewDataSource的UIPickerViewDataSource协议实现? 在 reloadAllComponents 函数后是否调用了 UIPickerViewDataSource 或 UIPickerViewDelegate 的任何方法? 是的,我已经调试了它们,是的,它们在 reloadAllComponents() 方法之后被调用。这就是为什么我感到困惑。 您确定显示的选择器视图与调用数据源和委托方法的选择器视图相同吗? 好的,你正在做一些事情,pickerView 只有在通过另一个屏幕调用屏幕(展开)时才会失败。它不是同一个 UIPickerView。但这在我看来应该不是问题。无论如何都会再次调用 viewDidLoad() 方法,因此它应该在展开操作之后重新创建 dataSource 和委托并将新实例关联到 pickerView 的新实例 【参考方案1】:

如果我理解正确,在 viewDidLoad 上,您正在使用新的委托和数据源初始化您的 pickerView,调用 reloadAllComponents 并期望所有内容都应该正确显示。但是您仍然从以前的视图控制器显示pickerView。您应该尝试在前一个视图控制器的 viewWillDisappear 方法中隐藏选择器视图,并在新视图控制器的 viewDidAppear 方法中显示新的。

【讨论】:

抱歉回复晚了……假期。看来我调用的 PickerView 与 unwind segue 再次调用 viewDidLoad() 方法并具有新的引用(所以我猜测 pickerView 的新实例)相同,并且新的引用被传递给 dataSource 的新实例。不幸的是,希望就是这样。 我已经把这个展示给了许多假期回来的同事。没有一个可以解决这个问题,所以我放弃了它并尝试了一种不同的方法。似乎展开转场是一个自定义转场类,它在展开后再次调用 viewDidLoad() 方法这一奇怪的事情。问题在于导航和视图以编程方式堆叠的方式。感谢您的所有帮助!

以上是关于UIPickerView 即使在重新查询后也不显示数据的主要内容,如果未能解决你的问题,请参考以下文章

即使在 React 中正确导入后也不包含默认导出

Excel 2007 VSTO 加载项即使在成功安装后也不可见

即使 PreparedStatement 仅使用一次,ResultSet 关闭错误后也不允许操作

即使重新安装节点后也不会删除打字稿

Linq to SQL即使通过工具和功能安装模块后也不会显示

UIView 即使在开始从超级视图中删除后也会重新出现