Created
November 30, 2020 01:16
-
-
Save christianselig/0d1c14834adfdf916cf7fc5a5aeefd5c to your computer and use it in GitHub Desktop.
I want to add a new cell to the top of the table view without causing the current position to be pushed down. Note that I'm also not removing the cell I would like to add to the top, but rather just also adding it to the top.
This file contains hidden or 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
import UIKit | |
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate { | |
let tableView = UITableView(frame: CGRect.zero, style: .plain) | |
var totalAdded = 0 | |
override func viewDidLoad() { | |
super.viewDidLoad() | |
tableView.translatesAutoresizingMaskIntoConstraints = false | |
tableView.register(UITableViewCell.self, forCellReuseIdentifier: "MyCell") | |
tableView.dataSource = self | |
tableView.delegate = self | |
view.addSubview(tableView) | |
view.addConstraint(NSLayoutConstraint(item: tableView, attribute: .top, relatedBy: .equal, toItem: view, attribute: .top, multiplier: 1.0, constant: 0.0)) | |
view.addConstraint(NSLayoutConstraint(item: tableView, attribute: .bottom, relatedBy: .equal, toItem: view, attribute: .bottom, multiplier: 1.0, constant: 0.0)) | |
view.addConstraint(NSLayoutConstraint(item: tableView, attribute: .left, relatedBy: .equal, toItem: view, attribute: .left, multiplier: 1.0, constant: 0.0)) | |
view.addConstraint(NSLayoutConstraint(item: tableView, attribute: .right, relatedBy: .equal, toItem: view, attribute: .right, multiplier: 1.0, constant: 0.0)) | |
} | |
func numberOfSections(in tableView: UITableView) -> Int { | |
return UILocalizedIndexedCollation.current().sectionTitles.count + 1 | |
} | |
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { | |
return section == 0 ? totalAdded : 8 | |
} | |
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { | |
let cell = tableView.dequeueReusableCell(withIdentifier: "MyCell", for: indexPath) | |
cell.textLabel?.text = "Oranges \(indexPath.row)" | |
cell.accessoryView = createStarAccessoryButton() | |
return cell | |
} | |
func sectionIndexTitles(for tableView: UITableView) -> [String]? { | |
return ["*"] + UILocalizedIndexedCollation.current().sectionTitles | |
} | |
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? { | |
return section == 0 ? "Favorites" : UILocalizedIndexedCollation.current().sectionTitles[section - 1] | |
} | |
func createStarAccessoryButton() -> UIButton { | |
let button = UIButton(type: .system) | |
button.tintColor = .lightGray | |
button.setImage(UIImage(systemName: "star.fill")!, for: .normal) | |
button.sizeToFit() | |
button.addTarget(self, action: #selector(starButtonTapped(sender:)), for: .touchUpInside) | |
return button | |
} | |
@objc func starButtonTapped(sender: UIButton) { | |
let buttonPosition = sender.convert(CGPoint.zero, to: tableView) | |
guard let indexPath = tableView.indexPathForRow(at: buttonPosition) else { return } | |
let height = tableView.cellForRow(at: indexPath)!.bounds.height | |
let oldContentOffset = tableView.contentOffset.y | |
totalAdded += 1 | |
tableView.reloadData() | |
// The ol' "dispatch ahead one run loop iteration" sorta works most of the time :/ | |
DispatchQueue.main.async { | |
self.tableView.contentOffset.y = oldContentOffset + height | |
} | |
} | |
} |
Oh gosh I didn't realize how much I butchered the indentation in the main gist. I'm so sorry!
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Solution per Nathan Lawrence, don't use reloadData just use the cell insert methods! Doh!