Как перекрасить NSTableView сразу после reloadData - PullRequest
0 голосов
/ 21 февраля 2012

Я добавил NSTableView и правильно установил делегат и источник данных.

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
    _items = [[NSMutableArray alloc] init];
    [_items addObject:@"ready"];
    [self.mainTableView reloadData];
}

- (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView {
    return [self.items count];
}

- (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row {
    NSTableCellView *result = [tableView makeViewWithIdentifier:tableColumn.identifier owner:self];
    result.textField.stringValue = [self.items objectAtIndex:row];
    return result;
}

Также имеется NSButton, связанный со следующим кодом:

- (IBAction)buttonPressed:(id)sender {
    for (int i = 1; i <= 10; i++) {
        NSString *item = [NSString stringWithFormat:@"%d", i];
        [_items replaceObjectAtIndex:0 withObject:item];
        [self.mainTableView reloadData];
        [NSThread sleepForTimeInterval:0.2f];
    }
}

Программа работала правильно ив представлении таблицы отображается «готово», но когда я нажал кнопку, содержимое представления таблицы изменилось не сразу.Он изменился через 2 секунды и просто показывает последнее число - 10.

Что мне нужно, так это изменить содержимое NSTableViw с 1 ​​на 10, но напрямую не получить окончательное число.Как я могу заставить его перекрасить сразу после reloadData?

Ответы [ 2 ]

3 голосов
/ 21 февраля 2012
[NSThread sleepForTimeInterval:0.2f];

Ты спишь в теме и удивляешься, почему вещи кажутся отсроченными?

[_items replaceObjectAtIndex:0 withObject:item];

Вы заменяете каждый элемент в массиве и задаетесь вопросом, почему отображается только последний элемент?!

Вы вообще не должны спать в главной теме. Удалить эту строку; отправка reloadData заставит представление таблицы снова отобразиться как можно скорее.

Чтобы заполнить массив, сделайте следующее:

for (int i = 1; i <= 10; i++) {
    NSString *item = [NSString stringWithFormat:@"%d", i];
    [_items addObject:item];
}
[self.mainTableView reloadData];

Обратите внимание, что я переместил reloadData за пределы цикла. Вы не должны отправлять это, пока не закончите обновление данных и не будете готовы к перерисовке представления таблицы.

2 голосов
/ 22 февраля 2012

Как сделать так, чтобы он перекрашивался сразу после reloadData?

Вернувшись после reloadData.Другого пути нет.Вы не можете заставить таблицу перерисовываться, пока ваш код еще работает.Даже если вы используете другой поток, он не будет работать так, как вы предполагаете.

Если вы хотите изменить таблицу с течением времени, вы можете использовать NSTimer для периодического изменения данных, а затемзвоните reloadData (или еще лучше reloadRowsAtIndexPaths:withRowAnimation:) после каждого изменения.

Пользовательский интерфейс никогда не будет рисоваться в середине вашего кода.Вы должны вернуться, чтобы позволить ему обновляться.


Пользовательский интерфейс не может обновляться, пока ваш код выполняется в главном потоке.Существует несколько подходов к предоставлению обновлений пользовательского интерфейса во время обработки:

  • Выполните некоторую работу, запланируйте дополнительную работу с таймером или performSelector:withObject:afterDelay:, вернитесь, чтобы пользовательский интерфейс мог обновляться.Это то, что я описал выше.
  • Разбейте свою работу на небольшие блоки и запланируйте их, используя очередь NSOperationQueue или GCD.Если вы запускаете их в основной очереди, это фактически совпадает с первым вариантом;вы просто позволяете ОС выполнять планирование.
  • Запустите обработку в фоновом потоке и обновите данные асинхронно.Периодически обновляйте пользовательский интерфейс с помощью таймера.Это хорошо для простых индикаторов прогресса, но трудно синхронизировать, если вы хотите, чтобы обновления пользовательского интерфейса были в определенных точках.Это вводит все головные боли многопоточного кода, такие как блокировка и atomicy.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...