3

特定のセルがスーパービューに移動するときにスクロール中にラグが発生する UITableView で問題が発生しています。

フォームフィールド/セルごとにすべてを手動で再コーディングすることなく、さまざまな種類のinputViewを使用して美しい入力フォームを簡単に作成できるように、独自のIPFormKitを作成しました。

IPFormKit とそのフィールドを初期化する UITableViewController があります。デキューされたカスタム セル (IPFormTableViewCell と呼ばれる)- (UITableViewCell *) cellForRowAtIndexPath:(NSIndexPath)indexPath;をロードし、IPFormField を各セルに割り当てます。

カスタム UITableViewCell (IPFormTableViewCell) は、初期化時に CGRectZero を使用して、(おそらく) 必要なすべての inputView (UITextField、UITextView、CustomUILabel) を作成します。

inputViewIPFormField のタイプ (セルの iVar として既に初期化されている) に応じたマッチングは、サイズが変更され、サブビューとして内部に追加されcell.contentViewます。

- (UITableViewCell *)cellForRowAtIndexPath:(NSIndexPath)indexPath

UITextField と CustomUILabelの場合、これは問題なく機能しますが、inputView が UIText Viewの場合、このセルが初めて表示されるときに UITableView のスクロールが (わずかに) 遅れます。

少しスクロールした後でセルが再び表示される場合 (セルが再利用され、UITextView が削除されて再読み込みされた場合でも)、遅延はなく、それらのセルのスクロールは非常にスムーズです。

この遅延の理由が何であるかについて、私はアイデアを使い果たしています。どんなアイデアでも大歓迎です。

PS: 遅延は iPhone 4 と iPhone 4S の両方で顕著であり、ほぼ同じ時間です (したがって、CPU に関連するものではありません)。

UITableViewController.m:

- (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

- (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *CellIdentifier = @"IPFormFieldCell";

    // Get Form Field for indexPath
    IPFormField *formField = [self.form fieldAtIndexPath:indexPath];

    IPTableViewCell *cell = (IPTableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    if (cell == nil) {
        cell = [[[IPTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
        cell.backgroundView = nil;
        cell.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"background.png"]];
        cell.selectedBackgroundView = nil;
        cell.selectionStyle = UITableViewCellSelectionStyleNone;
    }

    [cell assignFormField:formField];

    return cell;
}  

IPFormTableViewCell.m:

- (void) assignFormField:(IPFormField *)フィールド:

- (void) assignFormField:(IPFormField *)field {
    if (formField != nil) {
        formField.inputView = nil; // unlink old field
    }

    self.formField = field;

    // Change Field Label
    [fieldLabel setText:[field label]];

    // Add an Input View to the Field
    UIView *labelView = nil;
    UIView *inputView = nil;

    switch (formField.type) {
        case IPFormFieldTypeTextField:
        {
            labelView = fieldLabel;

            UITextField *textField = inputTextField;
            textField.delegate = (IPFormTextField *)formField;
            textField.inputAccessoryView = [formField.form inputAccessoryView];
            textField.placeholder = [self.formField stringFromValue:self.formField.defaultValue];
            textField.keyboardType = [(IPFormTextField *)formField keyboardType];

            if (self.formField.value == nil || [[self.formField stringFromValue:self.formField.value] isEqualToString:[self.formField stringFromValue:self.formField.defaultValue]]) {
                textField.clearsOnBeginEditing = YES;
            } else {
                textField.text = [self.formField stringFromValue:self.formField.value];
                textField.clearsOnBeginEditing = NO;
            }

            inputView = textField;
            break;
        }

        case IPFormFieldTypeTextArea:
        {            
            UITextView *textView = inputTextView;
            textView.delegate = (IPFormTextArea *)formField;
            textView.inputAccessoryView = [formField.form inputAccessoryView];

            if (self.formField.value == nil || ![[self.formField stringFromValue:self.formField.value] length] > 0) {
                textView.text = [self.formField stringFromValue:self.formField.defaultValue];
            } else {
                textView.text = [self.formField stringFromValue:self.formField.value];
            }

            inputView = textView;
            break;
        }

        default:
            break;
    }

    self.leftItem = labelView;
    self.rightItem = inputView;

    if (leftItem != nil) {
        [self.contentView addSubview:leftItem];
    }

    if (rightItem != nil) {
        [self.contentView addSubview:rightItem];
    }

    formField.inputView = rightItem;
}
4

2 に答える 2

1

どうやら、cellForRowAtIndexPath:私の dataSource はフィールドのプロパティを利用し、@property (nonatomic, copy)代わりに@property (nonatomic, readonly).

修正したので、スクロールが遅れなくなりました。

于 2013-01-06T15:49:14.477 に答える
0

私が推測したように、ここでの問題はカスタムコントロールにあります。はい、セルを再利用していますが、セルを要求するたびにセルごとに新しいカスタムコントロールを作成しているため、これでは何も得られません。私のアドバイスでは、カスタムコントロールを作成してインスタンス変数として保持し、必要に応じて多くif-elseのsなしでそれらを返すか、2つのケースのカスタムセルを作成し、それらを異なるセル識別子でデキューして再利用することができます。幸運を!

于 2013-01-05T10:33:57.207 に答える