Files
2021-12-06 10:53:47 +00:00

276 lines
8.8 KiB
Swift

//
// 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
}
}