From 577e2c665a30de9078c644f32edb6f535b5c15e7 Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Sat, 24 Dec 2022 01:02:21 +0100 Subject: [PATCH] [WIP] Replace alt-button on MediaPreview with MediaAltTextOverlay (#806) - Scrolling doesn't work yet - toolbar is broken for now --- Mastodon.xcodeproj/project.pbxproj | 4 - .../MediaPreview/AltViewController.swift | 89 ------------------- .../MediaPreviewViewController.swift | 36 ++++---- 3 files changed, 17 insertions(+), 112 deletions(-) delete mode 100644 Mastodon/Scene/MediaPreview/AltViewController.swift diff --git a/Mastodon.xcodeproj/project.pbxproj b/Mastodon.xcodeproj/project.pbxproj index 0ae425706..a6a27026e 100644 --- a/Mastodon.xcodeproj/project.pbxproj +++ b/Mastodon.xcodeproj/project.pbxproj @@ -103,7 +103,6 @@ 62FD27D52893708A00B205C5 /* BookmarkViewModel+Diffable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62FD27D42893708A00B205C5 /* BookmarkViewModel+Diffable.swift */; }; 85904C02293BC0EB0011C817 /* ImageProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85904C01293BC0EB0011C817 /* ImageProvider.swift */; }; 85904C04293BC1940011C817 /* URLActivityItemWithMetadata.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85904C03293BC1940011C817 /* URLActivityItemWithMetadata.swift */; }; - 85BC11B32932414900E191CD /* AltViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85BC11B22932414900E191CD /* AltViewController.swift */; }; 87FFDA5D898A5C42ADCB35E7 /* Pods_Mastodon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A4ABE34829701A4496C5BB64 /* Pods_Mastodon.framework */; }; C24C97032922F30500BAE8CB /* RefreshControl.swift in Sources */ = {isa = PBXBuildFile; fileRef = C24C97022922F30500BAE8CB /* RefreshControl.swift */; }; D87BFC8B291D5C6B00FEE264 /* MastodonLoginView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D87BFC8A291D5C6B00FEE264 /* MastodonLoginView.swift */; }; @@ -621,7 +620,6 @@ 819CEC9DCAD8E8E7BD85A7BB /* Pods-Mastodon.asdk.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Mastodon.asdk.xcconfig"; path = "Target Support Files/Pods-Mastodon/Pods-Mastodon.asdk.xcconfig"; sourceTree = ""; }; 85904C01293BC0EB0011C817 /* ImageProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageProvider.swift; sourceTree = ""; }; 85904C03293BC1940011C817 /* URLActivityItemWithMetadata.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = URLActivityItemWithMetadata.swift; sourceTree = ""; }; - 85BC11B22932414900E191CD /* AltViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AltViewController.swift; sourceTree = ""; }; 8850E70A1D5FF51432E43653 /* Pods-Mastodon-MastodonUITests.asdk - release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Mastodon-MastodonUITests.asdk - release.xcconfig"; path = "Target Support Files/Pods-Mastodon-MastodonUITests/Pods-Mastodon-MastodonUITests.asdk - release.xcconfig"; sourceTree = ""; }; 8E79CCBE51FBC3F7FE8CF49F /* Pods-MastodonTests.release snapshot.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MastodonTests.release snapshot.xcconfig"; path = "Target Support Files/Pods-MastodonTests/Pods-MastodonTests.release snapshot.xcconfig"; sourceTree = ""; }; 8ED8C4B1F1BA2DCFF2926BB1 /* Pods-Mastodon-NotificationService.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Mastodon-NotificationService.debug.xcconfig"; path = "Target Support Files/Pods-Mastodon-NotificationService/Pods-Mastodon-NotificationService.debug.xcconfig"; sourceTree = ""; }; @@ -1975,7 +1973,6 @@ DB6180F026391CAB0018D199 /* Image */, DB6180E1263919780018D199 /* Paging */, DB6180DC263918E30018D199 /* MediaPreviewViewController.swift */, - 85BC11B22932414900E191CD /* AltViewController.swift */, DB6180F926391F2E0018D199 /* MediaPreviewViewModel.swift */, ); path = MediaPreview; @@ -3532,7 +3529,6 @@ DB9D6BFF25E4F5940051B173 /* ProfileViewController.swift in Sources */, 2D4AD8A226316CD200613EFC /* SelectedAccountSection.swift in Sources */, DB3EA8F1281B9EF600598866 /* DiscoveryCommunityViewModel+Diffable.swift in Sources */, - 85BC11B32932414900E191CD /* AltViewController.swift in Sources */, DB63F775279A997D00455B82 /* NotificationTableViewCell+ViewModel.swift in Sources */, DB98EB5927B109890082E365 /* ReportSupplementaryViewController.swift in Sources */, DB0617EB277EF3820030EE79 /* GradientBorderView.swift in Sources */, diff --git a/Mastodon/Scene/MediaPreview/AltViewController.swift b/Mastodon/Scene/MediaPreview/AltViewController.swift deleted file mode 100644 index a483a45c3..000000000 --- a/Mastodon/Scene/MediaPreview/AltViewController.swift +++ /dev/null @@ -1,89 +0,0 @@ -// -// AltViewController.swift -// Mastodon -// -// Created by Jed Fox on 2022-11-26. -// - -import SwiftUI - -class AltViewController: UIViewController { - private var alt: String - let label = { - return UITextView() - }() - - init(alt: String, sourceView: UIView?) { - self.alt = alt - super.init(nibName: nil, bundle: nil) - self.modalPresentationStyle = .popover - self.popoverPresentationController?.delegate = self - self.popoverPresentationController?.permittedArrowDirections = .up - self.popoverPresentationController?.sourceView = sourceView - self.overrideUserInterfaceStyle = .dark - } - - @MainActor required dynamic init?(coder aDecoder: NSCoder) { - fatalError("init(coder:) has not been implemented") - } - - override func loadView() { - super.loadView() - view.translatesAutoresizingMaskIntoConstraints = false - } - - override func viewDidLoad() { - super.viewDidLoad() - - label.translatesAutoresizingMaskIntoConstraints = false - label.textContainer.maximumNumberOfLines = 0 - label.textContainer.lineBreakMode = .byWordWrapping - label.textContainerInset = UIEdgeInsets( - top: 8, - left: 0, - bottom: -label.textContainer.lineFragmentPadding, - right: 0 - ) - label.font = .preferredFont(forTextStyle: .callout) - label.isScrollEnabled = true - label.backgroundColor = .clear - label.isOpaque = false - label.isEditable = false - label.tintColor = .white - label.text = alt - label.textContainerInset = UIEdgeInsets(top: 12, left: 8, bottom: 8, right: 8) - label.contentInsetAdjustmentBehavior = .always - label.verticalScrollIndicatorInsets.bottom = 4 - - view.backgroundColor = .systemBackground - view.addSubview(label) - - label.pinToParent() - NSLayoutConstraint.activate([ - label.widthAnchor.constraint(lessThanOrEqualToConstant: 400), - ]) - } - - override func viewDidLayoutSubviews() { - super.viewDidLayoutSubviews() - UIView.performWithoutAnimation { - let size = label.layoutManager.boundingRect(forGlyphRange: NSMakeRange(0, (label.textStorage.string as NSString).length), in: label.textContainer).size - preferredContentSize = CGSize( - width: size.width + (8 + label.textContainer.lineFragmentPadding) * 2, - height: size.height + 12 + (label.textContainer.lineFragmentPadding * 2) - ) - } - } - - override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) { - super.traitCollectionDidChange(previousTraitCollection) - label.font = .preferredFont(forTextStyle: .callout) - } -} - -// MARK: UIPopoverPresentationControllerDelegate -extension AltViewController: UIPopoverPresentationControllerDelegate { - func adaptivePresentationStyle(for controller: UIPresentationController, traitCollection: UITraitCollection) -> UIModalPresentationStyle { - .none - } -} diff --git a/Mastodon/Scene/MediaPreview/MediaPreviewViewController.swift b/Mastodon/Scene/MediaPreview/MediaPreviewViewController.swift index 1200c7d85..c61f90a50 100644 --- a/Mastodon/Scene/MediaPreview/MediaPreviewViewController.swift +++ b/Mastodon/Scene/MediaPreview/MediaPreviewViewController.swift @@ -13,6 +13,8 @@ import MastodonAsset import MastodonCore import MastodonUI import MastodonLocalization +import SwiftUI +import MastodonSDK final class MediaPreviewViewController: UIViewController, NeedsDependency { @@ -38,14 +40,11 @@ final class MediaPreviewViewController: UIViewController, NeedsDependency { button.setImage(UIImage(systemName: "xmark", withConfiguration: UIImage.SymbolConfiguration(pointSize: 16, weight: .bold))!, for: .normal) } - let altButton = HUDButton { button in - button.setTitle("ALT", for: .normal) - } - - deinit { - os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s", ((#file as NSString).lastPathComponent), #line, #function) - } - + let altViewController: UIHostingController = { + let vc = UIHostingController(rootView: MediaAltTextOverlay()) + vc.view.backgroundColor = .clear + return vc + }() } extension MediaPreviewViewController { @@ -77,7 +76,10 @@ extension MediaPreviewViewController { closeButton.widthAnchor.constraint(equalToConstant: HUDButton.height).priority(.defaultHigh), ]) - topToolbar.addArrangedSubview(altButton) + altViewController.view.translatesAutoresizingMaskIntoConstraints = false + view.addSubview(altViewController.view) + altViewController.didMove(toParent: self) + altViewController.view.pinToParent() viewModel.mediaPreviewImageViewControllerDelegate = self @@ -86,7 +88,6 @@ extension MediaPreviewViewController { pagingViewController.dataSource = viewModel closeButton.button.addTarget(self, action: #selector(MediaPreviewViewController.closeButtonPressed(_:)), for: .touchUpInside) - altButton.button.addTarget(self, action: #selector(MediaPreviewViewController.altButtonPressed(_:)), for: .touchUpInside) // bind view model viewModel.$currentPage @@ -129,11 +130,14 @@ extension MediaPreviewViewController { .receive(on: DispatchQueue.main) .sink { [weak self] altText in guard let self else { return } + + self.altViewController.rootView.altDescription = altText + UIView.animate(withDuration: 0.3) { if altText == nil { - self.altButton.alpha = 0 - } else { - self.altButton.alpha = 1 +// self.altButton.alpha = 0 +// } else { +// self.altButton.alpha = 1 } } } @@ -178,12 +182,6 @@ extension MediaPreviewViewController { @objc private func closeButtonPressed(_ sender: UIButton) { dismiss(animated: true, completion: nil) } - - @objc private func altButtonPressed(_ sender: UIButton) { - guard let alt = viewModel.altText else { return } - present(AltViewController(alt: alt, sourceView: sender), animated: true) - } - } // MARK: - MediaPreviewingViewController