1

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

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

在此处输入图像描述

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

在此处输入图像描述

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

在此处输入图像描述

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

在此处输入图像描述

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

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

谢谢!

4

3 回答 3

0

您是否尝试过致电reloadComponent:reloadAllComponents在您的UIPickerView实例上?

于 2015-02-18T12:12:36.500 回答
0

我在这里发布我的答案,以解释我在按照reloadAllComponentsfpg1503 在他的回答中建议使用时作为副作用的解决方法做了什么。

基本上我记得选择,然后在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];
    });
于 2015-08-26T14:14:34.920 回答
0

@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];
});
于 2015-08-26T17:10:33.110 回答