Tusker/Tusker/Views/Profile Header/ProfileFieldsView.swift

161 lines
6.0 KiB
Swift

//
// ProfileFieldsView.swift
// Tusker
//
// Created by Shadowfacts on 11/4/22.
// Copyright © 2022 Shadowfacts. All rights reserved.
//
import UIKit
class ProfileFieldsView: UIView {
weak var delegate: ProfileHeaderViewDelegate?
private let stack = UIStackView()
private var fieldViews: [(EmojiLabel, ContentTextView)] = []
private var fieldConstraints: [NSLayoutConstraint] = []
private var isUsingSingleColumn: Bool = false
private var needsSingleColumn: Bool {
traitCollection.preferredContentSizeCategory > .large
}
override init(frame: CGRect) {
super.init(frame: frame)
commonInit()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
commonInit()
}
private func commonInit() {
stack.axis = .vertical
stack.alignment = .fill
stack.translatesAutoresizingMaskIntoConstraints = false
addSubview(stack)
NSLayoutConstraint.activate([
stack.leadingAnchor.constraint(equalTo: leadingAnchor),
stack.trailingAnchor.constraint(equalTo: trailingAnchor),
stack.topAnchor.constraint(equalTo: topAnchor),
stack.bottomAnchor.constraint(equalTo: bottomAnchor),
])
}
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
super.traitCollectionDidChange(previousTraitCollection)
if isUsingSingleColumn != needsSingleColumn {
configureFields()
}
}
func updateUI(account: AccountMO) {
isHidden = account.fields.isEmpty
guard !account.fields.isEmpty else {
return
}
for (name, value) in fieldViews {
name.removeFromSuperview()
value.removeFromSuperview()
}
fieldViews = []
for field in account.fields {
let nameLabel = EmojiLabel()
nameLabel.text = field.name
nameLabel.font = .preferredFont(forTextStyle: .body).withTraits(.traitBold)!
nameLabel.adjustsFontForContentSizeCategory = true
nameLabel.numberOfLines = 0
nameLabel.lineBreakMode = .byWordWrapping
nameLabel.setEmojis(account.emojis, identifier: account.id)
nameLabel.setContentCompressionResistancePriority(.defaultLow, for: .horizontal)
let valueTextView = ContentTextView()
valueTextView.isSelectable = false
valueTextView.defaultFont = .preferredFont(forTextStyle: .body)
valueTextView.adjustsFontForContentSizeCategory = true
valueTextView.setTextFromHtml(field.value)
valueTextView.setEmojis(account.emojis, identifier: account.id)
valueTextView.navigationDelegate = delegate
valueTextView.setContentCompressionResistancePriority(.defaultLow, for: .horizontal)
fieldViews.append((nameLabel, valueTextView))
}
configureFields()
}
@objc private func configureFields() {
guard !isHidden else {
return
}
isUsingSingleColumn = needsSingleColumn
NSLayoutConstraint.deactivate(fieldConstraints)
fieldConstraints = []
stack.arrangedSubviews.forEach { $0.removeFromSuperview() }
if needsSingleColumn {
stack.spacing = 4
var isFirst = true
for (name, value) in fieldViews {
if isFirst {
isFirst = false
} else {
let spacer = UIView()
// don't need any height, since there's 4pts of padding on either side
spacer.heightAnchor.constraint(equalToConstant: 0).isActive = true
stack.addArrangedSubview(spacer)
}
name.textAlignment = .natural
stack.addArrangedSubview(name)
value.textAlignment = .natural
stack.addArrangedSubview(value)
}
} else {
stack.spacing = 8
let dividerLayoutGuide = UILayoutGuide()
addLayoutGuide(dividerLayoutGuide)
fieldConstraints.append(contentsOf: [
dividerLayoutGuide.widthAnchor.constraint(equalToConstant: 8),
])
for (name, value) in fieldViews {
name.textAlignment = .right
name.translatesAutoresizingMaskIntoConstraints = false
value.textAlignment = .left
value.translatesAutoresizingMaskIntoConstraints = false
let fieldContainer = UIView()
fieldContainer.addSubview(name)
fieldContainer.addSubview(value)
stack.addArrangedSubview(fieldContainer)
fieldConstraints.append(contentsOf: [
name.leadingAnchor.constraint(equalTo: fieldContainer.leadingAnchor),
name.trailingAnchor.constraint(equalTo: dividerLayoutGuide.leadingAnchor),
name.topAnchor.constraint(equalTo: fieldContainer.topAnchor),
name.bottomAnchor.constraint(equalTo: fieldContainer.bottomAnchor),
value.leadingAnchor.constraint(equalTo: dividerLayoutGuide.trailingAnchor),
value.trailingAnchor.constraint(equalTo: fieldContainer.trailingAnchor),
value.topAnchor.constraint(equalTo: fieldContainer.topAnchor),
value.bottomAnchor.constraint(equalTo: fieldContainer.bottomAnchor),
name.widthAnchor.constraint(greaterThanOrEqualTo: value.widthAnchor, multiplier: 0.5),
name.widthAnchor.constraint(lessThanOrEqualTo: value.widthAnchor, multiplier: 2),
])
}
}
NSLayoutConstraint.activate(fieldConstraints)
}
}