276 lines
8.8 KiB
Swift
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
|
|
}
|
|
}
|