特定のセルがスーパービューに移動するときにスクロール中にラグが発生する UITableView で問題が発生しています。
フォームフィールド/セルごとにすべてを手動で再コーディングすることなく、さまざまな種類のinputViewを使用して美しい入力フォームを簡単に作成できるように、独自のIPFormKitを作成しました。
IPFormKit とそのフィールドを初期化する UITableViewController があります。デキューされたカスタム セル (IPFormTableViewCell と呼ばれる)- (UITableViewCell *) cellForRowAtIndexPath:(NSIndexPath)indexPath;
をロードし、IPFormField を各セルに割り当てます。
カスタム UITableViewCell (IPFormTableViewCell) は、初期化時に CGRectZero を使用して、(おそらく) 必要なすべての inputView (UITextField、UITextView、CustomUILabel) を作成します。
inputView
IPFormField のタイプ (セルの 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;
}