2009-08-18 2 views
2

Я создаю приложение для iPhone, для которого часть интерфейса в точности похожа на раздел «Самый популярный» в приложении iPhone для iPhone.UITableView не будет обновляться должным образом (даже с вызовом reloadData)

Этот раздел «популярный» доступен из бара Tab в нижней части и панель навигации в верхней части содержит UISegmentedControl, чтобы выбрать «Сегодня, на этой неделе, месяц и т.д ..»

Поскольку большинство приложение состоит из UITableViews с ячейками, содержащими очень сходное структурированное содержимое, я создал общий MyAppTableViewController, который наследует UITableViewController. Мой ' популярный' раздел, таким образом, состоит из PopularTableViewController, который наследует MyAppTableViewController. Фактический UITableView находится в пределах MyAppTableViewController.

PopularTableViewController имеет метод:

- (void) segmentChangeTimeframe:(id)sender { 
    UISegmentedControl *segCtl = sender; 
    if([segCtl selectedSegmentIndex] == 0) 
    { 
     // Call [self parse-xml-method-which-resides-in-MyAppTableViewController] 
    } 
    //... ... ... 
} 

MyAppTableViewController делает использование NSXMLParser и, следовательно, имеет код:

- (void)parserDidEndDocument:(NSXMLParser *)parser { 
    [self.myTableView reloadData]; 
} 

(Существуют и другие методы, которые обновляет структура данных, из которой представление таблицы получает свои данные)

Я поместил код вывода консоли в методы разбора xml, и при запуске, выбрав разные сегменты, нужно правильно разобрать правильные XML-файлы, и структура данных, похоже, содержит правильные значения.

Проблема в том, что содержимое ячеек таблицы не изменится! ГРР! УБЕДИТЕСЬ! ... Ячейка прокручивается вне поля зрения, а затем возвращается в поле зрения ... ТОГДА изменилось!

Я много раз искал эту проблему, и одно предложение по аналогичной проблеме заключалось в том, чтобы поместить [self.myTableView reloadData] в свой собственный метод, например. myReloadDataMethod, а затем использовать:

[self performSelectorOnMainThread:@selector(myReloadDataMethod) withObject:nil waitUntilDone:NO]; 

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

Update:

Код для заполнения ячеек осуществляется с помощью:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 
    static NSString *MyIdentifier = @"MyIdentifier"; 
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier]; 
    if (cell == nil) { 
     cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:MyIdentifier] autorelease]; 
    } 

    // Set up the cell 
    int itemIndex = [indexPath indexAtPosition: [indexPath length] - 1]; 
    NSString *artistName = [[myItemList objectAtIndex: itemIndex] objectForKey: @"itemA"]; 
    NSString *mixName = [[myItemList objectAtIndex: itemIndex] objectForKey: @"itemB"]; 
    cell.textLabel.text = itemA; 
    cell.detailTextLabel.text = itemB; 
    cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton; 

    return cell; 
} 

Приведенный выше код в MyAppTableViewController который также где myItemList проживает.

+0

вывесить гр оду вы используете для заполнения ваши клетки – Daniel

+0

@Daniel - Я обновил этот вопрос с просьбой. – IAmFledge

+2

Не связано с вашей проблемой, но вы можете получить itemIndex гораздо проще: NSUInteger itemIndex = [indexPath row]. –

ответ

5

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

Если вы меняете значение конкретной ячейки, то, как вы достигаете, это изменение самой ячейки. На iPhone ячейки имеют полный вид (в отличие от Mac), поэтому, если вы хотите изменить свои данные, вы просто изменяете свои данные и вызываете -setNeedsDisplay. Вы можете получить ячейку (просмотреть) для данного местоположения, используя -cellForRowAtIndexPath:. Вы можете определить, находится ли данная ячейка на экране, используя -indexPathsForVisibleRows или -visibleCells.

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

+0

Hi Rob. Спасибо за Ваш ответ. Каждый выбранный сегментный индекс приводит к анализу другого XML-файла (для «Сегодня»/«Неделя»/«Месяц»), и это только содержимое выбранного xml, которое я хочу отображать, а не добавляемое к существующим ячейкам. Должен ли я использовать reloadData в этом случае? – IAmFledge

+1

Это должно быть -reloadData. Вы анализируете основной поток или изменяете данные модели в фоновом режиме? –

+0

Поскольку я довольно новичок в программировании на iPhone/ObjC, я не совсем уверен, как iPhone OS обрабатывает потоки. (например, я не знаю, связаны ли соединения, которые вы создаете в построителе интерфейса, заставлять новые потоки запускаться за кулисами). Но я явно не объявлял новый поток. У меня просто есть приложение AppDelegate, которое содержит мой UITabBarController * tabBarController (для которого у меня нет кода, он просто подключен в IB.) И мои классы контроллера, как описано в вопросе. В I.B. мой TabBarController имеет право собственности на некоторые навигационные контроллеры, каждый из которых имеет право собственности на ... – IAmFledge

0

Вы попробовали [tableView setNeedsDisplay:YES]?

1

У меня была такая же проблема, и это было потому, что у меня был вызов [tableView beginUpdates] без вызова endUpdates после.

-1

После вызова -reloadData вы получаете обратный вызов в tableView: numberOfRowsInSection:? Я почти уверен, что self.myTableView равна нулю здесь:

- (void)parserDidEndDocument:(NSXMLParser *)parser { 
[self.myTableView reloadData]; 

}

Смежные вопросы