From ef80b743da96c965b87ba8983f043b041aeccb0c Mon Sep 17 00:00:00 2001 From: Justin Mazzocchi <2831158+jzzocc@users.noreply.github.com> Date: Tue, 2 Feb 2021 13:04:11 -0800 Subject: [PATCH] VoiceOver wip --- .../Extensions/Date+Extensions.swift | 29 +++++++++++++++++++ .../View Models/NotificationViewModel.swift | 4 +++ .../View Models/StatusViewModel.swift | 14 +-------- .../Content Views/NotificationView.swift | 22 ++++++++++++++ Views/UIKit/Content Views/StatusView.swift | 4 ++- Views/UIKit/StatusBodyView.swift | 2 +- .../NotificationTableViewCell.swift | 1 + 7 files changed, 61 insertions(+), 15 deletions(-) diff --git a/ViewModels/Sources/ViewModels/Extensions/Date+Extensions.swift b/ViewModels/Sources/ViewModels/Extensions/Date+Extensions.swift index 95cf625..94e5c91 100644 --- a/ViewModels/Sources/ViewModels/Extensions/Date+Extensions.swift +++ b/ViewModels/Sources/ViewModels/Extensions/Date+Extensions.swift @@ -30,6 +30,19 @@ extension Date { return Self.abbreviatedDateComponentsFormatter.string(from: self, to: now) } + var accessibilityTimeAgo: String? { + let calendar = Calendar.autoupdatingCurrent + let now = Date() + + if + let oneWeekAgo = calendar.date(byAdding: DateComponents(weekOfMonth: -1), to: now), + oneWeekAgo < self { + return Self.realtiveTimeFormatter.localizedString(for: self, relativeTo: Date()) + } + + return Self.accessibilityFullDateComponentsFormatter.string(from: self) + } + var fullUnitTimeUntil: String? { let calendar = Calendar.autoupdatingCurrent let now = Date() @@ -78,4 +91,20 @@ private extension Date { return dateFormatter }() + + private static let realtiveTimeFormatter: RelativeDateTimeFormatter = { + let dateFormatter = RelativeDateTimeFormatter() + + dateFormatter.unitsStyle = .full + + return dateFormatter + }() + + private static let accessibilityFullDateComponentsFormatter: DateFormatter = { + let dateFormatter = DateFormatter() + + dateFormatter.dateStyle = .long + + return dateFormatter + }() } diff --git a/ViewModels/Sources/ViewModels/View Models/NotificationViewModel.swift b/ViewModels/Sources/ViewModels/View Models/NotificationViewModel.swift index bc2dcb2..aac1799 100644 --- a/ViewModels/Sources/ViewModels/View Models/NotificationViewModel.swift +++ b/ViewModels/Sources/ViewModels/View Models/NotificationViewModel.swift @@ -41,6 +41,10 @@ public extension NotificationViewModel { var time: String? { notificationService.notification.createdAt.timeAgo } + var accessibilityTime: String? { + notificationService.notification.createdAt.accessibilityTimeAgo + } + func accountSelected() { eventsSubject.send( Just(.navigation( diff --git a/ViewModels/Sources/ViewModels/View Models/StatusViewModel.swift b/ViewModels/Sources/ViewModels/View Models/StatusViewModel.swift index 0607f79..1ee5931 100644 --- a/ViewModels/Sources/ViewModels/View Models/StatusViewModel.swift +++ b/ViewModels/Sources/ViewModels/View Models/StatusViewModel.swift @@ -89,11 +89,7 @@ public extension StatusViewModel { var time: String? { statusService.status.displayStatus.createdAt.timeAgo } - var accessibilityTime: String { - Self.accessiblityTimeFormatter.localizedString( - for: statusService.status.displayStatus.createdAt, - relativeTo: Date()) - } + var accessibilityTime: String? { statusService.status.displayStatus.createdAt.accessibilityTimeAgo } var contextParentTime: String { Self.contextParentDateFormatter.string(from: statusService.status.displayStatus.createdAt) @@ -345,14 +341,6 @@ public extension StatusViewModel { } private extension StatusViewModel { - private static let accessiblityTimeFormatter: RelativeDateTimeFormatter = { - let dateFormatter = RelativeDateTimeFormatter() - - dateFormatter.unitsStyle = .full - - return dateFormatter - }() - private static let contextParentDateFormatter: DateFormatter = { let dateFormatter = DateFormatter() diff --git a/Views/UIKit/Content Views/NotificationView.swift b/Views/UIKit/Content Views/NotificationView.swift index c49a3d7..7c8e1db 100644 --- a/Views/UIKit/Content Views/NotificationView.swift +++ b/Views/UIKit/Content Views/NotificationView.swift @@ -159,6 +159,8 @@ private extension NotificationView { avatarButton.bottomAnchor.constraint(equalTo: avatarImageView.bottomAnchor), avatarButton.trailingAnchor.constraint(equalTo: avatarImageView.trailingAnchor) ]) + + isAccessibilityElement = true } func applyNotificationConfiguration() { @@ -218,10 +220,30 @@ private extension NotificationView { } timeLabel.text = viewModel.time + timeLabel.accessibilityLabel = viewModel.accessibilityTime iconImageView.image = UIImage( systemName: viewModel.type.systemImageName, withConfiguration: UIImage.SymbolConfiguration(scale: .medium)) + + let accessibilityAttributedLabel = NSMutableAttributedString(string: "") + + if let typeText = typeLabel.attributedText { + accessibilityAttributedLabel.appendWithSeparator(typeText) + } + + if !statusBodyView.isHidden, + let statusBodyAccessibilityAttributedLabel = statusBodyView.accessibilityAttributedLabel { + accessibilityAttributedLabel.appendWithSeparator(statusBodyAccessibilityAttributedLabel) + } else if !accountLabel.isHidden, let accountText = accountLabel.text { + accessibilityAttributedLabel.appendWithSeparator(accountText) + } + + if let accessibilityTime = viewModel.accessibilityTime { + accessibilityAttributedLabel.appendWithSeparator(accessibilityTime) + } + + self.accessibilityAttributedLabel = accessibilityAttributedLabel } // swiftlint:enable function_body_length } diff --git a/Views/UIKit/Content Views/StatusView.swift b/Views/UIKit/Content Views/StatusView.swift index db23ff5..6d9009c 100644 --- a/Views/UIKit/Content Views/StatusView.swift +++ b/Views/UIKit/Content Views/StatusView.swift @@ -504,7 +504,9 @@ private extension StatusView { accessibilityAttributedLabel.appendWithSeparator(bodyAccessibilityAttributedLabel) } - accessibilityAttributedLabel.appendWithSeparator(viewModel.accessibilityTime) + if let accessibilityTime = viewModel.accessibilityTime { + accessibilityAttributedLabel.appendWithSeparator(accessibilityTime) + } self.accessibilityAttributedLabel = accessibilityAttributedLabel diff --git a/Views/UIKit/StatusBodyView.swift b/Views/UIKit/StatusBodyView.swift index 5e2731e..f639dff 100644 --- a/Views/UIKit/StatusBodyView.swift +++ b/Views/UIKit/StatusBodyView.swift @@ -90,7 +90,7 @@ final class StatusBodyView: UIView { accessibilityAttributedLabel.appendWithSeparator(viewAccessibilityLabel) } - self.accessibilityLabel = accessibilityAttributedLabel.string + self.accessibilityAttributedLabel = accessibilityAttributedLabel } } diff --git a/Views/UIKit/Table View Cells/NotificationTableViewCell.swift b/Views/UIKit/Table View Cells/NotificationTableViewCell.swift index a160224..2fe37ec 100644 --- a/Views/UIKit/Table View Cells/NotificationTableViewCell.swift +++ b/Views/UIKit/Table View Cells/NotificationTableViewCell.swift @@ -10,6 +10,7 @@ final class NotificationTableViewCell: UITableViewCell { guard let viewModel = viewModel else { return } contentConfiguration = NotificationContentConfiguration(viewModel: viewModel).updated(for: state) + accessibilityElements = [contentView] } override func layoutSubviews() {