Antidote/Antidote/FullscreenPicker.swift
2024-02-22 21:43:11 +02:00

159 lines
4.8 KiB
Swift

// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
import UIKit
import SnapKit
private struct Constants {
static let AnimationDuration = 0.3
static let ToolbarHeight: CGFloat = 44.0
}
protocol FullscreenPickerDelegate: class {
func fullscreenPicker(_ picker: FullscreenPicker, willDismissWithSelectedIndex index: Int)
}
class FullscreenPicker: UIView {
weak var delegate: FullscreenPickerDelegate?
fileprivate var theme: Theme
fileprivate var blackoutButton: UIButton!
fileprivate var toolbar: UIToolbar!
fileprivate var picker: UIPickerView!
fileprivate var pickerBottomConstraint: Constraint!
fileprivate let stringsArray: [String]
init(theme: Theme, strings: [String], selectedIndex: Int) {
self.theme = theme
self.stringsArray = strings
super.init(frame: CGRect.zero)
configureSelf()
createSubviews()
installConstraints()
picker.selectRow(selectedIndex, inComponent: 0, animated: false)
}
required convenience init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func showAnimatedInView(_ view: UIView) {
view.addSubview(self)
snp.makeConstraints {
$0.edges.equalTo(view)
}
show()
}
}
// MARK: Actions
extension FullscreenPicker {
@objc func doneButtonPressed() {
delegate?.fullscreenPicker(self, willDismissWithSelectedIndex: picker.selectedRow(inComponent: 0))
hide()
}
}
extension FullscreenPicker: UIPickerViewDataSource {
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return stringsArray.count
}
}
extension FullscreenPicker: UIPickerViewDelegate {
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return stringsArray[row]
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
picker.reloadAllComponents()
}
}
private extension FullscreenPicker {
func configureSelf() {
backgroundColor = .clear
}
func createSubviews() {
blackoutButton = UIButton()
blackoutButton.backgroundColor = theme.colorForType(.TranslucentBackground)
blackoutButton.addTarget(self, action: #selector(FullscreenPicker.doneButtonPressed), for:.touchUpInside)
blackoutButton.accessibilityElementsHidden = true
blackoutButton.isAccessibilityElement = false
addSubview(blackoutButton)
toolbar = UIToolbar()
toolbar.tintColor = theme.colorForType(.LoginButtonText)
toolbar.barTintColor = theme.loginNavigationBarColor
toolbar.items = [
UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: self, action: nil),
UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(FullscreenPicker.doneButtonPressed))
]
addSubview(toolbar)
picker = UIPickerView()
// Picker is always white, despite choosen theme
picker.backgroundColor = .white
picker.delegate = self
picker.dataSource = self
addSubview(picker)
}
func installConstraints() {
blackoutButton.snp.makeConstraints {
$0.edges.equalTo(self)
}
toolbar.snp.makeConstraints {
$0.bottom.equalTo(self.picker.snp.top)
$0.height.equalTo(Constants.ToolbarHeight)
$0.width.equalTo(self)
}
picker.snp.makeConstraints {
$0.width.equalTo(self)
pickerBottomConstraint = $0.bottom.equalTo(self).constraint
}
}
func show() {
blackoutButton.alpha = 0.0
pickerBottomConstraint.update(offset: picker.frame.size.height + Constants.ToolbarHeight)
layoutIfNeeded()
UIView.animate(withDuration: Constants.AnimationDuration, animations: {
self.blackoutButton.alpha = 1.0
self.pickerBottomConstraint.update(offset: 0.0)
self.layoutIfNeeded()
UIAccessibilityPostNotification(UIAccessibilityScreenChangedNotification, self.picker);
})
}
func hide() {
UIView.animate(withDuration: Constants.AnimationDuration, animations: {
self.blackoutButton.alpha = 0.0
self.pickerBottomConstraint.update(offset: self.picker.frame.size.height + Constants.ToolbarHeight)
self.layoutIfNeeded()
}, completion: { finished in
self.removeFromSuperview()
})
}
}