我遇到了UITableView的问题,当特定单元格移动到superview时滚动时会出现滞后问题 .
我已经编写了自己的IPFormKit,可以轻松地使用不同类型的inputView创建漂亮的输入表单,而无需为每个表单字段/单元格手动重新编码所有内容 .
我有一个UITableViewController初始化我的IPFormKit及其字段 . - (UITableViewCell *) cellForRowAtIndexPath:(NSIndexPath)indexPath;
加载出列的自定义单元格(称为IPFormTableViewCell)并将IPFormField分配给每个单元格 .
自定义UITableViewCell(IPFormTableViewCell)在初始化时使用CGRectZero创建所有(可能)必需的inputViews(UITextField,UITextView,CustomUILabel) .
匹配 inputView
取决于IPFormField的类型(已经作为单元的iVar引入)被调整大小并作为子视图添加到 cell.contentView
内 .
- (UITableViewCell *)cellForRowAtIndexPath:(NSIndexPath)indexPath
对于UITextField和CustomUILabel,这可以完美地工作,但 when the inputView is a UITextView, the scrolling of the UITableView lags (slightly) noticable when this cell will be displayed for the first time.
稍后滚动一下后将再次显示单元格(即使单元格被重用,因此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;
}
2 回答
显然,我的dataSource的
cellForRowAtIndexPath:
使用了字段的属性,该属性设置为@property (nonatomic, copy)
而不是@property (nonatomic, readonly)
.现在我已经修好了,滚动不再滞后了 .
正如我猜测的那样,你的问题在于你的自定义控件 . 是的,您正在重复使用单元格,但这并不会给您带来任何影响,因为每次请求单元格时,您都会为每个单元格创建新的自定义控件 . 我建议,您可以创建并保留自定义控件作为实例变量,并在需要时返回它们而不需要很多
if-else
,或者,您可以为两种情况创建自定义单元格,并使用不同的单元标识符对它们进行出列并重复使用它们 . 祝好运!