From 2052e4ddc66c530f3263750d3f3bb72ba9566bb1 Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Wed, 8 Jul 2020 16:30:30 -0400 Subject: [PATCH 01/11] accessibility fixes --- .../BarsCarouselIndicatorModel.swift | 4 + .../CarouselIndicatorModel.swift | 1 + MVMCoreUI/Atomic/Organisms/Carousel.swift | 169 ++++++++++++++++-- .../Atomic/Organisms/CarouselModel.swift | 6 +- 4 files changed, 160 insertions(+), 20 deletions(-) diff --git a/MVMCoreUI/Atomic/Atoms/Views/CarouselIndicator/BarsCarouselIndicatorModel.swift b/MVMCoreUI/Atomic/Atoms/Views/CarouselIndicator/BarsCarouselIndicatorModel.swift index 1b5cae14..314d74c5 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/CarouselIndicator/BarsCarouselIndicatorModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/CarouselIndicator/BarsCarouselIndicatorModel.swift @@ -32,6 +32,10 @@ open class BarsCarouselIndicatorModel: CarouselIndicatorModel { // MARK: - Codec //-------------------------------------------------- + public override init() { + super.init() + } + public required init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) diff --git a/MVMCoreUI/Atomic/Atoms/Views/CarouselIndicator/CarouselIndicatorModel.swift b/MVMCoreUI/Atomic/Atoms/Views/CarouselIndicator/CarouselIndicatorModel.swift index 8bf3fa19..1a9486f6 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/CarouselIndicator/CarouselIndicatorModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/CarouselIndicator/CarouselIndicatorModel.swift @@ -61,6 +61,7 @@ open class CarouselIndicatorModel: CarouselPagingModelProtocol, MoleculeModelPro //-------------------------------------------------- // MARK: - Codec //-------------------------------------------------- + public init() {} required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) diff --git a/MVMCoreUI/Atomic/Organisms/Carousel.swift b/MVMCoreUI/Atomic/Organisms/Carousel.swift index 808c370e..00a05fc8 100644 --- a/MVMCoreUI/Atomic/Organisms/Carousel.swift +++ b/MVMCoreUI/Atomic/Organisms/Carousel.swift @@ -55,7 +55,7 @@ open class Carousel: View { /// The view that we use for paging public var pagingView: (UIView & CarouselPageControlProtocol)? - + /// If the carousel should loop after scrolling past the first and final cells. public var loop = false @@ -179,7 +179,7 @@ open class Carousel: View { numberOfPages = newMolecules.count molecules = newMolecules - if carouselModel?.loop ?? false && newMolecules.count > 1 { + if carouselModel?.loop ?? false && newMolecules.count > 1 && !UIAccessibility.isVoiceOverRunning { // Sets up the row data with buffer cells on each side (for illusion of endless scroll... also has one more buffer cell on each side in case we can peek that cell). loop = true @@ -277,31 +277,57 @@ open class Carousel: View { } } + func trackSwipeActionAnalyticsforIndex(_ index : Int){ + guard let itemModel = molecules?[index], + let viewControllerObject = delegateObject?.moleculeDelegate as? MVMCoreViewControllerProtocol else { return } + MVMCoreUILoggingHandler.shared()?.defaultLogAction(forController: viewControllerObject, actionInformation: itemModel.toJSON(), additionalData: nil) + } + + //-------------------------------------------------- + // MARK: - Accessibility + //-------------------------------------------------- + + /// Sets accessibility for the cell. Only the current cell is accessible. public func setAccessiblity(_ cell: UICollectionViewCell?, index: Int) { guard let cell = cell else { return } - if index == currentIndex { cell.accessibilityElementsHidden = false - var array = cell.accessibilityElements - if let pagingView = pagingView { - if let acc = pagingView.accessibilityElements { - array?.append(contentsOf: acc) - } else { - array?.append(pagingView) - } - } - - accessibilityElements = array + // set to nil to get fresh elements + accessibilityElements = nil } else { cell.accessibilityElementsHidden = true } } - func trackSwipeActionAnalyticsforIndex(_ index : Int){ - guard let itemModel = molecules?[index], - let viewControllerObject = delegateObject?.moleculeDelegate as? MVMCoreViewControllerProtocol else { return } - MVMCoreUILoggingHandler.shared()?.defaultLogAction(forController: viewControllerObject, actionInformation: itemModel.toJSON(), additionalData: nil) + /// Accessibility element that allows for adjustable carousel. + private lazy var carouselAccessibilityElement: CarouselAccessibilityElement = { + let accessibilityElement = CarouselAccessibilityElement(accessibilityContainer: self) + accessibilityElement.accessibilityFrameInContainerSpace = collectionView.frame + return accessibilityElement + }() + + private var _accessibilityElements: [Any]? + + /// Returns the accessibilityElements. If nil, will return current cell and carouselAccessibilityElement + override open var accessibilityElements: [Any]? { + set { + _accessibilityElements = newValue + } + + get { + // Only return custom accessibility if nil. + guard _accessibilityElements == nil else { + return _accessibilityElements + } + + if let currentCell = collectionView.cellForItem(at: IndexPath(row: currentIndex, section: 0)) { + _accessibilityElements = [currentCell, carouselAccessibilityElement] + } else { + _accessibilityElements = [carouselAccessibilityElement] + } + return _accessibilityElements + } } } @@ -347,7 +373,6 @@ extension Carousel: UIScrollViewDelegate { /// Go to the cell at the specified index. func goTo(_ index: Int, animated: Bool) { - showPeaking(false) setAccessiblity(collectionView.cellForItem(at: IndexPath(row: currentIndex, section: 0)), index: index) currentIndex = index @@ -378,7 +403,7 @@ extension Carousel: UIScrollViewDelegate { } } } - + open func scrollViewDidScroll(_ scrollView: UIScrollView) { // Adjust for looping @@ -395,12 +420,15 @@ extension Carousel: UIScrollViewDelegate { // Disable peaking when dragging. dragging = true + guard !UIAccessibility.isVoiceOverRunning else { return } + showPeaking(false) } public func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer) { dragging = false + guard !UIAccessibility.isVoiceOverRunning else { return } // This is for setting up smooth custom paging. (Since UICollectionView only handles paging based on collection view size and not cell size). Math requires that we are using UICollectionViewFlowLayout. guard (model as? CarouselModel)?.paging == true, @@ -464,3 +492,106 @@ extension Carousel: UIScrollViewDelegate { trackSwipeActionAnalyticsforIndex(pageIndex) } } + +// Adapted from: https://developer.apple.com/documentation/uikit/accessibility_for_ios_and_tvos/delivering_an_exceptional_accessibility_experience +/// Ensures a good accessibility experience. Adds adjustable swiping for cards. +class CarouselAccessibilityElement: UIAccessibilityElement { + + /// This indicates to the user what exactly this element is supposed to be. + override var accessibilityLabel: String? { + get { + guard let containerView = accessibilityContainer as? Carousel, + let accessibilityLabel = containerView.accessibilityLabel else { return super.accessibilityLabel } + return accessibilityLabel + } + set { + super.accessibilityLabel = newValue + } + } + + override var accessibilityValue: String? { + get { + // Read which card we are on. + guard let containerView = accessibilityContainer as? Carousel, + let format = MVMCoreUIUtility.hardcodedString(withKey: "index_string_of_total"), + let indexString = MVMCoreUIUtility.getOrdinalString(forIndex: NSNumber(value: containerView.currentIndex + 1)) else { + return super.accessibilityValue + } + return String(format: format, indexString, containerView.numberOfPages) + } + + set { + super.accessibilityValue = newValue + } + } + + // This tells VoiceOver that our element will support the increment and decrement callbacks. + /// - Tag: accessibility_traits + override var accessibilityTraits: UIAccessibilityTraits { + get { + return .adjustable + } + set { + super.accessibilityTraits = newValue + } + } + + /** + A convenience for forward scrolling in both `accessibilityIncrement` and `accessibilityScroll`. + It returns a `Bool` because `accessibilityScroll` needs to know if the scroll was successful. + */ + func accessibilityScrollForward() -> Bool { + guard let containerView = accessibilityContainer as? Carousel else { return false } + + let newIndex = containerView.currentIndex + 1 + guard newIndex < containerView.numberOfPages else { return false } + + containerView.goTo(newIndex, animated: false) + + return true + } + + /** + A convenience for backward scrolling in both `accessibilityIncrement` and `accessibilityScroll`. + It returns a `Bool` because `accessibilityScroll` needs to know if the scroll was successful. + */ + func accessibilityScrollBackward() -> Bool { + guard let containerView = accessibilityContainer as? Carousel else { return false } + + let newIndex = containerView.currentIndex - 1 + guard newIndex >= 0 else { return false } + + containerView.goTo(newIndex, animated: false) + + return true + } + + /* + Overriding the following two methods allows the user to perform increment and decrement actions + (done by swiping up or down). + */ + /// - Tag: accessibility_increment_decrement + override func accessibilityIncrement() { + // This causes the picker to move forward one if the user swipes up. + _ = accessibilityScrollForward() + } + + override func accessibilityDecrement() { + // This causes the picker to move back one if the user swipes down. + _ = accessibilityScrollBackward() + } + + /* + This will cause the picker to move forward or backwards on when the user does a 3-finger swipe, + depending on the direction of the swipe. The return value indicates whether or not the scroll was successful, + so that VoiceOver can alert the user if it was not. + */ + override func accessibilityScroll(_ direction: UIAccessibilityScrollDirection) -> Bool { + if direction == .left { + return accessibilityScrollForward() + } else if direction == .right { + return accessibilityScrollBackward() + } + return false + } +} diff --git a/MVMCoreUI/Atomic/Organisms/CarouselModel.swift b/MVMCoreUI/Atomic/Organisms/CarouselModel.swift index 20915799..ca0a4a10 100644 --- a/MVMCoreUI/Atomic/Organisms/CarouselModel.swift +++ b/MVMCoreUI/Atomic/Organisms/CarouselModel.swift @@ -32,7 +32,8 @@ import UIKit public var useHorizontalMargins: Bool? public var leftPadding: CGFloat? public var rightPadding: CGFloat? - + public var accessibilityText: String? + public init(molecules: [MoleculeModelProtocol & CarouselItemModelProtocol]) { self.molecules = molecules } @@ -57,6 +58,7 @@ import UIKit case useHorizontalMargins case leftPadding case rightPadding + case accessibilityText } //-------------------------------------------------- @@ -83,6 +85,7 @@ import UIKit useHorizontalMargins = try typeContainer.decodeIfPresent(Bool.self, forKey: .useHorizontalMargins) leftPadding = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .leftPadding) rightPadding = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .rightPadding) + accessibilityText = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityText) } public func encode(to encoder: Encoder) throws { @@ -101,5 +104,6 @@ import UIKit try container.encodeIfPresent(useHorizontalMargins, forKey: .useHorizontalMargins) try container.encodeIfPresent(leftPadding, forKey: .leftPadding) try container.encodeIfPresent(rightPadding, forKey: .rightPadding) + try container.encodeIfPresent(accessibilityText, forKey: .accessibilityText) } } From f9a57f5fe5dc9c3a078d71c8dce29aaf869b984a Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Wed, 8 Jul 2020 17:31:34 -0400 Subject: [PATCH 02/11] fixes for pager --- MVMCoreUI/Atomic/Organisms/Carousel.swift | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/MVMCoreUI/Atomic/Organisms/Carousel.swift b/MVMCoreUI/Atomic/Organisms/Carousel.swift index 00a05fc8..e507a999 100644 --- a/MVMCoreUI/Atomic/Organisms/Carousel.swift +++ b/MVMCoreUI/Atomic/Organisms/Carousel.swift @@ -88,7 +88,7 @@ open class Carousel: View { // Go to current cell. layoutIfNeeded is needed otherwise cellForItem returns nil for peaking logic. The dispatch is a sad way to ensure the collection view is ready to be scrolled. guard let model = model as? CarouselModel, - (model.paging == true || model.loop == true) else { return } + (model.paging == true || loop == true) else { return } DispatchQueue.main.async { self.collectionView.scrollToItem(at: IndexPath(row: self.currentIndex, section: 0), at: self.itemAlignment, animated: false) self.collectionView.layoutIfNeeded() @@ -108,6 +108,11 @@ open class Carousel: View { bottomPin = NSLayoutConstraint.constraintPinSubview(toSuperview: collectionView)?[ConstraintBot] as? NSLayoutConstraint collectionViewHeight = collectionView.heightAnchor.constraint(equalToConstant: 300) collectionViewHeight?.isActive = true + + // Fixes defects where it scrolls when it shouldn't with voiceover + if UIAccessibility.isVoiceOverRunning { + collectionView.isScrollEnabled = false + } } open override func updateView(_ size: CGFloat) { @@ -382,6 +387,11 @@ extension Carousel: UIScrollViewDelegate { setAccessiblity(collectionView.cellForItem(at: IndexPath(row: currentIndex, section: 0)), index: index) UIAccessibility.post(notification: .layoutChanged, argument: cell) } + + // Force call if no animation + if !animated { + scrollViewDidEndScrollingAnimation(collectionView) + } } /// Adjusts the current contentOffset if we are going onto buffer cells while looping to help with the endless scrolling appearance. @@ -407,8 +417,7 @@ extension Carousel: UIScrollViewDelegate { open func scrollViewDidScroll(_ scrollView: UIScrollView) { // Adjust for looping - if let model = model as? CarouselModel, - model.loop == true { + if loop == true { adjustOffsetForLooping(scrollView) } From 600d9a977e980778edbcd70eb9c6944526244e6d Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Thu, 9 Jul 2020 11:29:13 -0400 Subject: [PATCH 03/11] accessibility label --- MVMCoreUI/Atomic/Organisms/Carousel.swift | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/MVMCoreUI/Atomic/Organisms/Carousel.swift b/MVMCoreUI/Atomic/Organisms/Carousel.swift index e507a999..0ace27ff 100644 --- a/MVMCoreUI/Atomic/Organisms/Carousel.swift +++ b/MVMCoreUI/Atomic/Organisms/Carousel.swift @@ -76,6 +76,7 @@ open class Carousel: View { open override func layoutSubviews() { super.layoutSubviews() // Accounts for any collection size changes + carouselAccessibilityElement?.accessibilityFrameInContainerSpace = collectionView.frame DispatchQueue.main.async { self.layoutCollection() } @@ -144,7 +145,7 @@ open class Carousel: View { super.set(with: model, delegateObject, additionalData) guard let carouselModel = model as? CarouselModel else { return } - + accessibilityLabel = carouselModel.accessibilityText collectionView.backgroundColor = backgroundColor collectionView.layer.borderColor = backgroundColor?.cgColor collectionView.layer.borderWidth = (carouselModel.border ?? false) ? 1 : 0 @@ -306,11 +307,7 @@ open class Carousel: View { } /// Accessibility element that allows for adjustable carousel. - private lazy var carouselAccessibilityElement: CarouselAccessibilityElement = { - let accessibilityElement = CarouselAccessibilityElement(accessibilityContainer: self) - accessibilityElement.accessibilityFrameInContainerSpace = collectionView.frame - return accessibilityElement - }() + private var carouselAccessibilityElement: CarouselAccessibilityElement? private var _accessibilityElements: [Any]? @@ -325,6 +322,16 @@ open class Carousel: View { guard _accessibilityElements == nil else { return _accessibilityElements } + + // Create the accessibility helper if needed. + let carouselAccessibilityElement: CarouselAccessibilityElement + if let theCarouselAccessibilityElement = self.carouselAccessibilityElement { + carouselAccessibilityElement = theCarouselAccessibilityElement + } else { + carouselAccessibilityElement = CarouselAccessibilityElement(accessibilityContainer: self) + carouselAccessibilityElement.accessibilityFrameInContainerSpace = collectionView.frame + self.carouselAccessibilityElement = carouselAccessibilityElement + } if let currentCell = collectionView.cellForItem(at: IndexPath(row: currentIndex, section: 0)) { _accessibilityElements = [currentCell, carouselAccessibilityElement] From 4469387e4d4c44b27edb4d048dff51fe4345f7d5 Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Thu, 9 Jul 2020 11:40:23 -0400 Subject: [PATCH 04/11] remove now unneeded code --- MVMCoreUI/Atomic/Organisms/Carousel.swift | 2 -- 1 file changed, 2 deletions(-) diff --git a/MVMCoreUI/Atomic/Organisms/Carousel.swift b/MVMCoreUI/Atomic/Organisms/Carousel.swift index 0ace27ff..4fb7b413 100644 --- a/MVMCoreUI/Atomic/Organisms/Carousel.swift +++ b/MVMCoreUI/Atomic/Organisms/Carousel.swift @@ -436,7 +436,6 @@ extension Carousel: UIScrollViewDelegate { // Disable peaking when dragging. dragging = true - guard !UIAccessibility.isVoiceOverRunning else { return } showPeaking(false) } @@ -444,7 +443,6 @@ extension Carousel: UIScrollViewDelegate { public func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer) { dragging = false - guard !UIAccessibility.isVoiceOverRunning else { return } // This is for setting up smooth custom paging. (Since UICollectionView only handles paging based on collection view size and not cell size). Math requires that we are using UICollectionViewFlowLayout. guard (model as? CarouselModel)?.paging == true, From a18152f6b95763c664bc1e19087ea8a630a3a885 Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Thu, 9 Jul 2020 12:18:34 -0400 Subject: [PATCH 05/11] status observer for accessibility changes --- MVMCoreUI/Atomic/Organisms/Carousel.swift | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/MVMCoreUI/Atomic/Organisms/Carousel.swift b/MVMCoreUI/Atomic/Organisms/Carousel.swift index 4fb7b413..6cc67d4e 100644 --- a/MVMCoreUI/Atomic/Organisms/Carousel.swift +++ b/MVMCoreUI/Atomic/Organisms/Carousel.swift @@ -114,6 +114,9 @@ open class Carousel: View { if UIAccessibility.isVoiceOverRunning { collectionView.isScrollEnabled = false } + + // Listen for accessibility changes + NotificationCenter.default.addObserver(self, selector: #selector(accessibilityStatusChanged(_:)), name: UIAccessibility.voiceOverStatusDidChangeNotification, object: nil) } open override func updateView(_ size: CGFloat) { @@ -191,6 +194,8 @@ open class Carousel: View { molecules?.insert(contentsOf: newMolecules.suffix(2), at: 0) molecules?.append(contentsOf: newMolecules.prefix(2)) + } else { + loop = false } pageIndex = 0 @@ -306,6 +311,15 @@ open class Carousel: View { } } + /// Resets view + @objc private func accessibilityStatusChanged(_ sender: Notification) { + // Fixes defects where it scrolls when it shouldn't with voiceover + collectionView.isScrollEnabled = !UIAccessibility.isVoiceOverRunning + if let model = model { + set(with: model, delegateObject, nil) + } + } + /// Accessibility element that allows for adjustable carousel. private var carouselAccessibilityElement: CarouselAccessibilityElement? From 65d2129653a7f404094fa107bd4c4ce735c3c949 Mon Sep 17 00:00:00 2001 From: "Khan, Arshad" Date: Fri, 10 Jul 2020 22:24:36 +0530 Subject: [PATCH 06/11] adding titleView support on navigationBar --- .../Molecules/NavigationBar/NavigationItemModel.swift | 4 ++++ .../ModelProtocols/NavigationItemModelProtocol.swift | 1 + .../ModelProtocols/TabPageModelProtocol.swift | 2 +- .../MVMCoreUISplitViewController+Extension.swift | 10 ++++++++++ 4 files changed, 16 insertions(+), 1 deletion(-) diff --git a/MVMCoreUI/Atomic/Molecules/NavigationBar/NavigationItemModel.swift b/MVMCoreUI/Atomic/Molecules/NavigationBar/NavigationItemModel.swift index d7d677fa..4ba785f3 100644 --- a/MVMCoreUI/Atomic/Molecules/NavigationBar/NavigationItemModel.swift +++ b/MVMCoreUI/Atomic/Molecules/NavigationBar/NavigationItemModel.swift @@ -22,6 +22,7 @@ public class NavigationItemModel: NavigationItemModelProtocol, MoleculeModelProt public var backButton: (NavigationButtonModelProtocol & MoleculeModelProtocol)? = NavigationImageButtonModel(with: "nav_back", action: ActionBackModel()) public var additionalLeftButtons: [(NavigationButtonModelProtocol & MoleculeModelProtocol)]? public var additionalRightButtons: [(NavigationButtonModelProtocol & MoleculeModelProtocol)]? + public var titleView: MoleculeModelProtocol? public init() { hidden = false @@ -43,6 +44,7 @@ public class NavigationItemModel: NavigationItemModelProtocol, MoleculeModelProt case showRightPanelButton case additionalLeftButtons case additionalRightButtons + case titleView } required public init(from decoder: Decoder) throws { @@ -58,6 +60,7 @@ public class NavigationItemModel: NavigationItemModelProtocol, MoleculeModelProt } additionalLeftButtons = try typeContainer.decodeModelsIfPresent(codingKey: .additionalLeftButtons) additionalRightButtons = try typeContainer.decodeModelsIfPresent(codingKey: .additionalRightButtons) + titleView = try typeContainer.decodeModelIfPresent(codingKey: .titleView) } open func encode(to encoder: Encoder) throws { @@ -72,5 +75,6 @@ public class NavigationItemModel: NavigationItemModelProtocol, MoleculeModelProt try container.encodeModelIfPresent(backButton, forKey: .backButton) try container.encodeModelsIfPresent(additionalLeftButtons, forKey: .additionalLeftButtons) try container.encodeModelsIfPresent(additionalRightButtons, forKey: .additionalRightButtons) + try container.encodeModelIfPresent(titleView, forKey: .titleView) } } diff --git a/MVMCoreUI/Atomic/Protocols/ModelProtocols/NavigationItemModelProtocol.swift b/MVMCoreUI/Atomic/Protocols/ModelProtocols/NavigationItemModelProtocol.swift index 084509e0..38d95555 100644 --- a/MVMCoreUI/Atomic/Protocols/ModelProtocols/NavigationItemModelProtocol.swift +++ b/MVMCoreUI/Atomic/Protocols/ModelProtocols/NavigationItemModelProtocol.swift @@ -18,4 +18,5 @@ public protocol NavigationItemModelProtocol { var backButton: (NavigationButtonModelProtocol & MoleculeModelProtocol)? { get set } var additionalLeftButtons: [(NavigationButtonModelProtocol & MoleculeModelProtocol)]? { get set } var additionalRightButtons: [(NavigationButtonModelProtocol & MoleculeModelProtocol)]? { get set } + var titleView: MoleculeModelProtocol? { get set } } diff --git a/MVMCoreUI/Atomic/Protocols/ModelProtocols/TabPageModelProtocol.swift b/MVMCoreUI/Atomic/Protocols/ModelProtocols/TabPageModelProtocol.swift index dbee61bd..b755e1f5 100644 --- a/MVMCoreUI/Atomic/Protocols/ModelProtocols/TabPageModelProtocol.swift +++ b/MVMCoreUI/Atomic/Protocols/ModelProtocols/TabPageModelProtocol.swift @@ -8,7 +8,7 @@ import Foundation -public protocol TabPageModelProtocol { +public protocol TabPageModelProtocol : ModelProtocol { var tabBarHidden: Bool { get set } var tabBarIndex: Int? { get set } } diff --git a/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController+Extension.swift b/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController+Extension.swift index 963834ff..4a785a69 100644 --- a/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController+Extension.swift +++ b/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController+Extension.swift @@ -37,6 +37,8 @@ public extension MVMCoreUISplitViewController { setNavigationIconColor(navigationItemModel.tintColor.uiColor) + setNavigationTitle(navigationController: navigationController, navigationItemModel: navigationItemModel, viewController: viewController) + if let progress = progress { setBottomProgressBarProgress(progress) } @@ -108,6 +110,14 @@ public extension MVMCoreUISplitViewController { viewController.navigationItem.setRightBarButtonItems(rightItems.count > 0 ? rightItems : nil, animated: !DisableAnimations.boolValue) } + /// Sets the title of navigation item for the view controller based on model and splitview. + func setNavigationTitle(navigationController: UINavigationController, navigationItemModel: NavigationItemModelProtocol?, viewController: UIViewController) { + let delegate = (viewController as? MVMCoreViewControllerProtocol)?.delegateObject?() as? MVMCoreUIDelegateObject + if let titleViewModel = navigationItemModel?.titleView, let molecule = MoleculeObjectMapping.shared()?.createMolecule(titleViewModel, delegateObject: delegate, additionalData: nil) { + viewController.navigationItem.titleView = molecule + } + } + // MARK: - Legacy Functions /// Convenience setter for legacy files. Sets the navigation item for the view controller based on the json and splitview controller @objc static func setSplitViewController(for viewController: UIViewController, navigationController: UINavigationController, navigationJSON: [String: Any], leftPanelAccessible: Bool, rightPanelAccessible: Bool, progress: NSNumber?) throws { From eba851f2eaf838c4508e6f1f4c1188720a56ad67 Mon Sep 17 00:00:00 2001 From: "Khan, Arshad" Date: Fri, 10 Jul 2020 22:26:31 +0530 Subject: [PATCH 07/11] remove wrong commit --- .../Atomic/Protocols/ModelProtocols/TabPageModelProtocol.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MVMCoreUI/Atomic/Protocols/ModelProtocols/TabPageModelProtocol.swift b/MVMCoreUI/Atomic/Protocols/ModelProtocols/TabPageModelProtocol.swift index b755e1f5..dbee61bd 100644 --- a/MVMCoreUI/Atomic/Protocols/ModelProtocols/TabPageModelProtocol.swift +++ b/MVMCoreUI/Atomic/Protocols/ModelProtocols/TabPageModelProtocol.swift @@ -8,7 +8,7 @@ import Foundation -public protocol TabPageModelProtocol : ModelProtocol { +public protocol TabPageModelProtocol { var tabBarHidden: Bool { get set } var tabBarIndex: Int? { get set } } From 5410cef8bf94e8837e4597060969f0e00cffdd95 Mon Sep 17 00:00:00 2001 From: "Khan, Arshad" Date: Fri, 10 Jul 2020 23:08:46 +0530 Subject: [PATCH 08/11] Moved to NavigationController --- MVMCoreUI/Containers/NavigationController.swift | 9 +++++++++ .../MVMCoreUISplitViewController+Extension.swift | 10 ---------- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/MVMCoreUI/Containers/NavigationController.swift b/MVMCoreUI/Containers/NavigationController.swift index 0cad62c5..d1d70b13 100644 --- a/MVMCoreUI/Containers/NavigationController.swift +++ b/MVMCoreUI/Containers/NavigationController.swift @@ -49,6 +49,7 @@ import UIKit viewController.navigationItem.accessibilityLabel = navigationItemModel.title viewController.navigationItem.hidesBackButton = (navigationItemModel.backButton != nil) setNavigationButtons(navigationController: navigationController, navigationItemModel: navigationItemModel, viewController: viewController) + setNavigationTitle(navigationController: navigationController, navigationItemModel: navigationItemModel, viewController: viewController) } /// Convenience function for setting the navigation buttons. @@ -109,4 +110,12 @@ import UIKit } setNavigationBarUI(navigationController: navigationController, navigationItemModel: barModel, viewController: viewController) } + + /// Sets the title of navigation item for the view controller based on model and splitview. + public static func setNavigationTitle(navigationController: UINavigationController, navigationItemModel: NavigationItemModelProtocol?, viewController: UIViewController) { + let delegate = (viewController as? MVMCoreViewControllerProtocol)?.delegateObject?() as? MVMCoreUIDelegateObject + if let titleViewModel = navigationItemModel?.titleView, let molecule = MoleculeObjectMapping.shared()?.createMolecule(titleViewModel, delegateObject: delegate, additionalData: nil) { + viewController.navigationItem.titleView = molecule + } + } } diff --git a/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController+Extension.swift b/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController+Extension.swift index 4a785a69..963834ff 100644 --- a/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController+Extension.swift +++ b/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController+Extension.swift @@ -37,8 +37,6 @@ public extension MVMCoreUISplitViewController { setNavigationIconColor(navigationItemModel.tintColor.uiColor) - setNavigationTitle(navigationController: navigationController, navigationItemModel: navigationItemModel, viewController: viewController) - if let progress = progress { setBottomProgressBarProgress(progress) } @@ -110,14 +108,6 @@ public extension MVMCoreUISplitViewController { viewController.navigationItem.setRightBarButtonItems(rightItems.count > 0 ? rightItems : nil, animated: !DisableAnimations.boolValue) } - /// Sets the title of navigation item for the view controller based on model and splitview. - func setNavigationTitle(navigationController: UINavigationController, navigationItemModel: NavigationItemModelProtocol?, viewController: UIViewController) { - let delegate = (viewController as? MVMCoreViewControllerProtocol)?.delegateObject?() as? MVMCoreUIDelegateObject - if let titleViewModel = navigationItemModel?.titleView, let molecule = MoleculeObjectMapping.shared()?.createMolecule(titleViewModel, delegateObject: delegate, additionalData: nil) { - viewController.navigationItem.titleView = molecule - } - } - // MARK: - Legacy Functions /// Convenience setter for legacy files. Sets the navigation item for the view controller based on the json and splitview controller @objc static func setSplitViewController(for viewController: UIViewController, navigationController: UINavigationController, navigationJSON: [String: Any], leftPanelAccessible: Bool, rightPanelAccessible: Bool, progress: NSNumber?) throws { From 35fda848c3a8b6bea97f94908eb9902b6996ed14 Mon Sep 17 00:00:00 2001 From: "Khan, Arshad" Date: Fri, 10 Jul 2020 23:18:44 +0530 Subject: [PATCH 09/11] updated comments --- MVMCoreUI/Containers/NavigationController.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MVMCoreUI/Containers/NavigationController.swift b/MVMCoreUI/Containers/NavigationController.swift index d1d70b13..1f59f114 100644 --- a/MVMCoreUI/Containers/NavigationController.swift +++ b/MVMCoreUI/Containers/NavigationController.swift @@ -111,7 +111,7 @@ import UIKit setNavigationBarUI(navigationController: navigationController, navigationItemModel: barModel, viewController: viewController) } - /// Sets the title of navigation item for the view controller based on model and splitview. + /// Convenience function for setting the navigation title. public static func setNavigationTitle(navigationController: UINavigationController, navigationItemModel: NavigationItemModelProtocol?, viewController: UIViewController) { let delegate = (viewController as? MVMCoreViewControllerProtocol)?.delegateObject?() as? MVMCoreUIDelegateObject if let titleViewModel = navigationItemModel?.titleView, let molecule = MoleculeObjectMapping.shared()?.createMolecule(titleViewModel, delegateObject: delegate, additionalData: nil) { From 97d058bdac65a033f8ec8915dd0af300a5561c68 Mon Sep 17 00:00:00 2001 From: "Khan, Arshad" Date: Fri, 10 Jul 2020 23:23:08 +0530 Subject: [PATCH 10/11] rename to titleView --- MVMCoreUI/Containers/NavigationController.swift | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/MVMCoreUI/Containers/NavigationController.swift b/MVMCoreUI/Containers/NavigationController.swift index 1f59f114..74f24957 100644 --- a/MVMCoreUI/Containers/NavigationController.swift +++ b/MVMCoreUI/Containers/NavigationController.swift @@ -49,7 +49,7 @@ import UIKit viewController.navigationItem.accessibilityLabel = navigationItemModel.title viewController.navigationItem.hidesBackButton = (navigationItemModel.backButton != nil) setNavigationButtons(navigationController: navigationController, navigationItemModel: navigationItemModel, viewController: viewController) - setNavigationTitle(navigationController: navigationController, navigationItemModel: navigationItemModel, viewController: viewController) + setNavigationTitleView(navigationController: navigationController, navigationItemModel: navigationItemModel, viewController: viewController) } /// Convenience function for setting the navigation buttons. @@ -111,8 +111,8 @@ import UIKit setNavigationBarUI(navigationController: navigationController, navigationItemModel: barModel, viewController: viewController) } - /// Convenience function for setting the navigation title. - public static func setNavigationTitle(navigationController: UINavigationController, navigationItemModel: NavigationItemModelProtocol?, viewController: UIViewController) { + /// Convenience function for setting the navigation titleView. + public static func setNavigationTitleView(navigationController: UINavigationController, navigationItemModel: NavigationItemModelProtocol?, viewController: UIViewController) { let delegate = (viewController as? MVMCoreViewControllerProtocol)?.delegateObject?() as? MVMCoreUIDelegateObject if let titleViewModel = navigationItemModel?.titleView, let molecule = MoleculeObjectMapping.shared()?.createMolecule(titleViewModel, delegateObject: delegate, additionalData: nil) { viewController.navigationItem.titleView = molecule From 781f51d749dc16798696422cef8d116258d4a2c6 Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Fri, 10 Jul 2020 15:14:46 -0400 Subject: [PATCH 11/11] color update for tab --- .../Molecules/HorizontalCombinationViews/TabBarModel.swift | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TabBarModel.swift b/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TabBarModel.swift index 0afb5ff5..212c63f1 100644 --- a/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TabBarModel.swift +++ b/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TabBarModel.swift @@ -8,12 +8,15 @@ import Foundation +/// coolGray4: #A6A8A8. This color is currently limited to only the tab bar. +private let mvmCoolGray4 = UIColor(red: 0.65, green: 0.659, blue: 0.659, alpha: 1) + public class TabBarModel: MoleculeModelProtocol { public static var identifier: String = "tabBar" public var backgroundColor: Color? = Color(uiColor: .white) public var tabs: [TabBarItemModel] public var selectedColor = Color(uiColor: .mvmBlack) - public var unSelectedColor = Color(uiColor: .mvmCoolGray3) + public var unSelectedColor = Color(uiColor: mvmCoolGray4) // Must be capped to 0...(tabs.count - 1) public var selectedTab: Int = 0