Skip to content

Instantly share code, notes, and snippets.

@skagedal
Last active March 7, 2017 22:18
Show Gist options
  • Save skagedal/45d11b0268c105c8ebbdbc9805d602a4 to your computer and use it in GitHub Desktop.
Save skagedal/45d11b0268c105c8ebbdbc9805d602a4 to your computer and use it in GitHub Desktop.
// Demo for SO question:
//
// http://stackoverflow.com/questions/42659251/can-a-table-view-row-stay-put-while-its-section-is-moving
import UIKit
enum State: Int {
case first
case second
}
class TableViewController: UITableViewController {
var state: State = .first
override func viewDidLoad() {
super.viewDidLoad()
tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell")
update()
}
// Hook up to a bar button item for testing
@IBAction func cycle(_ sender: Any) {
if let new = State(rawValue: state.rawValue + 1) {
state = new
} else {
state = .first
}
update()
}
var sections: [(String, [String])] = []
func update() {
tableView.beginUpdates()
// Pick on of these:
switchItems()
// switchSections()
// switchBothNoOp()
// switchBothCrash()
tableView.endUpdates()
}
func switchItems() {
switch state {
case .first:
sections = [("Fruits", ["Banana"]),
("Vegetables", ["Carrot"])]
case .second:
sections = [("Fruits", ["Carrot"]),
("Vegetables", ["Banana"])]
}
tableView.moveRow(at: [0, 0], to: [1, 0])
tableView.moveRow(at: [1, 0], to: [0, 0])
}
func switchSections() {
switch state {
case .first:
sections = [("Fruits", ["Banana"]),
("Vegetables", ["Carrot"])]
case .second:
sections = [("Vegetables", ["Carrot"]),
("Fruits", ["Banana"])]
}
tableView.moveSection(0, toSection: 1)
}
func switchBothNoOp() {
switch state {
case .first:
sections = [("Fruits", ["Banana"]),
("Vegetables", ["Carrot"])]
case .second:
sections = [("Vegetables", ["Banana"]),
("Fruits", ["Carrot"])]
}
tableView.moveSection(0, toSection: 1)
tableView.moveSection(1, toSection: 0)
tableView.moveRow(at: [0, 0], to: [0, 0])
tableView.moveRow(at: [1, 0], to: [1, 0])
}
func switchBothCrash() {
switch state {
case .first:
sections = [("Fruits", ["Banana"]),
("Vegetables", ["Carrot"])]
case .second:
sections = [("Vegetables", ["Banana"]),
("Fruits", ["Carrot"])]
}
tableView.moveSection(0, toSection: 1)
tableView.moveSection(1, toSection: 0)
tableView.deleteRows(at: [[0, 0], [1, 0]], with: .fade)
tableView.insertRows(at: [[0, 0], [1, 0]], with: .fade)
}
// MARK: Data source
override func numberOfSections(in tableView: UITableView) -> Int {
return sections.count
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return sections[section].1.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
cell.textLabel?.text = sections[indexPath.section].1[indexPath.row]
return cell
}
override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return sections[section].0
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment