【问题标题】:UIPickerView doesn't immediately redraw unselected rowsUIPickerView 不会立即重绘未选中的行
【发布时间】:2015-02-18 12:05:41
【问题描述】:

我有一个特殊的UIPickerView,通过点击它手动选择行。发生这种情况时,所选行的样式会发生变化(文本颜色会发生变化并显示带有复选标记的图像)。同样,如果选择了另一行,则先前选择的行将“取消选择”,即它的样式更改为正常。

现在,当我选择一行时,它看起来是正确的:

但是,当我滚动到另一行并且所选行不再位于中间时,不会应用新样式(此处应选择 Antarktis):

但是,如果我进一步向下滚动几行,然后将其备份,则会将该行更新为正确的样式:

我在取消选择时遇到了同样的问题。如果我选择另一行,旧行似乎没有被取消选择,我得到了这个(现在应该取消选择 Antarktis):

但是,如果我将 Antarktis 行向后滚动到中间,它确实会被取消选择。 所以我的问题是UIPickerView 不会立即重绘可见但不在中间的行(它们可能以某种方式被缓存)。它们仅在特定行消失然后返回或显示全新行时才会重绘。

那么我可以强制它重绘这些行吗?我尝试在 UIPickerView 和特定行(它们是 UITableViewCell 的子类)上调用 setNeedsDisplay 方法,但它什么也没做。

谢谢!

【问题讨论】:

    标签: ios cocoa-touch uiview uipickerview setneedsdisplay


    【解决方案1】:

    您是否尝试在您的 UIPickerView 实例上调用 reloadComponent:reloadAllComponents

    【讨论】:

    • 是的,没有任何区别。也许这是因为底层数据实际上并没有改变。
    • 你不更新你的模型?如何将行标记为选中?
    • 该模型仅用于填充行的文本。选择行时,其数据是USET填充UILabel。选择由行本身记住(即UITableViewCell 的子类)。 PS。我从以前的开发人员那里继承了这个项目,所以我无法回答为什么选择这个实现:)
    • 儿子...打电话给reloadAllComponents 确实工作。只是这个类在一个单独的框架中,所以它需要一个干净的:)
    • 但是,调用reloadAllComponents 有副作用。我选择的行丢失了它的位置,即选择器滚动到第一个元素。知道如何防止这种情况吗?
    【解决方案2】:

    我在这里发布我的答案,以解释我在使用 reloadAllComponents 时所做的解决方法,以解决 fpg1503 在他的回答中建议的副作用。

    基本上我记得选择,然后在reloadAllComponents 完成后以编程方式再次设置它:

        // We tell the picker to reload data in order to force it to redraw all rows.
        // Otherwise it may look like multiple rows are selected as checkmarks from previously selected row remains visible.
        // When reloading data the picker will automatically scroll to first row. That's why we will make it to go to the selected row afterwards.
        NSInteger selectedIndex = [self.countryCodePicker selectedRowInComponent:0];
        [self.countryCodePicker reloadAllComponents];
        // We have to make the selection with a delay, otherwise it may perform it before reloading was finished.
        double delayInSeconds = 1.0;
        dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
        dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
            [self.countryCodePicker selectRow:selectedIndex inComponent:0 animated:NO];
        });
    

    【讨论】:

      【解决方案3】:

      @NobleK 感谢您的快速回复!我尝试了您的解决方案,但发现选择器来回移动的视觉效果令人分心-但是...它给了我一个好主意:问题实际上不是导致跳转的 reloadAllComponents 调用-而是从通过的水龙头重新加载后将事情搞砸的gestureRecognizer。所以......我所做的就是将重新加载调用放入定时调度中,瞧!完美运行! :-D

      // delay the reload slightly
      double delayInSeconds = 0.1;
      dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
      dispatch_after(popTime, dispatch_get_main_queue(), ^(void)
      {
          [self.pickerView reloadAllComponents];
      });
      

      【讨论】:

        猜你喜欢
        • 2012-11-07
        • 1970-01-01
        • 2011-12-05
        • 2015-12-12
        • 1970-01-01
        • 2018-08-19
        • 1970-01-01
        • 1970-01-01
        • 2014-09-25
        相关资源
        最近更新 更多