Files
2021-09-06 13:04:05 +03:00

229 lines
8.7 KiB
Swift

//
// MessageView.swift
// PrivadoVPN
//
// Created by Zhandos Bolatbekov on 25.01.2021.
// Copyright © 2021 Privado LLC. All rights reserved.
//
import Foundation
import UIKit
protocol MessageViewInput: AnyObject {
func showMessage(text: String)
func setVisibility(hidden: Bool)
}
protocol MessageViewOutput: AnyObject {
func didTap()
func changeVisibility(isHidden: Bool)
func didTapViewButton()
func didTapClose()
}
final class MessageView: UIView, MessageViewInput {
private enum Constants {
enum Color {
static let background = UIColor.clear
static let messageContainerBackground = UIColor(rgb: 0x363f83)
static let messageText = UIColor(rgb: 0x28d799)
static let button = UIColor(rgb: 0x030f48)
static let buttonSeparator = UIColor(rgb: 0x363f83)
}
enum Geometry {
static let height: CGFloat = 53
static let messageIndent: CGFloat = 16
static let buttonsWidth: CGFloat = 158
static let buttonsSeparatorWidth: CGFloat = 1
static let buttonsIndentY: CGFloat = 6
static let cornerRadius: CGFloat = 5
}
enum LocalizedString {
static let viewButton = "messageView.button.view"
static let closeButton = "messageView.button.close"
}
static let messageFont = UIFont(name: "SFProText-Regular", size: 16.7)
static let swipeAnimationDuration: Double = 0.2
}
private let output: MessageViewOutput
private var messageLabel: UILabel?
private var messageContainerRightConstraint: NSLayoutConstraint?
// MARK: - Init
init(output: MessageViewOutput) {
self.output = output
super.init(frame: .zero)
self.configureUI()
}
required init?(coder: NSCoder) { nil }
// MARK: - View
private func configureUI() {
self.translatesAutoresizingMaskIntoConstraints = false
self.backgroundColor = Constants.Color.background
self.layer.cornerRadius = Constants.Geometry.cornerRadius
self.layer.maskedCorners = [.layerMinXMaxYCorner, .layerMaxXMaxYCorner]
self.clipsToBounds = true
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(self.onTapGesture))
self.addGestureRecognizer(tapGesture)
let buttonsView = self.initializeButtons()
NSLayoutConstraint.activate([
buttonsView.widthAnchor.constraint(equalToConstant: Constants.Geometry.buttonsWidth),
buttonsView.topAnchor.constraint(equalTo: self.topAnchor),
buttonsView.bottomAnchor.constraint(equalTo: self.bottomAnchor),
buttonsView.rightAnchor.constraint(equalTo: self.rightAnchor)
])
let messageContainer = self.initializeMessageContainer()
self.addSubview(messageContainer)
self.messageContainerRightConstraint = messageContainer.rightAnchor.constraint(equalTo: self.rightAnchor)
NSLayoutConstraint.activate([
messageContainer.heightAnchor.constraint(equalToConstant: Constants.Geometry.height),
messageContainer.topAnchor.constraint(equalTo: self.topAnchor),
messageContainer.bottomAnchor.constraint(equalTo: self.bottomAnchor),
messageContainer.widthAnchor.constraint(equalTo: self.widthAnchor),
self.messageContainerRightConstraint!
])
let messageLabel = self.createMessageLabel()
messageContainer.addSubview(messageLabel)
NSLayoutConstraint.activate([
messageLabel.leftAnchor.constraint(equalTo: messageContainer.leftAnchor, constant: Constants.Geometry.messageIndent),
messageLabel.rightAnchor.constraint(equalTo: messageContainer.rightAnchor, constant: -Constants.Geometry.messageIndent),
messageLabel.centerYAnchor.constraint(equalTo: messageContainer.centerYAnchor)
])
}
// MARK: - MessageViewInput
func showMessage(text: String) {
self.messageLabel?.attributedText = NSAttributedString(
string: text,
attributes: [.underlineStyle: NSUnderlineStyle.single.rawValue, .kern: -1.0]
)
self.output.changeVisibility(isHidden: false)
}
func setVisibility(hidden: Bool) { }
// MARK: - Private
private func initializeMessageContainer() -> UIView {
let view = UIView()
view.translatesAutoresizingMaskIntoConstraints = false
view.backgroundColor = Constants.Color.messageContainerBackground
let leftSwipe = UISwipeGestureRecognizer(target: self, action: #selector(self.leftSwipeAction))
leftSwipe.direction = .right
// view.addGestureRecognizer(leftSwipe)
let rightSwipe = UISwipeGestureRecognizer(target: self, action: #selector(self.rightSwipeAction))
rightSwipe.direction = .left
// view.addGestureRecognizer(rightSwipe)
return view
}
private func createMessageLabel() -> UILabel {
let label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false
label.font = Constants.messageFont
label.lineBreakMode = .byTruncatingTail
label.textColor = Constants.Color.messageText
label.textAlignment = .center
self.messageLabel = label
return label
}
private func initializeButtons() -> UIView {
let view = UIView()
view.translatesAutoresizingMaskIntoConstraints = false
let separator: UIView = {
let view = UIView()
view.translatesAutoresizingMaskIntoConstraints = false
view.backgroundColor = Constants.Color.buttonSeparator
return view
}()
view.addSubview(separator)
NSLayoutConstraint.activate([
separator.centerXAnchor.constraint(equalTo: view.centerXAnchor),
separator.widthAnchor.constraint(equalToConstant: Constants.Geometry.buttonsSeparatorWidth),
separator.topAnchor.constraint(equalTo: view.topAnchor, constant: Constants.Geometry.buttonsIndentY),
separator.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -Constants.Geometry.buttonsIndentY)
])
let viewButtonTitle = NSLocalizedString(Constants.LocalizedString.viewButton, comment: "View")
let viewButton = self.createButton(title: viewButtonTitle)
viewButton.addTarget(self, action: #selector(self.didTapViewButton), for: .touchUpInside)
view.addSubview(viewButton)
NSLayoutConstraint.activate([
viewButton.topAnchor.constraint(equalTo: view.topAnchor),
viewButton.leadingAnchor.constraint(equalTo: view.leadingAnchor),
viewButton.trailingAnchor.constraint(equalTo: separator.leadingAnchor),
viewButton.bottomAnchor.constraint(equalTo: view.bottomAnchor)
])
let closeButtonTitle = NSLocalizedString(Constants.LocalizedString.closeButton, comment: "Close")
let closeButton = self.createButton(title: closeButtonTitle)
closeButton.addTarget(self, action: #selector(self.didTapCloseButton), for: .touchUpInside)
view.addSubview(closeButton)
NSLayoutConstraint.activate([
closeButton.topAnchor.constraint(equalTo: view.topAnchor),
closeButton.leadingAnchor.constraint(equalTo: separator.trailingAnchor),
closeButton.trailingAnchor.constraint(equalTo: view.trailingAnchor),
closeButton.bottomAnchor.constraint(equalTo: view.bottomAnchor)
])
self.addSubview(view)
return view
}
private func createButton(title: String) -> UIButton {
let button = UIButton()
button.translatesAutoresizingMaskIntoConstraints = false
button.setTitle(title, for: .normal)
button.backgroundColor = Constants.Color.button
return button
}
@objc
private func onTapGesture() {
self.output.didTap()
}
@objc
private func leftSwipeAction() {
UIView.animate(withDuration: Constants.swipeAnimationDuration) { [weak self] in
self?.messageContainerRightConstraint?.constant = 0
self?.layoutIfNeeded()
}
}
@objc
private func rightSwipeAction() {
UIView.animate(withDuration: Constants.swipeAnimationDuration) { [weak self] in
self?.messageContainerRightConstraint?.constant = -Constants.Geometry.buttonsWidth
self?.layoutIfNeeded()
}
}
@objc
private func didTapViewButton() {
self.output.didTapViewButton()
}
@objc
private func didTapCloseButton() {
self.output.didTapClose()
}
}