Conosco l'interfaccia utente di aggiornamento quando App in background non è consigliata da Apple, in particolare per OpenGL.Come preparare l'aggiornamento dell'interfaccia utente prima che l'app entri inground
Tuttavia ho appena realizzato che iMessenger e il messenger di Facebook sembrano in grado di farlo. Inserisci un thread di messaggi con il tuo amico e poi passa in background, quindi ricevi un nuovo messaggio mentre l'app è ancora in background, quindi porta questa app in primo piano (fai clic sulla notifica push o sull'icona App), troverai la nuova bolla del messaggio già lì con l'animazione di espansione dell'app dall'icona.
Per quanto mi consta, questo può accadere solo perché la nuova bolla di messaggio è già disegnata in modalità background. Quindi, mentre l'app entra in primo piano, può apparire nell'animazione.
Tuttavia, dal mio risultato del test, in iOS8 e iOS9, l'aggiornamento dell'interfaccia utente in background verrà posticipato dopo l'attivazione dell'applicazione. Inoltre, iOS aggiungerà una transazione di animazione implicita per tale aggiornamento dell'interfaccia utente.
Ho elencato il mio codice di test come di seguito, vedrete la nuova cella essere aggiunta nella tabella con una transazione di animazione ovvia quando l'app passa in primo piano, totalmente diversa dall'iMessenger. TableView: numberOfRowsInSection: verrà eseguito solo in ritardo quando l'app entrerà in primo piano.
E non solo per l'aggiornamento della cella tableview, anche aggiungendo una sottoview in background si attiverà anche transazione ritardata simile per l'immissione in primo piano.
Forse sono in direzione totalmente sbagliata. Qualcuno potrebbe aiutarmi a capire come iMessenger e il messenger di FB sono in grado di ottenere questo effetto? Grazie in anticipo!
@interface ViewController() <UITableViewDataSource, UITableViewDelegate>
@property (nonatomic) UITableView *tableView;
@property (nonatomic) NSMutableArray *dataTable;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.tableView = [[UITableView alloc] initWithFrame:self.view.bounds];
[self.view addSubview:self.tableView];
self.tableView.delegate = self;
self.tableView.dataSource = self;
[self.tableView registerClass:[UITableViewCell class]
forCellReuseIdentifier:@"kCellId"];
self.dataTable = [[NSMutableArray alloc] initWithArray:@[@"1", @"2", @"3"]];
__weak __typeof(self) weakSelf = self;
[[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationDidEnterBackgroundNotification
object:nil
queue:[NSOperationQueue mainQueue]
usingBlock:^(NSNotification * _Nonnull note) {
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)),
dispatch_get_main_queue(), ^{
[weakSelf.dataTable addObject:[@(weakSelf.dataTable.count + 1) stringValue]];
[weakSelf.tableView reloadData];
});
}];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return self.dataTable.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"kCellId"];
cell.textLabel.text = self.dataTable[indexPath.row];
return cell;
}
@end
Perché stai usando 'dispatch_after'? Ciò impone di attendere un ciclo di esecuzione ed eseguire il blocco in un secondo momento, dopo che lo schermo è già stato disegnato una volta. NSNotificationCenter in realtà * sempre * chiama i suoi osservatori nel thread principale. Ciò significa che non è necessario utilizzare GCD. Prova a rimuovere la chiamata 'dispatch_after'. – Farthen
utilizzando dispatch_after si tenta di simulare l'aggiornamento dell'interfaccia utente quando App in background. Chiamare direttamente l'aggiornamento dell'interfaccia utente dopo aver inserito la notifica in background non può garantire che l'animazione principale sia già stata interrotta. – Pei
Consiglierei di non codificare un caso di test come questo. Se desideri un test migliore, invierò una notifica push alla tua app, con alcuni dati arbitrari. Quando l'app riceve la notifica push, aggiorna il dataTable con i dati ricevuti dalla notifica push. –