Я постараюсь быть как можно более кратким. Я разрабатываю приложение, которое использует контакты. Он позволяет создавать группы контактов, а также использует базовые данные для управления этими группами. Я написал функцию для перестановки списка контактов, чтобы вывести выбранные контакты в верхнюю часть списка. Это полезно для людей с особенно большим списком контактов.
Это приложение использует 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 (), контакты во время определенных событий, таких как выбор или отмена выбора (если не редактирование).