アップルが特にバックグラウンドでAppを推奨していないとき、特にOpenGLの場合、アップデートUIを知っています。アプリがforgroundに入る前にUIアップデートを準備する方法
しかし、私はちょうどiMessengerとFacebookのメッセンジャーがそのように見えることを認識しました。あなたの友人とメッセージスレッドを入力し、バックグラウンドに行くと、アプリがバックグラウンドにある間に新しいメッセージを受け取った後、このアプリをフォアグラウンドに持ってきて(プッシュ通知またはアプリアイコンをクリックする)、新しいメッセージバブルは既にアイコンからアプリの展開アニメーションが表示されます。
これは、新しいメッセージのバブルが既にバックグラウンドモードで描画されているために発生します。アプリがフォアグラウンドに入ると、それがアニメーションに表示されます。
私のテスト結果から、iOS8とiOS9では、アプリがアクティブになった後、すべてのバックグラウンドUIアップデートが延期されます。さらに、iOSはそのUIアップデートに対して暗黙のアニメーショントランザクションを追加します。
私のテストコードを以下に列挙すると、iMessengerとは違って、アプリケーションがフォアグラウンドになったときに新しいセルがテーブルに追加されることがわかります。 tableView:numberOfRowsInSection:は、アプリがフォアグラウンドに入るときにのみ実行されます。
テーブルビューセルの更新だけでなく、バックグラウンドでサブビューを追加しても、フォアグラウンドに入るために同様の遅延トランザクションが発生します。
多分私はこれについて完全に間違った方向にあります。誰でも私がiMessengerとFBのメッセンジャーがこの効果を達成する方法を理解するのを助けてくれますか? ありがとうございます!
@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
なぜあなたが使用している 'dispatch_after'でアプリをウェイクアップすることができます取得?これは、画面がすでに1度描かれた後に、1つの実行ループを待ち、ブロックを後で実行するように強制します。 NSNotificationCenterは実際には*常に*メインスレッドでオブザーバーを呼び出します。つまり、GCDをまったく使用する必要はありません。 'dispatch_after'呼び出しを削除してみてください。 – Farthen
dispatch_afterを使用すると、アプリがバックグラウンドでUIを更新するようにシミュレートしようとしています。バックグラウンド通知を入力した後にUIアップデートを直接呼び出すと、コアアニメーションが既に停止していることを保証できません。 – Pei
このようなテストケースをハードコードしないことをお勧めします。より良いテストが必要な場合は、アプリに任意のデータを含むプッシュ通知を送信します。アプリがプッシュ通知を受け取ると、プッシュ通知から受け取ったデータでdataTableを更新します。 –