SetupTableViewController.swift 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. //
  2. // SetupTableViewController.swift
  3. // Loop
  4. //
  5. // Copyright © 2018 LoopKit Authors. All rights reserved.
  6. //
  7. import UIKit
  8. public protocol SetupTableViewControllerDelegate: AnyObject {
  9. func setupTableViewControllerCancelButtonPressed(_ viewController: SetupTableViewController)
  10. }
  11. open class SetupTableViewController: UITableViewController {
  12. private(set) open lazy var footerView = SetupTableFooterView(frame: .zero)
  13. private var lastContentHeight: CGFloat = 0
  14. public var padFooterToBottom: Bool = true
  15. public weak var delegate: SetupTableViewControllerDelegate?
  16. open override func viewDidLoad() {
  17. super.viewDidLoad()
  18. navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .cancel, target: self, action: #selector(cancelButtonPressed(_:)))
  19. footerView.primaryButton.addTarget(self, action: #selector(continueButtonPressed(_:)), for: .touchUpInside)
  20. }
  21. open override func viewDidLayoutSubviews() {
  22. super.viewDidLayoutSubviews()
  23. // Reposition footer view if necessary
  24. if tableView.contentSize.height != lastContentHeight {
  25. lastContentHeight = tableView.contentSize.height
  26. tableView.tableFooterView = nil
  27. var footerSize = footerView.systemLayoutSizeFitting(CGSize(width: tableView.frame.size.width, height: UIView.layoutFittingCompressedSize.height))
  28. let visibleHeight = tableView.bounds.size.height - (tableView.adjustedContentInset.top + tableView.adjustedContentInset.bottom)
  29. let footerHeight = padFooterToBottom ? max(footerSize.height, visibleHeight - tableView.contentSize.height) : footerSize.height
  30. footerSize.height = footerHeight
  31. footerView.frame.size = footerSize
  32. tableView.tableFooterView = footerView
  33. }
  34. }
  35. @IBAction open func cancelButtonPressed(_: Any) {
  36. delegate?.setupTableViewControllerCancelButtonPressed(self)
  37. }
  38. @IBAction open func continueButtonPressed(_ sender: Any) {
  39. if shouldPerformSegue(withIdentifier: "Continue", sender: sender) {
  40. performSegue(withIdentifier: "Continue", sender: sender)
  41. }
  42. }
  43. // MARK: - UITableViewDelegate
  44. open override func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
  45. return UITableView.automaticDimension
  46. }
  47. open override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
  48. return UITableView.automaticDimension
  49. }
  50. open override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
  51. return UITableView.automaticDimension
  52. }
  53. }
  54. open class SetupTableFooterView: UIView {
  55. public let primaryButton = SetupButton(type: .custom)
  56. public override init(frame: CGRect) {
  57. let buttonStack = UIStackView(arrangedSubviews: [primaryButton])
  58. super.init(frame: frame)
  59. autoresizingMask = [.flexibleWidth]
  60. primaryButton.resetTitle()
  61. buttonStack.alignment = .center
  62. buttonStack.axis = .vertical
  63. buttonStack.distribution = .fillEqually
  64. buttonStack.translatesAutoresizingMaskIntoConstraints = false
  65. addSubview(buttonStack)
  66. NSLayoutConstraint.activate([
  67. primaryButton.leadingAnchor.constraint(equalTo: buttonStack.leadingAnchor),
  68. primaryButton.trailingAnchor.constraint(equalTo: buttonStack.trailingAnchor),
  69. buttonStack.topAnchor.constraint(greaterThanOrEqualTo: layoutMarginsGuide.topAnchor),
  70. buttonStack.leadingAnchor.constraint(equalToSystemSpacingAfter: layoutMarginsGuide.leadingAnchor, multiplier: 1),
  71. layoutMarginsGuide.trailingAnchor.constraint(equalToSystemSpacingAfter: buttonStack.trailingAnchor, multiplier: 1),
  72. safeAreaLayoutGuide.bottomAnchor.constraint(equalToSystemSpacingBelow: buttonStack.bottomAnchor, multiplier: 2),
  73. ])
  74. }
  75. public required init?(coder aDecoder: NSCoder) {
  76. fatalError("init(coder:) has not been implemented")
  77. }
  78. }
  79. public extension SetupButton {
  80. func resetTitle() {
  81. setTitle(LocalizedString("Continue", comment: "Title of the setup button to continue"), for: .normal)
  82. }
  83. }