diff --git a/iOS/Base.lproj/Main.storyboard b/iOS/Base.lproj/Main.storyboard index 8f94d6cd9..85522696f 100644 --- a/iOS/Base.lproj/Main.storyboard +++ b/iOS/Base.lproj/Main.storyboard @@ -171,13 +171,13 @@ - + - + - + diff --git a/iOS/Master/Cell/MasterTableViewSectionHeader.swift b/iOS/Master/Cell/MasterTableViewSectionHeader.swift index ed3d6ae94..08b4c597c 100644 --- a/iOS/Master/Cell/MasterTableViewSectionHeader.swift +++ b/iOS/Master/Cell/MasterTableViewSectionHeader.swift @@ -48,6 +48,12 @@ class MasterTableViewSectionHeader: UITableViewHeaderFooterView { } } + var disclosureExpanded = false { + didSet { + updateDisclosureImage() + } + } + private let titleView: UILabel = { let label = UILabel() label.font = UIFont.boldSystemFont(ofSize: 17.0) @@ -58,7 +64,12 @@ class MasterTableViewSectionHeader: UITableViewHeaderFooterView { }() private let unreadCountView = MasterUnreadCountView(frame: CGRect.zero) - + private var disclosureView: UIImageView = { + let iView = UIImageView() + iView.contentMode = .center + return iView + }() + override init(reuseIdentifier: String?) { super.init(reuseIdentifier: reuseIdentifier) commonInit() @@ -71,10 +82,11 @@ class MasterTableViewSectionHeader: UITableViewHeaderFooterView { override func layoutSubviews() { super.layoutSubviews() - let layout = MasterTableViewCellLayout(cellSize: bounds.size, insets: safeAreaInsets, shouldShowImage: false, label: titleView, unreadCountView: unreadCountView, showingEditingControl: false, indent: true, shouldShowDisclosure: false) + let layout = MasterTableViewCellLayout(cellSize: bounds.size, insets: safeAreaInsets, shouldShowImage: false, label: titleView, unreadCountView: unreadCountView, showingEditingControl: false, indent: true, shouldShowDisclosure: true) layoutWith(layout) } + } private extension MasterTableViewSectionHeader { @@ -85,8 +97,18 @@ private extension MasterTableViewSectionHeader { backgroundView = view addSubviewAtInit(unreadCountView) addSubviewAtInit(titleView) + updateDisclosureImage() + addSubviewAtInit(disclosureView) } + func updateDisclosureImage() { + if disclosureExpanded { + disclosureView.image = AppAssets.chevronDownImage + } else { + disclosureView.image = AppAssets.chevronRightImage + } + } + func addSubviewAtInit(_ view: UIView) { addSubview(view) view.translatesAutoresizingMaskIntoConstraints = false @@ -95,6 +117,7 @@ private extension MasterTableViewSectionHeader { func layoutWith(_ layout: MasterTableViewCellLayout) { titleView.setFrameIfNotEqual(layout.titleRect) unreadCountView.setFrameIfNotEqual(layout.unreadCountRect) + disclosureView.setFrameIfNotEqual(layout.disclosureButtonRect) } } diff --git a/iOS/Master/MasterViewController.swift b/iOS/Master/MasterViewController.swift index 3be9e183f..92e088c9f 100644 --- a/iOS/Master/MasterViewController.swift +++ b/iOS/Master/MasterViewController.swift @@ -173,6 +173,10 @@ class MasterViewController: UITableViewController, UndoableCommandRunner { return shadowTable[section].count } + override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat { + return CGFloat(integerLiteral: 44) + } + override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? { guard let nameProvider = treeController.rootNode.childAtIndex(section)?.representedObject as? DisplayNameProvider else { @@ -182,20 +186,33 @@ class MasterViewController: UITableViewController, UndoableCommandRunner { let headerView = tableView.dequeueReusableHeaderFooterView(withIdentifier: "SectionHeader") as! MasterTableViewSectionHeader headerView.name = nameProvider.nameForDisplay - if let account = treeController.rootNode.childAtIndex(section)?.representedObject as? Account { + guard let sectionNode = treeController.rootNode.childAtIndex(section) else { + return headerView + } + + if let account = sectionNode.representedObject as? Account { headerView.unreadCount = account.unreadCount } else { headerView.unreadCount = 0 } headerView.tag = section - + headerView.disclosureExpanded = expandedNodes.contains(sectionNode) + let tap = UITapGestureRecognizer(target: self, action:#selector(self.toggleSectionHeader(_:))) headerView.addGestureRecognizer(tap) return headerView } + + override func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat { + return CGFloat.leastNormalMagnitude + } + + override func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? { + return UIView(frame: CGRect.zero) + } override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { @@ -469,14 +486,17 @@ class MasterViewController: UITableViewController, UndoableCommandRunner { @objc func toggleSectionHeader(_ sender: UITapGestureRecognizer) { guard let sectionIndex = sender.view?.tag, - let sectionNode = treeController.rootNode.childAtIndex(sectionIndex) + let sectionNode = treeController.rootNode.childAtIndex(sectionIndex), + let headerView = sender.view as? MasterTableViewSectionHeader else { return } if expandedNodes.contains(sectionNode) { + headerView.disclosureExpanded = false collapse(section: sectionIndex) } else { + headerView.disclosureExpanded = true expand(section: sectionIndex) } @@ -788,6 +808,7 @@ private extension MasterViewController { guard let collapseNode = treeController.rootNode.childAtIndex(section) else { return } + if let removeNode = expandedNodes.firstIndex(of: collapseNode) { expandedNodes.remove(at: removeNode) } @@ -803,6 +824,7 @@ private extension MasterViewController { tableView.endUpdates() animatingChanges = false + } func collapse(_ cell: MasterTableViewCell) {