У меня есть следующий код:Проблем по обновлению пользовательского интерфейса от асинхронного обратного вызова
@property (weak, nonatomic) IBOutlet UIView *loadingView;
-(void) hideLoadingScreen{
self.loadingViewRect = self.loadingView.frame;
[self.loadingView setHidden:YES];
[self.loadingView setFrame:CGRectMake(0,0,0,0)];
}
- (void)viewDidAppear:(BOOL)animated{
[self.apiClient checkLoggedInWithCallback:^(int status){
if(status == ONLINE_LOGGED_IN){
[self.dbAPI isPullSynchronized:^(BOOL isPullSynced){
if(isPullSynced){
self.data = [self.dbAPI getTodayVisits];
[[self tableView] reloadData];
[self hideLoadingScreen];
} else {
[self.apiClient getTodayVisits:^(NSArray* visits){
[self.dbAPI insertTodayVisits:visits withCallback:^(int status){
self.data = [self.dbAPI getTodayVisits];
[[self tableView] reloadData];
}];
}];
}
}];
} else if(status == ONLINE_NOT_LOGGED_IN || status == ONLINE_INVALID_TOKEN || status == OFFLINE_NOT_LOGGED_IN) {
//Redirect to login
} else {
//Get from Local DB
self.data = [self.dbAPI getTodayVisits];
[[self tableView] reloadData];
}
}];
}
Метод hideLoadingScreen не будет выполнять (я имею в виду она будет выполнена, но интерфейс не обновляется).
Я пробовал все, чтобы заставить его работать (в том числе отправить [self hideLoadingScreen] в основной поток через GCD и выполнитьSelectorOnMainThread/сделать переменную BOOL __block isLoading и спать в основном потоке до тех пор, пока эта переменная не была изменена и т. Д.). Я также вызвал метод hideLoadingView метода viewDidAppear, и он работает, но я хочу, чтобы он скрывался при выполнении обратного вызова. К сожалению, я не смог найти решение, выполнив поиск в stackoverflow, ни в google (я должен сказать, что я пробовал все найденные решения).
L.E. Я вошел self.loadingView, как Rob Napier предложил
Новый код:
-(void) hideLoadingScreen{
self.loadingViewRect = self.loadingView.frame;
NSLog(@"hideLoadingScreen before: %@",self.loadingView);
[self.loadingView setHidden:YES];
[self.loadingView setFrame:CGRectMake(0,0,0,0)];
NSLog(@"hideLoadingScreen after: %@",self.loadingView);
}
- (void)viewDidAppear:(BOOL)animated{
NSLog(@"%@",self.loadingView);
[self.apiClient checkLoggedInWithCallback:^(int status){
if(status == ONLINE_LOGGED_IN){
[self.dbAPI isPullSynchronized:^(BOOL isPullSynced){
if(isPullSynced){
dispatch_async(dispatch_get_main_queue(), ^{
self.data = [self.dbAPI getTodayVisits];
[[self tableView] reloadData];
NSLog(@"async before: %@",self.loadingView);
[self hideLoadingScreen];
NSLog(@"async after: %@",self.loadingView);
});
} else {
[self.apiClient getTodayVisits:^(NSArray* visits){
[self.dbAPI insertTodayVisits:visits withCallback:^(int status){
self.data = [self.dbAPI getTodayVisits];
[[self tableView] reloadData];
}];
}];
}
}];
} else if(status == ONLINE_NOT_LOGGED_IN || status == ONLINE_INVALID_TOKEN || status == OFFLINE_NOT_LOGGED_IN) {
//Redirect to login
} else {
//Get from Local DB
self.data = [self.dbAPI getTodayVisits];
[[self tableView] reloadData];
}
}];
}
Журналы:
2016-01-08 16:22:25.973 sunwaves.reporting[4566:282042] async before: <UIView: 0x7fa681e745d0; frame = (0 0; 1024 650); autoresize = RM+H+BM; layer = <CALayer: 0x7fa681e291c0>>
2016-01-08 16:22:25.973 sunwaves.reporting[4566:282042] hideLoadingScreen before: <UIView: 0x7fa681e745d0; frame = (0 0; 1024 650); autoresize = RM+H+BM; layer = <CALayer: 0x7fa681e291c0>>
2016-01-08 16:22:25.974 sunwaves.reporting[4566:282042] hideLoadingScreen after: <UIView: 0x7fa681e745d0; frame = (0 0; 0 0); hidden = YES; autoresize = RM+H+BM; layer = <CALayer: 0x7fa681e291c0>>
2016-01-08 16:22:25.974 sunwaves.reporting[4566:282042] async after: <UIView: 0x7fa681e745d0; frame = (0 0; 0 0); hidden = YES; autoresize = RM+H+BM; layer = <CALayer: 0x7fa681e291c0>>
self.data присваивается, а вызов reloadData работает, но представление не скрывает. Я понимаю, что как назначение self.data, так и reloadData следует вызывать в основном потоке, но метод hideLoadingScreen по-прежнему не обновляет пользовательский интерфейс. Я попытался использовать dispatch_async, как в вашем ответе, без успеха. Метод hideLoadingScreen корректен и делает то, что ожидается (я попробовал запустить его по методу viewDidAppear). Спасибо, хотя, я ценю это! – bandrei2408
Добавить регистрацию. Убедитесь, что (a) 'hideLoadingScreen' фактически запущен, (b)' self.loadingView' не равен нулю. Обратите внимание, что установка значения для скрытия, а также установка кадра в ноль является нечетной. Скрывать его должно быть достаточно. –
Еще раз спасибо! Я изменил свой вопрос с вашими предложениями. Как вы можете видеть, метод и обратный вызов относятся к разным UIView. Любая идея почему? – bandrei2408