Merge branch 'develop' of https://gitlab.verizon.com/BPHV_MIPS/mvm_core_ui into feature/unified_grid
This commit is contained in:
commit
1e27d0712c
@ -319,12 +319,14 @@ import UIKit
|
|||||||
model.updateUIDynamicError = { [weak self] in
|
model.updateUIDynamicError = { [weak self] in
|
||||||
MVMCoreDispatchUtility.performBlock(onMainThread: {
|
MVMCoreDispatchUtility.performBlock(onMainThread: {
|
||||||
guard let self = self else { return }
|
guard let self = self else { return }
|
||||||
|
|
||||||
let validState = model.isValid ?? false
|
let validState = model.isValid ?? false
|
||||||
self.updateValidation(validState)
|
|
||||||
if !validState && model.shouldClearText {
|
if !validState && model.shouldClearText {
|
||||||
self.text = ""
|
self.text = ""
|
||||||
model.shouldClearText = false
|
model.shouldClearText = false
|
||||||
}
|
}
|
||||||
|
_ = FormValidator.validate(delegate: self.delegateObject?.formHolderDelegate)
|
||||||
|
self.updateValidation(validState)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -147,6 +147,16 @@ import MVMCore
|
|||||||
MVMCoreNavigationHandler.shared()?.present(picker, animated: true)
|
MVMCoreNavigationHandler.shared()?.present(picker, animated: true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - MoleculeViewProtocol
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
|
public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
||||||
|
super.set(with: model, delegateObject, additionalData)
|
||||||
|
|
||||||
|
textField.keyboardType = .phonePad
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Contact Picker Delegate
|
// MARK: - Contact Picker Delegate
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
|
|||||||
@ -200,6 +200,7 @@ import UIKit
|
|||||||
open override func reset() {
|
open override func reset() {
|
||||||
super.reset()
|
super.reset()
|
||||||
|
|
||||||
|
textField.isSecureTextEntry = false
|
||||||
textField.font = Styler.Font.RegularBodyLarge.getFont()
|
textField.font = Styler.Font.RegularBodyLarge.getFont()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -350,7 +351,8 @@ import UIKit
|
|||||||
case .phone:
|
case .phone:
|
||||||
textField.keyboardType = .phonePad
|
textField.keyboardType = .phonePad
|
||||||
|
|
||||||
default: break
|
default:
|
||||||
|
textField.keyboardType = .default
|
||||||
}
|
}
|
||||||
|
|
||||||
// Override the preset keyboard set in type.
|
// Override the preset keyboard set in type.
|
||||||
@ -364,6 +366,12 @@ import UIKit
|
|||||||
setupTextFieldToolbar()
|
setupTextFieldToolbar()
|
||||||
|
|
||||||
if isSelected { startEditing() }
|
if isSelected { startEditing() }
|
||||||
|
|
||||||
|
//Added to override text when view is reloaded.
|
||||||
|
if let text = model.text, !text.isEmpty {
|
||||||
|
regexTextFieldOutputIfAvailable()
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -624,9 +624,6 @@ public typealias ActionBlock = () -> ()
|
|||||||
} else if !MVMCoreGetterUtility.fequal(a: Float(standardFontSize), b: 0.0), let sizeObject = sizeObject ?? MFStyler.sizeObjectGeneric(forCurrentDevice: standardFontSize) {
|
} else if !MVMCoreGetterUtility.fequal(a: Float(standardFontSize), b: 0.0), let sizeObject = sizeObject ?? MFStyler.sizeObjectGeneric(forCurrentDevice: standardFontSize) {
|
||||||
font = font.updateSize(sizeObject.getValueBased(onSize: size))
|
font = font.updateSize(sizeObject.getValueBased(onSize: size))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Provide the label additional size information to help calculate its intrinsic content.
|
|
||||||
preferredMaxLayoutWidth = Styler.maxAvailableLayoutWidth(size: size)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@objc public func setFont(_ font: UIFont, scale: Bool) {
|
@objc public func setFont(_ font: UIFont, scale: Bool) {
|
||||||
@ -688,7 +685,7 @@ public typealias ActionBlock = () -> ()
|
|||||||
static func getTextAttachmentImage(name: String = "externalLink", dimension: CGFloat) -> NSTextAttachment {
|
static func getTextAttachmentImage(name: String = "externalLink", dimension: CGFloat) -> NSTextAttachment {
|
||||||
|
|
||||||
let imageAttachment = NSTextAttachment()
|
let imageAttachment = NSTextAttachment()
|
||||||
imageAttachment.image = MVMCoreUIUtility.imageNamed(name)
|
imageAttachment.image = MVMCoreCache.shared()?.getImageFromRegisteredBundles(name)
|
||||||
imageAttachment.bounds = CGRect(x: 0, y: 0, width: dimension, height: dimension)
|
imageAttachment.bounds = CGRect(x: 0, y: 0, width: dimension, height: dimension)
|
||||||
|
|
||||||
return imageAttachment
|
return imageAttachment
|
||||||
|
|||||||
@ -16,8 +16,8 @@ import WebKit
|
|||||||
var webviewModel: WebViewModel? {
|
var webviewModel: WebViewModel? {
|
||||||
return model as? WebViewModel
|
return model as? WebViewModel
|
||||||
}
|
}
|
||||||
var webView: WKWebView?
|
open var webView: WKWebView?
|
||||||
var overLayer = MVMCoreUICommonViewsUtility.commonView()
|
open var overLayer = MVMCoreUICommonViewsUtility.commonView()
|
||||||
public let loadingSpinner = MFLoadingSpinner(frame: .zero)
|
public let loadingSpinner = MFLoadingSpinner(frame: .zero)
|
||||||
var delegateObject: MVMCoreUIDelegateObject?
|
var delegateObject: MVMCoreUIDelegateObject?
|
||||||
var webViewHeight: NSLayoutConstraint?
|
var webViewHeight: NSLayoutConstraint?
|
||||||
|
|||||||
@ -9,9 +9,6 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
@objcMembers public class MoleculeObjectMapping: NSObject {
|
@objcMembers public class MoleculeObjectMapping: NSObject {
|
||||||
|
|
||||||
public var moleculeMapping: [String: MoleculeViewProtocol.Type] = [:]
|
|
||||||
|
|
||||||
/// Returns the mapping object stored in the singleton
|
/// Returns the mapping object stored in the singleton
|
||||||
public static func shared() -> Self? {
|
public static func shared() -> Self? {
|
||||||
return MVMCoreActionUtility.initializerClassCheck(CoreUIObject.sharedInstance()?.moleculeMap, classToVerify: self) as? Self
|
return MVMCoreActionUtility.initializerClassCheck(CoreUIObject.sharedInstance()?.moleculeMap, classToVerify: self) as? Self
|
||||||
@ -19,18 +16,17 @@ import Foundation
|
|||||||
|
|
||||||
/// Registers the model with the model registry and the view with the mapper.
|
/// Registers the model with the model registry and the view with the mapper.
|
||||||
public func register<M: ModelProtocol, V: MoleculeViewProtocol>(viewClass: V.Type, viewModelClass: M.Type) {
|
public func register<M: ModelProtocol, V: MoleculeViewProtocol>(viewClass: V.Type, viewModelClass: M.Type) {
|
||||||
try? ModelRegistry.register(viewModelClass)
|
try? ModelRegistry.register(handler: viewClass, for: viewModelClass)
|
||||||
moleculeMapping.updateValue(viewClass, forKey: viewModelClass.identifier)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the type of molecule view for the given model
|
/// Returns the type of molecule view for the given model
|
||||||
public func getMoleculeClass(_ model: MoleculeModelProtocol) -> MoleculeViewProtocol.Type? {
|
public func getMoleculeClass(_ model: MoleculeModelProtocol) -> MoleculeViewProtocol.Type? {
|
||||||
return moleculeMapping[model.moleculeName]
|
return ModelRegistry.getHandler(model) as? MoleculeViewProtocol.Type
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a molecule with the given model.
|
/// Creates a molecule with the given model.
|
||||||
public func createMolecule(_ model: MoleculeModelProtocol, delegateObject: MVMCoreUIDelegateObject? = nil, additionalData: [AnyHashable: Any]? = nil) -> MoleculeViewProtocol? {
|
public func createMolecule(_ model: MoleculeModelProtocol, delegateObject: MVMCoreUIDelegateObject? = nil, additionalData: [AnyHashable: Any]? = nil) -> MoleculeViewProtocol? {
|
||||||
guard let type = moleculeMapping[model.moleculeName] else { return nil }
|
guard let type = getMoleculeClass(model) else { return nil }
|
||||||
return type.init(model: model, delegateObject, additionalData)
|
return type.init(model: model, delegateObject, additionalData)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -286,3 +282,4 @@ import Foundation
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -12,7 +12,7 @@
|
|||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
|
|
||||||
public let leftImage = LoadImageView(pinnedEdges: .all)
|
public let leftImage = LoadImageView(pinnedEdges: .all)
|
||||||
public let eyebrowHeadlineBodyLink = EyebrowHeadlineBodyLink()
|
public let eyebrowHeadlineBodyLink = EyebrowHeadlineBodyLink(spacing: 2.0)
|
||||||
public let rightLabel = Label(fontStyle: .RegularBodySmall)
|
public let rightLabel = Label(fontStyle: .RegularBodySmall)
|
||||||
|
|
||||||
public lazy var rightLabelStackItem: StackItem = {
|
public lazy var rightLabelStackItem: StackItem = {
|
||||||
|
|||||||
@ -21,6 +21,9 @@ import Foundation
|
|||||||
public var peakingUI: Bool?
|
public var peakingUI: Bool?
|
||||||
public var peakingArrowColor: Color?
|
public var peakingArrowColor: Color?
|
||||||
public var analyticsData: JSONValueDictionary?
|
public var analyticsData: JSONValueDictionary?
|
||||||
|
public var fieldValue: String?
|
||||||
|
|
||||||
|
public func formFieldValue() -> AnyHashable? { return fieldValue }
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Keys
|
// MARK: - Keys
|
||||||
@ -30,6 +33,7 @@ import Foundation
|
|||||||
case peakingUI
|
case peakingUI
|
||||||
case peakingArrowColor
|
case peakingArrowColor
|
||||||
case analyticsData
|
case analyticsData
|
||||||
|
case fieldValue
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -41,6 +45,7 @@ import Foundation
|
|||||||
peakingUI = try typeContainer.decodeIfPresent(Bool.self, forKey: .peakingUI)
|
peakingUI = try typeContainer.decodeIfPresent(Bool.self, forKey: .peakingUI)
|
||||||
peakingArrowColor = try typeContainer.decodeIfPresent(Color.self, forKey: .peakingArrowColor)
|
peakingArrowColor = try typeContainer.decodeIfPresent(Color.self, forKey: .peakingArrowColor)
|
||||||
analyticsData = try typeContainer.decodeIfPresent(JSONValueDictionary.self, forKey: .analyticsData)
|
analyticsData = try typeContainer.decodeIfPresent(JSONValueDictionary.self, forKey: .analyticsData)
|
||||||
|
fieldValue = try typeContainer.decodeIfPresent(String.self, forKey: .fieldValue)
|
||||||
try super.init(from: decoder)
|
try super.init(from: decoder)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -50,5 +55,6 @@ import Foundation
|
|||||||
try container.encodeIfPresent(peakingUI, forKey: .peakingUI)
|
try container.encodeIfPresent(peakingUI, forKey: .peakingUI)
|
||||||
try container.encodeIfPresent(peakingArrowColor, forKey: .peakingArrowColor)
|
try container.encodeIfPresent(peakingArrowColor, forKey: .peakingArrowColor)
|
||||||
try container.encodeIfPresent(analyticsData, forKey: .analyticsData)
|
try container.encodeIfPresent(analyticsData, forKey: .analyticsData)
|
||||||
|
try container.encodeIfPresent(fieldValue, forKey: .fieldValue)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -22,6 +22,16 @@
|
|||||||
get { return model as? EyebrowHeadlineBodyLinkModel }
|
get { return model as? EyebrowHeadlineBodyLinkModel }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - Initialization
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
|
public convenience init(spacing: CGFloat) {
|
||||||
|
self.init(frame: .zero)
|
||||||
|
stack.stackModel?.spacing = spacing
|
||||||
|
stack.restack()
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - MFViewProtocol
|
// MARK: - MFViewProtocol
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
|
|||||||
@ -167,12 +167,17 @@ open class Carousel: View {
|
|||||||
|
|
||||||
registerCells(with: carouselModel, delegateObject: delegateObject)
|
registerCells(with: carouselModel, delegateObject: delegateObject)
|
||||||
prepareMolecules(with: carouselModel)
|
prepareMolecules(with: carouselModel)
|
||||||
|
FormValidator.setupValidation(for: carouselModel, delegate: delegateObject?.formHolderDelegate)
|
||||||
|
|
||||||
setupPagingMolecule(carouselModel.pagingMolecule, delegateObject: delegateObject)
|
setupPagingMolecule(carouselModel.pagingMolecule, delegateObject: delegateObject)
|
||||||
|
|
||||||
pageIndex = carouselModel.index
|
pageIndex = carouselModel.index
|
||||||
pagingView?.currentIndex = carouselModel.index
|
pagingView?.currentIndex = carouselModel.index
|
||||||
collectionView.reloadData()
|
collectionView.reloadData()
|
||||||
|
if let selectedIndex = carouselModel.selectedIndex {
|
||||||
|
let adjustedIndex = loop ? selectedIndex + 2 : selectedIndex
|
||||||
|
collectionView.selectItem(at: IndexPath(row: adjustedIndex, section: 0), animated: false, scrollPosition: [])
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -391,8 +396,25 @@ extension Carousel: UICollectionViewDataSource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
extension Carousel: UICollectionViewDelegate {
|
extension Carousel: UICollectionViewDelegate {
|
||||||
|
public func collectionView(_ collectionView: UICollectionView, shouldSelectItemAt indexPath: IndexPath) -> Bool {
|
||||||
|
guard let cell = collectionView.cellForItem(at: indexPath) as? CollectionTemplateItemProtocol else { return false }
|
||||||
|
return cell.shouldSelect(at: indexPath, delegateObject: delegateObject, additionalData: nil)
|
||||||
|
}
|
||||||
|
|
||||||
open func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
|
open func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
|
||||||
(collectionView.cellForItem(at: indexPath) as? CollectionTemplateItemProtocol)?.didSelectCell(at: indexPath, delegateObject: delegateObject, additionalData: nil)
|
// Set the selection in the model
|
||||||
|
if let model = model as? CarouselModel {
|
||||||
|
// Adjust for looping
|
||||||
|
var adjustedIndex = loop ? indexPath.row - 2 : indexPath.row
|
||||||
|
if adjustedIndex < 0 {
|
||||||
|
adjustedIndex = adjustedIndex + numberOfPages
|
||||||
|
}
|
||||||
|
model.selectedIndex = adjustedIndex
|
||||||
|
}
|
||||||
|
if let cell = collectionView.cellForItem(at: indexPath) as? CollectionTemplateItemProtocol {
|
||||||
|
cell.didSelectCell(at: indexPath, delegateObject: delegateObject, additionalData: nil)
|
||||||
|
}
|
||||||
|
_ = FormValidator.validate(delegate: delegateObject?.formHolderDelegate)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -414,6 +436,7 @@ extension Carousel: UIScrollViewDelegate {
|
|||||||
if !animated {
|
if !animated {
|
||||||
scrollViewDidEndScrollingAnimation(collectionView)
|
scrollViewDidEndScrollingAnimation(collectionView)
|
||||||
}
|
}
|
||||||
|
_ = FormValidator.validate(delegate: delegateObject?.formHolderDelegate)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 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.
|
||||||
|
|||||||
@ -9,7 +9,8 @@
|
|||||||
import UIKit
|
import UIKit
|
||||||
|
|
||||||
|
|
||||||
@objcMembers public class CarouselModel: MoleculeModelProtocol {
|
@objcMembers public class CarouselModel: MoleculeModelProtocol, FormFieldProtocol {
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Properties
|
// MARK: - Properties
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -33,11 +34,31 @@ import UIKit
|
|||||||
public var leftPadding: CGFloat?
|
public var leftPadding: CGFloat?
|
||||||
public var rightPadding: CGFloat?
|
public var rightPadding: CGFloat?
|
||||||
public var accessibilityText: String?
|
public var accessibilityText: String?
|
||||||
|
public var baseValue: AnyHashable?
|
||||||
|
public var fieldKey: String?
|
||||||
|
public var groupName: String = FormValidator.defaultGroupName
|
||||||
|
|
||||||
|
public var selectable = false
|
||||||
|
public var selectedIndex: Int?
|
||||||
|
|
||||||
public init(molecules: [MoleculeModelProtocol & CarouselItemModelProtocol]) {
|
public init(molecules: [MoleculeModelProtocol & CarouselItemModelProtocol]) {
|
||||||
self.molecules = molecules
|
self.molecules = molecules
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public func formFieldValue() -> AnyHashable? {
|
||||||
|
guard selectable else {
|
||||||
|
// Use visible item value, else index
|
||||||
|
if let fieldValue = molecules[index].formFieldValue() {
|
||||||
|
return fieldValue
|
||||||
|
}
|
||||||
|
return index
|
||||||
|
}
|
||||||
|
// Use selected item value, else index
|
||||||
|
guard let selectedIndex = selectedIndex else { return nil }
|
||||||
|
guard let fieldValue = molecules[selectedIndex].formFieldValue() else { return selectedIndex }
|
||||||
|
return fieldValue
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Keys
|
// MARK: - Keys
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -59,6 +80,10 @@ import UIKit
|
|||||||
case leftPadding
|
case leftPadding
|
||||||
case rightPadding
|
case rightPadding
|
||||||
case accessibilityText
|
case accessibilityText
|
||||||
|
case groupName
|
||||||
|
case fieldKey
|
||||||
|
case selectable
|
||||||
|
case selectedIndex
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -69,6 +94,8 @@ import UIKit
|
|||||||
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||||
molecules = try typeContainer.decodeModels(codingKey: .molecules)
|
molecules = try typeContainer.decodeModels(codingKey: .molecules)
|
||||||
index = try typeContainer.decodeIfPresent(Int.self, forKey: .index) ?? 0
|
index = try typeContainer.decodeIfPresent(Int.self, forKey: .index) ?? 0
|
||||||
|
selectable = try typeContainer.decodeIfPresent(Bool.self, forKey: .selectable) ?? false
|
||||||
|
selectedIndex = try typeContainer.decodeIfPresent(Int.self, forKey: .selectedIndex)
|
||||||
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
|
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
|
||||||
spacing = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .spacing)
|
spacing = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .spacing)
|
||||||
border = try typeContainer.decodeIfPresent(Bool.self, forKey: .border)
|
border = try typeContainer.decodeIfPresent(Bool.self, forKey: .border)
|
||||||
@ -86,6 +113,11 @@ import UIKit
|
|||||||
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)
|
accessibilityText = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityText)
|
||||||
|
fieldKey = try typeContainer.decodeIfPresent(String.self, forKey: .fieldKey)
|
||||||
|
if let groupName = try typeContainer.decodeIfPresent(String.self, forKey: .groupName) {
|
||||||
|
self.groupName = groupName
|
||||||
|
}
|
||||||
|
baseValue = formFieldValue()
|
||||||
}
|
}
|
||||||
|
|
||||||
public func encode(to encoder: Encoder) throws {
|
public func encode(to encoder: Encoder) throws {
|
||||||
@ -105,5 +137,10 @@ import UIKit
|
|||||||
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)
|
try container.encodeIfPresent(accessibilityText, forKey: .accessibilityText)
|
||||||
|
try container.encodeIfPresent(fieldKey, forKey: .fieldKey)
|
||||||
|
try container.encode(groupName, forKey: .groupName)
|
||||||
|
try container.encode(index, forKey: .index)
|
||||||
|
try container.encode(selectable, forKey: .selectable)
|
||||||
|
try container.encode(selectedIndex, forKey: .selectedIndex)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -199,7 +199,7 @@ open class Stack<T>: Container where T: (StackModelProtocol & MoleculeModelProto
|
|||||||
}
|
}
|
||||||
var name = "stack<"
|
var name = "stack<"
|
||||||
for case let item in model.molecules {
|
for case let item in model.molecules {
|
||||||
if let moleculeClass = MoleculeObjectMapping.shared()?.moleculeMapping[item.moleculeName],
|
if let moleculeClass = MoleculeObjectMapping.shared()?.getMoleculeClass(item),
|
||||||
let nameForReuse = moleculeClass.nameForReuse(with: item, delegateObject) {
|
let nameForReuse = moleculeClass.nameForReuse(with: item, delegateObject) {
|
||||||
name.append(nameForReuse + ",")
|
name.append(nameForReuse + ",")
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -11,11 +11,14 @@ import Foundation
|
|||||||
|
|
||||||
public protocol CarouselItemModelProtocol: ContainerModelProtocol {
|
public protocol CarouselItemModelProtocol: ContainerModelProtocol {
|
||||||
var analyticsData: JSONValueDictionary? { get set }
|
var analyticsData: JSONValueDictionary? { get set }
|
||||||
|
func formFieldValue() -> AnyHashable?
|
||||||
}
|
}
|
||||||
|
|
||||||
public extension CarouselItemModelProtocol {
|
public extension CarouselItemModelProtocol {
|
||||||
|
|
||||||
var analyticsData: JSONValueDictionary? {
|
var analyticsData: JSONValueDictionary? {
|
||||||
get { return nil }
|
get { return nil }
|
||||||
set { analyticsData = newValue }
|
set { analyticsData = newValue }
|
||||||
}
|
}
|
||||||
|
func formFieldValue() -> AnyHashable? { return nil }
|
||||||
}
|
}
|
||||||
|
|||||||
@ -14,7 +14,7 @@ public protocol MoleculeModelProtocol: ModelProtocol, AccessibilityModelProtocol
|
|||||||
|
|
||||||
public extension MoleculeModelProtocol {
|
public extension MoleculeModelProtocol {
|
||||||
|
|
||||||
var moleculeName: String { Self.identifier }
|
var moleculeName: String { type(of: self).identifier }
|
||||||
|
|
||||||
static var categoryName: String { "\(MoleculeModelProtocol.self)" }
|
static var categoryName: String { "\(MoleculeModelProtocol.self)" }
|
||||||
|
|
||||||
|
|||||||
@ -9,7 +9,7 @@
|
|||||||
import UIKit
|
import UIKit
|
||||||
import MVMCore.MVMCoreViewProtocol
|
import MVMCore.MVMCoreViewProtocol
|
||||||
|
|
||||||
public protocol MoleculeViewProtocol: UIView {
|
public protocol MoleculeViewProtocol: UIView, ModelHandlerProtocol {
|
||||||
|
|
||||||
/// Initializes the view with the model
|
/// Initializes the view with the model
|
||||||
init(model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?)
|
init(model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?)
|
||||||
@ -31,6 +31,7 @@ public protocol MoleculeViewProtocol: UIView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
extension MoleculeViewProtocol {
|
extension MoleculeViewProtocol {
|
||||||
|
|
||||||
/// Calls set with model
|
/// Calls set with model
|
||||||
public init(model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
public init(model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
||||||
self.init(frame: .zero)
|
self.init(frame: .zero)
|
||||||
|
|||||||
@ -19,6 +19,9 @@ public protocol CollectionTemplateItemProtocol: UICollectionViewCell {
|
|||||||
|
|
||||||
/// Called when the cell will display.
|
/// Called when the cell will display.
|
||||||
func willDisplay()
|
func willDisplay()
|
||||||
|
|
||||||
|
/// Handle the selection of cell
|
||||||
|
func shouldSelect(at index: IndexPath, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) -> Bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// Default implementation does nothing
|
// Default implementation does nothing
|
||||||
@ -26,4 +29,8 @@ extension CollectionTemplateItemProtocol {
|
|||||||
public func didSelectCell(at index: IndexPath, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) {}
|
public func didSelectCell(at index: IndexPath, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) {}
|
||||||
|
|
||||||
public func willDisplay() {}
|
public func willDisplay() {}
|
||||||
|
|
||||||
|
public func shouldSelect(at index: IndexPath, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) -> Bool {
|
||||||
|
return false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -116,11 +116,15 @@ open class CollectionViewCell: UICollectionViewCell, MoleculeViewProtocol, MVMCo
|
|||||||
|
|
||||||
// MARK: - Override
|
// MARK: - Override
|
||||||
|
|
||||||
open func didSelectCell(at index: IndexPath, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable : Any]?) {
|
open func shouldSelect(at index: IndexPath, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) -> Bool {
|
||||||
guard let action = model?.action else { return }
|
if let action = model?.action {
|
||||||
Button.performButtonAction(with: action, button: self, delegateObject: delegateObject, additionalData: additionalData)
|
Button.performButtonAction(with: action, button: self, delegateObject: delegateObject, additionalData: additionalData)
|
||||||
|
}
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
open func didSelectCell(at index: IndexPath, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable : Any]?) {}
|
||||||
|
|
||||||
// Column logic, set width.
|
// Column logic, set width.
|
||||||
override open func preferredLayoutAttributesFitting(_ layoutAttributes: UICollectionViewLayoutAttributes) -> UICollectionViewLayoutAttributes {
|
override open func preferredLayoutAttributesFitting(_ layoutAttributes: UICollectionViewLayoutAttributes) -> UICollectionViewLayoutAttributes {
|
||||||
let autoLayoutAttributes = super.preferredLayoutAttributesFitting(layoutAttributes)
|
let autoLayoutAttributes = super.preferredLayoutAttributesFitting(layoutAttributes)
|
||||||
|
|||||||
@ -461,7 +461,7 @@ import UIKit
|
|||||||
open func handleOpenPage(for requestParameters: MVMCoreRequestParameters, actionInformation: [AnyHashable: Any]?, additionalData: [AnyHashable: Any]?) {
|
open func handleOpenPage(for requestParameters: MVMCoreRequestParameters, actionInformation: [AnyHashable: Any]?, additionalData: [AnyHashable: Any]?) {
|
||||||
addFormParams(requestParameters)
|
addFormParams(requestParameters)
|
||||||
requestParameters.parentPageType = loadObject?.pageJSON?.optionalStringForKey("parentPageType")
|
requestParameters.parentPageType = loadObject?.pageJSON?.optionalStringForKey("parentPageType")
|
||||||
MVMCoreActionHandler.defaultHandleOpenPage(for: requestParameters, additionalData: additionalData, delegateObject: delegateObject())
|
MVMCoreActionHandler.defaultHandleOpenPage(for: requestParameters, actionInformation: actionInformation, additionalData: additionalData, delegateObject: delegateObject())
|
||||||
}
|
}
|
||||||
|
|
||||||
open func logAction(withActionInformation actionInformation: [AnyHashable: Any]?, additionalData: [AnyHashable: Any]?) {
|
open func logAction(withActionInformation actionInformation: [AnyHashable: Any]?, additionalData: [AnyHashable: Any]?) {
|
||||||
|
|||||||
@ -16,7 +16,7 @@ NS_ASSUME_NONNULL_BEGIN
|
|||||||
|
|
||||||
#pragma mark - Getters
|
#pragma mark - Getters
|
||||||
|
|
||||||
//Returns localized imageName
|
// Returns localized imageName
|
||||||
+ (nullable NSString *)localizedImageName:(nullable NSString *)imageName;
|
+ (nullable NSString *)localizedImageName:(nullable NSString *)imageName;
|
||||||
|
|
||||||
// The bundle for this framework
|
// The bundle for this framework
|
||||||
|
|||||||
@ -23,24 +23,14 @@
|
|||||||
return [NSBundle bundleWithIdentifier:@"com.vzw.MVMCoreUI"];
|
return [NSBundle bundleWithIdentifier:@"com.vzw.MVMCoreUI"];
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (BOOL)userPrefersSpanish {
|
|
||||||
// This should be enough for us to look at what the user prefers.
|
|
||||||
NSString *preference = [[[[NSLocale preferredLanguages] objectAtIndex:0] substringToIndex:2] lowercaseString];
|
|
||||||
return [preference isEqualToString:@"es"] || [preference isEqualToString:@"es-mx"];
|
|
||||||
}
|
|
||||||
|
|
||||||
+ (nullable NSString *)hardcodedStringWithKey:(nonnull NSString *)key {
|
+ (nullable NSString *)hardcodedStringWithKey:(nonnull NSString *)key {
|
||||||
// If the app language is not english... force load from the english file anyway.
|
// Redirect key with relevant module.
|
||||||
if ([MVMCoreUIUtility userPrefersSpanish]) {
|
return [MVMCoreGetterUtility hardcodedStringWithKey:key bundle:[MVMCoreUIUtility bundleForMVMCoreUI]];
|
||||||
return [[NSBundle bundleWithPath:[[MVMCoreUIUtility bundleForMVMCoreUI] pathForResource:@"es" ofType:@"lproj"]] localizedStringForKey:key value:@"" table:nil];
|
|
||||||
} else {
|
|
||||||
return [[NSBundle bundleWithPath:[[MVMCoreUIUtility bundleForMVMCoreUI] pathForResource:@"en" ofType:@"lproj"]] localizedStringForKey:key value:@"" table:nil];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (nullable NSString *)localizedImageName:(nullable NSString *)imageName {
|
+ (nullable NSString *)localizedImageName:(nullable NSString *)imageName {
|
||||||
if (imageName.length > 0) {
|
if (imageName.length > 0) {
|
||||||
if ([MVMCoreUIUtility userPrefersSpanish]) {
|
if ([MVMCoreGetterUtility userPrefersSpanish]) {
|
||||||
imageName = [NSString stringWithFormat:@"%@_es", imageName];
|
imageName = [NSString stringWithFormat:@"%@_es", imageName];
|
||||||
} else {
|
} else {
|
||||||
imageName = [NSString stringWithFormat:@"%@_en", imageName];
|
imageName = [NSString stringWithFormat:@"%@_en", imageName];
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user