From 28b52533f9039b774a571c9fe70e05a9202a96d7 Mon Sep 17 00:00:00 2001 From: Jed Fox Date: Tue, 20 Dec 2022 11:45:20 -0500 Subject: [PATCH] =?UTF-8?q?Add=20a=20non-functional=20=E2=80=9CALT?= =?UTF-8?q?=E2=80=9D=20button=20to=20MediaView?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../View/Content/MediaAltTextOverlay.swift | 62 +++++++++++++++++++ .../MastodonUI/View/Content/MediaView.swift | 36 +++++++++++ 2 files changed, 98 insertions(+) create mode 100644 MastodonSDK/Sources/MastodonUI/View/Content/MediaAltTextOverlay.swift diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/MediaAltTextOverlay.swift b/MastodonSDK/Sources/MastodonUI/View/Content/MediaAltTextOverlay.swift new file mode 100644 index 000000000..91aeb8993 --- /dev/null +++ b/MastodonSDK/Sources/MastodonUI/View/Content/MediaAltTextOverlay.swift @@ -0,0 +1,62 @@ +// +// MediaAltTextOverlay.swift +// +// +// Created by Jed Fox on 2022-12-20. +// + +import SwiftUI + +@available(iOS 15.0, *) +struct MediaAltTextOverlay: View { + var altDescription: String? + + @State private var showingAlt = false + + var body: some View { + HStack { + VStack { + Spacer(minLength: 0) + if altDescription != nil { + Button("ALT") {} + .buttonStyle(AltButtonStyle()) + } + } + Spacer(minLength: 0) + } + .padding(.horizontal, 16) + .padding(.vertical, 8) + .onChange(of: altDescription) { _ in + showingAlt = false + } + } +} + +@available(iOS 15.0, *) +private struct AltButtonStyle: ButtonStyle { + @Environment(\.pixelLength) private var pixelLength + func makeBody(configuration: Configuration) -> some View { + configuration.label + .font(.caption.weight(.semibold)) + .foregroundColor(.white) + .padding(.horizontal, 8) + .padding(.vertical, 3) + .background(Color.black.opacity(0.85)) + .cornerRadius(4) + .opacity(configuration.isPressed ? 0.5 : 1) + .overlay( + .white.opacity(0.4), + in: RoundedRectangle(cornerRadius: 4) + .inset(by: -0.5) + .stroke(lineWidth: 0.5) + ) + } +} + +@available(iOS 15.0, *) +struct MediaAltTextOverlay_Previews: PreviewProvider { + static var previews: some View { + MediaAltTextOverlay(altDescription: nil) + MediaAltTextOverlay(altDescription: "Hello, world!") + } +} diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/MediaView.swift b/MastodonSDK/Sources/MastodonUI/View/Content/MediaView.swift index 2e1a751c0..8ce96674e 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/MediaView.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/MediaView.swift @@ -10,6 +10,7 @@ import AVKit import UIKit import Combine import AlamofireImage +import SwiftUI public final class MediaView: UIView { @@ -71,6 +72,20 @@ public final class MediaView: UIView { return label }() + let _altViewController: UIViewController! = { + if #available(iOS 15.0, *) { + let vc = UIHostingController(rootView: MediaAltTextOverlay()) + vc.view.backgroundColor = .clear + return vc + } else { + return nil + } + }() + @available(iOS 15.0, *) + var altViewController: UIHostingController { + _altViewController as! UIHostingController + } + public override init(frame: CGRect) { super.init(frame: frame) _init() @@ -133,6 +148,7 @@ extension MediaView { imageView.translatesAutoresizingMaskIntoConstraints = false container.addSubview(imageView) imageView.pinToParent() + layoutAlt() } private func bindImage(configuration: Configuration, info: Configuration.ImageInfo) { @@ -151,6 +167,9 @@ extension MediaView { self.imageView.image = image } .store(in: &configuration.disposeBag) + if #available(iOS 15.0, *) { + altViewController.rootView.altDescription = info.altDescription + } } private func layoutGIF() { @@ -161,6 +180,8 @@ extension MediaView { setupIndicatorViewHierarchy() playerIndicatorLabel.attributedText = NSAttributedString(string: "GIF") + + layoutAlt() } private func bindGIF(configuration: Configuration, info: Configuration.VideoInfo) { @@ -171,6 +192,9 @@ extension MediaView { // auto play for GIF player.play() + if #available(iOS 15.0, *) { + altViewController.rootView.altDescription = info.altDescription + } } private func layoutVideo() { @@ -223,6 +247,14 @@ extension MediaView { .store(in: &_disposeBag) } + private func layoutAlt() { + if #available(iOS 15.0, *) { + altViewController.view.translatesAutoresizingMaskIntoConstraints = false + container.addSubview(altViewController.view) + altViewController.view.pinToParent() + } + } + public func prepareForReuse() { _disposeBag.removeAll() @@ -258,6 +290,10 @@ extension MediaView { container.removeFromSuperview() container.removeConstraints(container.constraints) + if #available(iOS 15.0, *) { + altViewController.rootView.altDescription = nil + } + // reset configuration configuration = nil }