Merge branch 'develop' into feature/order_tracker
This commit is contained in:
commit
e714a6ff12
@ -32,6 +32,10 @@ open class BarsCarouselIndicatorModel: CarouselIndicatorModel {
|
|||||||
// MARK: - Codec
|
// MARK: - Codec
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
|
|
||||||
|
public override init() {
|
||||||
|
super.init()
|
||||||
|
}
|
||||||
|
|
||||||
public required init(from decoder: Decoder) throws {
|
public required init(from decoder: Decoder) throws {
|
||||||
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||||
|
|
||||||
|
|||||||
@ -61,6 +61,7 @@ open class CarouselIndicatorModel: CarouselPagingModelProtocol, MoleculeModelPro
|
|||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Codec
|
// MARK: - Codec
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
|
public init() {}
|
||||||
|
|
||||||
required public init(from decoder: Decoder) throws {
|
required public init(from decoder: Decoder) throws {
|
||||||
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||||
|
|||||||
@ -8,12 +8,15 @@
|
|||||||
|
|
||||||
import Foundation
|
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 class TabBarModel: MoleculeModelProtocol {
|
||||||
public static var identifier: String = "tabBar"
|
public static var identifier: String = "tabBar"
|
||||||
public var backgroundColor: Color? = Color(uiColor: .white)
|
public var backgroundColor: Color? = Color(uiColor: .white)
|
||||||
public var tabs: [TabBarItemModel]
|
public var tabs: [TabBarItemModel]
|
||||||
public var selectedColor = Color(uiColor: .mvmBlack)
|
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)
|
// Must be capped to 0...(tabs.count - 1)
|
||||||
public var selectedTab: Int = 0
|
public var selectedTab: Int = 0
|
||||||
|
|||||||
@ -22,6 +22,7 @@ public class NavigationItemModel: NavigationItemModelProtocol, MoleculeModelProt
|
|||||||
public var backButton: (NavigationButtonModelProtocol & MoleculeModelProtocol)? = NavigationImageButtonModel(with: "nav_back", action: ActionBackModel())
|
public var backButton: (NavigationButtonModelProtocol & MoleculeModelProtocol)? = NavigationImageButtonModel(with: "nav_back", action: ActionBackModel())
|
||||||
public var additionalLeftButtons: [(NavigationButtonModelProtocol & MoleculeModelProtocol)]?
|
public var additionalLeftButtons: [(NavigationButtonModelProtocol & MoleculeModelProtocol)]?
|
||||||
public var additionalRightButtons: [(NavigationButtonModelProtocol & MoleculeModelProtocol)]?
|
public var additionalRightButtons: [(NavigationButtonModelProtocol & MoleculeModelProtocol)]?
|
||||||
|
public var titleView: MoleculeModelProtocol?
|
||||||
|
|
||||||
public init() {
|
public init() {
|
||||||
hidden = false
|
hidden = false
|
||||||
@ -43,6 +44,7 @@ public class NavigationItemModel: NavigationItemModelProtocol, MoleculeModelProt
|
|||||||
case showRightPanelButton
|
case showRightPanelButton
|
||||||
case additionalLeftButtons
|
case additionalLeftButtons
|
||||||
case additionalRightButtons
|
case additionalRightButtons
|
||||||
|
case titleView
|
||||||
}
|
}
|
||||||
|
|
||||||
required public init(from decoder: Decoder) throws {
|
required public init(from decoder: Decoder) throws {
|
||||||
@ -58,6 +60,7 @@ public class NavigationItemModel: NavigationItemModelProtocol, MoleculeModelProt
|
|||||||
}
|
}
|
||||||
additionalLeftButtons = try typeContainer.decodeModelsIfPresent(codingKey: .additionalLeftButtons)
|
additionalLeftButtons = try typeContainer.decodeModelsIfPresent(codingKey: .additionalLeftButtons)
|
||||||
additionalRightButtons = try typeContainer.decodeModelsIfPresent(codingKey: .additionalRightButtons)
|
additionalRightButtons = try typeContainer.decodeModelsIfPresent(codingKey: .additionalRightButtons)
|
||||||
|
titleView = try typeContainer.decodeModelIfPresent(codingKey: .titleView)
|
||||||
}
|
}
|
||||||
|
|
||||||
open func encode(to encoder: Encoder) throws {
|
open func encode(to encoder: Encoder) throws {
|
||||||
@ -72,5 +75,6 @@ public class NavigationItemModel: NavigationItemModelProtocol, MoleculeModelProt
|
|||||||
try container.encodeModelIfPresent(backButton, forKey: .backButton)
|
try container.encodeModelIfPresent(backButton, forKey: .backButton)
|
||||||
try container.encodeModelsIfPresent(additionalLeftButtons, forKey: .additionalLeftButtons)
|
try container.encodeModelsIfPresent(additionalLeftButtons, forKey: .additionalLeftButtons)
|
||||||
try container.encodeModelsIfPresent(additionalRightButtons, forKey: .additionalRightButtons)
|
try container.encodeModelsIfPresent(additionalRightButtons, forKey: .additionalRightButtons)
|
||||||
|
try container.encodeModelIfPresent(titleView, forKey: .titleView)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -55,7 +55,7 @@ open class Carousel: View {
|
|||||||
|
|
||||||
/// The view that we use for paging
|
/// The view that we use for paging
|
||||||
public var pagingView: (UIView & CarouselPageControlProtocol)?
|
public var pagingView: (UIView & CarouselPageControlProtocol)?
|
||||||
|
|
||||||
/// If the carousel should loop after scrolling past the first and final cells.
|
/// If the carousel should loop after scrolling past the first and final cells.
|
||||||
public var loop = false
|
public var loop = false
|
||||||
|
|
||||||
@ -76,6 +76,7 @@ open class Carousel: View {
|
|||||||
open override func layoutSubviews() {
|
open override func layoutSubviews() {
|
||||||
super.layoutSubviews()
|
super.layoutSubviews()
|
||||||
// Accounts for any collection size changes
|
// Accounts for any collection size changes
|
||||||
|
carouselAccessibilityElement?.accessibilityFrameInContainerSpace = collectionView.frame
|
||||||
DispatchQueue.main.async {
|
DispatchQueue.main.async {
|
||||||
self.layoutCollection()
|
self.layoutCollection()
|
||||||
}
|
}
|
||||||
@ -88,7 +89,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.
|
// 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,
|
guard let model = model as? CarouselModel,
|
||||||
(model.paging == true || model.loop == true) else { return }
|
(model.paging == true || loop == true) else { return }
|
||||||
DispatchQueue.main.async {
|
DispatchQueue.main.async {
|
||||||
self.collectionView.scrollToItem(at: IndexPath(row: self.currentIndex, section: 0), at: self.itemAlignment, animated: false)
|
self.collectionView.scrollToItem(at: IndexPath(row: self.currentIndex, section: 0), at: self.itemAlignment, animated: false)
|
||||||
self.collectionView.layoutIfNeeded()
|
self.collectionView.layoutIfNeeded()
|
||||||
@ -108,6 +109,14 @@ open class Carousel: View {
|
|||||||
bottomPin = NSLayoutConstraint.constraintPinSubview(toSuperview: collectionView)?[ConstraintBot] as? NSLayoutConstraint
|
bottomPin = NSLayoutConstraint.constraintPinSubview(toSuperview: collectionView)?[ConstraintBot] as? NSLayoutConstraint
|
||||||
collectionViewHeight = collectionView.heightAnchor.constraint(equalToConstant: 300)
|
collectionViewHeight = collectionView.heightAnchor.constraint(equalToConstant: 300)
|
||||||
collectionViewHeight?.isActive = true
|
collectionViewHeight?.isActive = true
|
||||||
|
|
||||||
|
// Fixes defects where it scrolls when it shouldn't with voiceover
|
||||||
|
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) {
|
open override func updateView(_ size: CGFloat) {
|
||||||
@ -139,7 +148,7 @@ open class Carousel: View {
|
|||||||
super.set(with: model, delegateObject, additionalData)
|
super.set(with: model, delegateObject, additionalData)
|
||||||
|
|
||||||
guard let carouselModel = model as? CarouselModel else { return }
|
guard let carouselModel = model as? CarouselModel else { return }
|
||||||
|
accessibilityLabel = carouselModel.accessibilityText
|
||||||
collectionView.backgroundColor = backgroundColor
|
collectionView.backgroundColor = backgroundColor
|
||||||
collectionView.layer.borderColor = backgroundColor?.cgColor
|
collectionView.layer.borderColor = backgroundColor?.cgColor
|
||||||
collectionView.layer.borderWidth = (carouselModel.border ?? false) ? 1 : 0
|
collectionView.layer.borderWidth = (carouselModel.border ?? false) ? 1 : 0
|
||||||
@ -179,12 +188,14 @@ open class Carousel: View {
|
|||||||
numberOfPages = newMolecules.count
|
numberOfPages = newMolecules.count
|
||||||
molecules = newMolecules
|
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).
|
// 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
|
loop = true
|
||||||
|
|
||||||
molecules?.insert(contentsOf: newMolecules.suffix(2), at: 0)
|
molecules?.insert(contentsOf: newMolecules.suffix(2), at: 0)
|
||||||
molecules?.append(contentsOf: newMolecules.prefix(2))
|
molecules?.append(contentsOf: newMolecules.prefix(2))
|
||||||
|
} else {
|
||||||
|
loop = false
|
||||||
}
|
}
|
||||||
|
|
||||||
pageIndex = 0
|
pageIndex = 0
|
||||||
@ -277,31 +288,72 @@ 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) {
|
public func setAccessiblity(_ cell: UICollectionViewCell?, index: Int) {
|
||||||
guard let cell = cell else { return }
|
guard let cell = cell else { return }
|
||||||
|
|
||||||
if index == currentIndex {
|
if index == currentIndex {
|
||||||
cell.accessibilityElementsHidden = false
|
cell.accessibilityElementsHidden = false
|
||||||
var array = cell.accessibilityElements
|
|
||||||
|
|
||||||
if let pagingView = pagingView {
|
// set to nil to get fresh elements
|
||||||
if let acc = pagingView.accessibilityElements {
|
accessibilityElements = nil
|
||||||
array?.append(contentsOf: acc)
|
|
||||||
} else {
|
|
||||||
array?.append(pagingView)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
accessibilityElements = array
|
|
||||||
} else {
|
} else {
|
||||||
cell.accessibilityElementsHidden = true
|
cell.accessibilityElementsHidden = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func trackSwipeActionAnalyticsforIndex(_ index : Int){
|
/// Resets view
|
||||||
guard let itemModel = molecules?[index],
|
@objc private func accessibilityStatusChanged(_ sender: Notification) {
|
||||||
let viewControllerObject = delegateObject?.moleculeDelegate as? MVMCoreViewControllerProtocol else { return }
|
// Fixes defects where it scrolls when it shouldn't with voiceover
|
||||||
MVMCoreUILoggingHandler.shared()?.defaultLogAction(forController: viewControllerObject, actionInformation: itemModel.toJSON(), additionalData: nil)
|
collectionView.isScrollEnabled = !UIAccessibility.isVoiceOverRunning
|
||||||
|
if let model = model {
|
||||||
|
set(with: model, delegateObject, nil)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Accessibility element that allows for adjustable carousel.
|
||||||
|
private var carouselAccessibilityElement: CarouselAccessibilityElement?
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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]
|
||||||
|
} else {
|
||||||
|
_accessibilityElements = [carouselAccessibilityElement]
|
||||||
|
}
|
||||||
|
return _accessibilityElements
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -347,7 +399,6 @@ extension Carousel: UIScrollViewDelegate {
|
|||||||
|
|
||||||
/// Go to the cell at the specified index.
|
/// Go to the cell at the specified index.
|
||||||
func goTo(_ index: Int, animated: Bool) {
|
func goTo(_ index: Int, animated: Bool) {
|
||||||
|
|
||||||
showPeaking(false)
|
showPeaking(false)
|
||||||
setAccessiblity(collectionView.cellForItem(at: IndexPath(row: currentIndex, section: 0)), index: index)
|
setAccessiblity(collectionView.cellForItem(at: IndexPath(row: currentIndex, section: 0)), index: index)
|
||||||
currentIndex = index
|
currentIndex = index
|
||||||
@ -357,6 +408,11 @@ extension Carousel: UIScrollViewDelegate {
|
|||||||
setAccessiblity(collectionView.cellForItem(at: IndexPath(row: currentIndex, section: 0)), index: index)
|
setAccessiblity(collectionView.cellForItem(at: IndexPath(row: currentIndex, section: 0)), index: index)
|
||||||
UIAccessibility.post(notification: .layoutChanged, argument: cell)
|
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.
|
/// Adjusts the current contentOffset if we are going onto buffer cells while looping to help with the endless scrolling appearance.
|
||||||
@ -378,12 +434,11 @@ extension Carousel: UIScrollViewDelegate {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
open func scrollViewDidScroll(_ scrollView: UIScrollView) {
|
open func scrollViewDidScroll(_ scrollView: UIScrollView) {
|
||||||
|
|
||||||
// Adjust for looping
|
// Adjust for looping
|
||||||
if let model = model as? CarouselModel,
|
if loop == true {
|
||||||
model.loop == true {
|
|
||||||
adjustOffsetForLooping(scrollView)
|
adjustOffsetForLooping(scrollView)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -395,6 +450,7 @@ extension Carousel: UIScrollViewDelegate {
|
|||||||
|
|
||||||
// Disable peaking when dragging.
|
// Disable peaking when dragging.
|
||||||
dragging = true
|
dragging = true
|
||||||
|
|
||||||
showPeaking(false)
|
showPeaking(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -464,3 +520,106 @@ extension Carousel: UIScrollViewDelegate {
|
|||||||
trackSwipeActionAnalyticsforIndex(pageIndex)
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -32,7 +32,8 @@ import UIKit
|
|||||||
public var useHorizontalMargins: Bool?
|
public var useHorizontalMargins: Bool?
|
||||||
public var leftPadding: CGFloat?
|
public var leftPadding: CGFloat?
|
||||||
public var rightPadding: CGFloat?
|
public var rightPadding: CGFloat?
|
||||||
|
public var accessibilityText: String?
|
||||||
|
|
||||||
public init(molecules: [MoleculeModelProtocol & CarouselItemModelProtocol]) {
|
public init(molecules: [MoleculeModelProtocol & CarouselItemModelProtocol]) {
|
||||||
self.molecules = molecules
|
self.molecules = molecules
|
||||||
}
|
}
|
||||||
@ -57,6 +58,7 @@ import UIKit
|
|||||||
case useHorizontalMargins
|
case useHorizontalMargins
|
||||||
case leftPadding
|
case leftPadding
|
||||||
case rightPadding
|
case rightPadding
|
||||||
|
case accessibilityText
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -83,6 +85,7 @@ import UIKit
|
|||||||
useHorizontalMargins = try typeContainer.decodeIfPresent(Bool.self, forKey: .useHorizontalMargins)
|
useHorizontalMargins = try typeContainer.decodeIfPresent(Bool.self, forKey: .useHorizontalMargins)
|
||||||
leftPadding = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .leftPadding)
|
leftPadding = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .leftPadding)
|
||||||
rightPadding = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .rightPadding)
|
rightPadding = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .rightPadding)
|
||||||
|
accessibilityText = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityText)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func encode(to encoder: Encoder) throws {
|
public func encode(to encoder: Encoder) throws {
|
||||||
@ -101,5 +104,6 @@ import UIKit
|
|||||||
try container.encodeIfPresent(useHorizontalMargins, forKey: .useHorizontalMargins)
|
try container.encodeIfPresent(useHorizontalMargins, forKey: .useHorizontalMargins)
|
||||||
try container.encodeIfPresent(leftPadding, forKey: .leftPadding)
|
try container.encodeIfPresent(leftPadding, forKey: .leftPadding)
|
||||||
try container.encodeIfPresent(rightPadding, forKey: .rightPadding)
|
try container.encodeIfPresent(rightPadding, forKey: .rightPadding)
|
||||||
|
try container.encodeIfPresent(accessibilityText, forKey: .accessibilityText)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -18,4 +18,5 @@ public protocol NavigationItemModelProtocol {
|
|||||||
var backButton: (NavigationButtonModelProtocol & MoleculeModelProtocol)? { get set }
|
var backButton: (NavigationButtonModelProtocol & MoleculeModelProtocol)? { get set }
|
||||||
var additionalLeftButtons: [(NavigationButtonModelProtocol & MoleculeModelProtocol)]? { get set }
|
var additionalLeftButtons: [(NavigationButtonModelProtocol & MoleculeModelProtocol)]? { get set }
|
||||||
var additionalRightButtons: [(NavigationButtonModelProtocol & MoleculeModelProtocol)]? { get set }
|
var additionalRightButtons: [(NavigationButtonModelProtocol & MoleculeModelProtocol)]? { get set }
|
||||||
|
var titleView: MoleculeModelProtocol? { get set }
|
||||||
}
|
}
|
||||||
|
|||||||
@ -49,6 +49,7 @@ import UIKit
|
|||||||
viewController.navigationItem.accessibilityLabel = navigationItemModel.title
|
viewController.navigationItem.accessibilityLabel = navigationItemModel.title
|
||||||
viewController.navigationItem.hidesBackButton = (navigationItemModel.backButton != nil)
|
viewController.navigationItem.hidesBackButton = (navigationItemModel.backButton != nil)
|
||||||
setNavigationButtons(navigationController: navigationController, navigationItemModel: navigationItemModel, viewController: viewController)
|
setNavigationButtons(navigationController: navigationController, navigationItemModel: navigationItemModel, viewController: viewController)
|
||||||
|
setNavigationTitleView(navigationController: navigationController, navigationItemModel: navigationItemModel, viewController: viewController)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Convenience function for setting the navigation buttons.
|
/// Convenience function for setting the navigation buttons.
|
||||||
@ -109,4 +110,12 @@ import UIKit
|
|||||||
}
|
}
|
||||||
setNavigationBarUI(navigationController: navigationController, navigationItemModel: barModel, viewController: viewController)
|
setNavigationBarUI(navigationController: navigationController, navigationItemModel: barModel, viewController: viewController)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 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
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user