Last active
March 7, 2017 22:18
-
-
Save skagedal/45d11b0268c105c8ebbdbc9805d602a4 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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