Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 如何正确识别哪些单元格的子视图已被用户修改?_Ios_Objective C_Uitableview_Swift - Fatal编程技术网

Ios 如何正确识别哪些单元格的子视图已被用户修改?

Ios 如何正确识别哪些单元格的子视图已被用户修改?,ios,objective-c,uitableview,swift,Ios,Objective C,Uitableview,Swift,我有一个tableView,里面是自定义单元格。整个过程与NSUserDefaults很好地同步,但是存在一个问题。在其他交互子视图中,这些自定义单元格内部有文本字段。当用户修改单元格的textfield时,如何确定单元格的索引,以便将数据模型与tableView正确匹配?我曾尝试在cellForIndexPath(…)方法中为每个单元格分配一个索引变量,但这会导致许多潜在的错误 要了解我的tableView是什么样子,只需看看Apple提醒应用程序,它有自定义单元格,其中还包含交互式子视图 无

我有一个tableView,里面是自定义单元格。整个过程与NSUserDefaults很好地同步,但是存在一个问题。在其他交互子视图中,这些自定义单元格内部有文本字段。当用户修改单元格的textfield时,如何确定单元格的索引,以便将数据模型与tableView正确匹配?我曾尝试在cellForIndexPath(…)方法中为每个单元格分配一个索引变量,但这会导致许多潜在的错误

要了解我的tableView是什么样子,只需看看Apple提醒应用程序,它有自定义单元格,其中还包含交互式子视图

无论如何,有没有其他方法来确定这类数据?有大量的提醒应用程序包含交互式子视图,所以一定有更好的方法

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

        var cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as GoalTableViewCell
        cell.goalTextField.text = goalsArray[indexPath.row].title
        cell.checkmarkImageView.visible = goalsArray[indexPath.row].checkmarked
        cell.blackLineView.visible = goalsArray[indexPath.row].checkmarked
        cell.enabled = goalsArray[indexPath.row].enabled
        cell.isLastCell = goalsArray[indexPath.row].isLastCell
        cell.priority = goalsArray[indexPath.row].priority as Priority
        cell.indexInTable = indexPath.row //this is how I assign the index of a cell. Problem is that cellForRowAtIndexPath is inconsistent.

        return cell
    }
然后检索该数据

func finishCreatingGoal(notification : NSNotification) { //this executes after a textfield resigns first responder status
        if (notification.name == "FinishCreatingGoal") {
            var userInfo = notification.userInfo!
            var text = userInfo["text"]! as String
            var index = userInfo["index"]! as Int //this index is pulled from the cell.indexInTable variable which is assigned in CellForIndexPath(...)

            goalsArray[index].title = text //this line crashes often after various manipulation of the tableView such as deleting rows and reordering them.
            saveGoals(goalsArray)

            let indexPath = NSIndexPath(forRow:index,inSection:0)
            self.tableView.reloadRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimation.None)
        }
    }

更好的选择是有一个
Goal
类(我猜您在
goalsArray
中已经有了这个类),它将包含用户存储的所有信息。然后,不必从表视图的委托中设置所有UI,只需向其传递一个
Goal
对象即可。即

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    var cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as GoalTableViewCell
    cell.goal = goalsArray[indexPath.row]
    return cell
}

然后在您的
GoalTableViewCell
类中,您保留对该目标的引用并更新UI。然后,当您想要检查单元格的
目标的索引时,您可以搜索它。

您可以通过TouchEvents获取单元格的索引,即在UITableview中获取点坐标。然后从点位置提取索引路径,然后通过该路径可以获得单元索引。下面是我在代码中使用的方法

- (void)checkButtonTapped:(id)sender event:(id)event
{
    NSSet *touches = [event allTouches];
    UITouch *touch = [touches anyObject];
    CGPoint currentTouchPosition = [touch locationInView:self.tableView];
    NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint: currentTouchPosition];
    if (indexPath != nil)
    {
        NSLog(@"the cell index : %d", (int)indexPath.row);
    }
}
更新---


在Objective-C中就是这样做的。我还没有读过关于swift的书,所以我不能用swift翻译它。

UITableView
有一个方法
indexPathForRowAtPoint:
,您可以使用

// textField is a subview of a cell

let point = tableView.convertPoint(CGPointZero, fromView: textField)
if let indexPath = tableView.indexPathForRowAtPoint(point) {
    let yourObject = dataSource[indexPath.row]
    // do something with it
}

应该是不言自明的。

你尝试过superview.superview之类的东西吗?不,你将如何实现它?顺便说一句,我正在添加示例代码来说明我目前的做法。如果在
CellForIndexPath
中设置了
index
值,那么在插入/删除行时出现崩溃就不足为奇了,因为您可能没有更新这些值。您完全正确。修改后我不会重新加载表数据,因为否则我会丢失动画,因此cellForIndexPath()没有机会更新cell.indexInTable值。非常优雅,谢谢。这还允许我保留当前的数据模型。