Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import UIKit
- import BetterSegmentedControl
- // MARK: - SearchViewController -
- final class SearchViewController: BBViewController, CollectionSource, UITextFieldDelegate {
- // MARK: - Types definitions
- private enum Filter {
- case all, movies, tvShows
- static let filters: [Filter] = [.all, .movies, .tvShows]
- static var names: [String] { return filters.map { $0.title.uppercased() } }
- var title: String {
- switch self {
- case .all: return R.string.localizable.filterAll()
- case .movies: return R.string.localizable.filterMovies()
- case .tvShows: return R.string.localizable.filterTvShows()
- }
- }
- }
- // MARK: - Properties
- private var query = ""
- private var filter: Filter = .all
- private var products: [BlockbusterProduct] = []
- private var filteredProducts: [BlockbusterProduct] {
- switch filter {
- case .all: return products
- case .movies: return products.filter { $0 is BlockbusterMovie }
- case .tvShows: return products.filter { $0 is BlockbusterSeries }
- }
- }
- private let collectionView = UICollectionView.instantinate
- private let textField = UITextField()
- private let crossButton = UIButton()
- private let segmentedControl = BetterSegmentedControl(frame: .zero, titles: Filter.names)
- private let iconImageView = UIImageView()
- private let separator = UIView()
- private var headerTopConstraint: NSLayoutConstraint?
- // MARK: - Static
- static func instantinate(query: String) -> SearchViewController {
- let controller = SearchViewController()
- controller.query = query
- return controller
- }
- // MARK: - Lifecycle
- override func viewDidLoad() {
- super.viewDidLoad()
- setup()
- underConstruction()
- }
- // MARK: - Search
- func updateQuery(_ query: String, shouldPerformNetworking: Bool = true) {
- self.query = query
- textField.text = query
- if shouldPerformNetworking { search(self.query) }
- }
- func search(_ query: String) {
- }
- @objc func filterChanged(_ filterControl: BetterSegmentedControl) {
- filter = Filter.filters[Int(filterControl.index)]
- collectionView.reloadData()
- }
- @objc func clearSearch() {
- textField.text = ""
- }
- private func updateUiOnFocus(_ isFocused: Bool) {
- let color = GUI.tintColor(isFocused: isFocused)
- separator.backgroundColor = color
- iconImageView.tintColor = color
- }
- // MARK: - UICollectionViewDataSource
- func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
- return filteredProducts.count
- }
- func collectionView(_ collectionView: UICollectionView,
- cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
- let cell = collectionView.dequeueReusableCell(cellClass: ProductCVCell.self, for: indexPath)
- cell.configure(with: filteredProducts[indexPath.row])
- return cell
- }
- // MARK: - UIScrollViewDelegate
- func scrollViewDidScroll(_ scrollView: UIScrollView) {
- headerTopConstraint?.constant = -scrollView.yOffset
- }
- // MARK: - UITextFieldDelegate
- func textFieldShouldReturn(_ textField: UITextField) -> Bool {
- view.endEditing(true)
- return false
- }
- func textFieldDidBeginEditing(_ textField: UITextField) {
- updateUiOnFocus(true)
- }
- func textFieldDidEndEditing(_ textField: UITextField) {
- updateUiOnFocus(false)
- }
- // MARK: - Configuration
- // swiftlint:disable function_body_length
- private func setup() {
- adjust {
- $0.title = GUI.title
- $0.view.backgroundColor = UIColor.bb_bg
- }
- collectionView.addTo(view).adjust {
- $0.pinSV()
- $0.backgroundColor = .clear
- $0.alwaysBounceVertical = true
- $0.contentInset = UIEdgeInsets(top: GUI.headerHeight, left: 0, bottom: GUI.padding, right: 0)
- $0.registerNib(for: ProductCVCell.self)
- $0.dataSource = self
- $0.delegate = self
- }
- let header = UIView().addTo(view).adjust {
- $0.pinL(view, GUI.headerMargin).pinR(view, -GUI.headerMargin).pinH(GUI.headerHeight)
- headerTopConstraint = $0.pinnedT(view)
- }
- textField.addTo(header).adjust {
- $0.pinT(header, GUI.textFieldY).pinL(header, GUI.textViewPadding).pinR(header, -GUI.textViewPadding)
- $0.font = UIFont.font(.bold, size: 17)
- $0.textColor = .white
- $0.attributedPlaceholder = R.string.localizable.searchTypeToStartMessage().attr.rgb(.white)
- $0.delegate = self
- $0.text = query
- }
- iconImageView.addTo(header).adjust {
- $0.pinL(header, GUI.padding).pinCY(textField, -2)
- $0.image = R.image.ic_search()?.withRenderingMode(.alwaysTemplate)
- $0.contentMode = .scaleAspectFit
- $0.tintColor = GUI.tintColor(isFocused: false)
- }
- UIButton(type: .custom).addTo(header).adjust {
- $0.pinR(header, -GUI.padding).pinCY(textField, -2)
- $0.setImage(R.image.close_search(), for: .normal)
- $0.addTarget(self, action: #selector(clearSearch), for: .touchUpInside)
- }
- separator.addTo(header).adjust {
- $0.pinUnder(textField, GUI.padding).pinL(header, GUI.padding).pinR(header, -GUI.padding).pinH(1)
- $0.backgroundColor = GUI.tintColor(isFocused: false)
- }
- segmentedControl.addTo(header).adjust {
- $0.pinUnder(separator, GUI.padding).pinL(header, GUI.padding).pinR(header, -GUI.padding).pinH(44)
- $0.addTarget(self, action: #selector(filterChanged(_:)), for: .valueChanged)
- $0.options = [.titleBorderWidth(1),
- .titleBorderColor(.lightGray),
- .cornerRadius(2),
- .titleFont(UIFont.font(.bold, size: 17)),
- .selectedTitleFont(UIFont.font(.bold, size: 17)),
- .titleColor(.darkGray)]
- }
- }
- // swiftlint:enable function_body_length
- // MARK: - GUI
- private struct GUI {
- static let headerHeight: CGFloat = isPad ? 150 : 100
- static let headerMargin: CGFloat = isPad ? 200 : 0
- static let textFieldY: CGFloat = isPad ? 48 : 24
- static let padding: CGFloat = 16
- static let searchIconSide: CGFloat = 30
- static let textViewMargin: CGFloat = 8
- static let textViewPadding = padding + searchIconSide + textViewMargin
- static let title = R.string.localizable.generalSearch().uppercased()
- static func tintColor(isFocused: Bool) -> UIColor { return isFocused ? .bb_yellow : .white }
- }
- }
Add Comment
Please, Sign In to add comment