From 786be4274a56afb0bf5065c7eba1996a148138f3 Mon Sep 17 00:00:00 2001 From: stepanokdev <100592747+Stepanokdev@users.noreply.github.com> Date: Mon, 16 Oct 2023 16:06:01 +0300 Subject: [PATCH 1/4] add accessibility support --- .../Extensions/UIApplicationExtension.swift | 2 +- Core/Core/View/Base/CourseCellView.swift | 2 ++ Core/Core/View/Base/NavigationBar.swift | 1 + Core/Core/View/Base/StyledButton.swift | 2 ++ .../Presentation/DashboardView.swift | 5 +++- .../Presentation/DiscoveryView.swift | 7 +++++- .../Discovery/Presentation/SearchView.swift | 3 +++ .../Presentation/Profile/ProfileView.swift | 24 +++++++++++++++++-- 8 files changed, 41 insertions(+), 5 deletions(-) diff --git a/Core/Core/Extensions/UIApplicationExtension.swift b/Core/Core/Extensions/UIApplicationExtension.swift index 616b9f466..7a47723fe 100644 --- a/Core/Core/Extensions/UIApplicationExtension.swift +++ b/Core/Core/Extensions/UIApplicationExtension.swift @@ -45,7 +45,7 @@ extension UINavigationController { let image = CoreAssets.arrowLeft.image navigationBar.backIndicatorImage = image.withTintColor(CoreAssets.accentColor.color) - navigationBar.tintColor = .clear + navigationBar.backItem?.backButtonTitle = " " navigationBar.backIndicatorTransitionMaskImage = image.withTintColor(CoreAssets.accentColor.color) navigationBar.titleTextAttributes = [.foregroundColor: CoreAssets.textPrimary.color] } diff --git a/Core/Core/View/Base/CourseCellView.swift b/Core/Core/View/Base/CourseCellView.swift index ae21b2e7f..b7e3b761c 100644 --- a/Core/Core/View/Base/CourseCellView.swift +++ b/Core/Core/View/Base/CourseCellView.swift @@ -98,6 +98,8 @@ public struct CourseCellView: View { } } } + .accessibilityElement(children: .ignore) + .accessibilityLabel(courseName + " " + (type == .dashboard ? courseStart : "")) VStack { if Int(index) != cellsCount { Divider() diff --git a/Core/Core/View/Base/NavigationBar.swift b/Core/Core/View/Base/NavigationBar.swift index 2af6581f9..c30888273 100644 --- a/Core/Core/View/Base/NavigationBar.swift +++ b/Core/Core/View/Base/NavigationBar.swift @@ -58,6 +58,7 @@ public struct NavigationBar: View { }) .foregroundColor(Theme.Colors.styledButtonText) + }.frame(minWidth: 0, maxWidth: .infinity, alignment: .topLeading) diff --git a/Core/Core/View/Base/StyledButton.swift b/Core/Core/View/Base/StyledButton.swift index b16f61a1a..fdad6a1d1 100644 --- a/Core/Core/View/Base/StyledButton.swift +++ b/Core/Core/View/Base/StyledButton.swift @@ -55,6 +55,8 @@ public struct StyledButton: View { .stroke(style: .init(lineWidth: 1, lineCap: .round, lineJoin: .round, miterLimit: 1)) .foregroundColor(isTransparent ? .white : .clear) ) + .accessibilityElement(children: .ignore) + .accessibilityLabel(title) } } diff --git a/Dashboard/Dashboard/Presentation/DashboardView.swift b/Dashboard/Dashboard/Presentation/DashboardView.swift index 4be6e62e7..80edb3ee5 100644 --- a/Dashboard/Dashboard/Presentation/DashboardView.swift +++ b/Dashboard/Dashboard/Presentation/DashboardView.swift @@ -18,6 +18,8 @@ public struct DashboardView: View { .foregroundColor(Theme.Colors.textPrimary) }.listRowBackground(Color.clear) .padding(.top, 24) + .accessibilityElement(children: .ignore) + .accessibilityLabel(DashboardLocalization.Header.courses + DashboardLocalization.Header.welcomeBack) @StateObject private var viewModel: DashboardViewModel @@ -91,7 +93,8 @@ public struct DashboardView: View { } } } - }.frameLimit() + }.accessibilityAction {} + .frameLimit() }.padding(.top, 8) // MARK: - Offline mode SnackBar diff --git a/Discovery/Discovery/Presentation/DiscoveryView.swift b/Discovery/Discovery/Presentation/DiscoveryView.swift index 8ca698572..777fec120 100644 --- a/Discovery/Discovery/Presentation/DiscoveryView.swift +++ b/Discovery/Discovery/Presentation/DiscoveryView.swift @@ -23,6 +23,8 @@ public struct DiscoveryView: View { .font(Theme.Fonts.titleSmall) .foregroundColor(Theme.Colors.textPrimary) }.listRowBackground(Color.clear) + .accessibilityElement(children: .ignore) + .accessibilityLabel(DiscoveryLocalization.Header.title1 + DiscoveryLocalization.Header.title2) public init(viewModel: DiscoveryViewModel, router: DiscoveryRouter) { self._viewModel = StateObject(wrappedValue: { viewModel }()) @@ -64,6 +66,8 @@ public struct DiscoveryView: View { } .padding(.horizontal, 24) .padding(.bottom, 20) + .accessibilityElement(children: .ignore) + .accessibilityLabel(DiscoveryLocalization.search) ZStack { RefreshableScrollViewCompat(action: { @@ -114,7 +118,8 @@ public struct DiscoveryView: View { } VStack {}.frame(height: 40) } - }.frameLimit() + }.accessibilityAction {} + .frameLimit() } }.padding(.top, 8) diff --git a/Discovery/Discovery/Presentation/SearchView.swift b/Discovery/Discovery/Presentation/SearchView.swift index 09e4619cf..2e6816dec 100644 --- a/Discovery/Discovery/Presentation/SearchView.swift +++ b/Discovery/Discovery/Presentation/SearchView.swift @@ -38,6 +38,7 @@ public struct SearchView: View { ? Theme.Colors.accentColor : Theme.Colors.textPrimary ) + .accessibilityHidden(true) TextField( !viewModel.isSearchActive @@ -169,6 +170,8 @@ public struct SearchView: View { .font(Theme.Fonts.titleSmall) .foregroundColor(Theme.Colors.textPrimary) }.listRowBackground(Color.clear) + .accessibilityElement(children: .ignore) + .accessibilityLabel(DiscoveryLocalization.Search.title + searchDescription(viewModel: viewModel)) } private func searchDescription(viewModel: SearchViewModel) -> String { diff --git a/Profile/Profile/Presentation/Profile/ProfileView.swift b/Profile/Profile/Presentation/Profile/ProfileView.swift index 2d61ed18c..f03a69a69 100644 --- a/Profile/Profile/Presentation/Profile/ProfileView.swift +++ b/Profile/Profile/Presentation/Profile/ProfileView.swift @@ -66,6 +66,15 @@ public struct ProfileView: View { } } } + .accessibilityElement(children: .ignore) + .accessibilityLabel( + (viewModel.userModel?.yearOfBirth != 0 ? + ProfileLocalization.Edit.Fields.yearOfBirth + String(viewModel.userModel?.yearOfBirth ?? 0) : + "") + + (viewModel.userModel?.shortBiography != nil ? + ProfileLocalization.bio + (viewModel.userModel?.shortBiography ?? "") : + "") + ) .cardStyle( bgColor: Theme.Colors.textInputUnfocusedBackground, strokeColor: .clear @@ -90,7 +99,10 @@ public struct ProfileView: View { } }) - }.cardStyle( + } + .accessibilityElement(children: .ignore) + .accessibilityLabel(ProfileLocalization.settingsVideo) + .cardStyle( bgColor: Theme.Colors.textInputUnfocusedBackground, strokeColor: .clear ) @@ -113,6 +125,8 @@ public struct ProfileView: View { }) .buttonStyle(PlainButtonStyle()) .foregroundColor(.primary) + .accessibilityElement(children: .ignore) + .accessibilityLabel(ProfileLocalization.supportInfo) Rectangle() .frame(height: 1) .foregroundColor(Theme.Colors.textSecondary) @@ -131,6 +145,8 @@ public struct ProfileView: View { }) .buttonStyle(PlainButtonStyle()) .foregroundColor(.primary) + .accessibilityElement(children: .ignore) + .accessibilityLabel(ProfileLocalization.terms) Rectangle() .frame(height: 1) .foregroundColor(Theme.Colors.textSecondary) @@ -149,6 +165,8 @@ public struct ProfileView: View { }) .buttonStyle(PlainButtonStyle()) .foregroundColor(.primary) + .accessibilityElement(children: .ignore) + .accessibilityLabel(ProfileLocalization.privacy) } }.cardStyle( bgColor: Theme.Colors.textInputUnfocusedBackground, @@ -180,7 +198,9 @@ public struct ProfileView: View { Spacer() Image(systemName: "rectangle.portrait.and.arrow.right") } - }) + }) + .accessibilityElement(children: .ignore) + .accessibilityLabel(ProfileLocalization.logout) } .foregroundColor(Theme.Colors.alert) From 4a04977ebbc6b1a5b95580b94931e0159004d1ae Mon Sep 17 00:00:00 2001 From: stepanokdev <100592747+Stepanokdev@users.noreply.github.com> Date: Tue, 17 Oct 2023 19:34:36 +0300 Subject: [PATCH 2/4] ios 17 fixes --- .../UINavigationController+Animation.swift | 2 +- .../Discovery/Presentation/DiscoveryView.swift | 7 ++++--- Discovery/Discovery/Presentation/SearchView.swift | 13 ++++++------- .../DiscussionSearchTopicsView.swift | 13 ++++++------- .../Discussion/Presentation/Posts/PostsView.swift | 2 +- .../Profile/Presentation/Profile/ProfileView.swift | 3 ++- 6 files changed, 20 insertions(+), 20 deletions(-) diff --git a/Core/Core/Extensions/UINavigationController+Animation.swift b/Core/Core/Extensions/UINavigationController+Animation.swift index 21671ea44..4f720f78c 100644 --- a/Core/Core/Extensions/UINavigationController+Animation.swift +++ b/Core/Core/Extensions/UINavigationController+Animation.swift @@ -24,7 +24,7 @@ public extension UINavigationController { duration: CFTimeInterval = 0.3 ) { addTransition(transitionType: type, duration: duration) - pushViewController(vc, animated: false) + pushViewController(vc, animated: UIAccessibility.isVoiceOverRunning) } private func addTransition( diff --git a/Discovery/Discovery/Presentation/DiscoveryView.swift b/Discovery/Discovery/Presentation/DiscoveryView.swift index 777fec120..34e936b7b 100644 --- a/Discovery/Discovery/Presentation/DiscoveryView.swift +++ b/Discovery/Discovery/Presentation/DiscoveryView.swift @@ -60,7 +60,8 @@ public struct DiscoveryView: View { Theme.Shapes.textInputShape .stroke(lineWidth: 1) .fill(Theme.Colors.textInputUnfocusedStroke) - ).onTapGesture { + ) + .onTapGesture { router.showDiscoverySearch() viewModel.discoverySearchBarClicked() } @@ -118,9 +119,9 @@ public struct DiscoveryView: View { } VStack {}.frame(height: 40) } - }.accessibilityAction {} + } .frameLimit() - } + }.accessibilityAction {} }.padding(.top, 8) // MARK: - Offline mode SnackBar diff --git a/Discovery/Discovery/Presentation/SearchView.swift b/Discovery/Discovery/Presentation/SearchView.swift index 2e6816dec..77dd693c8 100644 --- a/Discovery/Discovery/Presentation/SearchView.swift +++ b/Discovery/Discovery/Presentation/SearchView.swift @@ -10,10 +10,12 @@ import Core public struct SearchView: View { + @FocusState + private var focused: Bool + @ObservedObject private var viewModel: SearchViewModel @State private var animated: Bool = false - @State private var becomeFirstResponderRunOnce = false public init(viewModel: SearchViewModel) { self.viewModel = viewModel @@ -48,13 +50,10 @@ public struct SearchView: View { onEditingChanged: { editing in viewModel.isSearchActive = editing } - ) - .introspect(.textField, on: .iOS(.v14, .v15, .v16, .v17), customize: { textField in - if !becomeFirstResponderRunOnce { - textField.becomeFirstResponder() - self.becomeFirstResponderRunOnce = true + ).focused($focused) + .onAppear { + self.focused = true } - }) .foregroundColor(Theme.Colors.textPrimary) Spacer() if !viewModel.searchText.trimmingCharacters(in: .whitespaces).isEmpty { diff --git a/Discussion/Discussion/Presentation/DiscussionTopics/DiscussionSearchTopicsView.swift b/Discussion/Discussion/Presentation/DiscussionTopics/DiscussionSearchTopicsView.swift index 24d4335da..c1526b020 100644 --- a/Discussion/Discussion/Presentation/DiscussionTopics/DiscussionSearchTopicsView.swift +++ b/Discussion/Discussion/Presentation/DiscussionTopics/DiscussionSearchTopicsView.swift @@ -10,9 +10,11 @@ import Core public struct DiscussionSearchTopicsView: View { + @FocusState + private var focused: Bool + @ObservedObject private var viewModel: DiscussionSearchTopicsViewModel @State private var animated: Bool = false - @State private var becomeFirstResponderRunOnce = false public init(viewModel: DiscussionSearchTopicsViewModel) { self.viewModel = viewModel @@ -44,13 +46,10 @@ public struct DiscussionSearchTopicsView: View { onEditingChanged: { editing in viewModel.isSearchActive = editing } - ) - .introspect(.textField, on: .iOS(.v14, .v15, .v16, .v17), customize: { textField in - if !becomeFirstResponderRunOnce { - textField.becomeFirstResponder() - self.becomeFirstResponderRunOnce = true + ).focused($focused) + .onAppear { + self.focused = true } - }) .foregroundColor(Theme.Colors.textPrimary) Spacer() if !viewModel.searchText.trimmingCharacters(in: .whitespaces).isEmpty { diff --git a/Discussion/Discussion/Presentation/Posts/PostsView.swift b/Discussion/Discussion/Presentation/Posts/PostsView.swift index 906a47ce2..4cd8a227d 100644 --- a/Discussion/Discussion/Presentation/Posts/PostsView.swift +++ b/Discussion/Discussion/Presentation/Posts/PostsView.swift @@ -193,7 +193,7 @@ public struct PostsView: View { } } }.frame(maxWidth: .infinity) - } + }.accessibilityAction {} .padding(.top, 8) if viewModel.isShowProgress { VStack(alignment: .center) { diff --git a/Profile/Profile/Presentation/Profile/ProfileView.swift b/Profile/Profile/Presentation/Profile/ProfileView.swift index f03a69a69..03e8fd932 100644 --- a/Profile/Profile/Presentation/Profile/ProfileView.swift +++ b/Profile/Profile/Presentation/Profile/ProfileView.swift @@ -212,7 +212,8 @@ public struct ProfileView: View { Spacer() } } - }.frameLimit(sizePortrait: 420) + }.accessibilityAction {} + .frameLimit(sizePortrait: 420) .padding(.top, 8) .onChange(of: settingsTapped, perform: { _ in if let userModel = viewModel.userModel { From 78c2a24a54f2512e4f9a813c5b33ef06f01ebfc2 Mon Sep 17 00:00:00 2001 From: stepanokdev <100592747+Stepanokdev@users.noreply.github.com> Date: Wed, 18 Oct 2023 13:33:26 +0300 Subject: [PATCH 3/4] add voiceover to download states on CourseVertical and CourseOutline views --- Core/Core/Extensions/ViewExtension.swift | 2 +- Core/Core/View/Base/NavigationBar.swift | 3 +- .../Container/CourseContainerView.swift | 4 +- .../Outline/CourseOutlineView.swift | 158 ++++++++++-------- .../Outline/CourseVerticalView.swift | 15 +- Course/Course/SwiftGen/Strings.swift | 8 + Course/Course/en.lproj/Localizable.strings | 4 + Course/Course/uk.lproj/Localizable.strings | 4 + .../DiscussionTopicsView.swift | 2 + .../Presentation/Posts/PostsView.swift | 5 +- 10 files changed, 123 insertions(+), 82 deletions(-) diff --git a/Core/Core/Extensions/ViewExtension.swift b/Core/Core/Extensions/ViewExtension.swift index 91a66ed92..8ccc2ae6b 100644 --- a/Core/Core/Extensions/ViewExtension.swift +++ b/Core/Core/Extensions/ViewExtension.swift @@ -263,7 +263,7 @@ public extension Image { .scaledToFit() .frame(height: 24) .padding(.horizontal, 8) - .padding(.top, topPadding) + .offset(y: topPadding) .foregroundColor(color) } } diff --git a/Core/Core/View/Base/NavigationBar.swift b/Core/Core/View/Base/NavigationBar.swift index c30888273..bcfd9837b 100644 --- a/Core/Core/View/Base/NavigationBar.swift +++ b/Core/Core/View/Base/NavigationBar.swift @@ -55,13 +55,14 @@ public struct NavigationBar: View { }, label: { CoreAssets.arrowLeft.swiftUIImage .backButtonStyle(color: leftButtonColor) + .padding(8) }) .foregroundColor(Theme.Colors.styledButtonText) - }.frame(minWidth: 0, maxWidth: .infinity, alignment: .topLeading) + } if rightButtonType != nil { VStack { diff --git a/Course/Course/Presentation/Container/CourseContainerView.swift b/Course/Course/Presentation/Container/CourseContainerView.swift index 574f71b81..c10cb9643 100644 --- a/Course/Course/Presentation/Container/CourseContainerView.swift +++ b/Course/Course/Presentation/Container/CourseContainerView.swift @@ -55,7 +55,7 @@ public struct CourseContainerView: View { title: title, courseID: courseID, isVideo: false - ) + ).accessibilityAction {} .tabItem { CoreAssets.bookCircle.swiftUIImage.renderingMode(.template) Text(CourseLocalization.CourseContainer.course) @@ -67,7 +67,7 @@ public struct CourseContainerView: View { title: title, courseID: courseID, isVideo: true - ) + ).accessibilityAction {} .tabItem { CoreAssets.videoCircle.swiftUIImage.renderingMode(.template) Text(CourseLocalization.CourseContainer.videos) diff --git a/Course/Course/Presentation/Outline/CourseOutlineView.swift b/Course/Course/Presentation/Outline/CourseOutlineView.swift index 19a6fa413..03a5f623f 100644 --- a/Course/Course/Presentation/Outline/CourseOutlineView.swift +++ b/Course/Course/Presentation/Outline/CourseOutlineView.swift @@ -137,11 +137,13 @@ public struct CourseOutlineView: View { } Spacer(minLength: 84) } - }.frameLimit() + } + .frameLimit() .onRightSwipeGesture { viewModel.router.back() } }.padding(.top, 8) + .accessibilityAction {} // MARK: - Offline mode SnackBar OfflineSnackBarView( @@ -208,81 +210,91 @@ struct CourseStructureView: View { ForEach(chapter.childs, id: \.id) { child in let sequentialIndex = chapter.childs.firstIndex(where: { $0.id == child.id }) VStack(alignment: .leading) { - Button( - action: { - if let chapterIndex, let sequentialIndex { - viewModel.trackSequentialClicked(child) - viewModel.router.showCourseVerticalView( - courseID: viewModel.courseStructure?.id ?? "", - courseName: viewModel.courseStructure?.displayName ?? "", - title: child.displayName, - chapters: chapters, - chapterIndex: chapterIndex, - sequentialIndex: sequentialIndex - ) - } - }, - label: { - Group { - if child.completion == 1 { - CoreAssets.finished.swiftUIImage - .renderingMode(.template) - .foregroundColor(.accentColor) - } else { - child.type.image - } - Text(child.displayName) - .font(Theme.Fonts.titleMedium) - .multilineTextAlignment(.leading) - .lineLimit(1) - .frame( - maxWidth: idiom == .pad - ? proxy.size.width * 0.5 - : proxy.size.width * 0.6, - alignment: .leading + HStack { + Button( + action: { + if let chapterIndex, let sequentialIndex { + viewModel.trackSequentialClicked(child) + viewModel.router.showCourseVerticalView( + courseID: viewModel.courseStructure?.id ?? "", + courseName: viewModel.courseStructure?.displayName ?? "", + title: child.displayName, + chapters: chapters, + chapterIndex: chapterIndex, + sequentialIndex: sequentialIndex ) - }.foregroundColor(Theme.Colors.textPrimary) - Spacer() - if let state = viewModel.downloadState[child.id] { - switch state { - case .available: - DownloadAvailableView() - .onTapGesture { - viewModel.onDownloadViewTap( - chapter: chapter, - blockId: child.id, - state: state - ) - } - .onForeground { - viewModel.onForeground() - } - case .downloading: - DownloadProgressView() - .onTapGesture { - viewModel.onDownloadViewTap( - chapter: chapter, - blockId: child.id, - state: state - ) - } - .onBackground { - viewModel.onBackground() - } - case .finished: - DownloadFinishedView() - .onTapGesture { - viewModel.onDownloadViewTap( - chapter: chapter, - blockId: child.id, - state: state - ) - } } + }, + label: { + Group { + if child.completion == 1 { + CoreAssets.finished.swiftUIImage + .renderingMode(.template) + .foregroundColor(.accentColor) + } else { + child.type.image + } + Text(child.displayName) + .font(Theme.Fonts.titleMedium) + .multilineTextAlignment(.leading) + .lineLimit(1) + .frame( + maxWidth: idiom == .pad + ? proxy.size.width * 0.5 + : proxy.size.width * 0.6, + alignment: .leading + ) + }.foregroundColor(Theme.Colors.textPrimary) + }) .accessibilityElement(children: .ignore) + .accessibilityLabel(child.displayName) + Spacer() + if let state = viewModel.downloadState[child.id] { + switch state { + case .available: + DownloadAvailableView() + .accessibilityElement(children: .ignore) + .accessibilityLabel(CourseLocalization.Accessibility.download) + .onTapGesture { + viewModel.onDownloadViewTap( + chapter: chapter, + blockId: child.id, + state: state + ) + } + .onForeground { + viewModel.onForeground() + } + case .downloading: + DownloadProgressView() + .accessibilityElement(children: .ignore) + .accessibilityLabel(CourseLocalization.Accessibility.cancelDownload) + .onTapGesture { + viewModel.onDownloadViewTap( + chapter: chapter, + blockId: child.id, + state: state + ) + } + .onBackground { + viewModel.onBackground() + } + case .finished: + DownloadFinishedView() + .accessibilityElement(children: .ignore) + .accessibilityLabel(CourseLocalization.Accessibility.deleteDownload) + .onTapGesture { + viewModel.onDownloadViewTap( + chapter: chapter, + blockId: child.id, + state: state + ) + } } - Image(systemName: "chevron.right") - .foregroundColor(Theme.Colors.accentColor) - }).padding(.horizontal, 36) + } + Image(systemName: "chevron.right") + .foregroundColor(Theme.Colors.accentColor) + } + .padding(.horizontal, 36) .padding(.vertical, 20) if chapterIndex != chapters.count - 1 { Divider() diff --git a/Course/Course/Presentation/Outline/CourseVerticalView.swift b/Course/Course/Presentation/Outline/CourseVerticalView.swift index 20b1bc56f..b85677818 100644 --- a/Course/Course/Presentation/Outline/CourseVerticalView.swift +++ b/Course/Course/Presentation/Outline/CourseVerticalView.swift @@ -54,6 +54,7 @@ public struct CourseVerticalView: View { // MARK: - Lessons list ForEach(viewModel.verticals, id: \.id) { vertical in if let index = viewModel.verticals.firstIndex(where: {$0.id == vertical.id}) { + HStack { Button(action: { let vertical = viewModel.verticals[index] if let block = vertical.childs.first { @@ -74,7 +75,6 @@ public struct CourseVerticalView: View { ) } }, label: { - HStack { Group { if vertical.completion == 1 { CoreAssets.finished.swiftUIImage @@ -93,11 +93,15 @@ public struct CourseVerticalView: View { .multilineTextAlignment(.leading) .frame(maxWidth: .infinity, alignment: .leading) }.foregroundColor(Theme.Colors.textPrimary) + }).accessibilityElement(children: .ignore) + .accessibilityLabel(vertical.displayName) Spacer() if let state = viewModel.downloadState[vertical.id] { switch state { case .available: DownloadAvailableView() + .accessibilityElement(children: .ignore) + .accessibilityLabel(CourseLocalization.Accessibility.download) .onTapGesture { viewModel.onDownloadViewTap( blockId: vertical.id, @@ -109,6 +113,8 @@ public struct CourseVerticalView: View { } case .downloading: DownloadProgressView() + .accessibilityElement(children: .ignore) + .accessibilityLabel(CourseLocalization.Accessibility.cancelDownload) .onTapGesture { viewModel.onDownloadViewTap( blockId: vertical.id, @@ -120,6 +126,8 @@ public struct CourseVerticalView: View { } case .finished: DownloadFinishedView() + .accessibilityElement(children: .ignore) + .accessibilityLabel(CourseLocalization.Accessibility.deleteDownload) .onTapGesture { viewModel.onDownloadViewTap( blockId: vertical.id, @@ -131,7 +139,7 @@ public struct CourseVerticalView: View { Image(systemName: "chevron.right") .padding(.vertical, 8) } - }).padding(.horizontal, 36) + .padding(.horizontal, 36) .padding(.vertical, 14) if index != viewModel.verticals.count - 1 { Divider() @@ -143,7 +151,8 @@ public struct CourseVerticalView: View { } } Spacer(minLength: 84) - }.frameLimit() + }.accessibilityAction {} + .frameLimit() .onRightSwipeGesture { viewModel.router.back() } diff --git a/Course/Course/SwiftGen/Strings.swift b/Course/Course/SwiftGen/Strings.swift index f5719bf9d..27e677cf7 100644 --- a/Course/Course/SwiftGen/Strings.swift +++ b/Course/Course/SwiftGen/Strings.swift @@ -10,6 +10,14 @@ import Foundation // swiftlint:disable explicit_type_interface function_parameter_count identifier_name line_length // swiftlint:disable nesting type_body_length type_name vertical_whitespace_opening_braces public enum CourseLocalization { + public enum Accessibility { + /// Cancel download + public static let cancelDownload = CourseLocalization.tr("Localizable", "ACCESSIBILITY.CANCEL_DOWNLOAD", fallback: "Cancel download") + /// Delete download + public static let deleteDownload = CourseLocalization.tr("Localizable", "ACCESSIBILITY.DELETE_DOWNLOAD", fallback: "Delete download") + /// Download + public static let download = CourseLocalization.tr("Localizable", "ACCESSIBILITY.DOWNLOAD", fallback: "Download") + } public enum Alert { /// Rotate your device to view this video in full screen. public static let rotateDevice = CourseLocalization.tr("Localizable", "ALERT.ROTATE_DEVICE", fallback: "Rotate your device to view this video in full screen.") diff --git a/Course/Course/en.lproj/Localizable.strings b/Course/Course/en.lproj/Localizable.strings index 0f5edc88f..ccee17ddb 100644 --- a/Course/Course/en.lproj/Localizable.strings +++ b/Course/Course/en.lproj/Localizable.strings @@ -51,3 +51,7 @@ "NOT_AVALIABLE.BUTTON" = "Open in browser"; "SUBTITLES.TITLE" = "Subtitles"; + +"ACCESSIBILITY.DOWNLOAD" = "Download"; +"ACCESSIBILITY.CANCEL_DOWNLOAD" = "Cancel download"; +"ACCESSIBILITY.DELETE_DOWNLOAD" = "Delete download"; diff --git a/Course/Course/uk.lproj/Localizable.strings b/Course/Course/uk.lproj/Localizable.strings index cedc987f1..5ec8fd4b1 100644 --- a/Course/Course/uk.lproj/Localizable.strings +++ b/Course/Course/uk.lproj/Localizable.strings @@ -50,3 +50,7 @@ "NOT_AVALIABLE.BUTTON" = "Відкрити в браузері"; "SUBTITLES.TITLE" = "Субтитри"; + +"ACCESSIBILITY.DOWNLOAD" = "Скачати"; +"ACCESSIBILITY.CANCEL_DOWNLOAD" = "Скасувати завантаження"; +"ACCESSIBILITY.DELETE_DOWNLOAD" = "Видалити файл"; diff --git a/Discussion/Discussion/Presentation/DiscussionTopics/DiscussionTopicsView.swift b/Discussion/Discussion/Presentation/DiscussionTopics/DiscussionTopicsView.swift index 722e1b9fd..4e690d15a 100644 --- a/Discussion/Discussion/Presentation/DiscussionTopics/DiscussionTopicsView.swift +++ b/Discussion/Discussion/Presentation/DiscussionTopics/DiscussionTopicsView.swift @@ -49,6 +49,8 @@ public struct DiscussionTopicsView: View { } .padding(.horizontal, 24) .padding(.bottom, 20) + .accessibilityElement(children: .ignore) + .accessibilityLabel(DiscussionLocalization.Topics.search) // MARK: - Page Body VStack { diff --git a/Discussion/Discussion/Presentation/Posts/PostsView.swift b/Discussion/Discussion/Presentation/Posts/PostsView.swift index 4cd8a227d..4cd46f5cb 100644 --- a/Discussion/Discussion/Presentation/Posts/PostsView.swift +++ b/Discussion/Discussion/Presentation/Posts/PostsView.swift @@ -186,14 +186,15 @@ public struct PostsView: View { } } } - }.frameLimit() + }.accessibilityAction {} + .frameLimit() .animation(nil) .onRightSwipeGesture { router.back() } } }.frame(maxWidth: .infinity) - }.accessibilityAction {} + } .padding(.top, 8) if viewModel.isShowProgress { VStack(alignment: .center) { From c471358c96a296608791769b8a06675fdb26e3dd Mon Sep 17 00:00:00 2001 From: stepanokdev <100592747+Stepanokdev@users.noreply.github.com> Date: Wed, 15 Nov 2023 11:47:58 +0200 Subject: [PATCH 4/4] Update CourseCellView.swift --- Core/Core/View/Base/CourseCellView.swift | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Core/Core/View/Base/CourseCellView.swift b/Core/Core/View/Base/CourseCellView.swift index b7e3b761c..7c6fd419a 100644 --- a/Core/Core/View/Base/CourseCellView.swift +++ b/Core/Core/View/Base/CourseCellView.swift @@ -48,6 +48,7 @@ public struct CourseCellView: View { .cornerRadius(8) .clipShape(RoundedRectangle(cornerRadius: Theme.Shapes.cardImageRadius)) .padding(.leading, 3) + .accessibilityElement(children: .ignore) VStack(alignment: .leading) { Text(courseOrg) @@ -90,6 +91,8 @@ public struct CourseCellView: View { .background(Theme.Colors.background) .opacity(showView ? 1 : 0) .offset(y: showView ? 0 : 20) + .accessibilityElement(children: .ignore) + .accessibilityLabel(courseName + " " + (type == .dashboard ? (courseEnd == "" ? courseStart : courseEnd) : "")) .onAppear { DispatchQueue.main.asyncAfter(deadline: .now()) { withAnimation(.easeInOut(duration: (index <= 5 ? 0.3 : 0.1)) @@ -98,8 +101,7 @@ public struct CourseCellView: View { } } } - .accessibilityElement(children: .ignore) - .accessibilityLabel(courseName + " " + (type == .dashboard ? courseStart : "")) + VStack { if Int(index) != cellsCount { Divider()