使用自定义UITableViewCell时,在编辑之前更改UITextField文本

时间:2012-03-27 18:48:42

标签: ios uitableview uitextfield

我在这里有一个奇怪的问题。我有一个使用自定义UITableViewCells的UITableView。除了特定问题,一切都按预期工作。

以下是该方案:

我需要在编辑开始之前删除UITextField中的“$”符号。这是通过textFieldShouldBeginEditing:方法完成的。

- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField {
    LifeEarningsLineItemTableViewCell *cell = (LifeEarningsLineItemTableViewCell *)[self tableViewCellContainingObject:textField inTableView:self.lifeEarningsTableView];
    if (textField == cell.itemAmount) {
        /*Remove currency symbol for editing.*/
        NSString *currencySymbol = [self.currencyFormatter currencySymbol];
        NSMutableString *mutableText = [NSMutableString stringWithString:textField.text];
        [mutableText replaceOccurrencesOfString:currencySymbol withString:@"" options:NSCaseInsensitiveSearch range:NSMakeRange(0, [mutableText length])];
        textField.text = mutableText;
    }

    return YES;
}  

以下是问题所在:

  • 不同行之间,从textField1移动到textField2(在另一行中),删除了“$” ,这是 GOOD
  • 相同行中,从textField1移至textField2,删除了“$” ,这是 BAD

为什么“$”不会在同一行中删除,而是在不同的行中删除?

以下是该问题的直观表示:Issue

[EDIT ... ADDITION]
我用这些流程得到这些日志:

Flow1
应该开始.....行:0,标签:0
应该开始.....行:0,标签:1
DID END .....行:0,标记:0
DID END .....行:0,标记:1

Flow2
应该开始.....行:0,标签:0
应该开始.....行:1,标签:1
DID END .....行:0,标记:0
DID END .....行:1,标记:1

此外,这是tableViewCellContainingObject:inTableView:tableView方法:

- (UITableViewCell *)tableViewCellContainingObject:(UIView *)view inTableView:(UITableView *)tableView {
    CGPoint objectRectInTableViewCoordinates = [tableView convertPoint:view.bounds.origin fromView:view];
    NSIndexPath *cellIndexPath = [tableView indexPathForRowAtPoint:objectRectInTableViewCoordinates];
    return [tableView cellForRowAtIndexPath:cellIndexPath];
}

textFieldDidEndEditing方法:

- (void)textFieldDidEndEditing:(UITextField *)textField {
    LifeEarningsLineItemTableViewCell *cell = (LifeEarningsLineItemTableViewCell *)[self tableViewCellContainingObject:textField inTableView:self.lifeEarningsTableView];
    LifeEarningsLineItem *lifeEarningsLineItem = [self.lifeEarningsFetchedResultsController objectAtIndexPath:[self.lifeEarningsTableView indexPathForCell:cell]];

    if (textField == cell.itemAmount) {
        NSNumber *absInteger = [NSNumber numberWithInteger:abs([textField.text integerValue])];
        textField.text = [self.currencyFormatter stringFromNumber:absInteger];
        lifeEarningsLineItem.amount = absInteger;
        [self sumAmountsAndDisplay];
    } else if (textField == cell.itemName) {
        lifeEarningsLineItem.name = textField.text;
    }
}

2 个答案:

答案 0 :(得分:1)

好的,我发现了问题......这是gosh darn NSFetchedResultsController委托方法,特别是NSFetchedResultsChangeUpdate更改类型。这不是NSFetchedResultsController第一次走遍我的桌子。我应该记得NSFetchedResultsController与用户驱动的编辑不相符。

所以这就是我如何解决这个问题(但我仍然担心整个事情都会崩溃):

由于事件的顺序......

SHOULD BEGIN.....Row:0, Tag:0  
SHOULD BEGIN.....Row:0, Tag:1  
DID END.....Row:0, Tag:0  
DID END.....Row:0, Tag:1  

...我不能只使用BOOL属性来说明文字字段处于编辑模式(事件的顺序必须是BEGIN-> END-> BEGIN-> END )。

所以我创造了这个属性:
@property (nonatomic, strong) NSMutableSet *stackOfEditingTextFields;

然后在textFieldShouldBeginEditing:方法开始时,我添加了:

/*Add text field to stack of editing text fields and disable the fetched results controller delegate.*/
[self.stackOfEditingTextFields addObject:textField];
self.lifeEarningsFetchedResultsController.delegate = nil;

然后在textFieldDidEndEditing:方法结束时,我添加了:

/*Remove text field from stack of editing text fields. If stack count is 0, reengage the fetched results controller delegate.*/
[self.stackOfEditingTextFields removeObject:textField];
if ([self.stackOfEditingTextFields count] == 0) self.lifeEarningsFetchedResultsController.delegate = self;

如果有更好的建议或任何我看不到的无法预见的副产品错误,我全都听见了。

感谢帮助lnafziger,帮助我完成工作,并提出不同的角度(我给你的评论加了1分)。

答案 1 :(得分:1)

我认为你的解决方案(在编辑过程中解耦FRC)可能会有点激烈,并且可能产生无法预料的影响。以下是一些替代建议。我假设问题是由完成编辑单元格中第一个字段后重新加载正在编辑的行的表引起的。

  • 不要将货币符号存储在模型中,将其添加到cellForRowAtIndexPath中显示的文本中,如果文本字段未编辑。文本字段开始编辑时,将其文本直接从模型设置为值。您无需在结束编辑中执行任何操作,因为重新加载将为您重新添加货币符号。
  • 如果您不想更改模型,您可以执行类似的操作 - 在cellForRowAtIndexPath中,如果单元格正在编辑,则删除货币符号。
  • 存储当前编辑行的索引路径,并有条理地忽略FRC委托方法中对此行的更改。