import UIKit import Theme import Shared import Combine import DrawerFeature import DependencyInjection public final class ScanContainerController: UIViewController { @Dependency private var coordinator: ScanCoordinating @Dependency private var statusBarController: StatusBarStyleControlling lazy private var screenView = ScanContainerView() private var previousPoint: CGPoint = .zero private let scanController = ScanController() private let displayController = ScanDisplayController() private var cancellables = Set<AnyCancellable>() private var drawerCancellables = Set<AnyCancellable>() public override func loadView() { view = screenView screenView.scrollView.delegate = self addChild(scanController) addChild(displayController) screenView.scrollView.addSubview(scanController.view) screenView.scrollView.addSubview(displayController.view) scanController.view.snp.makeConstraints { $0.top.equalTo(screenView) $0.width.equalTo(screenView) $0.bottom.equalTo(screenView) $0.left.equalToSuperview() $0.right.equalTo(displayController.view.snp.left) } displayController.view.snp.makeConstraints { $0.top.equalTo(screenView.segmentedControl.snp.bottom) $0.width.equalTo(scanController.view) $0.bottom.equalTo(scanController.view) } scanController.didMove(toParent: self) displayController.didMove(toParent: self) screenView.bringSubviewToFront(screenView.segmentedControl) } public override func viewDidLayoutSubviews() { super.viewDidLayoutSubviews() screenView.scrollView.contentOffset = previousPoint } public override func viewWillDisappear(_ animated: Bool) { super.viewWillDisappear(animated) previousPoint = screenView.scrollView.contentOffset screenView.scrollView.contentOffset = .zero } public override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) statusBarController.style.send(.lightContent) navigationController?.navigationBar.customize(translucent: true) screenView.scrollView.contentOffset = .zero } public override func viewDidLoad() { super.viewDidLoad() setupNavigationBar() setupBindings() displayController.didTapInfo = { [weak self] in self?.presentInfo( title: Localized.Scan.Info.title, subtitle: Localized.Scan.Info.subtitle ) } displayController.didTapAddEmail = { [weak self] in guard let self = self else { return } self.coordinator.toEmail(from: self) } displayController.didTapAddPhone = { [weak self] in guard let self = self else { return } self.coordinator.toPhone(from: self) } } private func setupNavigationBar() { navigationItem.backButtonTitle = "" let titleLabel = UILabel() titleLabel.text = "QR Code" titleLabel.font = Fonts.Mulish.semiBold.font(size: 18.0) titleLabel.textColor = Asset.neutralWhite.color let menuButton = UIButton() menuButton.tintColor = Asset.neutralWhite.color menuButton.setImage(Asset.chatListMenu.image, for: .normal) menuButton.addTarget(self, action: #selector(didTapMenu), for: .touchUpInside) menuButton.snp.makeConstraints { $0.width.equalTo(50) } navigationItem.leftBarButtonItem = UIBarButtonItem( customView: UIStackView(arrangedSubviews: [menuButton, titleLabel]) ) } private func setupBindings() { screenView.segmentedControl.leftButton .publisher(for: .touchUpInside) .sink { [unowned self] _ in screenView.scrollView.setContentOffset(.zero, animated: true) } .store(in: &cancellables) screenView.segmentedControl.rightButton .publisher(for: .touchUpInside) .sink { [unowned self] _ in let point = CGPoint(x: screenView.frame.width, y: 0.0) screenView.scrollView.setContentOffset(point, animated: true) }.store(in: &cancellables) } @objc private func didTapMenu() { coordinator.toSideMenu(from: self) } public func scrollViewDidScroll(_ scrollView: UIScrollView) { let percentage = scrollView.contentOffset.x / view.frame.width scanController.view.alpha = 1 - percentage displayController.view.alpha = percentage screenView.segmentedControl.updateLeftConstraint(percentage) } private func presentInfo(title: String, subtitle: String) { let actionButton = CapsuleButton() actionButton.set( style: .seeThrough, title: Localized.Settings.InfoDrawer.action ) let drawer = DrawerController(with: [ DrawerText( font: Fonts.Mulish.bold.font(size: 26.0), text: title, color: Asset.neutralActive.color, alignment: .left, spacingAfter: 19 ), DrawerText( font: Fonts.Mulish.regular.font(size: 16.0), text: subtitle, color: Asset.neutralBody.color, alignment: .left, lineHeightMultiple: 1.1, spacingAfter: 37 ), DrawerStack(views: [ actionButton, FlexibleSpace() ]) ]) actionButton.publisher(for: .touchUpInside) .receive(on: DispatchQueue.main) .sink { drawer.dismiss(animated: true) { [weak self] in guard let self = self else { return } self.drawerCancellables.removeAll() } }.store(in: &drawerCancellables) coordinator.toDrawer(drawer, from: self) } } extension ScanContainerController: UIScrollViewDelegate {}