如何在表格视图中选择单元格而不滚动它?

时间:2023-01-23 14:41:09

I am building the settings screen for my app using a table VC. In the viewDidLoad, I want to show the user his/her current settings by selecting the cells. Then there will be a checkmark on the left of the selected cells. This is the didSelectrowAtIndexPath method:

我正在使用表VC为我的应用程序构建设置屏幕。在viewDidLoad中,我想通过选择单元格向用户显示他/她的当前设置。然后在所选单元格的左侧将有一个复选标记。这是didSelectrowAtIndexPath方法:

override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    let cell = tableView.cellForRowAtIndexPath(indexPath)
    for row in 0..<tableView.numberOfRowsInSection(indexPath.section) {
        let cellToBeDeselected = tableView.cellForRowAtIndexPath(NSIndexPath(forRow: row, inSection: indexPath.section))
        cellToBeDeselected?.accessoryType = .None
    }
    cell!.accessoryType = .Checkmark
    tableView.deselectRowAtIndexPath(indexPath, animated: true)
}

This works well. When I select a row, a checkmark appears. When I select another row, the previous checkmark disappears and a new one appears.

这很好用。当我选择一行时,会出现一个复选标记。当我选择另一行时,前一个复选标记消失,并出现一个新的复选标记。

However, I want to select the rows programmatically in viewDidLoad, in order to show the current settings.

但是,我想在viewDidLoad中以编程方式选择行,以显示当前设置。

I found a method called selectRowAtIndexPath. I tried to use this but it requires a UITableViewScrollPosition. The docs says:

我找到了一个名为selectRowAtIndexPath的方法。我试图使用它,但它需要一个UITableViewScrollPosition。文档说:

The position in the table view (top, middle, bottom) to which a given row is scrolled.

表格视图中的位置(顶部,中间,底部),滚动给定行。

It seems that whenever I want to select a row, the table view must scroll to where the selected row is. But I just want to select it, and only select it.

似乎每当我想要选择一行时,表视图必须滚动到所选行的位置。但我只是想选择它,而只选择它。

How to do this?

这该怎么做?

3 个解决方案

#1


1  

This is purely depends on the logic.

这纯粹取决于逻辑。

Your are trying to deselect all the rows first, when any row is selected. As checked your current code, found that you are not maintaining the state of selected row, so it will also cause the dequeue problem i.e. when selected cell will be reused for other cell, it will show checkMark even if that is not selected.

当您选择任何行时,您将尝试首先取消选择所有行。检查当前代码时,发现您没有保持所选行的状态,因此它也会导致出列问题,即当所选单元格将被重用于其他单元格时,即使未选中,也会显示checkMark。

Instead of this, you just need to maintain index variable which will store indexPath of selected row. You have 3 sections, and 3selections are allowed, in this case, you just need to maintain one array which holds values of selectedIndexPaths.

而不是这个,你只需要维护索引变量,它将存储所选行的indexPath。您有3个部分,并且允许3个选项,在这种情况下,您只需要维护一个包含selectedIndexPaths值的数组。

declare one property in your viewController as below.

在viewController中声明一个属性,如下所示。

var arraySelectedIndexPaths : Array<NSIndexPath> = Array();

In viewDidLoad: add three default value as per last selected setting.

在viewDidLoad中:根据上次选择的设置添加三个默认值。

suppose last time user have selected

假设用户上次选择了

row1 in section0

section0中的row1

row2 in section1

section1中的row2

row0 in section2

第2节中的row0

then your array will be as follow,

然后你的阵列将如下,

        //in viewDidLoad
        arraySelectedIndexPaths.append(NSIndexPath(forRow: 1, inSection: 0));
        arraySelectedIndexPaths.append(NSIndexPath(forRow: 2, inSection: 1));
        arraySelectedIndexPaths.append(NSIndexPath(forRow: 0, inSection: 2));

so in your tableView:cellForRowAtIndexPath: write below logic. this logic will show checkMark in cell if it is selected, when it comes onto the screen.

所以在你的tableView:cellForRowAtIndexPath:写下逻辑。这个逻辑将在单元格中显示checkMark,如果它被选中,当它进入屏幕时。

if indexPath == self.arraySelectedIndexPaths[indexPath.section] {
   cell!.accessoryType = .Checkmark
}else{
   cell!.accessoryType = .None
}

And in tableView:didSelectedRowAtIndexPath: write logic as below. This will update indexPath in array as per selection. Will also deSelect previous row and select new row.

并在tableView中:didSelectedRowAtIndexPath:写入逻辑如下。这将根据选择更新数组中的indexPath。还将取消选择上一行并选择新行。

override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    let cell = tableView.cellForRowAtIndexPath(indexPath)

//deSelected previously selected Cell
        let cellToBeDeselected = tableView.cellForRowAtIndexPath(self.arraySelectedIndexPaths[indexPath.section])
        cellToBeDeselected?.accessoryType = .None

    cell!.accessoryType = .Checkmark
    tableView.deselectRowAtIndexPath(indexPath, animated: true)
    self.arraySelectedIndexPaths[indexPath.section] = indexPath;//update new selected indexPath in array
}

I have wrote above logic, as per our discussion in comments for your question. below is our discussion.

根据我们在您的问题评论中的讨论,我已经写了上面的逻辑。以下是我们的讨论。

@Sweeper are you trying to show only check mark in one row, based on the last setting value ? – HitendraHckr

@Sweeper你是否试图根据最后的设定值在一行中只显示复选标记? - HitendraHckr

@HitendraHckr Yes I am. I am trying to show check mark in three different rows, since there are three settings – Sweeper

@HitendraHckr是的我。我试图在三个不同的行中显示复选标记,因为有三个设置 - 清扫器

so, do you have 3 sections for different 3 settings ? – Hitendra Hckr

那么,你有3个部分用于不同的3个设置吗? - Hitendra Hckr

and I think any can be selected in one section, am I right ? – Hitendra Hckr

我认为任何一个都可以在一个部分中选择,对吗? - Hitendra Hckr

@HitendraHckr Yes you're right – Sweeper

@HitendraHckr是的你是对的 - 清扫工

#2


4  

As the documentation mentions, you can specify UITableViewScrollPositionNone for the scroll position, which will result in no scrolling.

如文档所述,您可以为滚动位置指定UITableViewScrollPositionNone,这将导致不滚动。

#3


1  

you can directly call did select method of table view using the below code

您可以使用下面的代码直接调用表选择方法

let indexpath = NSIndexPath(forRow: yourRow, inSection: yourColumn);
self.tableView(tblObj, didSelectRowAtIndexPath: indexpath);

Actually you want to call did select to perform some operation which can be manage by this. Try this, it may be work for you.

实际上你想调用did select来执行一些可以由此管理的操作。试试这个,它可能适合你。

#1


1  

This is purely depends on the logic.

这纯粹取决于逻辑。

Your are trying to deselect all the rows first, when any row is selected. As checked your current code, found that you are not maintaining the state of selected row, so it will also cause the dequeue problem i.e. when selected cell will be reused for other cell, it will show checkMark even if that is not selected.

当您选择任何行时,您将尝试首先取消选择所有行。检查当前代码时,发现您没有保持所选行的状态,因此它也会导致出列问题,即当所选单元格将被重用于其他单元格时,即使未选中,也会显示checkMark。

Instead of this, you just need to maintain index variable which will store indexPath of selected row. You have 3 sections, and 3selections are allowed, in this case, you just need to maintain one array which holds values of selectedIndexPaths.

而不是这个,你只需要维护索引变量,它将存储所选行的indexPath。您有3个部分,并且允许3个选项,在这种情况下,您只需要维护一个包含selectedIndexPaths值的数组。

declare one property in your viewController as below.

在viewController中声明一个属性,如下所示。

var arraySelectedIndexPaths : Array<NSIndexPath> = Array();

In viewDidLoad: add three default value as per last selected setting.

在viewDidLoad中:根据上次选择的设置添加三个默认值。

suppose last time user have selected

假设用户上次选择了

row1 in section0

section0中的row1

row2 in section1

section1中的row2

row0 in section2

第2节中的row0

then your array will be as follow,

然后你的阵列将如下,

        //in viewDidLoad
        arraySelectedIndexPaths.append(NSIndexPath(forRow: 1, inSection: 0));
        arraySelectedIndexPaths.append(NSIndexPath(forRow: 2, inSection: 1));
        arraySelectedIndexPaths.append(NSIndexPath(forRow: 0, inSection: 2));

so in your tableView:cellForRowAtIndexPath: write below logic. this logic will show checkMark in cell if it is selected, when it comes onto the screen.

所以在你的tableView:cellForRowAtIndexPath:写下逻辑。这个逻辑将在单元格中显示checkMark,如果它被选中,当它进入屏幕时。

if indexPath == self.arraySelectedIndexPaths[indexPath.section] {
   cell!.accessoryType = .Checkmark
}else{
   cell!.accessoryType = .None
}

And in tableView:didSelectedRowAtIndexPath: write logic as below. This will update indexPath in array as per selection. Will also deSelect previous row and select new row.

并在tableView中:didSelectedRowAtIndexPath:写入逻辑如下。这将根据选择更新数组中的indexPath。还将取消选择上一行并选择新行。

override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    let cell = tableView.cellForRowAtIndexPath(indexPath)

//deSelected previously selected Cell
        let cellToBeDeselected = tableView.cellForRowAtIndexPath(self.arraySelectedIndexPaths[indexPath.section])
        cellToBeDeselected?.accessoryType = .None

    cell!.accessoryType = .Checkmark
    tableView.deselectRowAtIndexPath(indexPath, animated: true)
    self.arraySelectedIndexPaths[indexPath.section] = indexPath;//update new selected indexPath in array
}

I have wrote above logic, as per our discussion in comments for your question. below is our discussion.

根据我们在您的问题评论中的讨论,我已经写了上面的逻辑。以下是我们的讨论。

@Sweeper are you trying to show only check mark in one row, based on the last setting value ? – HitendraHckr

@Sweeper你是否试图根据最后的设定值在一行中只显示复选标记? - HitendraHckr

@HitendraHckr Yes I am. I am trying to show check mark in three different rows, since there are three settings – Sweeper

@HitendraHckr是的我。我试图在三个不同的行中显示复选标记,因为有三个设置 - 清扫器

so, do you have 3 sections for different 3 settings ? – Hitendra Hckr

那么,你有3个部分用于不同的3个设置吗? - Hitendra Hckr

and I think any can be selected in one section, am I right ? – Hitendra Hckr

我认为任何一个都可以在一个部分中选择,对吗? - Hitendra Hckr

@HitendraHckr Yes you're right – Sweeper

@HitendraHckr是的你是对的 - 清扫工

#2


4  

As the documentation mentions, you can specify UITableViewScrollPositionNone for the scroll position, which will result in no scrolling.

如文档所述,您可以为滚动位置指定UITableViewScrollPositionNone,这将导致不滚动。

#3


1  

you can directly call did select method of table view using the below code

您可以使用下面的代码直接调用表选择方法

let indexpath = NSIndexPath(forRow: yourRow, inSection: yourColumn);
self.tableView(tblObj, didSelectRowAtIndexPath: indexpath);

Actually you want to call did select to perform some operation which can be manage by this. Try this, it may be work for you.

实际上你想调用did select来执行一些可以由此管理的操作。试试这个,它可能适合你。