2022-01-27 14:23:39 +01:00
|
|
|
//
|
|
|
|
// ProfileFieldCollectionViewCell.swift
|
|
|
|
// Mastodon
|
|
|
|
//
|
|
|
|
// Created by MainasuK Cirno on 2021-5-25.
|
|
|
|
//
|
|
|
|
|
|
|
|
import os.log
|
|
|
|
import UIKit
|
|
|
|
import Combine
|
|
|
|
import MetaTextKit
|
|
|
|
import MastodonAsset
|
|
|
|
import MastodonLocalization
|
|
|
|
|
|
|
|
protocol ProfileFieldCollectionViewCellDelegate: AnyObject {
|
|
|
|
func profileFieldCollectionViewCell(_ cell: ProfileFieldCollectionViewCell, metaLebel: MetaLabel, didSelectMeta meta: Meta)
|
|
|
|
}
|
|
|
|
|
|
|
|
final class ProfileFieldCollectionViewCell: UICollectionViewCell {
|
|
|
|
|
|
|
|
var disposeBag = Set<AnyCancellable>()
|
|
|
|
|
|
|
|
weak var delegate: ProfileFieldCollectionViewCellDelegate?
|
|
|
|
|
|
|
|
// for custom emoji display
|
|
|
|
let keyMetaLabel = MetaLabel(style: .profileFieldName)
|
|
|
|
let valueMetaLabel = MetaLabel(style: .profileFieldValue)
|
|
|
|
|
2022-11-11 21:34:26 +01:00
|
|
|
let checkmark = UIImageView(image: Asset.Editing.checkmark.image.withRenderingMode(.alwaysTemplate))
|
2022-11-12 15:42:00 +01:00
|
|
|
var checkmarkPopoverString: String? = nil;
|
2022-11-12 02:53:12 +01:00
|
|
|
let tapGesture = UITapGestureRecognizer();
|
2022-11-12 15:42:00 +01:00
|
|
|
private var _editMenuInteraction: Any? = nil
|
|
|
|
@available(iOS 16, *)
|
|
|
|
fileprivate var editMenuInteraction: UIEditMenuInteraction {
|
|
|
|
_editMenuInteraction = _editMenuInteraction ?? UIEditMenuInteraction(delegate: self)
|
|
|
|
return _editMenuInteraction as! UIEditMenuInteraction
|
|
|
|
}
|
2022-11-11 21:34:26 +01:00
|
|
|
|
2022-01-27 14:23:39 +01:00
|
|
|
override func prepareForReuse() {
|
|
|
|
super.prepareForReuse()
|
|
|
|
|
|
|
|
disposeBag.removeAll()
|
|
|
|
}
|
|
|
|
|
|
|
|
override init(frame: CGRect) {
|
|
|
|
super.init(frame: frame)
|
|
|
|
_init()
|
|
|
|
}
|
|
|
|
|
|
|
|
required init?(coder: NSCoder) {
|
|
|
|
super.init(coder: coder)
|
|
|
|
_init()
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
extension ProfileFieldCollectionViewCell {
|
|
|
|
|
|
|
|
private func _init() {
|
2022-11-12 02:53:12 +01:00
|
|
|
// Setup colors
|
2022-11-12 03:10:16 +01:00
|
|
|
checkmark.tintColor = Asset.Scene.Profile.About.bioAboutFieldVerifiedCheckmark.color;
|
2022-11-11 21:34:26 +01:00
|
|
|
|
2022-11-12 02:53:12 +01:00
|
|
|
// Setup gestures
|
|
|
|
tapGesture.addTarget(self, action: #selector(ProfileFieldCollectionViewCell.didTapCheckmark(_:)))
|
|
|
|
checkmark.addGestureRecognizer(tapGesture)
|
|
|
|
checkmark.isUserInteractionEnabled = true
|
2022-11-12 15:42:00 +01:00
|
|
|
if #available(iOS 16, *) {
|
|
|
|
checkmark.addInteraction(editMenuInteraction)
|
|
|
|
}
|
2022-11-12 02:53:12 +01:00
|
|
|
|
2022-01-27 14:23:39 +01:00
|
|
|
// containerStackView: V - [ metaContainer | plainContainer ]
|
|
|
|
let containerStackView = UIStackView()
|
|
|
|
containerStackView.axis = .vertical
|
|
|
|
|
|
|
|
contentView.preservesSuperviewLayoutMargins = true
|
|
|
|
containerStackView.preservesSuperviewLayoutMargins = true
|
|
|
|
containerStackView.isLayoutMarginsRelativeArrangement = true
|
|
|
|
containerStackView.translatesAutoresizingMaskIntoConstraints = false
|
|
|
|
addSubview(containerStackView)
|
|
|
|
NSLayoutConstraint.activate([
|
|
|
|
containerStackView.topAnchor.constraint(equalTo: topAnchor, constant: 11),
|
|
|
|
containerStackView.leadingAnchor.constraint(equalTo: leadingAnchor),
|
|
|
|
containerStackView.trailingAnchor.constraint(equalTo: trailingAnchor),
|
|
|
|
bottomAnchor.constraint(equalTo: containerStackView.bottomAnchor, constant: 11),
|
|
|
|
])
|
|
|
|
|
2022-11-11 21:34:26 +01:00
|
|
|
// metaContainer: V - [ keyMetaLabel | valueContainer ]
|
2022-01-27 14:23:39 +01:00
|
|
|
let metaContainer = UIStackView()
|
|
|
|
metaContainer.axis = .vertical
|
|
|
|
metaContainer.spacing = 2
|
|
|
|
containerStackView.addArrangedSubview(metaContainer)
|
|
|
|
|
2022-11-11 21:34:26 +01:00
|
|
|
// valueContainer: H - [ valueMetaLabel | checkmark ]
|
|
|
|
let valueContainer = UIStackView()
|
|
|
|
valueContainer.axis = .horizontal
|
|
|
|
valueContainer.spacing = 2
|
|
|
|
|
2022-01-27 14:23:39 +01:00
|
|
|
metaContainer.addArrangedSubview(keyMetaLabel)
|
2022-11-11 21:34:26 +01:00
|
|
|
valueContainer.addArrangedSubview(valueMetaLabel)
|
|
|
|
valueContainer.addArrangedSubview(checkmark)
|
|
|
|
metaContainer.addArrangedSubview(valueContainer)
|
2022-01-27 14:23:39 +01:00
|
|
|
|
|
|
|
keyMetaLabel.linkDelegate = self
|
|
|
|
valueMetaLabel.linkDelegate = self
|
|
|
|
}
|
|
|
|
|
2022-11-12 15:42:00 +01:00
|
|
|
@objc public func didTapCheckmark(_ recognizer: UITapGestureRecognizer) {
|
|
|
|
if #available(iOS 16, *) {
|
|
|
|
editMenuInteraction.presentEditMenu(with: UIEditMenuConfiguration(identifier: nil, sourcePoint: recognizer.location(in: checkmark)))
|
|
|
|
} else {
|
|
|
|
guard let editMenuLabel = checkmarkPopoverString else { return }
|
|
|
|
|
|
|
|
self.isUserInteractionEnabled = true
|
|
|
|
self.becomeFirstResponder()
|
|
|
|
|
|
|
|
UIMenuController.shared.menuItems = [
|
|
|
|
UIMenuItem(
|
|
|
|
title: editMenuLabel,
|
|
|
|
action: #selector(dismissVerifiedMenu)
|
|
|
|
)
|
|
|
|
]
|
|
|
|
UIMenuController.shared.showMenu(from: checkmark, rect: checkmark.bounds)
|
|
|
|
}
|
2022-11-12 02:53:12 +01:00
|
|
|
}
|
2022-11-12 15:42:00 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// UIMenuController boilerplate
|
|
|
|
@available(iOS, deprecated: 16, message: "Can be removed when target version is >=16 -- boilerplate to maintain compatibility with UIMenuController")
|
|
|
|
extension ProfileFieldCollectionViewCell {
|
|
|
|
override var canBecomeFirstResponder: Bool { true }
|
2022-11-12 02:53:12 +01:00
|
|
|
|
2022-11-12 15:42:00 +01:00
|
|
|
override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
|
|
|
|
if action == #selector(dismissVerifiedMenu) {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
|
|
|
return super.canPerformAction(action, withSender: sender)
|
|
|
|
}
|
|
|
|
|
|
|
|
@objc public func dismissVerifiedMenu() {
|
|
|
|
UIMenuController.shared.hideMenu()
|
|
|
|
}
|
2022-01-27 14:23:39 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// MARK: - MetaLabelDelegate
|
|
|
|
extension ProfileFieldCollectionViewCell: MetaLabelDelegate {
|
|
|
|
func metaLabel(_ metaLabel: MetaLabel, didSelectMeta meta: Meta) {
|
|
|
|
os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s", ((#file as NSString).lastPathComponent), #line, #function)
|
|
|
|
delegate?.profileFieldCollectionViewCell(self, metaLebel: metaLabel, didSelectMeta: meta)
|
|
|
|
}
|
|
|
|
}
|
2022-11-12 15:42:00 +01:00
|
|
|
|
|
|
|
// MARK: UIEditMenuInteractionDelegate
|
|
|
|
@available(iOS 16.0, *)
|
|
|
|
extension ProfileFieldCollectionViewCell: UIEditMenuInteractionDelegate {
|
|
|
|
func editMenuInteraction(_ interaction: UIEditMenuInteraction, menuFor configuration: UIEditMenuConfiguration, suggestedActions: [UIMenuElement]) -> UIMenu? {
|
|
|
|
guard let editMenuLabel = checkmarkPopoverString else { return UIMenu(children: []) }
|
|
|
|
return UIMenu(children: [UIAction(title: editMenuLabel) { _ in return }])
|
|
|
|
}
|
|
|
|
|
|
|
|
func editMenuInteraction(_ interaction: UIEditMenuInteraction, targetRectFor configuration: UIEditMenuConfiguration) -> CGRect {
|
|
|
|
return checkmark.frame
|
|
|
|
}
|
|
|
|
}
|