mastodon-app-ufficiale-ipho.../Mastodon/Scene/Onboarding/PickServer/View/PickServerServerSectionTabl...

207 lines
9.2 KiB
Swift

//
// PickServerServerSectionTableHeaderView.swift
// Mastodon
//
// Created by MainasuK on 2022-1-4.
//
import os.log
import UIKit
import Tabman
import MastodonAsset
import MastodonLocalization
protocol PickServerServerSectionTableHeaderViewDelegate: AnyObject {
func pickServerServerSectionTableHeaderView(_ headerView: PickServerServerSectionTableHeaderView, collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath)
func pickServerServerSectionTableHeaderView(_ headerView: PickServerServerSectionTableHeaderView, searchTextDidChange searchText: String?)
}
final class PickServerServerSectionTableHeaderView: UIView {
static let collectionViewHeight: CGFloat = 88
static let searchTextFieldHeight: CGFloat = 38
static let spacing: CGFloat = 11
static let height: CGFloat = collectionViewHeight + spacing + searchTextFieldHeight + spacing
weak var delegate: PickServerServerSectionTableHeaderViewDelegate?
var diffableDataSource: UICollectionViewDiffableDataSource<CategoryPickerSection, CategoryPickerItem>?
static func createCollectionViewLayout() -> UICollectionViewLayout {
let itemSize = NSCollectionLayoutSize(widthDimension: .estimated(88), heightDimension: .absolute(PickServerServerSectionTableHeaderView.collectionViewHeight))
let item = NSCollectionLayoutItem(layoutSize: itemSize)
let groupSize = NSCollectionLayoutSize(widthDimension: itemSize.widthDimension, heightDimension: itemSize.heightDimension)
let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize, subitems: [item])
let section = NSCollectionLayoutSection(group: group)
section.orthogonalScrollingBehavior = .continuous
section.contentInsetsReference = .readableContent
section.interGroupSpacing = 16
return UICollectionViewCompositionalLayout(section: section)
}
let collectionView: UICollectionView = {
let collectionViewLayout = PickServerServerSectionTableHeaderView.createCollectionViewLayout()
let view = ControlContainableCollectionView(
frame: CGRect(origin: .zero, size: CGSize(width: 100, height: PickServerServerSectionTableHeaderView.collectionViewHeight)),
collectionViewLayout: collectionViewLayout
)
view.register(PickServerCategoryCollectionViewCell.self, forCellWithReuseIdentifier: String(describing: PickServerCategoryCollectionViewCell.self))
view.backgroundColor = .clear
view.alwaysBounceVertical = false
view.showsHorizontalScrollIndicator = false
view.showsVerticalScrollIndicator = false
view.layer.masksToBounds = false
return view
}()
let searchTextField: UITextField = {
let textField = UITextField()
textField.backgroundColor = Asset.Scene.Onboarding.searchBarBackground.color
textField.leftView = {
let imageView = UIImageView(
image: UIImage(
systemName: "magnifyingglass",
withConfiguration: UIImage.SymbolConfiguration(pointSize: 15, weight: .regular)
)
)
imageView.tintColor = Asset.Colors.Label.secondary.color.withAlphaComponent(0.6)
let containerView = UIView()
imageView.translatesAutoresizingMaskIntoConstraints = false
containerView.addSubview(imageView)
NSLayoutConstraint.activate([
imageView.topAnchor.constraint(equalTo: containerView.topAnchor),
imageView.leadingAnchor.constraint(equalTo: containerView.leadingAnchor, constant: 8),
imageView.bottomAnchor.constraint(equalTo: containerView.bottomAnchor),
])
let paddingView = UIView()
paddingView.translatesAutoresizingMaskIntoConstraints = false
containerView.addSubview(paddingView)
NSLayoutConstraint.activate([
paddingView.topAnchor.constraint(equalTo: containerView.topAnchor),
paddingView.leadingAnchor.constraint(equalTo: imageView.trailingAnchor),
paddingView.trailingAnchor.constraint(equalTo: containerView.trailingAnchor),
paddingView.bottomAnchor.constraint(equalTo: containerView.bottomAnchor),
paddingView.widthAnchor.constraint(equalToConstant: 4).priority(.defaultHigh),
])
return containerView
}()
textField.leftViewMode = .always
textField.font = .systemFont(ofSize: 15, weight: .regular)
textField.tintColor = Asset.Colors.Label.primary.color
textField.textColor = Asset.Colors.Label.primary.color
textField.adjustsFontForContentSizeCategory = true
textField.attributedPlaceholder =
NSAttributedString(
string: L10n.Scene.ServerPicker.Input.placeholder,
attributes: [.font: UIFont.systemFont(ofSize: 15, weight: .regular),
.foregroundColor: Asset.Colors.Label.secondary.color.withAlphaComponent(0.6)])
textField.clearButtonMode = .whileEditing
textField.autocapitalizationType = .none
textField.autocorrectionType = .no
textField.returnKeyType = .done
textField.keyboardType = .URL
textField.borderStyle = .none
textField.layer.masksToBounds = true
textField.layer.cornerRadius = 10
textField.layer.cornerCurve = .continuous
return textField
}()
override init(frame: CGRect) {
super.init(frame: frame)
_init()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
_init()
}
override func layoutSubviews() {
super.layoutSubviews()
collectionView.invalidateIntrinsicContentSize()
}
}
extension PickServerServerSectionTableHeaderView {
private func _init() {
preservesSuperviewLayoutMargins = true
backgroundColor = Asset.Scene.Onboarding.background.color
collectionView.translatesAutoresizingMaskIntoConstraints = false
collectionView.preservesSuperviewLayoutMargins = true
addSubview(collectionView)
NSLayoutConstraint.activate([
collectionView.topAnchor.constraint(equalTo: topAnchor),
collectionView.leadingAnchor.constraint(equalTo: leadingAnchor),
collectionView.trailingAnchor.constraint(equalTo: trailingAnchor),
collectionView.heightAnchor.constraint(equalToConstant: PickServerServerSectionTableHeaderView.collectionViewHeight).priority(.required - 1),
])
searchTextField.translatesAutoresizingMaskIntoConstraints = false
addSubview(searchTextField)
NSLayoutConstraint.activate([
searchTextField.topAnchor.constraint(equalTo: collectionView.bottomAnchor, constant: PickServerServerSectionTableHeaderView.spacing),
searchTextField.leadingAnchor.constraint(equalTo: readableContentGuide.leadingAnchor),
searchTextField.trailingAnchor.constraint(equalTo: readableContentGuide.trailingAnchor),
bottomAnchor.constraint(equalTo: searchTextField.bottomAnchor, constant: PickServerServerSectionTableHeaderView.spacing),
searchTextField.heightAnchor.constraint(equalToConstant: PickServerServerSectionTableHeaderView.searchTextFieldHeight).priority(.required - 1),
])
collectionView.delegate = self
searchTextField.delegate = self
searchTextField.addTarget(self, action: #selector(PickServerServerSectionTableHeaderView.textFieldDidChange(_:)), for: .editingChanged)
}
}
extension PickServerServerSectionTableHeaderView {
@objc private func textFieldDidChange(_ textField: UITextField) {
delegate?.pickServerServerSectionTableHeaderView(self, searchTextDidChange: textField.text)
}
}
// MARK: - UICollectionViewDelegate
extension PickServerServerSectionTableHeaderView: UICollectionViewDelegate {
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s: indexPath: %s", ((#file as NSString).lastPathComponent), #line, #function, indexPath.debugDescription)
collectionView.selectItem(at: indexPath, animated: true, scrollPosition: .centeredHorizontally)
delegate?.pickServerServerSectionTableHeaderView(self, collectionView: collectionView, didSelectItemAt: indexPath)
}
}
extension PickServerServerSectionTableHeaderView {
override func accessibilityElementCount() -> Int {
guard let diffableDataSource = diffableDataSource else { return 0 }
return diffableDataSource.snapshot().itemIdentifiers.count + 1
}
override func accessibilityElement(at index: Int) -> Any? {
if let item = collectionView.cellForItem(at: IndexPath(item: index, section: 0)) { return item }
return searchTextField
}
}
// MARK: - UITextFieldDelegate
extension PickServerServerSectionTableHeaderView: UITextFieldDelegate {
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
textField.resignFirstResponder()
return false
}
}