addSubViewで追加されるタイミングでsub Viewを表示
課題
iphoneでViewが表示されるときに下位にViewやControlを追加するときのことです。viewDidAppear:でaddSubViewを使ってViewやControlを追加すると、viewDidAppearの処理が完了してから、UiKitによって一括して描画が行われることになります。こうすると下位の要素数が多い場合などは、描画が始めるまで時間がかかってしまうことになる。そのため、最後に一括して、描画されるのではなくaddSubViewでView階層に追加されるたびに表示したい場合があります。
解決方法
まず、下位のView,Controlを追加するための処理は、UIKitの描画処理と非同期に行われるようにviewDidAppear:から新規スレッドで起動されるようにします。具体的にはNSThreadを使うことになります。
その別スレッドで、下位のView,Controlを追加していくのだが、その別起動されているスレッドでaddSubViewしても、もちろん、描画の処理は起動されない。そこで、描画を行うスレッド、つまりメインスレッドでaddSubViewを行う必要があります。そこで、個々のaddSubViewを行う別メソッドを作成、NSObjectのperformSelectorOnMainThread:withObject:waitUntilDoneメソッドを使って、それがメインスレッドで起動されるようにします。
それで、具体的のどのような実装になるかが以下です。
viewDidAppear:では、以下のとおり、NSThreadの detachNewThreadSelector:toTaarget:withObjectなどにより、view追加のメソッドを別スレッドで呼び出します。
- (void) viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; [NSThread detachNewThreadSelector:@selector(afterViewDidAppear:) toTarget:self withObject:nil]; }
別スレッドで起動される、メソッド内では、view。そのviewが、メインスレッドで追加されるように、NSObjectのperformSelectorOnMainThread:withObject:waitUntilDoneメソッドにより、実際のview追加を行うメソッドを呼び出します。
- (void) afterViewDidAppear:(id)arg { for(NSUInteger i = 0; i < [self subViewCount]; ++i) { UIView *subView = [self subViewAt:i]; if(imageView) { [self performSelectorOnMainThread:@selector(addView:) withObject:subView waitUntilDone:NO]; } }
実際にview,controlの追加を行うメソッドは、単純な場合は、以下のように単にaddSubViewを呼び出すだけとなります。
- (void)addView:(id)subView { [self.view addSubview:subView]; }