metatext-app-ios-iphone-ipad/Views/AccountFieldView.swift

154 lines
6.6 KiB
Swift

// Copyright © 2020 Metabolist. All rights reserved.
import Mastodon
import UIKit
final class AccountFieldView: UIView {
let nameLabel = UILabel()
let valueTextView = TouchFallthroughTextView()
// swiftlint:disable:next function_body_length
init(name: String, value: NSAttributedString, verifiedAt: Date?, emojis: [Emoji]) {
super.init(frame: .zero)
backgroundColor = .systemBackground
let nameBackgroundView = UIView()
addSubview(nameBackgroundView)
nameBackgroundView.translatesAutoresizingMaskIntoConstraints = false
nameBackgroundView.backgroundColor = .secondarySystemBackground
let valueBackgroundView = UIView()
addSubview(valueBackgroundView)
valueBackgroundView.translatesAutoresizingMaskIntoConstraints = false
valueBackgroundView.backgroundColor = verifiedAt == nil
? .systemBackground
: UIColor.systemGreen.withAlphaComponent(0.25)
addSubview(nameLabel)
nameLabel.translatesAutoresizingMaskIntoConstraints = false
nameLabel.numberOfLines = 0
nameLabel.font = .preferredFont(forTextStyle: .headline)
nameLabel.textAlignment = .center
nameLabel.textColor = .secondaryLabel
let mutableName = NSMutableAttributedString(string: name)
mutableName.insert(emojis: emojis, view: nameLabel)
mutableName.resizeAttachments(toLineHeight: nameLabel.font.lineHeight)
nameLabel.attributedText = mutableName
let dividerView = UIView()
addSubview(dividerView)
dividerView.translatesAutoresizingMaskIntoConstraints = false
dividerView.backgroundColor = .separator
addSubview(valueTextView)
valueTextView.translatesAutoresizingMaskIntoConstraints = false
valueTextView.backgroundColor = .clear
if verifiedAt != nil {
valueTextView.linkTextAttributes = [
.foregroundColor: UIColor.systemGreen as Any,
.underlineColor: UIColor.clear]
}
let valueFont = UIFont.preferredFont(forTextStyle: verifiedAt == nil ? .body : .headline)
let mutableValue = NSMutableAttributedString(attributedString: value)
let valueRange = NSRange(location: 0, length: mutableValue.length)
mutableValue.removeAttribute(.font, range: valueRange)
mutableValue.addAttributes(
[.font: valueFont as Any,
.foregroundColor: UIColor.label],
range: valueRange)
mutableValue.insert(emojis: emojis, view: valueTextView)
mutableValue.resizeAttachments(toLineHeight: valueFont.lineHeight)
valueTextView.attributedText = mutableValue
valueTextView.textAlignment = .center
let checkButton = UIButton()
checkButton.setImage(
UIImage(
systemName: "checkmark",
withConfiguration: UIImage.SymbolConfiguration(scale: .small)),
for: .normal)
addSubview(checkButton)
checkButton.translatesAutoresizingMaskIntoConstraints = false
checkButton.tintColor = .systemGreen
checkButton.isHidden = verifiedAt == nil
checkButton.showsMenuAsPrimaryAction = true
checkButton.setContentCompressionResistancePriority(.required, for: .horizontal)
checkButton.setContentHuggingPriority(.required, for: .horizontal)
if let verifiedAt = verifiedAt {
checkButton.menu = UIMenu(
title: String.localizedStringWithFormat(
NSLocalizedString("account.field.verified", comment: ""),
Self.dateFormatter.string(from: verifiedAt)),
options: .displayInline,
children: [UIAction(title: NSLocalizedString("ok", comment: "")) { _ in }])
}
let nameLabelBottomConstraint = nameLabel.bottomAnchor.constraint(
equalTo: bottomAnchor,
constant: -.defaultSpacing)
let valueTextViewBottomConstraint = valueTextView.bottomAnchor.constraint(
lessThanOrEqualTo: bottomAnchor,
constant: -.defaultSpacing)
for constraint in [nameLabelBottomConstraint, valueTextViewBottomConstraint] {
constraint.priority = .justBelowMax
}
NSLayoutConstraint.activate([
nameLabel.leadingAnchor.constraint(equalTo: leadingAnchor, constant: .defaultSpacing),
nameLabel.topAnchor.constraint(equalTo: topAnchor, constant: .defaultSpacing),
nameLabelBottomConstraint,
dividerView.leadingAnchor.constraint(equalTo: nameLabel.trailingAnchor, constant: .defaultSpacing),
dividerView.topAnchor.constraint(equalTo: topAnchor),
dividerView.bottomAnchor.constraint(equalTo: bottomAnchor),
dividerView.widthAnchor.constraint(equalToConstant: .hairline),
checkButton.leadingAnchor.constraint(equalTo: dividerView.trailingAnchor, constant: .defaultSpacing),
valueTextView.leadingAnchor.constraint(
equalTo: verifiedAt == nil ? dividerView.trailingAnchor : checkButton.trailingAnchor,
constant: .defaultSpacing),
valueTextView.topAnchor.constraint(greaterThanOrEqualTo: topAnchor, constant: .defaultSpacing),
valueTextView.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -.defaultSpacing),
valueTextViewBottomConstraint,
nameLabel.widthAnchor.constraint(equalTo: widthAnchor, multiplier: 1 / 3),
checkButton.centerYAnchor.constraint(equalTo: valueTextView.centerYAnchor),
valueTextView.centerYAnchor.constraint(equalTo: nameLabel.centerYAnchor),
nameBackgroundView.leadingAnchor.constraint(equalTo: leadingAnchor),
nameBackgroundView.topAnchor.constraint(equalTo: topAnchor),
nameBackgroundView.trailingAnchor.constraint(equalTo: dividerView.leadingAnchor),
nameBackgroundView.bottomAnchor.constraint(equalTo: bottomAnchor),
valueBackgroundView.leadingAnchor.constraint(equalTo: dividerView.trailingAnchor),
valueBackgroundView.topAnchor.constraint(equalTo: topAnchor),
valueBackgroundView.trailingAnchor.constraint(equalTo: trailingAnchor),
valueBackgroundView.bottomAnchor.constraint(equalTo: bottomAnchor)
])
}
@available(*, unavailable)
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
private extension AccountFieldView {
static let dateFormatter: DateFormatter = {
let formatter = DateFormatter()
formatter.dateStyle = .full
return formatter
}()
}