简体   繁体   English

迅捷3-ViewController不取消选择UITableView中的选定行

[英]swift 3 - ViewController not deselecting selected rows in a UITableView

I have a tableview where the user is able to select multiple rows (these rows are distinguished by a checkbox in the row). 我有一个tableview,用户可以选择多行(这些行由该行中的复选框区分)。 For some reason, however, I can't implement the functionality to deselect any selected row. 但是由于某种原因,我无法实现取消选择任何选定行的功能。 Can somebody tell me what I'm missing? 有人可以告诉我我所缺少的吗?

SomeViewController.m SomeViewController.m

@objc class SomeViewController: UIViewController, NSFetchedResultsControllerDelegate, UITableViewDataSource, UITableViewDelegate {

    var deviceArray:[Device] = []

    // [perform a fetch]
    // [insert fetch results into deviceArray to be displayed in the tableview]

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        let cell = tableView.dequeueReusableCell(withIdentifier: "customcell", for:
        indexPath)

        // Set up the cell
        let device = self.deviceArray[indexPath.row]
        cell.textLabel?.text = device.name

        return cell
    }

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        self.tableView(tableView, cellForRowAt: indexPath).accessoryType = UITableViewCellAccessoryType.checkmark
        NSLog("Selected Row")
    }

    func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
        self.tableView(tableView, cellForRowAt: indexPath).accessoryType = UITableViewCellAccessoryType.none
        NSLog("Deselected Row")
    }
}

More info: Looking at the debug logs inserted, I can share the following observations: 更多信息:查看插入的调试日志,我可以分享以下观察结果:

  1. When selecting an unselected row, the console prints "Selected Row" 选择未选择的行时,控制台将打印“ Selected Row”

  2. If I click the same row from observation #1, the console prints "Selected Row" only 如果我从观察#1中单击同一行,则控制台仅输出“选定行”

  3. If I click on any other row, the console prints "Deselected Row" and then "Selected Row" 如果我单击任何其他行,则控制台将打印“ Deselected Row”,然后打印“ Selected Row”

  4. If I click on the same row as observation #3, the console prints "Selected Row" only. 如果单击与观察#3相同的行,则控制台仅打印“选定的行”。

So, it looks like everytime I click on a different row, tableView: didDeselectRowAt: gets called; 因此,看起来就像每次我单击不同的行时,tableView:didDeselectRowAt:被调用; however, checkmarks in the clicked row do not go away. 但是,单击的行中的复选标记不会消失。

More Info 2: 更多信息2:

So I'm new to storyboards and didn't set the "allowsMultipleSelection" property. 因此,我是情节提要的新手,并且未设置“ allowsMultipleSelection”属性。 Going into the Attributes Inspector, this is what my settings look like: 进入“属性”检查器,这是我的设置:

在此处输入图片说明

Now, when pressing the same row in the tableView, my console confirms that the app is alternating between tableView:didSelectRowAt: and tableView:didDeselectRowAt:, however, the checkmark doesn't disappear; 现在,当在tableView中按同一行时,控制台将确认该应用程序在tableView:didSelectRowAt:和tableView:didDeselectRowAt:之间交替显示,但是,选中标记不会消失; once the user selects a row, the checkmark remains selected even when tableView:didDeselectRowAt: is called. 一旦用户选择了一行,即使调用tableView:didDeselectRowAt:,复选标记也保持选中状态。 What else am I missing? 我还想念什么?

First off make sure your datasource AND delegate outlets are set if you are setting them from storyboard. 首先,请确保从情节提要中设置了数据源和代理出口。

在此处输入图片说明

Another thing is you need to set allowsMultipleSelection property to true to get the didSelect , didDeselect methods to get called in the behavior you want. 另一件事是,您需要将allowsMultipleSelection属性设置为true,以在需要的行为中获取didSelectdidDeselect方法。 Otherwise it will always call didSelect for the cell you tapped on and didDeselect for the most previously selected cell. 否则,它将始终为您点击的单元didDeselectdidSelect ,并为之前didDeselect选择的单元didDeselect

The other thing to note is that you are referencing self.tableView when setting your cell.accessoryType property. 还要注意的另一件事是,在设置cell.accessoryType属性时引用的是self.tableView This may be different instance of the tableView being passed into the delegate method. 这可能是将tableView的不同实例传递到委托方法中的情况。 I recommend a guard let statment to ensure the code setting the accessory type only applies if the tableView being passed into the function. 我建议使用guard let语句,以确保仅在将tableView传递到函数中时设置附件类型的代码才适用。 Here is code I used to get it to work. 这是我用来使其工作的代码。

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    //Notice I use tableView being passed into func instead of self.tableView
    guard let cell = tableView.cellForRow(at: indexPath) else {
        return
    }
    cell.accessoryType = .checkmark

}

func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
    guard let cell = tableView.cellForRow(at: indexPath) else {
        return
    }
    cell.accessoryType = .none
}

如果希望用户能够选择多个单元格,则需要在viewDidLoad方法中设置tableView.allowsMultipleSelection = true或在属性检查器中设置多个选择。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM