从 TableViewCell 上的 UITextField 获取文本

Posted

技术标签:

【中文标题】从 TableViewCell 上的 UITextField 获取文本【英文标题】:Get text from UITextField on a TableViewCell 【发布时间】:2012-04-27 19:32:35 【问题描述】:

我有一个 UITableViewController,其原型单元格包含 UITextFields。为了配置这些自定义单元格,我创建了一个 UITableViewCell 子类。我已通过插座 (nonatomic, weak) 将 textField 连接到单元格子类。

在这个子类上,我创建了一个协议,UITableViewController 是它的委托,这样每当这些文本字段发生变化时,TableViewController 就会知道它。基本上我希望这可以保存 NSUserDefaults 上的值

此外,为了从这些文本字段中动态获取值,我可以这样做:

((TextFieldCell*)[self.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:2 inSection:0]]).textField.text

大多数时候都可以正常工作。但是,当 textField 因为滚动而位于视图之外时,我从 textField.text 获得的值是(null)。一旦它再次出现在视图中,一切都会恢复正常。

我试图将出口从弱改为强,但无济于事。

我想我可以在类上定义一些私有的 NSString,并在调用委托协议时填写它们。问题是我想让我的代码尽可能通用,尽可能降低对私有变量的需求,主要是为了简化单元生成代码。

当文本字段在视图之外时,还有其他方法可以获取它们的值吗?

提前致谢!

【问题讨论】:

【参考方案1】:

但是你知道 UITableView 只保留可见矩形的单元格吗? 当一个单元格离开屏幕,而另一个单元格需要一个新单元格来移动到可见区域时,旧单元格将被重新用于新内容。

因此,表格视图的每一行都没有一个单元格。 如果您的表格包含大量数据,则行数远远多于单元格。

【讨论】:

是的,我知道。我只是对 textField 信息消失感到惊讶。【参考方案2】:

正如 Thyraz 所说,UITableView 仅保留可见矩形的单元格——以及允许滚动的合理缓冲区。这就是为什么“重用标识符”如此重要的原因,它们指示哪些单元格可用于哪些表格(当您需要担心多个表格时至关重要)。不幸的是,这本身并不能回答您的问题。

存储这些 textView 内容的责任不在 UITableView 的肩上。 您的工作是通过数据源委托协议提供该数据,因此您应该查询数据源以获取该信息。

编辑:这意味着是的,您应该将这些数据存储在其他地方,通常以包含表视图的视图控制器类的属性的形式。我建议为此目的使用 NSArray,但您也可以通过 dicts 甚至在 last 手段来做到这一点(这在理论上你可以做到这一点,但这是一个令人难以置信的坏主意),一系列属性。就个人而言,我几乎总是使用 NSArrays,因为它们的结构适合问题,但理论上你可以用其他方式来做。 (我只使用过一次基于 dict 的结构,那是我的数据以递归结构嵌套在自身内部的情况)

【讨论】:

不,它不会直接回答问题,但可以帮助我理解为什么会发生。无论如何,这是一种答案。非常感谢。我想我毕竟做对了。 是的,它适用于简单的 NSStrings,但 NSArray 是个好主意,因为它会简化 cellForRow 上的代码...感谢您的提示! Re:评论 1:了解“为什么”是 在这里提出的任何问题的 9/10; “教人钓鱼”是一个非常重要的编程概念!回复:评论2:正是。 UITableView 最初的设计方式与 NSArray 大致相似,这使得使用该数据结构提供数据变得自然且易于理解。 (如果你想严格一点,它实际上是一个数组数组,但你经常只有一个部分,使你的“***”数组成为一个单元素数组,当我做一个数组数据结构时,我不会浪费时间只有一个元素,永远)【参考方案3】:

UITableViewController 一旦离开屏幕就不会保留单元格。您可以使用以下模式来获得以前使用的模式作为内存管理优化,但您必须假设单元格每次出现在屏幕上时都需要重置它们的值(即使出队),因为无法保证什么值将是。

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

    static NSString *CellIdentifier1 = @"Cell1";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier2];
    if( cell == nil ) 
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier1] autorelease];
        cell2.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
        cell2.editingAccessoryType = UITableViewCellAccessoryNone;
       
    switch( indexPath.section ) 
        case first_Section:
            if( row == 0 ) 
                cell1.textLabel.text = @"Some Text";
                cell1.accessoryView = [self myCustomViewControl];
                cell = cell1;
            
            ... etc
    

【讨论】:

只是一个代码挑剔,但我倾向于避免在 XCode/ios 中使用 switch 语句;根据我的经验,它们通常会在您最不期望的时候产生奇怪的、难以调试的错误。最重要的是,您的代码似乎旨在对整个表格视图进行硬编码,我不喜欢将其作为一种编程风格。如果您只是对数据源进行硬编码,则更容易理解,并使代码在启动时更具可重用性。 (编辑:当然,您的偏好和结果可能会有所不同) 真的吗?!自 2008 年左右以来,我一直在那里使用 switch 语句,它们工作得很好。至于设计风格......这只是一个概念的说明,因为听起来询问者不熟悉基本的 UITableViewController 概念。一般来说,使用模型/视图模式总是好的做法。 如果您查看我最近的问题历史记录,就会发现其中有一个问题,因为开关不工作的事实让我发疯了!似乎每次我尝试在 iOS 中使用开关时,都会遇到一些无法正常工作的问题。我也可以通过使用函数调用而不是将工作放入 switch 块本身来经常“破坏”错误,但这会导致大量的函数调用,这往往会使文件变得混乱,就像一系列if/else 语句会。 (而且我以前做 C++ 编程的时候喜欢开关,所以我不认为它是纯粹的 PEBKAC) 发给我一个链接,我在你的页面上看到的唯一一个与 tableview 和 switch 有关的问题已关闭。 很遗憾,我认为这个网站不包含 PM 功能。我提到的问题实际上已经结束,我设法完全错过了一个几乎相同的问题,归结为“开关只是简单地向下不适用于动画”。这杀死了我记得的一个例子,但还有其他例子,我不认为它们都涉及动画。 (它们发生在几年前,所以我的记忆很模糊)***.com/questions/10254585/…

以上是关于从 TableViewCell 上的 UITextField 获取文本的主要内容,如果未能解决你的问题,请参考以下文章

部分之间的多个自定义 TableviewCell 上的多个自定义 UICollectionView

将 UITapGestureRecognizer 添加到 tableViewCell 上的子视图

实际操作-手把手探究tableViewCell上的控件点击事件

TableViewCell 上的 UIImageView 缺少单击单元格的约束

获取屏幕上的某个控件相对位置,尤其是tableviewcell上的某一个控件的相对位置

iOS7 上的 TableViewCell 中不会显示复选标记