From 414df3154aa82e9c5bd2bb35ceaa16355113e955 Mon Sep 17 00:00:00 2001 From: Jed Fox Date: Mon, 20 Mar 2023 03:39:11 -0400 Subject: [PATCH] IOS-92: Enlarge post action buttons at larger text sizes (#927) --- .../Provider/DataSourceFacade+Status.swift | 5 - .../MastodonUI/View/Content/StatusView.swift | 1 - .../View/Control/ActionToolbarContainer.swift | 163 +++++++++--------- 3 files changed, 81 insertions(+), 88 deletions(-) diff --git a/Mastodon/Protocol/Provider/DataSourceFacade+Status.swift b/Mastodon/Protocol/Provider/DataSourceFacade+Status.swift index ad8c44105..dacec8381 100644 --- a/Mastodon/Protocol/Provider/DataSourceFacade+Status.swift +++ b/Mastodon/Protocol/Provider/DataSourceFacade+Status.swift @@ -135,11 +135,6 @@ extension DataSourceFacade { provider: provider, status: status ) - case .bookmark: - try await DataSourceFacade.responseToStatusBookmarkAction( - provider: provider, - status: status - ) case .share: try await DataSourceFacade.responseToStatusShareAction( provider: provider, diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView.swift b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView.swift index 857b2d316..bdb12cd6f 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView.swift @@ -558,7 +558,6 @@ extension StatusView.Style { // action toolbar statusView.actionToolbarAdaptiveMarginContainerView.contentView = statusView.actionToolbarContainer statusView.actionToolbarAdaptiveMarginContainerView.margin = StatusView.containerLayoutMargin - statusView.actionToolbarContainer.configure(for: .inline) statusView.containerStackView.addArrangedSubview(statusView.actionToolbarAdaptiveMarginContainerView) // filterHintLabel diff --git a/MastodonSDK/Sources/MastodonUI/View/Control/ActionToolbarContainer.swift b/MastodonSDK/Sources/MastodonUI/View/Control/ActionToolbarContainer.swift index cf4bdaee7..dca57a181 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Control/ActionToolbarContainer.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Control/ActionToolbarContainer.swift @@ -35,8 +35,12 @@ public final class ActionToolbarContainer: UIView { public weak var delegate: ActionToolbarContainerDelegate? private let container = UIStackView() - private var style: Style? - + private let firstContainer = UIStackView() + private let secondContainer = UIStackView() + + private var isAccessibilityCategory: Bool? + private var shareButtonWidthConstraint: NSLayoutConstraint? + public override init(frame: CGRect) { super.init(frame: frame) _init() @@ -60,32 +64,24 @@ extension ActionToolbarContainer { trailingAnchor.constraint(equalTo: container.trailingAnchor), bottomAnchor.constraint(equalTo: container.bottomAnchor), ]) - + replyButton.addTarget(self, action: #selector(ActionToolbarContainer.buttonDidPressed(_:)), for: .touchUpInside) reblogButton.addTarget(self, action: #selector(ActionToolbarContainer.buttonDidPressed(_:)), for: .touchUpInside) favoriteButton.addTarget(self, action: #selector(ActionToolbarContainer.buttonDidPressed(_:)), for: .touchUpInside) shareButton.addTarget(self, action: #selector(ActionToolbarContainer.buttonDidPressed(_:)), for: .touchUpInside) - } - - public func configure(for style: Style) { - guard needsConfigure(for: style) else { - return - } - - self.style = style - container.arrangedSubviews.forEach { subview in - container.removeArrangedSubview(subview) - subview.removeFromSuperview() - } - + let buttons = [replyButton, reblogButton, favoriteButton, shareButton] buttons.forEach { button in button.tintColor = Asset.Colors.Button.actionToolbar.color - button.titleLabel?.font = .monospacedDigitSystemFont(ofSize: 12, weight: .regular) + button.titleLabel?.font = UIFontMetrics(forTextStyle: .caption1) + .scaledFont(for: .monospacedDigitSystemFont(ofSize: 12, weight: .regular)) + button.titleLabel?.adjustsFontForContentSizeCategory = true button.setTitle("", for: .normal) button.setTitleColor(.secondaryLabel, for: .normal) button.expandEdgeInsets = UIEdgeInsets(top: -10, left: -10, bottom: -10, right: -10) - button.setInsets(forContentPadding: .zero, imageTitlePadding: style.buttonTitleImagePadding) + button.setInsets(forContentPadding: .zero, imageTitlePadding: 4) + button.adjustsImageSizeForAccessibilityContentSizeCategory = true + button.setContentCompressionResistancePriority(.defaultHigh + 100, for: .horizontal) } // add more expand for menu button shareButton.expandEdgeInsets = UIEdgeInsets(top: -10, left: -20, bottom: -10, right: -20) @@ -95,61 +91,79 @@ extension ActionToolbarContainer { favoriteButton.accessibilityLabel = L10n.Common.Controls.Status.Actions.favorite // needs update to follow state shareButton.accessibilityLabel = L10n.Common.Controls.Actions.share - switch style { - case .inline: - buttons.forEach { button in - button.contentHorizontalAlignment = .leading - } - replyButton.setImage(ActionToolbarContainer.replyImage, for: .normal) - reblogButton.setImage(ActionToolbarContainer.reblogImage, for: .normal) - favoriteButton.setImage(ActionToolbarContainer.starImage, for: .normal) - shareButton.setImage(ActionToolbarContainer.shareImage, for: .normal) - + buttons.forEach { button in + button.contentHorizontalAlignment = .leading + } + replyButton.setImage(ActionToolbarContainer.replyImage, for: .normal) + reblogButton.setImage(ActionToolbarContainer.reblogImage, for: .normal) + favoriteButton.setImage(ActionToolbarContainer.starImage, for: .normal) + shareButton.setImage(ActionToolbarContainer.shareImage, for: .normal) + + container.axis = .horizontal + container.distribution = .equalSpacing + + replyButton.translatesAutoresizingMaskIntoConstraints = false + reblogButton.translatesAutoresizingMaskIntoConstraints = false + favoriteButton.translatesAutoresizingMaskIntoConstraints = false + shareButton.translatesAutoresizingMaskIntoConstraints = false + + firstContainer.translatesAutoresizingMaskIntoConstraints = false + firstContainer.axis = .horizontal + firstContainer.distribution = .equalSpacing + + secondContainer.translatesAutoresizingMaskIntoConstraints = false + secondContainer.axis = .horizontal + secondContainer.distribution = .equalSpacing + + shareButton.setContentHuggingPriority(.defaultHigh, for: .horizontal) + shareButton.setContentCompressionResistancePriority(.defaultHigh, for: .horizontal) + + shareButtonWidthConstraint = replyButton.widthAnchor.constraint(equalTo: shareButton.widthAnchor) + + traitCollectionDidChange(nil) + + NSLayoutConstraint.activate([ + replyButton.heightAnchor.constraint(equalToConstant: 36).priority(.defaultHigh), + replyButton.heightAnchor.constraint(equalTo: reblogButton.heightAnchor).priority(.defaultHigh), + replyButton.heightAnchor.constraint(equalTo: favoriteButton.heightAnchor).priority(.defaultHigh), + replyButton.heightAnchor.constraint(equalTo: shareButton.heightAnchor).priority(.defaultHigh), + replyButton.widthAnchor.constraint(equalTo: reblogButton.widthAnchor).priority(.defaultHigh), + replyButton.widthAnchor.constraint(equalTo: favoriteButton.widthAnchor).priority(.defaultHigh), + ]) + } + + public override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) { + super.traitCollectionDidChange(previousTraitCollection) + + let isAccessibilityCategory = traitCollection.preferredContentSizeCategory.isAccessibilityCategory + guard isAccessibilityCategory != self.isAccessibilityCategory else { return } + self.isAccessibilityCategory = isAccessibilityCategory + + if isAccessibilityCategory { + container.axis = .vertical + container.spacing = 12 + + firstContainer.addArrangedSubview(replyButton) + firstContainer.addArrangedSubview(reblogButton) + container.addArrangedSubview(firstContainer) + + secondContainer.addArrangedSubview(favoriteButton) + secondContainer.addArrangedSubview(shareButton) + container.addArrangedSubview(secondContainer) + } else { container.axis = .horizontal - container.distribution = .equalSpacing - - replyButton.translatesAutoresizingMaskIntoConstraints = false - reblogButton.translatesAutoresizingMaskIntoConstraints = false - favoriteButton.translatesAutoresizingMaskIntoConstraints = false - shareButton.translatesAutoresizingMaskIntoConstraints = false + container.spacing = 0 + container.addArrangedSubview(replyButton) container.addArrangedSubview(reblogButton) container.addArrangedSubview(favoriteButton) container.addArrangedSubview(shareButton) - NSLayoutConstraint.activate([ - replyButton.heightAnchor.constraint(equalToConstant: 36).priority(.defaultHigh), - replyButton.heightAnchor.constraint(equalTo: reblogButton.heightAnchor).priority(.defaultHigh), - replyButton.heightAnchor.constraint(equalTo: favoriteButton.heightAnchor).priority(.defaultHigh), - replyButton.heightAnchor.constraint(equalTo: shareButton.heightAnchor).priority(.defaultHigh), - replyButton.widthAnchor.constraint(equalTo: reblogButton.widthAnchor).priority(.defaultHigh), - replyButton.widthAnchor.constraint(equalTo: favoriteButton.widthAnchor).priority(.defaultHigh), - ]) - shareButton.setContentHuggingPriority(.defaultHigh, for: .horizontal) - shareButton.setContentCompressionResistancePriority(.defaultHigh, for: .horizontal) - - case .plain: - buttons.forEach { button in - button.contentHorizontalAlignment = .center - } - replyButton.setImage(ActionToolbarContainer.replyImage, for: .normal) - reblogButton.setImage(ActionToolbarContainer.reblogImage, for: .normal) - favoriteButton.setImage(ActionToolbarContainer.starImage, for: .normal) - - container.axis = .horizontal - container.spacing = 8 - container.distribution = .fillEqually - - container.addArrangedSubview(replyButton) - container.addArrangedSubview(reblogButton) - container.addArrangedSubview(favoriteButton) + + firstContainer.removeFromSuperview() + secondContainer.removeFromSuperview() } + shareButtonWidthConstraint!.isActive = isAccessibilityCategory } - - private func needsConfigure(for style: Style) -> Bool { - guard let oldStyle = self.style else { return true } - return oldStyle != style - } - } extension ActionToolbarContainer { @@ -158,22 +172,9 @@ extension ActionToolbarContainer { case reply case reblog case like - case bookmark case share } - public enum Style { - case inline - case plain - - var buttonTitleImagePadding: CGFloat { - switch self { - case .inline: return 4.0 - case .plain: return 0 - } - } - } - private func isReblogButtonHighlightStateDidChange(to isHighlight: Bool) { let tintColor = isHighlight ? Asset.Colors.successGreen.color : Asset.Colors.Button.actionToolbar.color reblogButton.tintColor = tintColor @@ -302,9 +303,7 @@ struct ActionToolbarContainer_Previews: PreviewProvider { static var previews: some View { Group { UIViewPreview(width: 300) { - let toolbar = ActionToolbarContainer() - toolbar.configure(for: .inline) - return toolbar + ActionToolbarContainer() } .previewLayout(.fixed(width: 300, height: 44)) .previewDisplayName("Inline")