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];
}