UITableView排序-我在做什么错了?

时间:2019-11-03 20:13:23

标签: ios swift uitableview sorting

我会尽量简洁。我正在开发一个利用联系人的应用程序。它允许创建联系人组,并使用Core Data允许对这些组进行操作。我编写了一个重新排列联系人列表的功能,以便将选定的联系人置于列表的顶部。这对于联系人列表特别多的人很有用。

您可能已经猜到此应用程序用作UITableView。我已经设法解决了该问题,因此无论用户何时选择联系人,取消选择联系人,搜索联系人或联系人组,表格视图都将重新排序。他们全都返回选中的联系人列表的顶部。

这是通过使用包含联系信息的结构数组来完成的,然后对数组进行排序并重新加载数据。具体是基于isSelected进行排序,然后根据lastName重新排序。

编辑功能是我唯一无法获取联系人列表进行正确排序和显示的区域。编辑功能是可切换的。用户选择一个组,打开编辑,然后选择或取消选择要包括的联系人。将自动选择该组的所有联系人,并从Core Data变量中添加或删除所有联系人。但是,它们都保留在列表中各自的位置,并且不会自动移到顶部。 (因为排序链接到选定和取消选定的功能,所以如果用户点击它们,它们的确会得到排序,但这是唯一的方法。)

我试图将我的重新排列函数链接到cellForRowAt函数中的编辑代码,以及通过viewDidLoad。两种方法都无法正常工作,大多数情况下,该列表为空,因为它陷入了无休止的重新加载数据的循环中。当我通过提供一个use变量来确定列表是否已排序来解决该问题时,它将运行,但随后没有任何排序。我觉得我已经尽力了。我将尝试提供什么代码。感谢任何出于任何原因做出回应的人。

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
    //let cell = tableView.dequeueReusableCell(withIdentifier: TVC_Identifier, for: indexPath) as! REDACTED_TVCCell
    let cell = REDACTED_TVCCell(style: .subtitle, reuseIdentifier: TVC_Identifier)
    cell.backgroundColor = .white
    cell.textLabel?.textColor = .black
    cell.detailTextLabel?.textColor = .lightGray

    //CELL CONTENT
    switch indexPath.section
    {
    case 0:
    cell.name = dataForREDACTED[indexPath.row].name
        switch mode
        {
        case true:
           if cell.name == REDACTEDtoBeEdited.name
            {
                tableView.selectRow(at: indexPath, animated: true, scrollPosition: UITableView.ScrollPosition.none)
                cell.isSelected = true
            }
        case false:
            print("")
        }

    case 1:
    cell.textLabel?.text = data[indexPath.row].nameLabel
    cell.detailTextLabel?.text = data[indexPath.row].phoneNumber
    data[indexPath.row].myIndex = indexPath

        switch mode
        {
        case true:
            let numbers = REDACTEDToBeEdited.numbers as! Array<String>

            for number in numbers
            {
                if data[indexPath.row].phoneNumber == number
                {
                    if data[indexPath.row].isSelected == false
                    {
                        tableView.selectRow(at: indexPath, animated: true, scrollPosition: UITableView.ScrollPosition.none)
                        cell.isSelected = true
                        tableView.moveRow(at: indexPath, to: IndexPath(row: 0, section: 1))
                        data[indexPath.row].isSelected = true
                        numOfContactsSelected += 1
                    }
                }
            }

        case false:
            switch data[indexPath.row].isSelected
            {
            case true:
                tableView.selectRow(at: indexPath, animated: true, scrollPosition: UITableView.ScrollPosition.none)
                cell.isSelected = true

            case false:
                tableView.deselectRow(at: indexPath, animated: true)
                cell.isSelected = false
            }
        }

    default:
        print("")
    }

    if selectAllButtonPressed == true
    {
        allContacts()
    }

    let selectedIndexPaths = tableView.indexPathsForSelectedRows
    let rowIsSelected = selectedIndexPaths != nil && selectedIndexPaths!.contains(indexPath)
    cell.accessoryType = rowIsSelected ? .checkmark : .none

    selectSections()

    return cell
}

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
{
    print("didSelect Called")
    let cell = tableView.cellForRow(at: indexPath)!
    cell.accessoryType = .checkmark

    //OVERRIDE SELECTION HIGHLIGHT COLOR -> BECAUSE STORYBOARDS ARE STUPID
    let selectedColor = UIView(frame: tableView.rectForRow(at: indexPath))
    selectedColor.backgroundColor = .systemBlue
    cell.selectedBackgroundView = selectedColor
    cell.textLabel!.textColor = .white

    switch indexPath.section
    {
    case 0:
        numOfREDACTEDSelected += 1

        printVariable(variable: numOfREDACTEDSelected, description: "numOfREDACTEDSelected")

    case 1:
        numOfContactsSelected += 1
        printVariable(variable: numOfContactsSelected, description: "numOfContactsSelected")
        switch mode
        {
        case true:
            let searchNumber = data[indexPath.row].phoneNumber
            var searchArray = REDACTEDToBeEdited.numbers as! Array<String>

            if !searchArray.contains(searchNumber)
            {
                print("Adding: \(searchNumber)")
                searchArray.append(searchNumber)
                REDACTEDToBeEdited.numbers = searchArray as NSObject
                PersistenceService.saveContext()
            }

        case false:
            print("")

        }

        data[indexPath.row].isSelected = !data[indexPath.row].isSelected
        rearrangeContacts(order: 1)

    default:
        print("sectionsSelected: \(sectionSelected)")
    }

    selectSections()

}

override func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath)
{
    print("didDeselect Called!")
    let cell = tableView.cellForRow(at: indexPath)!
    cell.accessoryType = .none
    cell.backgroundColor = .white

    switch indexPath.section
    {
    case 0:
        switch mode
        {
        case true:
            tableView.selectRow(at: indexPath, animated: true, scrollPosition: UITableView.ScrollPosition.none)
            self.clearsSelectionOnViewWillAppear = false
            presentErrorMessage(Title: "Exit Edit Mode!", Message: "You must toggle edit mode off before you can deselect a REDACTED!")

        case false:
            numOfREDACTEDSelected -= 1
            printVariable(variable: numOfREDACTEDSelected, description: "numOfREDACTEDSelected")
        }

    case 1:
        numOfContactsSelected -= 1

        if numOfContactsSelected < 0
        {
            print("numOfContactsSelected < 0 resetting to 0.")
            numOfContactsSelected = 0
        }

        printVariable(variable: numOfContactsSelected, description: "numOfContactsSelected")

        switch mode
        {
        case true:
            let searchNumber = data[indexPath.row].phoneNumber
            var searchArray = REDACTEDToBeEdited.numbers as! Array<String>

            if searchArray.contains(searchNumber)
            {
                print("Removing: \(searchNumber)")
                searchArray.remove(at: searchArray.firstIndex(of: searchNumber)!)
                REDACTEDToBeEdited.numbers = searchArray as NSObject
                PersistenceService.saveContext()
            }

        case false:
            print("View Mode is Active")
        }

        data[indexPath.row].isSelected = !data[indexPath.row].isSelected
        printVariable(variable: data[indexPath.row].isSelected, description: "\(data[indexPath.row].firstName) isSelected:")
        rearrangeContacts(order: 2)

    default:
        print("sectionsSelected: \(sectionSelected)")
    }

    selectSections()
    if sectionSelected == [false, false]
    {
        print("Resetting original data structure...")
        self.data = originalDataStruct
    }
}

func rearrangeContacts(order: Int)
{
    switch order
    {
    case 1:
        print("Sorting according to isSelected")
        data.sort { $0.isSelected && !$1.isSelected }
        self.clearsSelectionOnViewWillAppear = false
        tableView.reloadData()

    case 2:
        print("Sorting according to lastName & isSelected")
        data.sort { $0.lastName < $1.lastName }
        data.sort { $0.isSelected && !$1.isSelected }
        tableView.reloadData()

    default:
        print("")
    }
}

让我知道是否需要提供更多上下文,但是我认为所需的一切都在上述代码中。再次感谢所有可以帮助我弄清楚我做错了什么的人。

TLDR 当按下编辑键时,应将选定的联系人移至联系人列表的顶部。目前,它们保持原始索引。通常在某些事件(例如,选择或取消选择(未编辑时))期间,使用.sort()来重新安排联系人的功能。

0 个答案:

没有答案