|
| 1 | + |
| 2 | +import UIKit |
| 3 | + |
| 4 | +// move everything into the data source object! |
| 5 | + |
| 6 | +class MyDataSource: UITableViewDiffableDataSource<String, String> { |
| 7 | + let cellID = "Cell" |
| 8 | + let headerID = "Header" |
| 9 | + init(tableView: UITableView) { |
| 10 | + // table view configuration |
| 11 | + tableView.register(UITableViewCell.self, forCellReuseIdentifier: self.cellID) |
| 12 | + tableView.register(UITableViewHeaderFooterView.self, forHeaderFooterViewReuseIdentifier: self.headerID) |
| 13 | + tableView.sectionIndexColor = .white |
| 14 | + tableView.sectionIndexBackgroundColor = .red |
| 15 | + tableView.sectionIndexTrackingBackgroundColor = .blue |
| 16 | + let cellID = self.cellID |
| 17 | + super.init(tableView: tableView) { tv,ip,s in |
| 18 | + let cell = tv.dequeueReusableCell(withIdentifier: cellID, for: ip) |
| 19 | + cell.textLabel!.text = s |
| 20 | + |
| 21 | + var stateName = s |
| 22 | + stateName = stateName.lowercased() |
| 23 | + stateName = stateName.replacingOccurrences(of: " ", with:"") |
| 24 | + stateName = "flag_\(stateName).gif" |
| 25 | + let im = UIImage(named: stateName) |
| 26 | + cell.imageView!.image = im |
| 27 | + |
| 28 | + return cell |
| 29 | + } |
| 30 | + self.populate() |
| 31 | + } |
| 32 | + private func populate() { |
| 33 | + let s = try! String( |
| 34 | + contentsOfFile: Bundle.main.path( |
| 35 | + forResource: "states", ofType: "txt")!) |
| 36 | + let states = s.components(separatedBy:"\n") |
| 37 | + let d = Dictionary(grouping: states) {String($0.prefix(1))} |
| 38 | + let sections = Array(d).sorted{$0.key < $1.key} // * |
| 39 | + |
| 40 | + var snap = NSDiffableDataSourceSnapshot<String,String>() |
| 41 | + for section in sections { |
| 42 | + snap.appendSections([section.0]) |
| 43 | + snap.appendItems(section.1) |
| 44 | + } |
| 45 | + self.apply(snap, animatingDifferences: false) |
| 46 | + } |
| 47 | + override func sectionIndexTitles(for tableView: UITableView) -> [String]? { |
| 48 | + return self.snapshot().sectionIdentifiers |
| 49 | + } |
| 50 | + override func tableView(_ tableView: UITableView, sectionForSectionIndexTitle title: String, at index: Int) -> Int { |
| 51 | + return self.snapshot().sectionIdentifiers.firstIndex(of: title) ?? 0 |
| 52 | + } |
| 53 | +} |
| 54 | +extension MyDataSource : UITableViewDelegate { |
| 55 | + func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? { |
| 56 | + let h = tableView.dequeueReusableHeaderFooterView(withIdentifier: self.headerID)! |
| 57 | + h.tintColor = .red |
| 58 | + if h.viewWithTag(1) == nil { |
| 59 | + print("configuring a new header view") // only called about 8 times |
| 60 | + |
| 61 | + h.backgroundView = UIView() |
| 62 | + h.backgroundView?.backgroundColor = .black |
| 63 | + let lab = UILabel() |
| 64 | + lab.tag = 1 |
| 65 | + lab.font = UIFont(name:"Georgia-Bold", size:22) |
| 66 | + lab.textColor = .green |
| 67 | + lab.backgroundColor = .clear |
| 68 | + h.contentView.addSubview(lab) |
| 69 | + let v = UIImageView() |
| 70 | + v.tag = 2 |
| 71 | + v.backgroundColor = .black |
| 72 | + v.image = UIImage(named:"us_flag_small.gif") |
| 73 | + h.contentView.addSubview(v) |
| 74 | + lab.translatesAutoresizingMaskIntoConstraints = false |
| 75 | + v.translatesAutoresizingMaskIntoConstraints = false |
| 76 | + NSLayoutConstraint.activate([ |
| 77 | + NSLayoutConstraint.constraints(withVisualFormat:"H:|-5-[lab(25)]-10-[v(40)]", |
| 78 | + metrics:nil, views:["v":v, "lab":lab]), |
| 79 | + NSLayoutConstraint.constraints(withVisualFormat:"V:|[v]|", |
| 80 | + metrics:nil, views:["v":v]), |
| 81 | + NSLayoutConstraint.constraints(withVisualFormat:"V:|[lab]|", |
| 82 | + metrics:nil, views:["lab":lab]) |
| 83 | + ].flatMap{$0}) |
| 84 | + } |
| 85 | + let lab = h.contentView.viewWithTag(1) as! UILabel |
| 86 | + lab.text = self.snapshot().sectionIdentifiers[section] // * |
| 87 | + return h |
| 88 | + |
| 89 | + } |
| 90 | + |
| 91 | +} |
0 commit comments