UITableView не обновляется должным образом после изменения источника данных - PullRequest
14 голосов
/ 14 января 2010

У меня есть UITableView с несколькими источниками данных. Это потому, что мне нужно переключить данные с помощью UISegmentedControl, и если я добавлю их как подпредставления, я не смогу использовать statusBar для прокрутки вверх и т. Д.

Сначала я показываю экран входа в систему:

self.tableView.dataSource = loginTableView;
self.tableView.delegate = loginTableView;
[self.tableView reloadData];

Затем, как только пользователь вошел в систему, я делаю следующее, чтобы перейти к индексу: 1 из segmentedControler, который является их профилем:

self.tableView.dataSource = profileTableView;
self.tableView.delegate = profileTableView;
[self.tableView reloadData];

Тем не менее, представление таблицы обновляется, но представляет собой небольшую смесь двух источников данных. Часть текста изменилась, часть перекрывается, а часть полностью отсутствует.

Есть ли другой способ, которым я должен изменить источник данных для UITableView?

Thx

Ответы [ 6 ]

9 голосов
/ 12 октября 2012

У меня была точно такая же проблема. Моим решением было скрыть tableView, изменить его источник, перезагрузить данные и снова сделать видимым tableView.

Пример в C # (MonoTouch):

tableView.Hidden = true;
tableView.Source = newTableViewSource;
tableView.ReloadData();
tableView.Hidden = false;
4 голосов
/ 14 января 2010

Не уверен, почему это происходит из кода, который вы опубликовали.

Вместо изменения делегата и источника данных, замените все, что ivar представляет отображаемые данные:

- (NSArray*)tableData{

    if(showingLogin)
        return self.loginData;

    return self.profileData;
}

Теперь у вас есть только 1 экземпляр UITableViewController, но есть BOOL, чтобы указать, какой источник данных использовать.

2 голосов
/ 16 апреля 2010

Табличное представление внутренне кэширует ячейки, которые оно использует для отображения ваших данных. Поэтому, если вы меняете источник данных, вам также следует проверить, что ваш метод - - (UITableViewCell *) tableView: (UITableView *) tableView cellForRowAtIndexPath: (NSIndexPath *) метод indexPath обновляет все ячейки до правильных новых значений.

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

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil)
    {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
        cell.frame = CGRectZero;
        cell.textLabel.font = //Set font;
        cell.selectionStyle = UITableViewCellSelectionStyleNone;
        cell.textLabel.text = @"My Text for this cell"; // <==== Not good! Move it out of this if block
    }
    // Set cell text here
}

Самое простое решение, которое я нашел для такого рода проблем, это просто сделать строку, которую вы используете для создания ячейки (CellIdentifier), в зависимости от источника данных. В этом случае вы не смешиваете ячейки разных типов контента (и это также помогает вам, если ячейки должны выглядеть по-разному в зависимости от режима).

1 голос
/ 05 октября 2014

У меня была эта проблема, оказалось, потому что мои CellIdentifiers были одинаковыми ...

static NSString *CellIdentifier = @"Cell";

Измените одну из них и расположение ячеек правильно

static NSString *CellIdentifier2 = @"Cell2";
0 голосов
/ 04 августа 2014

У меня та же проблема, и вам нужно использовать другой идентификатор ячейки в пределах - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath.

if (self.segmentedControl.selectedSegmentIndex == 0) {
    self.cellIdentifier = @"segmentOne";
} else {
    caseAtIndexPath = [self.awaitingReviewCaseList caseAtIndex:indexPath.row];
    self.cellIdentifier = @"segmentTwo";
}
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:self.cellIdentifier forIndexPath:indexPath];
0 голосов
/ 14 января 2010

Ух ты, это странно.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...