我创建了一个自定义UITableViewCell
类,将UITextfield
嵌入到每个单元格中,在addItemTableViewController
中,我想在所有UITextField-embededd
单元格中获取文本值并创建新模型对象,但我遇到了问题:
cellForRowAtIndexPath
对于不可见的单元格返回nil,在我向下滚动到我的tableview的buttom之后然后点击Add按钮,第一行几行' textField文本值变为null。
无论如何我能解决这个问题吗?我已经玩了好几个小时但还是找不到答案。
这是我的addItemTableViewController代码:
- (IBAction)doneAdd:(UIBarButtonItem *)sender {
[self.delegate addItem:[self newItem]];
}
- (NSMutableArray *)newItem
{
NSMutableArray *newItem = [[NSMutableArray alloc] init];
for (int i = 0; i < [_appDelegate.title count]; i ++) {
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:i inSection:0];
UPFEditableUITableViewCell *cell = (UPFEditableUITableViewCell *)[self.tableView cellForRowAtIndexPath:indexPath];
NSLog(@"%@", cell.editField.text);
//[newItem addObject:cell.editField.text]; //this does not work as null cannot be added into a array
}
NSLog(@"%@", newItem);
return newItem;
}
这是我的自定义UITableViewCell
班级实施
#import "UPFEditableUITableViewCell.h"
@implementation UPFEditableUITableViewCell
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
self.editField = [[UITextField alloc] initWithFrame:CGRectZero];
[self.contentView addSubview:self.editField];
}
return self;
}
- (void)layoutSubviews
{
if ([self.detailTextLabel.text length] == 0) {
self.detailTextLabel.text = @" ";
}
[super layoutSubviews];
// place the edit field in the same place as the detail text field, give max width
self.editField.frame = CGRectMake(self.detailTextLabel.frame.origin.x, self.detailTextLabel.frame.origin.y, self.contentView.frame.size.width-self.detailTextLabel.frame.origin.x, self.detailTextLabel.frame.size.height);
}
- (void)showEditingField:(BOOL)show
{
self.detailTextLabel.hidden = YES;
self.editField.text = self.detailTextLabel.text;
}
@end
答案 0 :(得分:3)
我认为犯了一个根本性的错误,让我的观点与模型层进行对话,从中吸取教训......
无论如何,我设法找到了解决方案,简而言之,这就是我所做的:
这是代码:
在cellForRowAtIndex中:
[cell.editField addTarget:self action:@selector(textFieldDidChange:) forControlEvents:UIControlEventEditingChanged];
cell.editField.delegate = self;
这里是textFieldDidChange的代码:
- (void)textFieldDidChange :(UITextField *)theTextField
{
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
[self.item removeObjectAtIndex:indexPath.row];
[self.item insertObject:theTextField.text atIndex:indexPath.row];
}
答案 1 :(得分:1)
这不是问题。每当创建新单元格时,单元格都会出列并重新使用。当在顶部滚动tableview时,它们变为null,并且使用相同的标识符创建新单元格。
对于您的问题,您需要将textfield的值存储到字典中。为此,您需要在出列单元格时保存它。
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *cellReuseIdentifier = @"cellIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellReuseIdentifier];
if (!cell) {
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellReuseIdentifier];
}else{
NSLog(@"text is %@",cell.textLabel.text);
for (UIView *v in cell.contentView.subviews) {
if ([v isKindOfClass:[UITextField class]]) {
UITextField *textField = (UITextField *)v;
[myDictionary setObject:textField.text forKey:indexPath]; // declare myDictionary in the interface first.This will also prevent the values from duplicating
NSLog(@"%@",myDictionary);
}
}
}
return cell;
}
答案 2 :(得分:0)
要从UITextField
获取值,您可以在ViewController上设置委托。然后,您应该实现textField:shouldChangeCharactersInRange:replacementString:
,您可以在其中更新NSString值。
第二种解决方案可能是保留对NSMutableArray
中每个单元格的引用。
无论如何,你试图避免从表视图控制器调用cellForRowAtIndexPath :.
答案 3 :(得分:0)
您应该始终尝试将数据保存在模型类中,并使用这些模型类实例的数组来加载表。因此,您不需要tableCells来获取数据。数据始终是从模型而不是UI中获取的(在本例中为TableCells)。
您最初可能正在使用arra,y加载tablecell。如果是这样,请使用该数组创建您提到的模型类对象而不是tablecells。