UIPickerView不会立即重绘未选择的行

时间:2015-02-18 12:05:41

标签: ios cocoa-touch uiview uipickerview setneedsdisplay

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

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

enter image description here

但是,当我滚动到另一行并且所选行不再在中间时,它的新样式不会应用(应该在这里选择Antarktis):

enter image description here

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

enter image description here

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

enter image description here

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

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

谢谢!

3 个答案:

答案 0 :(得分:0)

您是否尝试在reloadComponent:个实例上拨打reloadAllComponentsUIPickerView

答案 1 :(得分:0)

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

基本上我记得选择,然后在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];
    });

答案 2 :(得分:0)

@NobleK感谢您的快速回复!我尝试了你的解决方案,但发现拾取器的视觉来回移动分散注意力 - 但是......它给了我一个好主意:问题实际上并不是调用reloadAllComponents导致跳跃 - 它是那个水龙头从重新加载后发生故障的gestureRecognizer传来。所以......我所做的就是把重载调用放到定时调度中,瞧!完美的工作! :-D

static int
command_execute(char* command) {
        char **arguments = g_strsplit(command, " ", 32);
        pid_t child_pid;

        if( !arguments ) {
            status = COMMAND_PARSE_ERROR;
            goto EXIT;
        }

        if( (child_pid = fork() ) == -1 ) {
            status = CHILD_FORK_ERROR;
            goto EXIT;
        }

        if( child_pid == 0 ) {
            execvp(arguments[0], arguments);
        } else {
            waitpid(child_pid, &status, 0);
            if(status) {
                goto EXIT;
            }
        }
}