【问题标题】:swift 3 - ViewController not deselecting selected rows in a UITableViewswift 3 - ViewController 没有取消选择 UITableView 中的选定行
【发布时间】:2017-02-28 21:34:16
【问题描述】:

我有一个表格视图,用户可以在其中选择多行(这些行由行中的复选框区分)。但是,由于某种原因,我无法实现取消选择任何选定行的功能。谁能告诉我我错过了什么?

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")
    }
}

更多信息: 查看插入的调试日志,我可以分享以下观察结果:

  1. 选择未选择的行时,控制台打印“选择行”

  2. 如果我单击观察 #1 中的同一行,控制台仅打印“选定行”

  3. 如果我点击任何其他行,控制台会打印“取消选定的行”,然后打印“选定的行”

  4. 如果我单击与观察 #3 相同的行,控制台将仅打印“选定行”。

所以,看起来每次我点击不同的行时,tableView: didDeselectRowAt: 都会被调用;但是,单击的行中的复选标记不会消失。

更多信息 2:

所以我是故事板的新手,没有设置“allowsMultipleSelection”属性。进入属性检查器,这就是我的设置:

现在,当按下 tableView 中的同一行时,我的控制台确认应用程序在 tableView:didSelectRowAt: 和 tableView:didDeselectRowAt: 之间交替,但是,复选标记并没有消失;一旦用户选择了一行,即使在调用 tableView:didDeselectRowAt: 时,复选标记仍保持选中状态。我还缺少什么?

【问题讨论】:

    标签: ios uitableview swift3


    【解决方案1】:

    首先,如果您从情节提要中设置数据源和委托出口,请确保已设置它们。

    另一件事是您需要将allowsMultipleSelection 属性设置为true 以获取didSelectdidDeselect 方法以在您想要的行为中调用。否则,它将始终为您点击的单元格调用didSelect,为先前选择的单元格调用didDeselect

    要注意的另一件事是,您在设置 cell.accessoryType 属性时引用了 self.tableView。这可能是传递给委托方法的 tableView 的不同实例。我建议使用guard let 语句,以确保设置附件类型的代码仅适用于tableView 被传递到函数中的情况。这是我用来让它工作的代码。

    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
    }
    

    【讨论】:

    • 我从 method1 测试了你的其余代码,它对我有用,所以我唯一能想到的是你的方法没有被调用。如果您没有设置委托,会发生这种情况。
    • 感谢您测试我的代码,NSGangster。检查我的数据源和委托出口,我可以确认它们是从情节提要中设置的。但是,我的“参考插座”不是(如您的屏幕截图所示),但我无法将其设置为 tableview(出于某种奇怪的原因,我只能将其设置为视图)。另外,我认为我的 UITable 委托方法正在被命中(我可以通过调试器确认),只是当我选择它们时,所选行的复选框被删除了。还有其他想法吗?
    • 您在数据源和委托方法之外的 viewController 类中根本不使用 tableView 吗?您在其他地方是否有更多代码正在创建另一个 tableView?听起来您默认情况下在单元格上启用了复选标记?
    • 刚刚用更多观察更新了这个问题。不,默认情况下未在单元格上启用复选标记。此 tableview 是此视图控制器中唯一的 tableView。
    • 我觉得“allowsMultipleSelection”属性没有设置为true。但我假设你是通过故事板设置的?
    【解决方案2】:

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

    【讨论】:

    • 感谢 Andrey - 我最终在属性检查器中设置了 allowMultipleSelection 属性。现在,日志确认在调用 tableView:didSelectRowAt: 和 tableView:didDeselectRowAt: 之间交替按下相同的按钮,但是,当调用 tableView:didDeselectRowAt 时,复选标记不会消失。我还缺少什么?
    猜你喜欢
    • 2021-08-28
    • 2017-03-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-27
    • 2017-12-01
    • 1970-01-01
    • 2015-05-19
    相关资源
    最近更新 更多