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

Ios 使用自定义UITableViewCell时,在编辑之前更改UITextField文本,ios,uitableview,uitextfield,Ios,Uitableview,Uitextfield,我有一个奇怪的问题。我有一个使用自定义UITableViewCells的UITableView。除了这个特殊问题外,一切都在按预期进行 以下是场景: 我需要在编辑开始之前删除UITextField中的“$”符号。这是通过textFieldShouldBeginEditing:方法完成的 - (BOOL)textFieldShouldBeginEditing:(UITextField *)textField { LifeEarningsLineItemTableViewCell *cell

我有一个奇怪的问题。我有一个使用自定义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(在不同的行中),删除“$”,这是好的
  • 相同的行中,从textField1移动到textField2,“$”未被删除,这是错误的
为什么不在同一行中删除“$”而在不同行中删除

以下是该问题的视觉表现:

[编辑…添加]
我使用这些流获取这些日志:


应开始…..行:0,标记:0
应开始…..行:0,标记:1
已结束…..行:0,标记:0
已结束…..行:0,标记:1


应开始…..行:0,标记:0
应开始…..行:1,标记:1
已结束…..行:0,标记:0
是否结束…..行: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];
}
以及
textfielddidediting
方法:

- (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;
    }
}

好的,我解决了问题…这是该死的
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
属性来表示文本字段处于编辑模式(事件的顺序必须是开始->结束->开始->结束)

因此,我创建了属性:
@property(非原子,强)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;
/*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;
然后在
textfielddidediting:
方法的末尾,我添加了:

/*Add text field to stack of editing text fields and disable the fetched results controller delegate.*/
[self.stackOfEditingTextFields addObject:textField];
self.lifeEarningsFetchedResultsController.delegate = nil;
/*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;
如果有更好的建议或任何我没有看到的未预见到的bi产品缺陷,我会洗耳恭听

感谢您的帮助,帮助我完成这项工作,并建议不同的角度(我希望您的评论)。

我认为您的解决方案(在编辑过程中分离FRC)可能有点过激,可能会产生不可预见的影响。这里有几个备选建议。我假设问题是由表格在编辑完单元格中的第一个字段后重新加载正在编辑的行引起的

  • 不要将货币符号存储在模型中,如果文本字段未编辑,请将其添加到cellForRowAtIndexPath中显示的文本中。当文本字段开始编辑时,将其文本设置为直接来自模型的值。您不必在结束编辑时执行任何操作,因为重新加载将为您重新添加货币符号
  • 如果不想更改模型,也可以执行类似的操作-在cellForRowAtIndexPath中,如果单元格正在编辑,请删除货币符号
  • 存储当前编辑行的索引路径,并在FRC委托方法中有条件地忽略对此行的更改
好吧,唯一可能的事情是,由于某种原因(您没有显示它的代码)
tableViewCellContainingObject:inTableView:
在发生这种情况时没有返回正确的单元格。我通过
indexPathForCell:
通过日志语句检查了这一点。它不仅记录了正确的行,还通过
theTextField.text
记录了这些UITextFields的正确值。根据上面的代码,当我记录
textField.text
时,它实际上记录了正确的文本(没有“$”)!但它在视觉上显示了“$”符号。仅供参考,这是通过模拟器(iOS 5.1)实现的。如果您登录
textField.text
,并且它显示了正确的值,它是否有可能从另一行中删除$呢?当然,当您更改文本时,UITextField会刷新它的视图……所以我猜您是在使用
textField shouldendediting
?实际上,唯一有意义的是,它在错误的行上执行操作,当它在错误的行上结束编辑时,它会将$back添加回。打开这两个函数,看看在您尝试时它们被调用了多少次。我猜当你直接穿过时,你会得到一个结束,然后一个开始,但当你切换时,你会得到一个结束,一个开始,和一个结束。很高兴你解决了这个问题,但我和你一样担心解决方案。如果在编辑过程中离开应用程序或切换到另一个选项卡,键盘是否会关闭,FRC代表是否会重新连接?特别是第一个要点。我已将NSNumber存储到我的模型中(即,未保存$)。但建议“如果文本字段未编辑,则将其添加到cellForRowAtIndexPath中显示的文本中”,if是一种非常简单的方法。我完全忽略了这是一个检查文本字段是否正在编辑的好地方。因此,在我的
configureCell
(在
cellforrowatinexpath
中调用)中,新编辑的行:
if(LifeEarningLineItemCell.itemAmount.editing==NO)LifeEarningLineItemCell.itemAmount.text=[self.currencyFormatter stringFromNumber:LifeEarningLineItem.amount]。谢谢,很乐意帮忙。我知道整天盯着一个问题看,却错过了一个显而易见的解决方案的感觉!