OGeek|极客世界-中国程序员成长平台

标题: ios - 在动态 tableView 中重新加载包含 textFields 的单元格时的奇怪行为 [打印本页]

作者: 菜鸟教程小白    时间: 2022-12-13 06:51
标题: ios - 在动态 tableView 中重新加载包含 textFields 的单元格时的奇怪行为

我有一个带有自定义单元格的动态 tableView,每个单元格都包含一个 textField 和标签。我想要以下行为:


用户点击“添加”按钮,表格在索引 0 处插入一个单元格,单元格的 textField 成为第一响应者。

当用户完成输入数据时,单行文本字段将作为第一响应者退出并隐藏自身。

然后单元格的标签变为可见,填充用户输入,并自动调整其高度以适应输入。此时单元格也会调整大小。


我的代码在第一次添加单元格时会执行此操作,但是当添加更多单元格时,它会变得很奇怪。第二个添加的单元格 s textField 不会成为第一响应者,而是由前一个 textField 中的文本填充。后续添加的单元格显示为空白,除每 6 个空白单元格外,显示第一个单元格的文本。

发生了什么,我该如何解决?

编辑:感谢@Rayfleck,我已经解决了第二个添加的单元格被前一个 textField 中的文本填充的问题,但是添加的第二个单元格(以及随后添加的单元格)仍然没有成为第一响应者。

这是展示此行为的演示:

enter image description here

这是我的代码:

#define FONT_SIZE 16.0f
#define CELL_CONTENT_WIDTH 300.0f // This will change for different size!
#define CELL_CONTENT_MARGIN_WIDTH 10.0f
#define CELL_CONTENT_MARGIN_HEIGHT 20.0f

@interface ViewController ()

@property (strong) IBOutlet UITableView *tableView;
@property (strong) NSMutableArray *notesArray;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    self.notesArray = [NSMutableArray arrayWithObjects"Testo 1", @"This is a long string of text to show how the cell resizes to fit a variable height label.", @"Testo 3", @"Testo 4", @"Testo 5", nil];
}

- (NSInteger)numberOfSectionsInTableViewUITableView *)tableView {

    // Return the number of sections.
    return 1;
}

- (IBAction)addButtonTapped {

    NSMutableArray *indexPaths = [NSMutableArray array];
    [indexPaths addObject:[NSIndexPath indexPathForRow:0 inSection:0]]; // insert at first index

    [self.tableView setEditing:YES animated:NO]; // go into edit mode so cell has label hidden and textField visible

    // do the insertion
    [self.notesArray insertObject"" atIndex:0]; // placeholder for when user starts typing
    [self.tableView beginUpdates];
    [self.tableView insertRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationTop];
    [self.tableView endUpdates];

    [self.tableView setEditing:NO animated:NO];
}

-(BOOL)textFieldShouldReturnUITextField *)textField {

    NSIndexPath *path = [NSIndexPath indexPathForRow:0 inSection:0]; // first table cell
    HC_NoteCell *cell = (HC_NoteCell *)[self.tableView cellForRowAtIndexPath:path];

    cell.noteTextField.hidden = YES;
    cell.noteLabel.text = cell.noteTextField.text;
    cell.noteLabel.hidden = NO;

    [self.notesArray replaceObjectAtIndex:0 withObject:cell.noteTextField.text];

    [textField resignFirstResponder];

    // Need to reload rows so cell height can be recalculated
    [self.tableView beginUpdates];
    [self.tableView reloadRowsAtIndexPaths[path] withRowAnimation:UITableViewRowAnimationAutomatic];
    [self.tableView endUpdates];

    return YES;
}

- (NSInteger)tableViewUITableView *)tableView numberOfRowsInSectionNSInteger)section {

    return self.notesArray.count;
}

- (CGFloat)tableViewUITableView *)tableView heightForRowAtIndexPathNSIndexPath *)indexPath {

    NSString *text;
    text = [self.notesArray objectAtIndex:indexPath.row];

    CGSize constraint = CGSizeMake(CELL_CONTENT_WIDTH - (CELL_CONTENT_MARGIN_WIDTH * 2), 20000.0f);

    UIFont *font = [UIFont fontWithName"Helvetica Neue" size:FONT_SIZE];
    NSDictionary *attrsDictionary = [NSDictionary dictionaryWithObject:font
                                                                forKey:NSFontAttributeName];
    NSAttributedString *attributedString = [[NSAttributedString alloc] initWithString:text attributes:attrsDictionary];

    CGRect paragraphRect = [attributedString boundingRectWithSize:constraint optionsNSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading) context:nil];

    CGFloat height = MAX(paragraphRect.size.height, 22.0f);

    return height + (CELL_CONTENT_MARGIN_HEIGHT * 2);

}

- (UITableViewCell *)tableViewUITableView *)tableView cellForRowAtIndexPathNSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"NoteCell";

    HC_NoteCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[HC_NoteCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
    }

    if (self.tableView.isEditing) {

        cell.noteLabel.hidden = YES;
        cell.noteTextField.hidden = NO;
        cell.noteTextField.delegate = self;

        [cell.noteTextField becomeFirstResponder];

    } else {

        cell.noteLabel.hidden = NO;
        cell.noteTextField.hidden = YES;
        cell.noteTextField.delegate = self;

        cell.noteLabel.text = [self.notesArray objectAtIndex:indexPath.row];
    }

    return cell;
}

@end



Best Answer-推荐答案


如果您正在重用/取消单元格,那么在 cellForRowAtIndexPath 中,您必须为单元格的每个 subview 设置新值,因为它可能包含前一个单元格的内容。

所以 cell.noteLabel.text = nil; 在所有情况下,然后在你的 else 情况下,从数组中设置它的值。

关于ios - 在动态 tableView 中重新加载包含 textFields 的单元格时的奇怪行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29946538/






欢迎光临 OGeek|极客世界-中国程序员成长平台 (http://sqlite.in/) Powered by Discuz! X3.4