// // PreferenceContainerView.swift // OpenVPN // // Created by Lizaveta Malinouskaya on 26.07.21. // Copyright © 2021 Privado LLC. All rights reserved. // import UIKit protocol PreferenceViewOutputIPAD: AnyObject { } enum PreferenceViewComponent { case options } protocol PreferenceControllerOutputIPAD: AnyObject { func appendToStack(view: UIView, title route: Route.iOSPreference?) func openAccount() func openContactUs() func didEnterSettings() func didExitSettings() } protocol PreferenceNavigationViewIPAD: AnyObject { var navigationBarOutput: PreferenceNBPresenterInputIPAD? { get set } var navigationBar: BaseView? { get set } } final class PreferenceViewControllerIPAD: BaseViewController, PreferenceViewInputIPAD, PreferenceNavigationViewIPAD, ViewModuleControllerType { // MARK: - Constants enum Constant { enum Geometry { enum Portrait { static let optionsWidth: CGFloat = { if UIDevice.current.orientation.isLandscape { return UIScreen.main.bounds.height > 770 ? 319 : 260 } else { return UIScreen.main.bounds.width > 770 ? 319 : 260 } }() } enum Landscape { static let optionsWidth: CGFloat = 288 } } enum Color { static let bg = Colors.Settings.bgMain.color } } // MARK: - PreferenceNavigationView private var content: UIView? private let output: PreferenceControllerOutputIPAD private var optionsTab: BaseView? var navigationBar: BaseView? var navigationBarOutput: PreferenceNBPresenterInputIPAD? // MARK: - properties typealias ComponentCreationClosure = (PreferenceViewComponent) -> BaseView let componentCreationClosure: ComponentCreationClosure var tabContainerViewController: BaseViewController? // MARK: - init init(output: PreferenceControllerOutputIPAD, _ componentCreationClosure: @escaping ComponentCreationClosure) { self.componentCreationClosure = componentCreationClosure self.output = output super.init() self.setupUI() } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } // MARK: - private UI private func setupUI() { self.view.translatesAutoresizingMaskIntoConstraints = false self.setupOptions(with: self) self.setupContent(with: self) } private func setupContent(with vc: BaseViewController) { let content = UIView() self.content = content self.output.appendToStack(view: content, title: .empty) } private func updateLayout() { let landscape = DeviceInfoProvider.isLandscapeOrienation && self.traitCollection.horizontalSizeClass == .regular self.layoutEmitter.invoke(landscape) guard let options = self.optionsTab else { return } guard let navbar = self.navigationBar else { return } options.layoutEmitter.invoke(landscape) navbar.layoutEmitter.invoke(landscape) guard let content = self.content as? BaseView else { return } content.layoutEmitter.invoke(landscape) } private func setupContentLayout(with content: UIView, and container: BaseViewController) -> UIView { guard let options = self.optionsTab else { return UIView() } guard let navigationBar = self.navigationBar else { return UIView() } content.isHidden = true self.view.addSubview(content) sharedConstraints.append(contentsOf: [ content.leadingAnchor.constraint(equalTo: options.trailingAnchor), content.topAnchor.constraint(equalTo: navigationBar.bottomAnchor), content.bottomAnchor.constraint(equalTo: container.view.bottomAnchor), content.trailingAnchor.constraint(equalTo: container.view.trailingAnchor) ]) self.content = content self.updateLayout() return content } private func setupNavigationBar(with container: UIView) { guard let navigationBar = self.navigationBar else { return } guard let options = self.optionsTab else { return } if navigationBar.isHidden == true { if self.content == nil { navigationBar.fade(fadeIn: true) } else { navigationBar.fade(fadeIn: true, 0.001) } return } container.addSubview(navigationBar) self.sharedConstraints.append(contentsOf: [ navigationBar.topAnchor.constraint(equalTo: container.topAnchor), navigationBar.leadingAnchor.constraint(equalTo: options.trailingAnchor), navigationBar.trailingAnchor.constraint(equalTo: container.trailingAnchor) ]) self.updateLayout() } private func setupOptions(with container: BaseViewController) { let menuOptions = componentCreationClosure(.options) container.view.addSubview(menuOptions) self.optionsTab = menuOptions container.sharedConstraints.append(contentsOf: [ menuOptions.leadingAnchor.constraint(equalTo: container.view.leadingAnchor), menuOptions.topAnchor.constraint(equalTo: container.view.topAnchor), menuOptions.bottomAnchor.constraint(equalTo: container.view.bottomAnchor) ]) container.portraitConstraints.append(menuOptions.widthAnchor.constraint(equalToConstant: Constant.Geometry.Portrait.optionsWidth)) container.landscapeConstraints.append(menuOptions.widthAnchor.constraint(equalToConstant: Constant.Geometry.Landscape.optionsWidth)) } private var isNavigationBarOnView = false private func removeContentConstraints() { self.sharedConstraints.forEach { constraint in self.sharedConstraints = self.sharedConstraints.filter { constraint in if sharedConstraints.contains(constraint) { return false } return true } } } // MARK: - PreferenceViewInput func showContent(for builder: ViewModuleBuilderClosure?, output: PreferenceControllerViewOutput, route: Route.iOSPreference?) -> Bool { print("Content shown!") if !isNavigationBarOnView { self.setupNavigationBar(with: self.view) isNavigationBarOnView = true } if let content = self.content , content.superview.isExist { self.removeContentConstraints() content.removeFromSuperview() } guard let formBuilder = builder else { return false } let content = setupContentLayout(with: formBuilder(self), and: self) switch route { case .account, .settings: if self.content == nil { content.fade(fadeIn: true) } else { content.isHidden = false } default: content.isHidden = false } self.output.appendToStack(view: content, title: route) self.updateLayout() self.navigationBarOutput?.setNavBar(for: route) if self.navigationBar?.isHidden == true { self.navigationBar?.fade(fadeIn: true) } switch route { case .settings: self.output.didEnterSettings() default: return true } return true } func showExistContent(view: UIView, route: Route.iOSPreference?) -> Bool { print("Existed content shown!") if !isNavigationBarOnView { self.setupNavigationBar(with: self.view) isNavigationBarOnView = true } if let content = self.content , content.superview.isExist { self.removeContentConstraints() content.removeFromSuperview() if content is SettingsView { self.output.didExitSettings() } } self.content = view switch route { case .empty: isNavigationBarOnView = false navigationBar?.isHidden = true self.navigationBar?.fade(fadeIn: false, 0.05) default: self.content = setupContentLayout(with: view, and: self) self.content?.isHidden = false self.navigationBarOutput?.setNavBar(for: route) } return true } }