Guest User

Untitled

a guest
Apr 25th, 2018
73
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.78 KB | None | 0 0
  1. import UIKit
  2. import BetterSegmentedControl
  3.  
  4. // MARK: - SearchViewController -
  5.  
  6. final class SearchViewController: BBViewController, CollectionSource, UITextFieldDelegate {
  7.  
  8. // MARK: - Types definitions
  9.  
  10. private enum Filter {
  11. case all, movies, tvShows
  12.  
  13. static let filters: [Filter] = [.all, .movies, .tvShows]
  14. static var names: [String] { return filters.map { $0.title.uppercased() } }
  15.  
  16. var title: String {
  17. switch self {
  18. case .all: return R.string.localizable.filterAll()
  19. case .movies: return R.string.localizable.filterMovies()
  20. case .tvShows: return R.string.localizable.filterTvShows()
  21. }
  22. }
  23. }
  24.  
  25. // MARK: - Properties
  26.  
  27. private var query = ""
  28. private var filter: Filter = .all
  29. private var products: [BlockbusterProduct] = []
  30. private var filteredProducts: [BlockbusterProduct] {
  31. switch filter {
  32. case .all: return products
  33. case .movies: return products.filter { $0 is BlockbusterMovie }
  34. case .tvShows: return products.filter { $0 is BlockbusterSeries }
  35. }
  36. }
  37.  
  38. private let collectionView = UICollectionView.instantinate
  39. private let textField = UITextField()
  40. private let crossButton = UIButton()
  41. private let segmentedControl = BetterSegmentedControl(frame: .zero, titles: Filter.names)
  42. private let iconImageView = UIImageView()
  43. private let separator = UIView()
  44. private var headerTopConstraint: NSLayoutConstraint?
  45.  
  46. // MARK: - Static
  47.  
  48. static func instantinate(query: String) -> SearchViewController {
  49. let controller = SearchViewController()
  50. controller.query = query
  51. return controller
  52. }
  53.  
  54. // MARK: - Lifecycle
  55.  
  56. override func viewDidLoad() {
  57. super.viewDidLoad()
  58. setup()
  59. underConstruction()
  60. }
  61.  
  62. // MARK: - Search
  63.  
  64. func updateQuery(_ query: String, shouldPerformNetworking: Bool = true) {
  65. self.query = query
  66. textField.text = query
  67. if shouldPerformNetworking { search(self.query) }
  68. }
  69.  
  70. func search(_ query: String) {
  71.  
  72. }
  73.  
  74. @objc func filterChanged(_ filterControl: BetterSegmentedControl) {
  75. filter = Filter.filters[Int(filterControl.index)]
  76. collectionView.reloadData()
  77. }
  78.  
  79. @objc func clearSearch() {
  80. textField.text = ""
  81. }
  82.  
  83. private func updateUiOnFocus(_ isFocused: Bool) {
  84. let color = GUI.tintColor(isFocused: isFocused)
  85. separator.backgroundColor = color
  86. iconImageView.tintColor = color
  87. }
  88.  
  89. // MARK: - UICollectionViewDataSource
  90.  
  91. func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
  92. return filteredProducts.count
  93. }
  94.  
  95. func collectionView(_ collectionView: UICollectionView,
  96. cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
  97. let cell = collectionView.dequeueReusableCell(cellClass: ProductCVCell.self, for: indexPath)
  98. cell.configure(with: filteredProducts[indexPath.row])
  99. return cell
  100. }
  101.  
  102. // MARK: - UIScrollViewDelegate
  103.  
  104. func scrollViewDidScroll(_ scrollView: UIScrollView) {
  105. headerTopConstraint?.constant = -scrollView.yOffset
  106. }
  107.  
  108. // MARK: - UITextFieldDelegate
  109.  
  110. func textFieldShouldReturn(_ textField: UITextField) -> Bool {
  111. view.endEditing(true)
  112. return false
  113. }
  114.  
  115. func textFieldDidBeginEditing(_ textField: UITextField) {
  116. updateUiOnFocus(true)
  117. }
  118.  
  119. func textFieldDidEndEditing(_ textField: UITextField) {
  120. updateUiOnFocus(false)
  121. }
  122.  
  123. // MARK: - Configuration
  124.  
  125. // swiftlint:disable function_body_length
  126.  
  127. private func setup() {
  128. adjust {
  129. $0.title = GUI.title
  130. $0.view.backgroundColor = UIColor.bb_bg
  131. }
  132.  
  133. collectionView.addTo(view).adjust {
  134. $0.pinSV()
  135. $0.backgroundColor = .clear
  136. $0.alwaysBounceVertical = true
  137. $0.contentInset = UIEdgeInsets(top: GUI.headerHeight, left: 0, bottom: GUI.padding, right: 0)
  138. $0.registerNib(for: ProductCVCell.self)
  139. $0.dataSource = self
  140. $0.delegate = self
  141. }
  142.  
  143. let header = UIView().addTo(view).adjust {
  144. $0.pinL(view, GUI.headerMargin).pinR(view, -GUI.headerMargin).pinH(GUI.headerHeight)
  145. headerTopConstraint = $0.pinnedT(view)
  146. }
  147.  
  148. textField.addTo(header).adjust {
  149. $0.pinT(header, GUI.textFieldY).pinL(header, GUI.textViewPadding).pinR(header, -GUI.textViewPadding)
  150. $0.font = UIFont.font(.bold, size: 17)
  151. $0.textColor = .white
  152. $0.attributedPlaceholder = R.string.localizable.searchTypeToStartMessage().attr.rgb(.white)
  153. $0.delegate = self
  154. $0.text = query
  155. }
  156.  
  157. iconImageView.addTo(header).adjust {
  158. $0.pinL(header, GUI.padding).pinCY(textField, -2)
  159. $0.image = R.image.ic_search()?.withRenderingMode(.alwaysTemplate)
  160. $0.contentMode = .scaleAspectFit
  161. $0.tintColor = GUI.tintColor(isFocused: false)
  162. }
  163.  
  164. UIButton(type: .custom).addTo(header).adjust {
  165. $0.pinR(header, -GUI.padding).pinCY(textField, -2)
  166. $0.setImage(R.image.close_search(), for: .normal)
  167. $0.addTarget(self, action: #selector(clearSearch), for: .touchUpInside)
  168. }
  169.  
  170. separator.addTo(header).adjust {
  171. $0.pinUnder(textField, GUI.padding).pinL(header, GUI.padding).pinR(header, -GUI.padding).pinH(1)
  172. $0.backgroundColor = GUI.tintColor(isFocused: false)
  173. }
  174.  
  175. segmentedControl.addTo(header).adjust {
  176. $0.pinUnder(separator, GUI.padding).pinL(header, GUI.padding).pinR(header, -GUI.padding).pinH(44)
  177. $0.addTarget(self, action: #selector(filterChanged(_:)), for: .valueChanged)
  178. $0.options = [.titleBorderWidth(1),
  179. .titleBorderColor(.lightGray),
  180. .cornerRadius(2),
  181. .titleFont(UIFont.font(.bold, size: 17)),
  182. .selectedTitleFont(UIFont.font(.bold, size: 17)),
  183. .titleColor(.darkGray)]
  184. }
  185. }
  186.  
  187. // swiftlint:enable function_body_length
  188.  
  189. // MARK: - GUI
  190.  
  191. private struct GUI {
  192. static let headerHeight: CGFloat = isPad ? 150 : 100
  193. static let headerMargin: CGFloat = isPad ? 200 : 0
  194. static let textFieldY: CGFloat = isPad ? 48 : 24
  195. static let padding: CGFloat = 16
  196. static let searchIconSide: CGFloat = 30
  197. static let textViewMargin: CGFloat = 8
  198. static let textViewPadding = padding + searchIconSide + textViewMargin
  199.  
  200. static let title = R.string.localizable.generalSearch().uppercased()
  201.  
  202. static func tintColor(isFocused: Bool) -> UIColor { return isFocused ? .bb_yellow : .white }
  203. }
  204. }
Add Comment
Please, Sign In to add comment