forked from shadowfacts/Tusker
Dyanmic type support in profile header view
This commit is contained in:
parent
a991e0f429
commit
11233f7d25
|
@ -125,6 +125,7 @@
|
|||
D64D0AAD2128D88B005A6F37 /* LocalData.swift in Sources */ = {isa = PBXBuildFile; fileRef = D64D0AAC2128D88B005A6F37 /* LocalData.swift */; };
|
||||
D64D0AB12128D9AE005A6F37 /* OnboardingViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D64D0AB02128D9AE005A6F37 /* OnboardingViewController.swift */; };
|
||||
D64D8CA92463B494006B0BAA /* MultiThreadDictionary.swift in Sources */ = {isa = PBXBuildFile; fileRef = D64D8CA82463B494006B0BAA /* MultiThreadDictionary.swift */; };
|
||||
D651C5B42915B00400236EF6 /* ProfileFieldsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D651C5B32915B00400236EF6 /* ProfileFieldsView.swift */; };
|
||||
D65234E12561AA68001AF9CF /* NotificationsTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D65234E02561AA68001AF9CF /* NotificationsTableViewController.swift */; };
|
||||
D6531DEE246B81C9000F9538 /* GifvAttachmentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6531DED246B81C9000F9538 /* GifvAttachmentView.swift */; };
|
||||
D6531DF0246B867E000F9538 /* GifvAttachmentViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6531DEF246B867E000F9538 /* GifvAttachmentViewController.swift */; };
|
||||
|
@ -479,6 +480,7 @@
|
|||
D64D0AAC2128D88B005A6F37 /* LocalData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocalData.swift; sourceTree = "<group>"; };
|
||||
D64D0AB02128D9AE005A6F37 /* OnboardingViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingViewController.swift; sourceTree = "<group>"; };
|
||||
D64D8CA82463B494006B0BAA /* MultiThreadDictionary.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MultiThreadDictionary.swift; sourceTree = "<group>"; };
|
||||
D651C5B32915B00400236EF6 /* ProfileFieldsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileFieldsView.swift; sourceTree = "<group>"; };
|
||||
D65234E02561AA68001AF9CF /* NotificationsTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationsTableViewController.swift; sourceTree = "<group>"; };
|
||||
D6531DED246B81C9000F9538 /* GifvAttachmentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GifvAttachmentView.swift; sourceTree = "<group>"; };
|
||||
D6531DEF246B867E000F9538 /* GifvAttachmentViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GifvAttachmentViewController.swift; sourceTree = "<group>"; };
|
||||
|
@ -1061,6 +1063,7 @@
|
|||
children = (
|
||||
D6412B0A24B0D4C600F5412E /* ProfileHeaderView.xib */,
|
||||
D6412B0C24B0D4CF00F5412E /* ProfileHeaderView.swift */,
|
||||
D651C5B32915B00400236EF6 /* ProfileFieldsView.swift */,
|
||||
);
|
||||
path = "Profile Header";
|
||||
sourceTree = "<group>";
|
||||
|
@ -1816,6 +1819,7 @@
|
|||
D6BC9DD7232D7811002CA326 /* TimelinesPageViewController.swift in Sources */,
|
||||
D60E2F2E244248BF005F8713 /* MastodonCachePersistentStore.swift in Sources */,
|
||||
D620483623D38075008A63EF /* ContentTextView.swift in Sources */,
|
||||
D651C5B42915B00400236EF6 /* ProfileFieldsView.swift in Sources */,
|
||||
D6F2E965249E8BFD005846BB /* IssueReporterViewController.swift in Sources */,
|
||||
D6A57408255C53EC00674551 /* ComposeTextViewCaretScrolling.swift in Sources */,
|
||||
D6CA6A94249FADE700AD45C1 /* GalleryPlayerViewController.swift in Sources */,
|
||||
|
|
|
@ -10,9 +10,17 @@ import UIKit
|
|||
|
||||
class LinkTextView: UITextView {
|
||||
|
||||
override func awakeFromNib() {
|
||||
super.awakeFromNib()
|
||||
override init(frame: CGRect, textContainer: NSTextContainer?) {
|
||||
super.init(frame: frame, textContainer: textContainer)
|
||||
commonInit()
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
super.init(coder: coder)
|
||||
commonInit()
|
||||
}
|
||||
|
||||
private func commonInit() {
|
||||
delaysContentTouches = false
|
||||
isScrollEnabled = false
|
||||
isEditable = false
|
||||
|
|
|
@ -0,0 +1,160 @@
|
|||
//
|
||||
// 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)
|
||||
}
|
||||
|
||||
}
|
|
@ -36,9 +36,7 @@ class ProfileHeaderView: UIView {
|
|||
@IBOutlet weak var usernameLabel: UILabel!
|
||||
@IBOutlet weak var followsYouLabel: UILabel!
|
||||
@IBOutlet weak var noteTextView: StatusContentTextView!
|
||||
@IBOutlet weak var fieldsStackView: UIStackView!
|
||||
@IBOutlet weak var fieldNamesStackView: UIStackView!
|
||||
@IBOutlet weak var fieldValuesStackView: UIStackView!
|
||||
@IBOutlet weak var fieldsView: ProfileFieldsView!
|
||||
@IBOutlet weak var pagesSegmentedControl: UISegmentedControl!
|
||||
|
||||
var accountID: String!
|
||||
|
@ -68,12 +66,23 @@ class ProfileHeaderView: UIView {
|
|||
|
||||
moreButton.layer.cornerRadius = 16
|
||||
moreButton.layer.masksToBounds = true
|
||||
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(updateUIForPreferences), name: .preferencesChanged, object: nil)
|
||||
|
||||
moreButton.addInteraction(UIPointerInteraction(delegate: self))
|
||||
moreButton.showsMenuAsPrimaryAction = true
|
||||
moreButton.isContextMenuInteractionEnabled = true
|
||||
|
||||
displayNameLabel.font = UIFontMetrics(forTextStyle: .title1).scaledFont(for: .systemFont(ofSize: 24, weight: .semibold))
|
||||
displayNameLabel.adjustsFontForContentSizeCategory = true
|
||||
|
||||
usernameLabel.font = UIFontMetrics(forTextStyle: .body).scaledFont(for: .systemFont(ofSize: 15, weight: .light))
|
||||
usernameLabel.adjustsFontForContentSizeCategory = true
|
||||
|
||||
followsYouLabel.font = UIFontMetrics(forTextStyle: .body).scaledFont(for: .systemFont(ofSize: 14))
|
||||
followsYouLabel.adjustsFontForContentSizeCategory = true
|
||||
|
||||
noteTextView.defaultFont = .preferredFont(forTextStyle: .body)
|
||||
noteTextView.adjustsFontForContentSizeCategory = true
|
||||
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(updateUIForPreferences), name: .preferencesChanged, object: nil)
|
||||
}
|
||||
|
||||
private func createObservers() {
|
||||
|
@ -128,43 +137,14 @@ class ProfileHeaderView: UIView {
|
|||
}
|
||||
}
|
||||
|
||||
fieldsStackView.isHidden = account.fields.isEmpty
|
||||
|
||||
fieldNamesStackView.arrangedSubviews.forEach { $0.removeFromSuperview() }
|
||||
fieldValuesStackView.arrangedSubviews.forEach { $0.removeFromSuperview() }
|
||||
var fieldAccessibilityElements = [Any]()
|
||||
for field in account.fields {
|
||||
let nameLabel = EmojiLabel()
|
||||
nameLabel.text = field.name
|
||||
nameLabel.font = .boldSystemFont(ofSize: 17)
|
||||
nameLabel.textAlignment = .right
|
||||
nameLabel.numberOfLines = 0
|
||||
nameLabel.lineBreakMode = .byWordWrapping
|
||||
nameLabel.setContentCompressionResistancePriority(.defaultLow, for: .horizontal)
|
||||
nameLabel.setEmojis(account.emojis, identifier: "")
|
||||
fieldNamesStackView.addArrangedSubview(nameLabel)
|
||||
|
||||
let valueTextView = ContentTextView()
|
||||
valueTextView.isSelectable = false
|
||||
valueTextView.font = .systemFont(ofSize: 17)
|
||||
valueTextView.setTextFromHtml(field.value)
|
||||
valueTextView.setEmojis(account.emojis, identifier: account.id)
|
||||
valueTextView.textAlignment = .left
|
||||
valueTextView.awakeFromNib()
|
||||
valueTextView.navigationDelegate = delegate
|
||||
valueTextView.setContentCompressionResistancePriority(.defaultLow, for: .horizontal)
|
||||
fieldValuesStackView.addArrangedSubview(valueTextView)
|
||||
|
||||
nameLabel.heightAnchor.constraint(equalTo: valueTextView.heightAnchor).isActive = true
|
||||
fieldAccessibilityElements.append(nameLabel)
|
||||
fieldAccessibilityElements.append(valueTextView)
|
||||
}
|
||||
fieldsView.updateUI(account: account)
|
||||
|
||||
accessibilityElements = [
|
||||
displayNameLabel!,
|
||||
usernameLabel!,
|
||||
noteTextView!,
|
||||
] + fieldAccessibilityElements + [
|
||||
// TODO: voiceover for fieldsview
|
||||
// fieldsView!,
|
||||
moreButton!,
|
||||
pagesSegmentedControl!,
|
||||
]
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="18121" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="21507" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
|
||||
<device id="retina6_1" orientation="portrait" appearance="light"/>
|
||||
<dependencies>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="18091"/>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="21505"/>
|
||||
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
|
||||
<capability name="System colors in document resources" minToolsVersion="11.0"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
|
@ -14,13 +15,13 @@
|
|||
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
|
||||
<subviews>
|
||||
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="dgG-dR-lSv">
|
||||
<rect key="frame" x="0.0" y="44" width="414" height="150"/>
|
||||
<rect key="frame" x="0.0" y="48" width="414" height="150"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="150" id="aCE-CA-XWm"/>
|
||||
</constraints>
|
||||
</imageView>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="wT9-2J-uSY">
|
||||
<rect key="frame" x="16" y="134" width="120" height="120"/>
|
||||
<rect key="frame" x="16" y="138" width="120" height="120"/>
|
||||
<subviews>
|
||||
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="TkY-oK-if4">
|
||||
<rect key="frame" x="2" y="2" width="116" height="116"/>
|
||||
|
@ -38,14 +39,14 @@
|
|||
<constraint firstItem="TkY-oK-if4" firstAttribute="centerX" secondItem="wT9-2J-uSY" secondAttribute="centerX" id="ozz-sa-gSc"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Display name" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" minimumFontSize="10" adjustsLetterSpacingToFitWidth="YES" translatesAutoresizingMaskIntoConstraints="NO" id="vcl-Gl-kXl" customClass="EmojiLabel" customModule="Tusker" customModuleProvider="target">
|
||||
<rect key="frame" x="144" y="202" width="254" height="24"/>
|
||||
<fontDescription key="fontDescription" type="system" weight="semibold" pointSize="20"/>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" text="Display name" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="10" adjustsLetterSpacingToFitWidth="YES" translatesAutoresizingMaskIntoConstraints="NO" id="vcl-Gl-kXl" customClass="EmojiLabel" customModule="Tusker" customModuleProvider="target">
|
||||
<rect key="frame" x="144" y="206" width="254" height="32"/>
|
||||
<fontDescription key="fontDescription" type="system" weight="semibold" pointSize="24"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="bRJ-Xf-kc9" customClass="VisualEffectImageButton" customModule="Tusker" customModuleProvider="target">
|
||||
<rect key="frame" x="374" y="154" width="32" height="32"/>
|
||||
<rect key="frame" x="374" y="158" width="32" height="32"/>
|
||||
<viewLayoutGuide key="safeArea" id="kQa-ou-pQz"/>
|
||||
<accessibility key="accessibilityConfiguration" label="More Actions">
|
||||
<accessibilityTraits key="traits" button="YES"/>
|
||||
|
@ -59,7 +60,7 @@
|
|||
</userDefinedRuntimeAttributes>
|
||||
</view>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" alignment="top" spacing="8" translatesAutoresizingMaskIntoConstraints="NO" id="u4P-3i-gEq">
|
||||
<rect key="frame" x="16" y="262" width="398" height="600"/>
|
||||
<rect key="frame" x="16" y="419" width="398" height="443"/>
|
||||
<subviews>
|
||||
<label hidden="YES" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Follows you" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="UF8-nI-KVj">
|
||||
<rect key="frame" x="0.0" y="0.0" width="75.5" height="0.0"/>
|
||||
|
@ -68,29 +69,21 @@
|
|||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<textView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" horizontalHuggingPriority="249" verticalHuggingPriority="251" horizontalCompressionResistancePriority="749" scrollEnabled="NO" delaysContentTouches="NO" editable="NO" textAlignment="natural" selectable="NO" translatesAutoresizingMaskIntoConstraints="NO" id="1O8-2P-Gbf" customClass="StatusContentTextView" customModule="Tusker" customModuleProvider="target">
|
||||
<rect key="frame" x="0.0" y="0.0" width="382" height="186.5"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="382" height="259.5"/>
|
||||
<string key="text">Lorem ipsum dolor sit er elit lamet, consectetaur cillium adipisicing pecu, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Nam liber te conscient to factor tum poen legum odioque civiuda.</string>
|
||||
<color key="textColor" systemColor="labelColor"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<textInputTraits key="textInputTraits" autocapitalizationType="sentences"/>
|
||||
</textView>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" verticalHuggingPriority="251" distribution="fillProportionally" spacing="8" translatesAutoresizingMaskIntoConstraints="NO" id="sp4-Zb-00B">
|
||||
<rect key="frame" x="0.0" y="194.5" width="382" height="358"/>
|
||||
<subviews>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="8" translatesAutoresizingMaskIntoConstraints="NO" id="aqG-FA-so5">
|
||||
<rect key="frame" x="0.0" y="0.0" width="186.5" height="358"/>
|
||||
</stackView>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="8" translatesAutoresizingMaskIntoConstraints="NO" id="EfH-Dj-Jmn">
|
||||
<rect key="frame" x="194.5" y="0.0" width="187.5" height="358"/>
|
||||
</stackView>
|
||||
</subviews>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="vKC-m1-Sbs" customClass="ProfileFieldsView" customModule="Tusker" customModuleProvider="target">
|
||||
<rect key="frame" x="0.0" y="267.5" width="398" height="128"/>
|
||||
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
|
||||
<constraints>
|
||||
<constraint firstItem="EfH-Dj-Jmn" firstAttribute="width" relation="greaterThanOrEqual" secondItem="aqG-FA-so5" secondAttribute="width" multiplier="0.5" id="2hZ-pF-C9b"/>
|
||||
<constraint firstItem="EfH-Dj-Jmn" firstAttribute="width" relation="lessThanOrEqual" secondItem="aqG-FA-so5" secondAttribute="width" multiplier="2" id="Lir-Ff-z0m"/>
|
||||
<constraint firstAttribute="height" constant="128" placeholder="YES" id="xbR-M6-H0I"/>
|
||||
</constraints>
|
||||
</stackView>
|
||||
</view>
|
||||
<segmentedControl opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="top" segmentControlStyle="plain" selectedSegmentIndex="0" translatesAutoresizingMaskIntoConstraints="NO" id="n1M-vM-Cj0">
|
||||
<rect key="frame" x="0.0" y="560.5" width="382" height="32"/>
|
||||
<rect key="frame" x="0.0" y="403.5" width="382" height="32"/>
|
||||
<segments>
|
||||
<segment title="Posts"/>
|
||||
<segment title="Posts and Replies"/>
|
||||
|
@ -101,7 +94,7 @@
|
|||
</connections>
|
||||
</segmentedControl>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="5ja-fK-Fqz">
|
||||
<rect key="frame" x="0.0" y="599.5" width="398" height="0.5"/>
|
||||
<rect key="frame" x="0.0" y="442.5" width="398" height="0.5"/>
|
||||
<color key="backgroundColor" systemColor="separatorColor"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="0.5" id="VwS-gV-q8M"/>
|
||||
|
@ -109,14 +102,14 @@
|
|||
</view>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstItem="vKC-m1-Sbs" firstAttribute="width" secondItem="u4P-3i-gEq" secondAttribute="width" id="0dI-ax-7eI"/>
|
||||
<constraint firstItem="n1M-vM-Cj0" firstAttribute="width" secondItem="u4P-3i-gEq" secondAttribute="width" constant="-16" id="9Ds-zl-acc"/>
|
||||
<constraint firstItem="sp4-Zb-00B" firstAttribute="width" secondItem="u4P-3i-gEq" secondAttribute="width" constant="-16" id="Qum-qT-goH"/>
|
||||
<constraint firstItem="5ja-fK-Fqz" firstAttribute="width" secondItem="u4P-3i-gEq" secondAttribute="width" id="azv-le-93y"/>
|
||||
<constraint firstItem="1O8-2P-Gbf" firstAttribute="width" secondItem="u4P-3i-gEq" secondAttribute="width" constant="-16" id="hnA-3G-B9B"/>
|
||||
</constraints>
|
||||
</stackView>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" verticalCompressionResistancePriority="751" text="@username" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="1C3-Pd-QiL">
|
||||
<rect key="frame" x="144" y="234" width="254" height="18"/>
|
||||
<rect key="frame" x="144" y="238" width="254" height="18"/>
|
||||
<fontDescription key="fontDescription" type="system" weight="light" pointSize="15"/>
|
||||
<color key="textColor" systemColor="secondaryLabelColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
|
@ -132,25 +125,24 @@
|
|||
<constraint firstItem="vcl-Gl-kXl" firstAttribute="leading" secondItem="wT9-2J-uSY" secondAttribute="trailing" constant="8" id="8ho-WU-MxW"/>
|
||||
<constraint firstItem="vUN-kp-3ea" firstAttribute="bottom" secondItem="u4P-3i-gEq" secondAttribute="bottom" id="9zc-N2-mfI"/>
|
||||
<constraint firstItem="bRJ-Xf-kc9" firstAttribute="bottom" secondItem="dgG-dR-lSv" secondAttribute="bottom" constant="-8" id="AXS-bG-20Q"/>
|
||||
<constraint firstItem="1C3-Pd-QiL" firstAttribute="bottom" secondItem="TkY-oK-if4" secondAttribute="bottom" id="OpB-YM-gyu"/>
|
||||
<constraint firstItem="1C3-Pd-QiL" firstAttribute="bottom" relation="greaterThanOrEqual" secondItem="TkY-oK-if4" secondAttribute="bottom" id="OpB-YM-gyu"/>
|
||||
<constraint firstItem="dgG-dR-lSv" firstAttribute="leading" secondItem="vUN-kp-3ea" secondAttribute="leading" id="VD1-yc-KSa"/>
|
||||
<constraint firstItem="wT9-2J-uSY" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="16" id="WNS-AR-ff2"/>
|
||||
<constraint firstItem="bRJ-Xf-kc9" firstAttribute="trailing" secondItem="vUN-kp-3ea" secondAttribute="trailing" constant="-8" id="ZB4-ys-9zP"/>
|
||||
<constraint firstItem="1C3-Pd-QiL" firstAttribute="top" relation="greaterThanOrEqual" secondItem="vcl-Gl-kXl" secondAttribute="bottom" id="d0z-X6-Sig"/>
|
||||
<constraint firstItem="1C3-Pd-QiL" firstAttribute="top" secondItem="vcl-Gl-kXl" secondAttribute="bottom" id="d0z-X6-Sig"/>
|
||||
<constraint firstItem="vUN-kp-3ea" firstAttribute="trailing" secondItem="vcl-Gl-kXl" secondAttribute="trailing" constant="16" id="e38-Od-kPg"/>
|
||||
<constraint firstItem="u4P-3i-gEq" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="16" id="hgl-UR-o3W"/>
|
||||
<constraint firstItem="vUN-kp-3ea" firstAttribute="trailing" secondItem="dgG-dR-lSv" secondAttribute="trailing" id="j0d-hY-815"/>
|
||||
<constraint firstItem="vUN-kp-3ea" firstAttribute="trailing" secondItem="1C3-Pd-QiL" secondAttribute="trailing" constant="16" id="pcH-vi-2zH"/>
|
||||
<constraint firstAttribute="trailing" secondItem="u4P-3i-gEq" secondAttribute="trailing" id="ph6-NT-A02"/>
|
||||
<constraint firstItem="u4P-3i-gEq" firstAttribute="top" secondItem="wT9-2J-uSY" secondAttribute="bottom" constant="8" id="tKQ-6d-Z55"/>
|
||||
<constraint firstItem="u4P-3i-gEq" firstAttribute="top" relation="greaterThanOrEqual" secondItem="wT9-2J-uSY" secondAttribute="bottom" constant="8" id="tKQ-6d-Z55"/>
|
||||
<constraint firstItem="u4P-3i-gEq" firstAttribute="top" relation="greaterThanOrEqual" secondItem="vcl-Gl-kXl" secondAttribute="bottom" constant="8" id="xDD-rx-gC0"/>
|
||||
</constraints>
|
||||
<connections>
|
||||
<outlet property="avatarContainerView" destination="wT9-2J-uSY" id="yEm-h7-tfq"/>
|
||||
<outlet property="avatarImageView" destination="TkY-oK-if4" id="bSJ-7z-j4w"/>
|
||||
<outlet property="displayNameLabel" destination="vcl-Gl-kXl" id="64n-a9-my0"/>
|
||||
<outlet property="fieldNamesStackView" destination="aqG-FA-so5" id="prA-n7-blZ"/>
|
||||
<outlet property="fieldValuesStackView" destination="EfH-Dj-Jmn" id="LMk-Hn-EkY"/>
|
||||
<outlet property="fieldsStackView" destination="sp4-Zb-00B" id="eyx-GF-2Wf"/>
|
||||
<outlet property="fieldsView" destination="vKC-m1-Sbs" id="FeE-jh-lYH"/>
|
||||
<outlet property="followsYouLabel" destination="UF8-nI-KVj" id="dTe-DQ-eJV"/>
|
||||
<outlet property="headerImageView" destination="dgG-dR-lSv" id="HXT-v4-2iX"/>
|
||||
<outlet property="moreButton" destination="bRJ-Xf-kc9" id="zIN-pz-L7y"/>
|
||||
|
@ -164,7 +156,7 @@
|
|||
<resources>
|
||||
<image name="ellipsis" catalog="system" width="128" height="37"/>
|
||||
<systemColor name="labelColor">
|
||||
<color white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<color red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</systemColor>
|
||||
<systemColor name="secondaryLabelColor">
|
||||
<color red="0.23529411764705882" green="0.23529411764705882" blue="0.2627450980392157" alpha="0.59999999999999998" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
|
|
|
@ -36,16 +36,22 @@ class StatusMetaIndicatorsView: UIView {
|
|||
|
||||
private func commonInit() {
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(configureImageViews), name: UIAccessibility.boldTextStatusDidChangeNotification, object: nil)
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(configureImageViews), name: UIContentSizeCategory.didChangeNotification, object: nil)
|
||||
}
|
||||
|
||||
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
|
||||
super.traitCollectionDidChange(previousTraitCollection)
|
||||
if isUsingSingleAxis != needsSingleAxis {
|
||||
for image in images {
|
||||
configureImageView(image)
|
||||
}
|
||||
placeImageViews(images)
|
||||
}
|
||||
}
|
||||
|
||||
@objc private func configureImageViews() {
|
||||
for image in images {
|
||||
configureImageView(image)
|
||||
}
|
||||
if isUsingSingleAxis != needsSingleAxis {
|
||||
placeImageViews(images)
|
||||
}
|
||||
}
|
||||
|
||||
private func configureImageView(_ imageView: UIImageView) {
|
||||
|
|
Loading…
Reference in New Issue