我会尽量简洁。我正在开发一个利用联系人的应用程序。它允许创建联系人组,并使用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()来重新安排联系人的功能。