UITableView не обновляется должным образом после изменения dataSource
У меня есть UITableView с несколькими источниками данных. Это связано с тем, что мне нужно переключать данные с помощью UISegmentedControl, и если я добавлю их в качестве подзонов, я не могу использовать statusBar для прокрутки вверх и т.д.
Сначала я показываю экран входа:
self.tableView.dataSource = loginTableView;
self.tableView.delegate = loginTableView;
[self.tableView reloadData];
Затем, как только пользователь вошел в систему, я делаю следующее, чтобы изменить на индекс: 1 сегмента segmentControler, который является их профилем:
self.tableView.dataSource = profileTableView;
self.tableView.delegate = profileTableView;
[self.tableView reloadData];
Тем не менее, представление таблицы обновляется, но представляет собой немного смешение между двумя источниками данных. Часть текста изменилась, некоторые перекрываются, а некоторые из них полностью отсутствуют.
Есть ли другой способ изменить источник данных для UITableView?
спасибо
Ответы
Ответ 1
Не уверен, почему это происходит из кода, который вы опубликовали.
Вместо того, чтобы изменять делегат и источник данных, замените все, что представляет ivar, на отображаемые данные:
- (NSArray*)tableData{
if(showingLogin)
return self.loginData;
return self.profileData;
}
Теперь у вас есть только 1 экземпляр UITableViewController, но BOOL сообщит вам, какой источник данных использовать.
Ответ 2
У меня была такая же проблема. Мое решение состояло в том, чтобы сделать tableView скрытым, изменить его источник, перезагрузить данные и снова отобразить таблицу.
Пример в С# (MonoTouch):
tableView.Hidden = true;
tableView.Source = newTableViewSource;
tableView.ReloadData();
tableView.Hidden = false;
Ответ 3
В представлении таблицы происходит кэширование ячеек, которые он использует для отображения ваших данных. Поэтому, если вы меняете источник данных, вы также должны проверить, что ваш - (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
}
Простейшим решением, которое я нашел для этой проблемы, является просто создание String, который вы используете для создания ячейки (CellIdentifier) в зависимости от источника данных. В этом случае вы не смешиваете ячейку разных типов контента (и это также помогает вам, если ячейки должны иметь другой вид в зависимости от режима).
Ответ 4
У меня была эта проблема, оказалось, что это потому, что мои CellIdentifiers были одинаковыми...
static NSString *CellIdentifier = @"Cell";
Измените один из них и расположение ячеек правильно
static NSString *CellIdentifier2 = @"Cell2";
Ответ 5
Ничего себе, этот причудливый.
В прошлый раз, когда я делал что-то вроде этого, я просто использовал несколько просмотров, скрывал один и показывал другой, когда был обработан сегментированный элемент управления. Существуют и другие возможные решения, но это, вероятно, самый простой и, возможно, самый эффективный.
Ответ 6
У меня такая же проблема, и вам нужно использовать другой идентификатор ячейки внутри - (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];