#iphone #objective-c
#iPhone #objective-c
Вопрос:
У меня есть небольшое приложение с некоторым контроллером деталей. Контроллер Detail — это веб-просмотр, помещенный в режим прокрутки: вот код контроллера detail view:
- (void)loadScrollViewWithPage:(int)page
{
if (page < 0)
return;
if (page >= detailTotalJobs)
return;
// replace the placeholder if necessary
SearchJobDetailWebViewController *controller = [viewControllers objectAtIndex:page];
if ((NSNull *)controller == [NSNull null])
{
NSLog(@"Vytvaram web controller: %d", page 1);
if (detailJobIndex == page) {
controller = [[SearchJobDetailWebViewController alloc] initWithNibName:@"SearchJobDetailWebViewController" bundle:nil page:page url:detailExportUrl];
[viewControllers replaceObjectAtIndex:page withObject:controller];
[controller release];
} else if (detailJobIndex 1 == page) {
controller = [[SearchJobDetailWebViewController alloc] initWithNibName:@"SearchJobDetailWebViewController" bundle:nil page:page url:detailNextExportUrl];
[viewControllers replaceObjectAtIndex:page withObject:controller];
[controller release];
} else {
[self performSelector:@selector(downloadData:) withObject:[NSNumber numberWithInt:page] afterDelay:0.1];
//[self downloadData:[NSNumber numberWithInt:page]];
controller = [[SearchJobDetailWebViewController alloc] initWithNibName:@"SearchJobDetailWebViewController" bundle:nil page:page url:nextArray.exportUrl];
[viewControllers replaceObjectAtIndex:page withObject:controller];
[controller release];
}
}
// add the controller's view to the scroll view
if (controller.view.superview == nil)
{
CGRect frame = scrollView.frame;
frame.origin.x = frame.size.width * page;
frame.origin.y = 0;
controller.view.frame = frame;
[scrollView addSubview:controller.view];
//NSDictionary *numberItem = [self.contentList objectAtIndex:page];
//controller.numberImage.image = [UIImage imageNamed:[numberItem valueForKey:ImageKey]];
//controller.myLabel.text = @"Test";
}
}
- (void)scrollViewDidScroll:(UIScrollView *)sender
{
// Нам не нужен «цикл обратной связи» между UIPageControl и делегатом прокрутки в
//, из которого событие прокрутки, генерируемое пользователем, нажимающим на элемент управления страницей, запускает обновления
// метод делегирования. Мы используем логическое значение для отключения логики делегирования при использовании элемента управления страницей.
если (pageControlUsed)
{
// ничего не делать — прокрутка была инициирована с элемента управления страницей, а не
с возвратом перетаскивания пользователем;
}
// Switch the indicator when more than 50% of the previous/next page is visible
CGFloat pageWidth = scrollView.frame.size.width;
int page = floor((scrollView.contentOffset.x - pageWidth / 2) / pageWidth) 1;
pageControl.currentPage = page;
NSString *detailTitleText = [NSString stringWithFormat:@"%d / %d", page 1, detailTotalJobs];
[self setTitle:detailTitleText];
//[detailTitleText release];
// load the visible page and the page on either side of it (to avoid flashes when the user starts scrolling)
[self loadScrollViewWithPage:page - 1];
[self loadScrollViewWithPage:page];
[self loadScrollViewWithPage:page 1];
// A possible optimization would be to unload the views controllers which are no longer visible
}
Код, вдохновленный Apple page control.
Проблема здесь:
if (detailJobIndex == page) {
controller = [[SearchJobDetailWebViewController alloc] initWithNibName:@"SearchJobDetailWebViewController" bundle:nil page:page url:detailExportUrl];
[viewControllers replaceObjectAtIndex:page withObject:controller];
[controller release];
} else if (detailJobIndex 1 == page) {
controller = [[SearchJobDetailWebViewController alloc] initWithNibName:@"SearchJobDetailWebViewController" bundle:nil page:page url:detailNextExportUrl];
[viewControllers replaceObjectAtIndex:page withObject:controller];
[controller release];
} else {
[self performSelector:@selector(downloadData:) withObject:[NSNumber numberWithInt:page] afterDelay:0.1];
//[self downloadData:[NSNumber numberWithInt:page]];
controller = [[SearchJobDetailWebViewController alloc] initWithNibName:@"SearchJobDetailWebViewController" bundle:nil page:page url:nextArray.exportUrl];
[viewControllers replaceObjectAtIndex:page withObject:controller];
[controller release];
}
Первая часть и вторая часть if работают правильно, потому что у меня есть данные для первого веб-просмотра и для второго веб-просмотра.
Но последняя часть, если есть проблема. когда я прокручиваю со второго веб-просмотра на третий веб-просмотр, в режиме прокрутки отображается пустая страница. Следующие страницы работают правильно. В чем проблема, пожалуйста?
Ответ №1:
Просто поставьте точку останова в режиме отладки в фигурных скобках.
Является ли контроллер нулевым? Проверьте свой пользовательский метод инициализации.
Возвращает ли он nil, если есть проблема?
[self = super initWithNibName..................];
if (!self) return nil;
// some inits
return self;
Если это сделано, а контроллер равен нулю, проверьте свой URL-адрес и попробуйте использовать его в веб-браузере. Отображается ли он?
Как вы заполняете свой WebView? Возвращается ли ошибка при ее заполнении? Проблема с кодировкой не возвращена?
Что ж, некоторый код мог бы помочь, но эти указания являются наиболее распространенными проблемами, которые у вас могут возникнуть.
Комментарии:
1. Сначала я вызываю этот метод: [self performSelector:@selector (downloadData:) withObject:[NSNumber numberWithInt:страница] afterDelay:0.1]; для загрузки данных затем я создаю контроллер веб-просмотра. Проблема в том, что когда я регистрирую эти два метода, которые: сначала регистрировался процесс создания контроллера веб-представления, а затем вызывался метод загрузки данных (контроллер получает URL как null), но почему…
2. Мне нужно загрузить следующие данные в фоновом режиме… Когда пользователь запускает приложение, загружаются первые две веб-страницы (это работает нормально …) при прокрутке с первой на вторую приложение должно загрузить следующую страницу в фоновом режиме (вот проблема), потому что третья страница пуста, а данные третьей страницы находятся на странице суда… следующие страницы работают нормально…
3. Почему вы задерживаете вызов. Это может быть причиной вашей проблемы. Почему бы вам просто не вызвать метод? Контроллер создается до загрузки ваших данных. 0,1 с, это огромное вычислительное время. DownloadData называется асинхронным, поэтому ваш контроллер создается до вызова загрузки
4. потому что, когда я вызываю только метод, этот метод блокирует guy во время загрузки данных…
5. Вы просто блокируете его на 0,1 секунды позже…. Затем вы должны преобразовать свой вызов как асинхронный (веб-вызов?) Или отправить его в другой поток, И сделать ваш WebView способным загружать данные после его создания. Проверяйте каждые 0,1 с, если контейнер данных равен нулю, и, если нет, заполняйте WebView. Не забудьте установить некоторый тайм-аут на случай, если данные не могут быть загружены.