title: UITableView Sorting - What am I doing wrong?
body: <p>I'll try to be as succinct as I can. I'm developing an app which utilizes contacts. It allows for the creation of groups of contacts as well as uses Core Data to allow for the manipulation of those groups. I've written a function to rearrange the contact list in order to bring selected contacts to the top of the list. This is useful for those with particularly large list of contacts.</p>
  
  <p>This app utilizes as UITableView as you may have guessed. I've managed to fix it so the tableview is reordered whenever the user selects a contact, deselects a contact, searches for a contact or group of contacts. They all return selected to the top of the contacts list.</p>
  
  <p>This is done using an array of structs which hold contact informations and then just sorting the array and reloading the data. Specifically sorting based on isSelected and then re-sorting based on the lastName.</p>
  
  <p>The edit feature is the only area I have not been able to get the contact list to sort and display properly. The edit feature is toggle-able. The user selects a group, toggles edit on and then selects or deselects the contacts to be included. All contacts for the group are automatically selected and all are either added or removed from Core Data variables. However, they all remain in their respective locations in the list and are not moved to the top automatically. (Because sort is linked to selected and deselected functions they do get sorted if a user taps them, but that is the only way.)</p>
  
  <p>I've tried to link my rearrange function to the edit code within cellForRowAt function as well as through viewDidLoad. Neither worked correctly, most of the time the list goes blank because it gets caught in an endless loop of reloading the data. When I solved that by providing a single use variable to determine if the list is sorted it runs, but then nothing is sorted. I feel like I've tried everything I can at this point. I'll try to provide what code I can. Thank you to anyone who responds for any reason.</p>
  
  <pre><code>func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -&gt; 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&lt;String&gt;
  
              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 &amp;&amp; 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 -&gt; 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&lt;String&gt;
  
              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 &lt; 0
          {
              print("numOfContactsSelected &lt; 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&lt;String&gt;
  
              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 &amp;&amp; !$1.isSelected }
          self.clearsSelectionOnViewWillAppear = false
          tableView.reloadData()
  
      case 2:
          print("Sorting according to lastName &amp; isSelected")
          data.sort { $0.lastName &lt; $1.lastName }
          data.sort { $0.isSelected &amp;&amp; !$1.isSelected }
          tableView.reloadData()
  
      default:
          print("")
      }
  }
  </code></pre>
  
  <p>Let me know if I need to provide more context, but I think everything needed is in the above code. Again, thanks to anyone who can help me figure out what I'm doing wrong.</p>
  
  <p><strong>TLDR</strong> Selected contacts should be moved to top of the contact list when edit is pressed. Currently they remain at their original index. Generally use a function to rearrange, which utilizes .sort(), contacts during certain events like selecting or deselecting (when not editing).</p>