当特定单元格移动到超级视图时,我遇到了 UITableView 在滚动时滞后的问题。
我编写了自己的 IPFormKit,以便轻松创建具有不同类型 inputViews 的漂亮输入表单,而无需为每个表单字段/单元格手动重新编码所有内容。
我有一个 UITableViewController 来初始化我的 IPFormKit 及其字段。加载出列的- (UITableViewCell *) cellForRowAtIndexPath:(NSIndexPath)indexPath;
自定义单元格(称为 IPFormTableViewCell)并将 IPFormField 分配给每个单元格。
自定义 UITableViewCell (IPFormTableViewCell) 在初始化时使用 CGRectZero 创建所有(可能)需要的输入视图(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 *)field:
- (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;
}