首页 文章

UITableView是第一次显示包含UITextView的单元格

提问于
浏览
3

我遇到了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 回答

  • 1

    显然,我的dataSource的 cellForRowAtIndexPath: 使用了字段的属性,该属性设置为 @property (nonatomic, copy) 而不是 @property (nonatomic, readonly) .

    现在我已经修好了,滚动不再滞后了 .

  • 0

    正如我猜测的那样,你的问题在于你的自定义控件 . 是的,您正在重复使用单元格,但这并不会给您带来任何影响,因为每次请求单元格时,您都会为每个单元格创建新的自定义控件 . 我建议,您可以创建并保留自定义控件作为实例变量,并在需要时返回它们而不需要很多 if-else ,或者,您可以为两种情况创建自定义单元格,并使用不同的单元标识符对它们进行出列并重复使用它们 . 祝好运!

相关问题