Add a non-functional “ALT” button to MediaView

This commit is contained in:
Jed Fox 2022-12-20 11:45:20 -05:00
parent c9a7405519
commit 28b52533f9
No known key found for this signature in database
GPG Key ID: 0B61D18EA54B47E1
2 changed files with 98 additions and 0 deletions

View File

@ -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!")
}
}

View File

@ -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<MediaAltTextOverlay> {
_altViewController as! UIHostingController<MediaAltTextOverlay>
}
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
}