UIPickerView не сразу перерисовывает невыбранные строки

У меня есть особый UIPickerView где строки выбираются вручную, нажав на нее. Когда это происходит, стиль выбранной строки изменяется (цвет текста меняется, и отображается изображение с галочкой). Аналогичным образом, если выбрана другая строка, ранее выбранная строка "отменяется", т. Е. Ее стиль меняется на обычный.

Теперь, когда я выбираю строку, она выглядит правильно:

Но когда я прокручиваю к другой строке, и выбранная строка больше не находится в середине, ее новый стиль не применяется (Антарктис должен быть выбран здесь):

Тем не менее, если я прокручиваю вниз на несколько строк дальше, а затем назад, он обновляет строку до правильного стиля:

У меня та же проблема при отмене выбора. Если я выберу другую строку, старая строка, по-видимому, не будет отменена, и я получу следующее (сейчас нужно отменить выбор Антарктиса):

Но если я прокручиваю строку Антарктиды обратно посередине, она действительно отменяется. Так что моя проблема в том, что UIPickerView не сразу перерисовывает строки, которые видны, но не в середине (они, вероятно, как-то кешируются). Они перерисовываются только тогда, когда конкретная строка выходит из поля зрения, а затем возвращается или когда отображаются совершенно новые строки.

Так я могу заставить его перерисовать эти строки? Я пытался позвонить setNeedsDisplay метод как на UIPickerView и конкретные строки (которые являются подклассами UITableViewCell) но это ничего не сделало.

Спасибо!

3 ответа

Решение

Вы пробовали звонить reloadComponent: или же reloadAllComponents на ваше UIPickerView пример?

Я публикую свой ответ здесь, чтобы объяснить, что я сделал в качестве обходного пути для побочного эффекта при использовании 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];
    });

@NobleK Спасибо за быстрый ответ! Я попробовал ваше решение, но обнаружил, что визуальный элемент выбора движется взад и вперед, отвлекаясь - ОДНАКО... Это дало мне отличную идею: проблема не в вызове reloadAllComponents, который вызывает переход, а в том, что сигнал передается из gestRecognizer, который волнует вещи после перезагрузки. Итак... что я сделал, так это перевел вызов в синхронизированную рассылку и вуаля! Работает отлично!:-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];
});
Другие вопросы по тегам