From f73dbee1902a3c91c83aa6134382ef713b019a73 Mon Sep 17 00:00:00 2001 From: Krishna Kishore Bandaru Date: Mon, 16 Oct 2023 18:48:49 +0530 Subject: [PATCH] Added rotor for checkbox --- MVMCoreUI/Accessibility/RotorHandler.swift | 45 +++++++++++++------ .../Atoms/Views/CheckboxLabelModel.swift | 3 +- 2 files changed, 34 insertions(+), 14 deletions(-) diff --git a/MVMCoreUI/Accessibility/RotorHandler.swift b/MVMCoreUI/Accessibility/RotorHandler.swift index 2d4b6e9c..5819b198 100644 --- a/MVMCoreUI/Accessibility/RotorHandler.swift +++ b/MVMCoreUI/Accessibility/RotorHandler.swift @@ -13,6 +13,7 @@ fileprivate enum RotorType: String, CaseIterable { case button = "Buttons" case header = "Header" + case checkbox = "Checkbox" var trait: UIAccessibilityTraits { switch self { @@ -20,6 +21,26 @@ fileprivate enum RotorType: String, CaseIterable { return .button case .header: return .header + default: + return .none + } + } + + var modelFilter: ((MoleculeModelProtocol) -> Bool) { + switch self { + case .checkbox: + return { $0 is CheckboxModel } + default: + return { $0.accessibilityTraits?.contains(trait) ?? false } + } + } + + var filter: ((UIView) -> Bool) { + switch self { + case .checkbox: + return { $0 is Checkbox } + default: + return { $0.accessibilityTraits.contains(trait) } } } @@ -35,7 +56,7 @@ fileprivate enum RotorType: String, CaseIterable { } } -public protocol RotorViewElementsProtocol: UIViewController { +public protocol RotorViewElementsProtocol: MVMCoreViewControllerProtocol { var topView: UIView? { get set } var middleView: UIView? { get set } var bottomView: UIView? { get set } @@ -89,7 +110,7 @@ class RotorHandler { private func identifyAndPrepareRotors(_ delegateObject: MVMCoreUIDelegateObject?) { guard UIAccessibility.isVoiceOverRunning, - let currentViewController = (delegateObject?.moleculeDelegate as? (MVMCoreViewControllerProtocol & UIViewController)) else { return } + let currentViewController = (delegateObject?.moleculeDelegate as? (MVMCoreViewControllerProtocol & UIViewController)) else { return } var customRotors: [UIAccessibilityCustomRotor] = [] for type in RotorType.allCases { if let elements = getTraitMappedElements(currentViewController, type: type), @@ -111,34 +132,32 @@ class RotorHandler { accessibilityElements.append(contentsOf: rotorElements) } if let tabBarHidden = (template as? TabPageModelProtocol)?.tabBarHidden, !tabBarHidden { - accessibilityElements.append(contentsOf: (MVMCoreUISplitViewController.main()?.tabBar?.subviews ?? []).filter { - $0.accessibilityTraits.contains(type.trait) - }) + accessibilityElements.append(contentsOf: (MVMCoreUISplitViewController.main()?.tabBar?.subviews ?? []).filter { type.filter($0) }) } return accessibilityElements.compactMap { $0 } } private func getRotorElementsFrom(manager: (MVMCoreViewControllerProtocol & UIViewController)?, type: RotorType) -> [Any]? { guard let elements = (manager as? MVMCoreViewManagerProtocol)?.getAccessibilityElements() as? [UIView] else { return nil } - return MVMCoreUIUtility.findViews(by: MoleculeViewProtocol.self, views: elements).filter { $0.accessibilityTraits.contains(type.trait) } as [Any] + return MVMCoreUIUtility.findViews(by: MoleculeViewProtocol.self, views: elements).filter { type.filter($0) } as [Any] } private func getRotorElementsFrom(template: (MVMCoreViewControllerProtocol & UIViewController)?, type: RotorType) -> [Any]? { guard let template = template as? (RotorViewElementsProtocol & MVMCoreViewControllerProtocol & UIViewController) else { - return MVMCoreUIUtility.findViews(by: UIView.self, views: [template?.view].compactMap { $0 }).filter { $0.accessibilityTraits.contains(type.trait) } as [Any] + return MVMCoreUIUtility.findViews(by: UIView.self, views: [template?.view].compactMap { $0 }).filter { type.filter($0) } as [Any] } - let topViewRotorElements = MVMCoreUIUtility.findViews(by: UIView.self, views: [template.topView].compactMap { $0 }).filter { $0.accessibilityTraits.contains(type.trait) } as [Any] + let topViewRotorElements = MVMCoreUIUtility.findViews(by: UIView.self, views: [template.topView].compactMap { $0 }).filter { type.filter($0) } as [Any] var reusableViewRotorElements: [Any] = [] if let middleView = template.middleView { if middleView.isKind(of: UITableView.self), let template = template as? (any MoleculeListProtocol & ViewController) { reusableViewRotorElements = getRotorElements(from: template, type: type) ?? [] } else { - reusableViewRotorElements = MVMCoreUIUtility.findViews(by: UIView.self, views: [middleView].compactMap { $0 }).filter { $0.accessibilityTraits.contains(type.trait) } as [Any] + reusableViewRotorElements = MVMCoreUIUtility.findViews(by: UIView.self, views: [middleView].compactMap { $0 }).filter { type.filter($0) } as [Any] } } - let bottomViewRotorElements = MVMCoreUIUtility.findViews(by: UIView.self, views: [template.bottomView].compactMap { $0 }).filter { $0.accessibilityTraits.contains(type.trait) } as [Any] - let remainingRotorElements = MVMCoreUIUtility.findViews(by: UIView.self, views: [template.view], excludedViews: [template.topView, template.middleView, template.middleView, template.bottomView].compactMap { $0 }).filter { $0.accessibilityTraits.contains(type.trait) } as [Any] + let bottomViewRotorElements = MVMCoreUIUtility.findViews(by: UIView.self, views: [template.bottomView].compactMap { $0 }).filter { type.filter($0) } as [Any] + let remainingRotorElements = MVMCoreUIUtility.findViews(by: UIView.self, views: [template.view], excludedViews: [template.topView, template.middleView, template.middleView, template.bottomView].compactMap { $0 }).filter { type.filter($0) } as [Any] return topViewRotorElements + reusableViewRotorElements + remainingRotorElements + bottomViewRotorElements } @@ -152,7 +171,7 @@ class RotorHandler { traitIndexPath = indexPath } var result = result - if (model.accessibilityTraits?.contains(type.trait) ?? false), let traitIndexPath { + if type.modelFilter(model), let traitIndexPath { result.append(.init(indexPath: traitIndexPath, model: model)) } return result @@ -179,7 +198,7 @@ class RotorHandler { let controller = self.delegate as? RotorListTypeDelegateProtocol { controller.scrollToRow(at: element.indexPath, at: .middle, animated: false) guard let cellView = controller.cellForRow(at: element.indexPath) else { return UIAccessibilityCustomRotorItemResult() } - rotorElement = MVMCoreUIUtility.findViews(by: MoleculeViewProtocol.self, views: [cellView]).filter { $0.accessibilityTraits.contains(type.trait) && $0.model?.id == element.model.id }.first as Any + rotorElement = MVMCoreUIUtility.findViews(by: MoleculeViewProtocol.self, views: [cellView]).filter { type.filter($0) && $0.model?.id == element.model.id }.first as Any } else { if let viewElement = (rotorElement as? UIView) { let convertedFrame = viewElement.convert(viewElement.frame, to: (self.delegate as? UIViewController)?.view) diff --git a/MVMCoreUI/Atomic/Atoms/Views/CheckboxLabelModel.swift b/MVMCoreUI/Atomic/Atoms/Views/CheckboxLabelModel.swift index ca0acd79..9618cfab 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/CheckboxLabelModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/CheckboxLabelModel.swift @@ -15,7 +15,7 @@ public enum CheckboxPosition: String, Codable { case bottom } -@objcMembers open class CheckboxLabelModel: MoleculeModelProtocol { +@objcMembers open class CheckboxLabelModel: MoleculeModelProtocol, ParentMoleculeModelProtocol { open class var identifier: String { "checkboxLabel" } public var moleculeName: String = CheckboxLabelModel.identifier @DecodableDefault.UUIDString public var id: String @@ -25,6 +25,7 @@ public enum CheckboxPosition: String, Codable { public var checkbox: CheckboxModel public var label: LabelModel + public var children: [MoleculeModelProtocol] { [checkbox, label] } //-------------------------------------------------- // MARK: - Initializer //--------------------------------------------------