UITableView Сортировка - Что я делаю не так? - PullRequest
0 голосов
/ 03 ноября 2019

Я постараюсь быть как можно более кратким. Я разрабатываю приложение, которое использует контакты. Он позволяет создавать группы контактов, а также использует базовые данные для управления этими группами. Я написал функцию для перестановки списка контактов, чтобы вывести выбранные контакты в верхнюю часть списка. Это полезно для людей с особенно большим списком контактов.

Это приложение использует UITableView, как вы уже догадались. Мне удалось исправить это так, что представление таблицы переупорядочивается всякий раз, когда пользователь выбирает контакт, отменяет выбор контакта, ищет контакт или группу контактов. Все они возвращают выбранные в начало списка контактов.

Это делается с использованием массива структур, которые содержат контактную информацию, а затем просто сортирует массив и перезагружает данные. В частности, сортировка на основе isSelected, а затем повторная сортировка на основе lastName.

Функция редактирования - единственная область, в которой мне не удалось получить список контактов для сортировки и отображения должным образом. Функция редактирования может переключаться. Пользователь выбирает группу, включает редактирование и затем выбирает или отменяет выбор контактов, которые будут включены. Все контакты для группы выбираются автоматически, и все они добавляются или удаляются из переменных базовых данных. Однако все они остаются на своих местах в списке и не перемещаются наверх автоматически. (Поскольку сортировка связана с выбранными и отмененными функциями, они сортируются, если пользователь нажимает на них, но это единственный способ.)

Я пытался связать свою функцию перестановки с кодом редактирования в функции cellForRowAtа также через viewDidLoad. Ни один из них не работал правильно, большую часть времени список становится пустым, потому что он попадает в бесконечный цикл перезагрузки данных. Когда я решил это, предоставив единственную переменную использования, чтобы определить, отсортирован ли список, он запускается, но тогда ничего не сортируется. Я чувствую, что перепробовал все, что мог, на данный момент. Я постараюсь предоставить, какой код я могу. Спасибо всем, кто отвечает по любой причине.

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 (), контакты во время определенных событий, таких как выбор или отмена выбора (если не редактирование).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...