UIActivityIndicatorView никогда не оживляет
У меня есть PhotoViewController
класс с @property UIActivityIndicatorView* spinner
, FlickrPhotoViewController
это подкласс PhotoViewController
он загружает фотографию с Flickr и сообщает центрифуге, когда начинать и останавливать анимацию. 'updatePhoto' вызывается каждый раз, когда контроллеру представления предоставляется фотография Flickr:
- (void)updatePhoto { // Download photo and set it
NSLog("updatePhoto called");
if (self.spinner) NSLog(@"Spinner exists in updatePhoto");
dispatch_queue_t downloadQueue = dispatch_queue_create("downloader",
NULL);
[self.spinner startAnimating];
dispatch_async(downloadQueue, ^{
// Download the photo
dispatch_async(dispatch_get_main_queue(), ^{
[self.spinner stopAnimating];
// Set the photo in the UI
}
});
});
}
Вышеприведенная методология - именно то, что я использую для отображения вращающегося колеса в контроллерах табличного представления при загрузке содержимого таблицы, и оно всегда работает там.
Вы заметите в начале updatePhoto
Я печатаю сообщение, если UIActivityIndicatorView
существует. Я помещаю подобное утверждение в awakeFromNib
, viewDidLoad
, а также viewWillAppear
, Когда я запускаю его, я получаю именно такой вывод:
2013-01-31 21:30:55.211 FlickrExplorer[1878:c07] updatePhoto called
2013-01-31 21:30:55.222 FlickrExplorer[1878:c07] Spinner exists in viewDidLoad
2013-01-31 21:30:55.223 FlickrExplorer[1878:c07] Spinner exists in viewWillAppear
Почему spinner
не существует в awakeFromNib
? Документы указывают, что "Когда объект получает сообщение awakeFromNib, он гарантирует, что все его подключения к выходу и действию уже установлены". Можно ли подключить IBOutlet без существования объекта, к которому он подключается? В этом случае может spinner
IBOutlet быть подключен к раскадровке без spinner
выделяется?
Выйдя за пределы этого, я отверг геттер для spinner
так что он будет создан, если он не существует. В результате вывод на печать теперь выглядит так:
2013-01-31 21:48:45.646 FlickrExplorer[2222:c07] Spinner exists in awakeFromNib
2013-01-31 21:48:45.647 FlickrExplorer[2222:c07] updatePhoto called
2013-01-31 21:48:45.647 FlickrExplorer[2222:c07] Spinner exists in updatePhoto
2013-01-31 21:48:45.649 FlickrExplorer[2222:c07] Spinner exists in viewDidLoad
2013-01-31 21:48:45.650 FlickrExplorer[2222:c07] Spinner exists in viewWillAppear
Это то, что я ожидал увидеть раньше. Тем не менее, я до сих пор не получаю никакой анимации.
Возможные проблемы, которые я исключил:
- Спиннер того же цвета, что и фон, что делает его невидимым. В моем проекте фон черный, а блесна белая.
- Я пытаюсь оживить
UIActivityIndicatorView
в то время как какой-то дорогой метод блокирует основной поток. В моем проекте все методы ввода-вывода и загрузки файловой системы вызываются неосновноdispatch_async
очередь. - IBOutlet прядильщика не подключен. В моем проекте я дважды проверял это много раз. Это видно из раскадровки и файла PhotoViewController.h, к которому он подключен.
Все три из этих возможностей исключены тем фактом, что [self.spinner startAnimating];
в viewWillAppear
делает его успешно анимированным на протяжении всего процесса загрузки.
Вы можете скачать этот проект, если хотите. Просто перейдите на любой экран, который пытается отобразить большое фото, и вы увидите, что счетчик не появляется. У этого проекта много проблем, но сейчас я остановлюсь именно на этом.
Изменить 1:
- Я добавил недостающие зависимости проекта от Git, так что теперь проект будет скомпилирован для вас
Изменить 2 (2 февраля 2013 года):
- Я вижу эту проблему только на iPhone, когда
updatePhoto
метод вызывается из-за другого контроллера представленияprepareForSegue
установка фото вFlickrPhotoViewController
, Возможно ли, что это усугубляет проблему?
1 ответ
Попробуйте запустить анимацию uiactivityindictor, прежде чем вызывать метод updatePoto, такой как Tru, вызывающий эту функцию вместо вызова UpdatePhoto только для всех:
[self startAnimatingAndThenUpdatePhoto];
-(void)startAnimatingAndThenUpdatePhoto{
if (self.spinner) NSLog(@"Spinner exists in updatePhoto");
[self.spinner startAnimating];
[self performSelector:@selector(updatePhoto) withObject:nil afterDelay:0.01];
}
- (void)updatePhoto { // Download photo and set it
NSLog("updatePhoto called");
dispatch_queue_t downloadQueue = dispatch_queue_create("downloader",
NULL);
dispatch_async(downloadQueue, ^{
// Download the photo
dispatch_async(dispatch_get_main_queue(), ^{
[self.spinner stopAnimating];
// Set the photo in the UI
}
});
});
}
Не лучший метод в мире, но он поможет