2014年10月2日木曜日

UITableViewCellの再利用について

UITableViewでは、画面内の表示に必要な分だけ、登録したセル(UITableViewCell)がシステム内部に用意される。
あくまで表示分だけであって、全体ではない。スクロールで表示外に出たセルは新しく入ってくる表示分に再利用される

表示外に出たセル→→→+
----------                 |
表示内                     |
                          |再利用
                          |
                          |
----------                 |
表示内に入るセル←←←+|
(実際には表示街に出たセルがすぐ入ってくるセルになるわけではない。
逆スクロールを考慮してか、若干の猶予がある。)

再利用されるとき、セル内に配置されたラベルなどの内容は「そのまま」なので、新しい表示を作るには、
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
で設定する必要がある。

「そのまま」なのは.textだけでなく.hiddenや.frame、addSubviewしている場合はそれもなので、
それらを変更した場合には、元に戻す必要がある。

カスタムセルの場合、awakeFromNibはセルの新規作成時のみ呼び出されるので、
この中で、変化する要素の変化前の情報を保存しておき、
cellForRowAtIndexPath内でまずそれに戻し、その後、新しい表示を設定する。

全体の手順

UITableViewCellの子クラス

@interface NewCell()
{
    CGRect frame;
}

- (void)awakeFromNib
{
    printSelf();
    [super awakeFromNib];
    //変更される要素の属性保存
    //「例」
    frame=label.frame;
}

-(void)initialize
{
    printSelf();
    label.frame=frame;
    // 追加されたボタンを削除する
    for (UIView *vw in self.subviews) {
        if (vw.tag==TAG_ADD_BUTTON) {
            [vw removeFromSuperview];
        }
    }
}

要素を追加するときは、.tagにTAG_ADD_BUTTONを入れて、後で識別できるようにするといい。




どうやってもセルに不必要な表示が残るのでわかったことであった。

0 件のコメント:

コメントを投稿