From 8dc475ffdd7ca2cd1fbb6c019eb403b12befcd36 Mon Sep 17 00:00:00 2001 From: Krishna Kishore Bandaru Date: Wed, 11 Oct 2023 00:47:31 +0530 Subject: [PATCH] addressed review comments & added model property to MoleculeViewProtocol --- .../Accessibility/AccessibilityHandler.swift | 322 +++++++++--------- MVMCoreUI/Atomic/Atoms/Selectors/Toggle.swift | 5 - .../Atomic/Atoms/Views/Label/Label.swift | 7 +- .../Atomic/Atoms/Views/ProgressBar.swift | 7 +- MVMCoreUI/Atomic/Atoms/Views/Tilelet.swift | 8 +- .../HorizontalCombinationViews/TabBar.swift | 16 +- .../Protocols/MoleculeViewProtocol.swift | 19 +- MVMCoreUI/BaseClasses/Button.swift | 5 - .../NavigationController.swift | 5 + ...MCoreUISplitViewController+Extension.swift | 5 + .../SubNav/SubNavManagerController.swift | 4 + 11 files changed, 205 insertions(+), 198 deletions(-) diff --git a/MVMCoreUI/Accessibility/AccessibilityHandler.swift b/MVMCoreUI/Accessibility/AccessibilityHandler.swift index c77137a6..f2bfd397 100644 --- a/MVMCoreUI/Accessibility/AccessibilityHandler.swift +++ b/MVMCoreUI/Accessibility/AccessibilityHandler.swift @@ -32,7 +32,13 @@ public class AccessbilityOperation: MVMCoreOperation { return } UIAccessibility.post(notification: self.notificationType, argument: self.argument) - self.markAsFinished() + if self.notificationType == .announcement { + NotificationCenter.default.addObserver(forName: UIAccessibility.announcementDidFinishNotification, object: nil, queue: .main) { _ in + self.markAsFinished() + } + } else { + self.markAsFinished() + } } } @@ -44,125 +50,6 @@ public class AccessbilityOperation: MVMCoreOperation { open class AccessibilityHandler { - public static func shared() -> Self? { - guard let shared = CoreUIObject.sharedInstance()?.accessibilityHandler else { return nil } - return MVMCoreActionUtility.fatalClassCheck(object: shared) - } - - public var previousAccessiblityElement: Any? - public var anyCancellable: Set = [] - public weak var delegate: MVMCoreViewControllerProtocol? - - private var accessibilityOperationQueue: OperationQueue = { - let queue = OperationQueue() - queue.maxConcurrentOperationCount = 1 - return queue - }() - public var accessibilityId: String? - public var hasTopNotificationInPage: Bool = false - - public init() { - registerForPageChanges() - registerForFocusChanges() - } - - // MARK: - Register with Accessibility Handler listeners - private func registerForFocusChanges() { - //Since foucs shifted to other elements cancelling existing focus shift notifications if any - NotificationCenter.default.publisher(for: UIAccessibility.elementFocusedNotification) - .sink { [weak self] _ in - self?.cancelAllOperations() - }.store(in: &anyCancellable) - } - - func registerForTopNotificationsChanges() { - NotificationHandler.shared()?.onNotificationWillShow - .sink { [weak self] (_, model) in - if self?.previousAccessiblityElement == nil { - self?.capturePreviousFocusElement() - } - }.store(in: &anyCancellable) - NotificationHandler.shared()?.onNotificationShown - .sink { [weak self] (view, model) in - self?.post(notification: .layoutChanged, argument: view) - self?.hasTopNotificationInPage = false - }.store(in: &anyCancellable) - NotificationHandler.shared()?.onNotificationWillDismiss - .sink { [weak self] (view, model) in - self?.post(notification: .announcement, argument: MVMCoreUIUtility.hardcodedString(withKey: "AccTopAlertClosed")) - }.store(in: &anyCancellable) - NotificationHandler.shared()?.onNotificationDismissed - .sink { [weak self] (view, model) in - self?.postAccessbilityToPrevElement() - }.store(in: &anyCancellable) - } - - /// Registers to know when pages change. - open func registerForPageChanges() { - NavigationHandler.shared() - .onNavigation - .sink { [self] (event, operation) in - switch event { - case .willNavigate: - willNavigate(operation) - default: - break - } - }.store(in: &anyCancellable) - } - - private func willNavigate(_ operation: NavigationOperation) { - previousAccessiblityElement = nil - if let subNavManagerController = (operation.toNavigationControllerViewControllers?.last as? MVMCoreViewManagerViewControllerProtocol)?.manager as? SubNavManagerController { - delegate = subNavManagerController.getCurrentViewController() as? MVMCoreViewControllerProtocol - } else { - delegate = operation.toNavigationControllerViewControllers?.last as? MVMCoreViewControllerProtocol - } - } - - // MARK: - Accessibility Handler operation events - open func capturePreviousFocusElement() { - previousAccessiblityElement = UIAccessibility.focusedElement(using: .notificationVoiceOver) - } - - open func postAccessbilityToPrevElement() { - post(notification: .layoutChanged, argument: previousAccessiblityElement) - } - - private func add(operation: Operation) { - accessibilityOperationQueue.addOperation(operation) - } - - private func cancelAllOperations() { - accessibilityOperationQueue.cancelAllOperations() - } - - public func post(notification type: UIAccessibility.Notification, argument: Any? = nil) { - guard UIAccessibility.isVoiceOverRunning else { return } - let accessbilityOperation = AccessbilityOperation(notificationType: type, argument: argument) - add(operation: accessbilityOperation) - } - - //To get first focus element on the screen - open func getFirstFocusedElementOnScreen() -> Any? { - (delegate as? UIViewController)?.navigationController?.navigationBar - } - - //Subclass can decide to trigger Accessibility notification on screen change. - open func canPostAccessbilityNotification(for viewController: UIViewController) -> Bool { true } - - func getPreDefinedFocusedElementIfAny() -> UIView? { - guard let accessibilityId, let view = (delegate as? UIViewController)?.view else { return nil } - return MVMCoreUIUtility.findViews(by: MoleculeViewProtocol.self, views: [view]).first { - ($0 as? MoleculeViewModelProtocol)?.moleculeModel?.id == accessibilityId - } - } -} - -// MARK: - Accessibility Handler Behaviour -///Accessibility Handler Behaviour to detect page shown and post notification to first interactive element on screen or the pre-defined focused element. -open class AccessibilityHandlerBehavior: PageVisibilityBehavior, PageMoleculeTransformationBehavior { - enum RotorType: String, CaseIterable { case button = "Buttons" @@ -189,72 +76,121 @@ open class AccessibilityHandlerBehavior: PageVisibilityBehavior, PageMoleculeTra } } - public var anyCancellable: Set = [] - private var delegateObj: MVMCoreUIDelegateObject? - private var rotorIndexes: [RotorType: Int] = [:] + public static func shared() -> Self? { + guard let shared = CoreUIObject.sharedInstance()?.accessibilityHandler else { return nil } + return MVMCoreActionUtility.fatalClassCheck(object: shared) + } - required public init(model: PageBehaviorModelProtocol, delegateObject: MVMCoreUIDelegateObject?) { } + public var accessibilityId: String? + public var previousAccessiblityElement: Any? + public var anyCancellable: Set = [] + public weak var delegate: MVMCoreViewControllerProtocol? + private var rotorIndexes: [RotorType: Int] = [:] + private var hasTopNotificationInPage: Bool { NotificationHandler.shared()?.isNotificationShowing() ?? false } + private let accessibilityOperationQueue: OperationQueue = { + let queue = OperationQueue() + queue.maxConcurrentOperationCount = 1 + return queue + }() + + public init() { + registerForFocusChanges() + } + + // MARK: - Accessibility Handler operation events + open func capturePreviousFocusElement() { + previousAccessiblityElement = UIAccessibility.focusedElement(using: .notificationVoiceOver) + } + + open func postAccessbilityToPrevElement() { + post(notification: .layoutChanged, argument: previousAccessiblityElement) + previousAccessiblityElement = nil + } + + public func post(notification type: UIAccessibility.Notification, argument: Any? = nil) { + guard UIAccessibility.isVoiceOverRunning else { return } + let accessbilityOperation = AccessbilityOperation(notificationType: type, argument: argument) + accessibilityOperationQueue.addOperation(accessbilityOperation) + } + + //To get first focus element on the screen + open func getFirstFocusedElementOnScreen() -> Any? { + (delegate as? UIViewController)?.navigationController?.navigationBar + } + + //Subclass can decide to trigger Accessibility notification on screen change. + open func canPostAccessbilityNotification(for viewController: UIViewController) -> Bool { true } + + func getPreDefinedFocusedElementIfAny() -> UIView? { + guard let accessibilityId, let view = (delegate as? UIViewController)?.view else { return nil } + return MVMCoreUIUtility.findViews(by: MoleculeViewProtocol.self, views: [view]).first { + $0.model?.id == accessibilityId + } + } +} + +extension AccessibilityHandler { public func onPageNew(rootMolecules: [MoleculeModelProtocol], _ delegateObject: MVMCoreUIDelegateObject?) { + rotorIndexes = [:] + previousAccessiblityElement = nil guard let loadObject = (delegateObject?.loadDelegate as? MVMCoreViewControllerProtocol)?.loadObject else { return } - AccessibilityHandler.shared()?.accessibilityId = loadObject?.pageJSON?.optionalStringForKey("accessibilityId") - //TODO: - Need to revisit this logic - AccessibilityHandler.shared()?.hasTopNotificationInPage = loadObject?.responseJSON?.optionalDictionaryForKey("TopNotification") != nil || loadObject?.responseInfoMap?.optionalStringForKey("userMessage") != nil + accessibilityId = loadObject?.pageJSON?.optionalStringForKey("accessibilityId") if let announcementText = loadObject?.pageJSON?.optionalStringForKey("announcementText") { - AccessibilityHandler.shared()?.post(notification: .announcement, argument: announcementText) + post(notification: .announcement, argument: announcementText) } + delegate = delegateObject?.moleculeDelegate as? MVMCoreViewControllerProtocol } //MARK: - PageVisibiltyBehaviour - open func willShowPage(_ delegateObject: MVMCoreUIDelegateObject?) { + public func willShowPage(_ delegateObject: MVMCoreUIDelegateObject?) { updateAccessibilityViews(delegateObject) guard let controller = delegateObject?.moleculeDelegate as? UIViewController, - (AccessibilityHandler.shared()?.canPostAccessbilityNotification(for: controller) ?? true), - AccessibilityHandler.shared()?.accessibilityId == nil else { return } - if AccessibilityHandler.shared()?.hasTopNotificationInPage ?? false { - AccessibilityHandler.shared()?.previousAccessiblityElement = AccessibilityHandler.shared()?.getFirstFocusedElementOnScreen() + canPostAccessbilityNotification(for: controller), + accessibilityId == nil else { return } + if hasTopNotificationInPage { + previousAccessiblityElement = getFirstFocusedElementOnScreen() } else { - AccessibilityHandler.shared()?.post(notification: .layoutChanged, argument: AccessibilityHandler.shared()?.getFirstFocusedElementOnScreen()) + post(notification: .layoutChanged, argument: getFirstFocusedElementOnScreen()) } - delegateObj = delegateObject } ///We need to shift focus to any element mentioned in server response i.e to retain focus of the element in new page, from where action is triggered. ///https://oneconfluence.verizon.com/display/MFD/Accessibility+-+Focus+Retain - open func onPageShown(_ delegateObject: MVMCoreUIDelegateObject?) { - updateAccessibilityViews(delegateObject) //To track FAB & HAB elements on UI - identifyAndPrepareRotors() - guard let accessibilityElement = AccessibilityHandler.shared()?.getPreDefinedFocusedElementIfAny() else { return } - AccessibilityHandler.shared()?.accessibilityId = nil - if AccessibilityHandler.shared()?.hasTopNotificationInPage ?? false { - AccessibilityHandler.shared()?.previousAccessiblityElement = accessibilityElement + public func onPageShown(_ delegateObject: MVMCoreUIDelegateObject?) { + identifyAndPrepareRotors(delegateObject) + DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { + (delegateObject?.moleculeDelegate as? UIViewController)?.view.accessibilityElements = nil + } + guard let accessibilityElement = getPreDefinedFocusedElementIfAny() else { return } + accessibilityId = nil + if hasTopNotificationInPage { + previousAccessiblityElement = accessibilityElement } else { - AccessibilityHandler.shared()?.post(notification: .layoutChanged, argument: accessibilityElement) + post(notification: .layoutChanged, argument: accessibilityElement) } } //MARK: - Accessibility Methods private func updateAccessibilityViews(_ delegateObject: MVMCoreUIDelegateObject?) { - //TODO: - Need to revisit this logic - var accessibilityElements: [Any?] = [MVMCoreUISplitViewController.main()?.topAlertView] - if let managerController = (delegateObject?.moleculeDelegate as? MVMCoreViewManagerViewControllerProtocol)?.manager as? SubNavManagerController { - accessibilityElements.append(managerController.navigationController) - accessibilityElements.append(managerController.tabs) - accessibilityElements.append(contentsOf: managerController.view.subviews) - accessibilityElements.append(MVMCoreUISplitViewController.main()?.tabBar) - managerController.view.accessibilityElements = accessibilityElements.compactMap { $0 } - } else if let controller = delegateObject?.moleculeDelegate as? UIViewController { - accessibilityElements.append(controller.navigationController) - accessibilityElements.append(contentsOf: controller.view.subviews.reversed()) - accessibilityElements.append(MVMCoreUISplitViewController.main()?.tabBar) - controller.view.accessibilityElements = accessibilityElements.compactMap { $0 } + var currentController = delegateObject?.moleculeDelegate as? UIViewController + var accessibilityElements: [Any?] = [MVMCoreUISplitViewController.main()?.topAlertView, MVMCoreUISplitViewController.main()?.navigationController] + if let manager = ((delegateObject?.moleculeDelegate as? MVMCoreViewManagerViewControllerProtocol)?.manager as? MVMCoreViewManagerProtocol & UIViewController), + let managerAccessibilityElements = manager.getAccessibilityElements() { + accessibilityElements.append(contentsOf: managerAccessibilityElements) + accessibilityElements.append(contentsOf: manager.view.subviews) + currentController = manager + } else { + accessibilityElements.append(contentsOf: currentController?.view.subviews ?? []) } + accessibilityElements.append(MVMCoreUISplitViewController.main()?.tabBar) + currentController?.view.accessibilityElements = accessibilityElements.compactMap { $0 } } - + //MARK: - Rotor Methods - private func identifyAndPrepareRotors() { + private func identifyAndPrepareRotors(_ delegateObject: MVMCoreUIDelegateObject?) { var rotorElements: [UIAccessibilityCustomRotor] = [] - let currentViewController = ((delegateObj?.moleculeDelegate as? MVMCoreViewManagerViewControllerProtocol)?.manager as? SubNavManagerController) ?? (delegateObj?.moleculeDelegate as? ViewController) + let currentViewController = ((delegateObject?.moleculeDelegate as? MVMCoreViewManagerViewControllerProtocol)?.manager as? SubNavManagerController) ?? (delegateObject?.moleculeDelegate as? ViewController) for type in RotorType.allCases { if let elements = getTraitMappedElements(currentViewController, type: type), let rotor = createRotor(elements, for: type) { @@ -337,14 +273,76 @@ open class AccessibilityHandlerBehavior: PageVisibilityBehavior, PageMoleculeTra } } var rotorElement = elements[rotorIndex - 1] - if let tableView = (self.delegateObj?.moleculeListDelegate as? MoleculeListTemplate)?.tableView, + if let tableView = (self.delegate as? MoleculeListTemplate)?.tableView, let element = rotorElement as? (model: MoleculeModelProtocol, indexPath: IndexPath) { //for List templates tableView.scrollToRow(at: element.indexPath, at: .middle, animated: false) - rotorElement = MVMCoreUIUtility.findViews(by: MoleculeViewProtocol.self, views: [tableView.cellForRow(at: element.indexPath)].compactMap { $0 }).filter { $0.accessibilityTraits.contains(type.trait) && ($0 as? MoleculeViewModelProtocol)?.moleculeModel?.id == element.model.id }.first as Any + rotorElement = MVMCoreUIUtility.findViews(by: MoleculeViewProtocol.self, views: [tableView.cellForRow(at: element.indexPath)].compactMap { $0 }).filter { $0.accessibilityTraits.contains(type.trait) && $0.model?.id == element.model.id }.first as Any } self.rotorIndexes[type] = rotorIndex - AccessibilityHandler.shared()?.post(notification: .layoutChanged, argument: rotorElement) + post(notification: .layoutChanged, argument: rotorElement) return UIAccessibilityCustomRotorItemResult(targetElement: rotorElement as! NSObjectProtocol, targetRange: nil) } } } + +@objc extension AccessibilityHandler { + + // MARK: - Register with Accessibility Handler listeners + private func registerForFocusChanges() { + //Since focus shifted to other elements cancelling existing focus shift notifications if any + NotificationCenter.default.publisher(for: UIAccessibility.elementFocusedNotification) + .sink { [weak self] _ in + self?.accessibilityOperationQueue.cancelAllOperations() + }.store(in: &anyCancellable) + } + + func registerForTopNotificationsChanges() { + NotificationHandler.shared()?.onNotificationWillShow + .sink { [weak self] (_, model) in + if self?.previousAccessiblityElement == nil { + self?.capturePreviousFocusElement() + } + }.store(in: &anyCancellable) + NotificationHandler.shared()?.onNotificationShown + .sink { [weak self] (view, model) in + self?.post(notification: .layoutChanged, argument: view) + }.store(in: &anyCancellable) + NotificationHandler.shared()?.onNotificationWillDismiss + .sink { [weak self] (view, model) in + self?.post(notification: .announcement, argument: MVMCoreUIUtility.hardcodedString(withKey: "AccTopAlertClosed"), priority: .veryHigh) + }.store(in: &anyCancellable) + NotificationHandler.shared()?.onNotificationDismissed + .sink { [weak self] (view, model) in + self?.postAccessbilityToPrevElement() + }.store(in: &anyCancellable) + } +} + +// MARK: - Accessibility Handler Behaviour +///Accessibility Handler Behaviour to detect page shown and post notification to first interactive element on screen or the pre-defined focused element. +open class AccessibilityHandlerBehavior: PageVisibilityBehavior, PageMoleculeTransformationBehavior { + + public let accessibilityHandler: AccessibilityHandler? + + public init(accessibilityHandler: AccessibilityHandler?) { + self.accessibilityHandler = accessibilityHandler + } + + required public init(model: PageBehaviorModelProtocol, delegateObject: MVMCoreUIDelegateObject?) { + accessibilityHandler = AccessibilityHandler.shared() //Protocol Mandatory init method. + } + + //MARK: - PageMoleculeTransformationBehavior + public func onPageNew(rootMolecules: [MoleculeModelProtocol], _ delegateObject: MVMCoreUIDelegateObject?) { + accessibilityHandler?.onPageNew(rootMolecules: rootMolecules, delegateObject) + } + + //MARK: - PageVisibiltyBehaviour + open func willShowPage(_ delegateObject: MVMCoreUIDelegateObject?) { + accessibilityHandler?.willShowPage(delegateObject) + } + + open func onPageShown(_ delegateObject: MVMCoreUIDelegateObject?) { + accessibilityHandler?.onPageShown(delegateObject) + } +} diff --git a/MVMCoreUI/Atomic/Atoms/Selectors/Toggle.swift b/MVMCoreUI/Atomic/Atoms/Selectors/Toggle.swift index d84efad6..4341614e 100644 --- a/MVMCoreUI/Atomic/Atoms/Selectors/Toggle.swift +++ b/MVMCoreUI/Atomic/Atoms/Selectors/Toggle.swift @@ -418,8 +418,3 @@ extension Toggle { public func horizontalAlignment() -> UIStackView.Alignment { .trailing } } - -extension Toggle: MoleculeViewModelProtocol { - - public var moleculeModel: MoleculeModelProtocol? { model } -} diff --git a/MVMCoreUI/Atomic/Atoms/Views/Label/Label.swift b/MVMCoreUI/Atomic/Atoms/Views/Label/Label.swift index 119fc66b..9af907e1 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/Label/Label.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/Label/Label.swift @@ -44,7 +44,7 @@ public typealias ActionBlock = () -> () public var shouldMaskWhileRecording: Bool = false - private var model: MoleculeModelProtocol? + public var model: MoleculeModelProtocol? //------------------------------------------------------ // MARK: - Multi-Action Text //------------------------------------------------------ @@ -1029,8 +1029,3 @@ func validateAttribute(range: NSRange, in string: NSAttributedString, type: Stri return range } - -extension Label: MoleculeViewModelProtocol { - - public var moleculeModel: MoleculeModelProtocol? { model } -} diff --git a/MVMCoreUI/Atomic/Atoms/Views/ProgressBar.swift b/MVMCoreUI/Atomic/Atoms/Views/ProgressBar.swift index a9fde5c1..a68cdc99 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/ProgressBar.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/ProgressBar.swift @@ -13,8 +13,11 @@ import Foundation //-------------------------------------------------- // MARK: - Properties //-------------------------------------------------- - - var progressBarModel: ProgressBarModel? + public var model: MoleculeModelProtocol? + public var progressBarModel: ProgressBarModel? { + get { model as? ProgressBarModel } + set { model = newValue } + } var thickness: CGFloat = 8.0 { willSet(newValue) { diff --git a/MVMCoreUI/Atomic/Atoms/Views/Tilelet.swift b/MVMCoreUI/Atomic/Atoms/Views/Tilelet.swift index 41d68493..55d83e75 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/Tilelet.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/Tilelet.swift @@ -18,7 +18,13 @@ open class Tilelet: VDS.Tilelet, VDSMoleculeViewProtocol{ //-------------------------------------------------- // MARK: - Properties //-------------------------------------------------- - public var viewModel: TileletModel! + + public var model: MoleculeModelProtocol? + + public var viewModel: TileletModel! { + get { model as? TileletModel } + set { model = newValue } + } public var delegateObject: MVMCoreUIDelegateObject? public var additionalData: [AnyHashable: Any]? diff --git a/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TabBar.swift b/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TabBar.swift index e49006fa..ebc7f469 100644 --- a/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TabBar.swift +++ b/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TabBar.swift @@ -9,7 +9,13 @@ import VDSColorTokens @objcMembers open class TabBar: UITabBar, MoleculeViewProtocol, TabBarProtocol, UITabBarDelegate { - public var model: TabBarModel + public var model: MoleculeModelProtocol? + + public var tabModel: TabBarModel { + get { model as! TabBarModel } + set { model = newValue } + } + public var delegateObject: MVMCoreUIDelegateObject? public let line = Line() @@ -68,8 +74,8 @@ import VDSColorTokens // MARK: - UITabBarDelegate public func tabBar(_ tabBar: UITabBar, didSelect item: UITabBarItem) { - model.selectedTab = item.tag - let action = model.tabs[item.tag].action + tabModel.selectedTab = item.tag + let action = tabModel.tabs[item.tag].action Task(priority: .userInitiated) { try await Button.performButtonAction(with: action, button: item, delegateObject: delegateObject, additionalData: nil) } @@ -79,7 +85,7 @@ import VDSColorTokens public func highlightTab(at index: Int) { MVMCoreDispatchUtility.performBlock(onMainThread: { guard let newSelectedItem = self.items?[index] else { return } - self.model.selectedTab = index + self.tabModel.selectedTab = index self.selectedItem = newSelectedItem }) } @@ -92,7 +98,7 @@ import VDSColorTokens }) } - public func currentTabIndex() -> Int { model.selectedTab } + public func currentTabIndex() -> Int { tabModel.selectedTab } } extension UITabBarItem: MFButtonProtocol { } diff --git a/MVMCoreUI/Atomic/Protocols/MoleculeViewProtocol.swift b/MVMCoreUI/Atomic/Protocols/MoleculeViewProtocol.swift index 1d7ebd03..7dd4fa26 100644 --- a/MVMCoreUI/Atomic/Protocols/MoleculeViewProtocol.swift +++ b/MVMCoreUI/Atomic/Protocols/MoleculeViewProtocol.swift @@ -12,6 +12,8 @@ import MVMCore.MVMCoreViewProtocol public protocol MoleculeViewProtocol: UIView, ModelHandlerProtocol { + var model: MoleculeModelProtocol? { get set } + /// Initializes the view with the model init(model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) @@ -33,6 +35,11 @@ public protocol MoleculeViewProtocol: UIView, ModelHandlerProtocol { extension MoleculeViewProtocol { + public var model: MoleculeModelProtocol? { + get { nil } + set { } + } + /// Calls set with model public init(model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { self.init(frame: .zero) @@ -101,15 +108,3 @@ public extension ModelRegistry { } } } - -public protocol MoleculeViewModelProtocol: UIView { - - var moleculeModel: MoleculeModelProtocol? { get } -} - -public extension MoleculeViewModelProtocol { - - var moleculeModel: MoleculeModelProtocol? { - get { nil } - } -} diff --git a/MVMCoreUI/BaseClasses/Button.swift b/MVMCoreUI/BaseClasses/Button.swift index c744452e..f4c7c418 100644 --- a/MVMCoreUI/BaseClasses/Button.swift +++ b/MVMCoreUI/BaseClasses/Button.swift @@ -165,8 +165,3 @@ extension Button: AppleGuidelinesProtocol { Self.acceptablyOutsideBounds(point: point, bounds: bounds) } } - -extension Button: MoleculeViewModelProtocol { - - public var moleculeModel: MoleculeModelProtocol? { model } -} diff --git a/MVMCoreUI/Containers/NavigationController/NavigationController.swift b/MVMCoreUI/Containers/NavigationController/NavigationController.swift index 8f72a792..5c7a9757 100644 --- a/MVMCoreUI/Containers/NavigationController/NavigationController.swift +++ b/MVMCoreUI/Containers/NavigationController/NavigationController.swift @@ -83,6 +83,11 @@ import Combine } extension NavigationController: MVMCoreViewManagerProtocol { + + public func getAccessibilityElements() -> [Any]? { + nil + } + public func getCurrentViewController() -> UIViewController? { guard let topViewController = topViewController else { return nil } return MVMCoreUIUtility.getViewControllerTraversingManagers(topViewController) diff --git a/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController+Extension.swift b/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController+Extension.swift index 20f4449c..55e1071c 100644 --- a/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController+Extension.swift +++ b/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController+Extension.swift @@ -249,6 +249,11 @@ public extension MVMCoreUISplitViewController { } extension MVMCoreUISplitViewController: MVMCoreViewManagerProtocol { + + public func getAccessibilityElements() -> [Any]? { + nil + } + public func getCurrentViewController() -> UIViewController? { navigationController?.getCurrentViewController() } diff --git a/MVMCoreUI/Managers/SubNav/SubNavManagerController.swift b/MVMCoreUI/Managers/SubNav/SubNavManagerController.swift index 458c0169..24c1ed23 100644 --- a/MVMCoreUI/Managers/SubNav/SubNavManagerController.swift +++ b/MVMCoreUI/Managers/SubNav/SubNavManagerController.swift @@ -307,6 +307,10 @@ open class SubNavManagerController: ViewController, MVMCoreViewManagerProtocol, } } + @objc public func getAccessibilityElements() -> [Any]? { + [tabs] + } + open func newDataReceived(in viewController: UIViewController) { manager?.newDataReceived?(in: viewController) hideNavigationBarLine(true)