Merge branch 'develop' into feature/viewInRoomArAtomicTemplate

This commit is contained in:
Lekshmi S 2021-01-05 10:35:36 +05:30
commit ca0d35dd96
28 changed files with 198 additions and 79 deletions

View File

@ -290,6 +290,7 @@
BBC0C4FF24811DCA0087C44F /* TagModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBC0C4FE24811DCA0087C44F /* TagModel.swift */; }; BBC0C4FF24811DCA0087C44F /* TagModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBC0C4FE24811DCA0087C44F /* TagModel.swift */; };
C003506123AA94CD00B6AC29 /* Button.swift in Sources */ = {isa = PBXBuildFile; fileRef = C003506023AA94CD00B6AC29 /* Button.swift */; }; C003506123AA94CD00B6AC29 /* Button.swift in Sources */ = {isa = PBXBuildFile; fileRef = C003506023AA94CD00B6AC29 /* Button.swift */; };
C07065C42395677300FBF997 /* Link.swift in Sources */ = {isa = PBXBuildFile; fileRef = C07065C32395677300FBF997 /* Link.swift */; }; C07065C42395677300FBF997 /* Link.swift in Sources */ = {isa = PBXBuildFile; fileRef = C07065C32395677300FBF997 /* Link.swift */; };
C6687441259D92D400F32D13 /* ActionTopNotificationModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = C6687440259D92D400F32D13 /* ActionTopNotificationModel.swift */; };
C695A67F23C9830600BFB94E /* UnOrderedListModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = C695A67E23C9830600BFB94E /* UnOrderedListModel.swift */; }; C695A67F23C9830600BFB94E /* UnOrderedListModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = C695A67E23C9830600BFB94E /* UnOrderedListModel.swift */; };
C695A68123C9830D00BFB94E /* NumberedListModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = C695A68023C9830D00BFB94E /* NumberedListModel.swift */; }; C695A68123C9830D00BFB94E /* NumberedListModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = C695A68023C9830D00BFB94E /* NumberedListModel.swift */; };
C695A69423C9909000BFB94E /* DoughnutChartModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = C695A69323C9909000BFB94E /* DoughnutChartModel.swift */; }; C695A69423C9909000BFB94E /* DoughnutChartModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = C695A69323C9909000BFB94E /* DoughnutChartModel.swift */; };
@ -833,6 +834,7 @@
BBC0C4FE24811DCA0087C44F /* TagModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TagModel.swift; sourceTree = "<group>"; }; BBC0C4FE24811DCA0087C44F /* TagModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TagModel.swift; sourceTree = "<group>"; };
C003506023AA94CD00B6AC29 /* Button.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Button.swift; sourceTree = "<group>"; }; C003506023AA94CD00B6AC29 /* Button.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Button.swift; sourceTree = "<group>"; };
C07065C32395677300FBF997 /* Link.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Link.swift; sourceTree = "<group>"; }; C07065C32395677300FBF997 /* Link.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Link.swift; sourceTree = "<group>"; };
C6687440259D92D400F32D13 /* ActionTopNotificationModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActionTopNotificationModel.swift; sourceTree = "<group>"; };
C695A67E23C9830600BFB94E /* UnOrderedListModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UnOrderedListModel.swift; sourceTree = "<group>"; }; C695A67E23C9830600BFB94E /* UnOrderedListModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UnOrderedListModel.swift; sourceTree = "<group>"; };
C695A68023C9830D00BFB94E /* NumberedListModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NumberedListModel.swift; sourceTree = "<group>"; }; C695A68023C9830D00BFB94E /* NumberedListModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NumberedListModel.swift; sourceTree = "<group>"; };
C695A69323C9909000BFB94E /* DoughnutChartModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DoughnutChartModel.swift; sourceTree = "<group>"; }; C695A69323C9909000BFB94E /* DoughnutChartModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DoughnutChartModel.swift; sourceTree = "<group>"; };
@ -1308,6 +1310,7 @@
D2ED27E9254B0CE600A1C293 /* ActionAlertModel.swift */, D2ED27E9254B0CE600A1C293 /* ActionAlertModel.swift */,
D2ED27EA254B0CE700A1C293 /* AlertModel.swift */, D2ED27EA254B0CE700A1C293 /* AlertModel.swift */,
D2ED27E8254B0CE600A1C293 /* ActionPopupModel.swift */, D2ED27E8254B0CE600A1C293 /* ActionPopupModel.swift */,
C6687440259D92D400F32D13 /* ActionTopNotificationModel.swift */,
); );
path = Actions; path = Actions;
sourceTree = "<group>"; sourceTree = "<group>";
@ -2432,6 +2435,7 @@
32F8804824765C8400C2ACB3 /* ListLeftVariableNumberedListAllTextAndLinks.swift in Sources */, 32F8804824765C8400C2ACB3 /* ListLeftVariableNumberedListAllTextAndLinks.swift in Sources */,
D2CAC7CF2511052300C75681 /* CollapsableNotificationModel.swift in Sources */, D2CAC7CF2511052300C75681 /* CollapsableNotificationModel.swift in Sources */,
DBC4391822442197001AB423 /* CaretView.swift in Sources */, DBC4391822442197001AB423 /* CaretView.swift in Sources */,
C6687441259D92D400F32D13 /* ActionTopNotificationModel.swift in Sources */,
C07065C42395677300FBF997 /* Link.swift in Sources */, C07065C42395677300FBF997 /* Link.swift in Sources */,
0A69F611241BDEA700F7231B /* RuleAnyRequiredModel.swift in Sources */, 0A69F611241BDEA700F7231B /* RuleAnyRequiredModel.swift in Sources */,
D29B771022C281F400D6ACE0 /* ModuleMolecule.swift in Sources */, D29B771022C281F400D6ACE0 /* ModuleMolecule.swift in Sources */,

View File

@ -0,0 +1,24 @@
//
// ActionTopNotificationModel.swift
// MVMCoreUI
//
// Created by Murugan, Vimal on 31/12/20.
// Copyright © 2020 Verizon Wireless. All rights reserved.
//
import UIKit
@objcMembers public class ActionTopNotificationModel: ActionModelProtocol {
public static var identifier: String = "topNotification"
public var actionType: String = ActionTopNotificationModel.identifier
public var topNotification: TopNotificationModel
public var extraParameters: JSONValueDictionary?
public var analyticsData: JSONValueDictionary?
public init(topNotification: TopNotificationModel, _ extraParameters: JSONValueDictionary? = nil, _ analyticsData: JSONValueDictionary? = nil) {
self.topNotification = topNotification
self.extraParameters = extraParameters
self.analyticsData = analyticsData
}
}

View File

@ -79,8 +79,6 @@ import UIKit
heightConstraint = heightAnchor.constraint(equalTo: widthAnchor, multiplier: 1) heightConstraint = heightAnchor.constraint(equalTo: widthAnchor, multiplier: 1)
heightConstraint?.isActive = true heightConstraint?.isActive = true
isAccessibilityElement = true isAccessibilityElement = true
accessibilityTraits = .button
updateAccessibilityLabel()
} }
public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
@ -89,6 +87,8 @@ import UIKit
self.additionalData = additionalData self.additionalData = additionalData
guard let model = model as? HeartModel else { return } guard let model = model as? HeartModel else { return }
isSelected = model.isActive isSelected = model.isActive
isEnabled = model.enabled
updateAccessibilityLabel()
} }
//-------------------------------------------------- //--------------------------------------------------
@ -96,11 +96,13 @@ import UIKit
//-------------------------------------------------- //--------------------------------------------------
/// Adjust accessibility label based on selection of Heart. /// Adjust accessibility label based on selection of Heart.
func updateAccessibilityLabel() { func updateAccessibilityLabel() {
accessibilityHint = MVMCoreUIUtility.hardcodedString(withKey: isSelected ? "heart_unfavorite_action_hint" : "heart_favorite_action_hint") accessibilityHint = isEnabled ? MVMCoreUIUtility.hardcodedString(withKey: isSelected ? "heart_unfavorite_action_hint" : "heart_favorite_action_hint") : nil
accessibilityTraits = isEnabled ? .button : .none
accessibilityLabel = MVMCoreUIUtility.hardcodedString(withKey: isSelected ? "heart_selected_state" : "heart_not_selected_state") accessibilityLabel = MVMCoreUIUtility.hardcodedString(withKey: isSelected ? "heart_selected_state" : "heart_not_selected_state")
} }
func tapAction() { func tapAction() {
guard isEnabled else { return }
isSelected = !isSelected isSelected = !isSelected
if let heartModel = heartModel { if let heartModel = heartModel {
Button.performButtonAction(with: heartModel.action, button: self, delegateObject: delegateObject, additionalData: additionalData, sourceModel: heartModel) Button.performButtonAction(with: heartModel.action, button: self, delegateObject: delegateObject, additionalData: additionalData, sourceModel: heartModel)

View File

@ -8,7 +8,7 @@
import Foundation import Foundation
open class HeartModel: MoleculeModelProtocol { open class HeartModel: MoleculeModelProtocol, EnableableModelProtocol {
//-------------------------------------------------- //--------------------------------------------------
// MARK: - Properties // MARK: - Properties
@ -19,6 +19,7 @@ open class HeartModel: MoleculeModelProtocol {
public var activeColor: Color = Color(uiColor: .mvmRed) public var activeColor: Color = Color(uiColor: .mvmRed)
public var inActiveColor: Color = Color(uiColor: .clear) public var inActiveColor: Color = Color(uiColor: .clear)
public var action: ActionModelProtocol = ActionNoopModel() public var action: ActionModelProtocol = ActionNoopModel()
public var enabled: Bool = true
//-------------------------------------------------- //--------------------------------------------------
// MARK: - Keys // MARK: - Keys
@ -30,6 +31,7 @@ open class HeartModel: MoleculeModelProtocol {
case activeColor case activeColor
case inActiveColor case inActiveColor
case action case action
case enabled
} }
//-------------------------------------------------- //--------------------------------------------------
@ -51,6 +53,9 @@ open class HeartModel: MoleculeModelProtocol {
if let action: ActionModelProtocol = try typeContainer.decodeModelIfPresent(codingKey: .action) { if let action: ActionModelProtocol = try typeContainer.decodeModelIfPresent(codingKey: .action) {
self.action = action self.action = action
} }
if let enabled = try typeContainer.decodeIfPresent(Bool.self, forKey: .enabled) {
self.enabled = enabled
}
} }
public func encode(to encoder: Encoder) throws { public func encode(to encoder: Encoder) throws {
@ -61,5 +66,6 @@ open class HeartModel: MoleculeModelProtocol {
try container.encode(activeColor, forKey: .activeColor) try container.encode(activeColor, forKey: .activeColor)
try container.encode(inActiveColor, forKey: .inActiveColor) try container.encode(inActiveColor, forKey: .inActiveColor)
try container.encodeModel(action, forKey: .action) try container.encodeModel(action, forKey: .action)
try container.encode(enabled, forKey: .enabled)
} }
} }

View File

@ -351,9 +351,13 @@ public typealias ActionBlock = () -> ()
} else { } else {
imageAttachment = Label.getTextAttachmentImage(name: imageName, dimension: fontSize) imageAttachment = Label.getTextAttachmentImage(name: imageName, dimension: fontSize)
} }
let mutableString = NSMutableAttributedString()
mutableString.append(NSAttributedString(attachment: imageAttachment)) // Confirm that the intended image location is within range.
attributedString.insert(mutableString, at: imageAtt.location) if 0...labelText.count ~= imageAtt.location {
let mutableString = NSMutableAttributedString()
mutableString.append(NSAttributedString(attachment: imageAttachment))
attributedString.insert(mutableString, at: imageAtt.location)
}
case let fontAtt as LabelAttributeFontModel: case let fontAtt as LabelAttributeFontModel:
if let fontStyle = fontAtt.style { if let fontStyle = fontAtt.style {

View File

@ -20,6 +20,10 @@ public extension UIDatePicker {
let locale = NSLocale.current as NSLocale let locale = NSLocale.current as NSLocale
datePicker.locale = locale as Locale datePicker.locale = locale as Locale
datePicker.calendar = locale.object(forKey: .calendar) as? Calendar datePicker.calendar = locale.object(forKey: .calendar) as? Calendar
//To support old style wheel
if #available(iOS 13.4, *) {
datePicker.preferredDatePickerStyle = .wheels
}
textField.inputView = datePicker textField.inputView = datePicker
return datePicker return datePicker
@ -30,6 +34,10 @@ public extension UIDatePicker {
let datePicker = UIDatePicker() let datePicker = UIDatePicker()
datePicker.backgroundColor = .mvmWhite datePicker.backgroundColor = .mvmWhite
datePicker.datePickerMode = .time datePicker.datePickerMode = .time
//To support old style wheel
if #available(iOS 13.4, *) {
datePicker.preferredDatePickerStyle = .wheels
}
textField.inputView = datePicker textField.inputView = datePicker
return datePicker return datePicker

View File

@ -259,6 +259,7 @@ import Foundation
try? ModelRegistry.register(ActionTopAlertModel.self) try? ModelRegistry.register(ActionTopAlertModel.self)
try? ModelRegistry.register(ActionCollapseNotificationModel.self) try? ModelRegistry.register(ActionCollapseNotificationModel.self)
try? ModelRegistry.register(ActionOpenPanelModel.self) try? ModelRegistry.register(ActionOpenPanelModel.self)
try? ModelRegistry.register(ActionTopNotificationModel.self)
// MARK:- Behaviors // MARK:- Behaviors
try? ModelRegistry.register(ScreenBrightnessModifierBehavior.self) try? ModelRegistry.register(ScreenBrightnessModifierBehavior.self)

View File

@ -42,8 +42,6 @@
addMolecule(stack) addMolecule(stack)
stack.restack() stack.restack()
horizontalStack.restack() horizontalStack.restack()
accessibilityHint = heart.accessibilityHint
accessibilityTraits = heart.accessibilityTraits
} }
public override func updateView(_ size: CGFloat) { public override func updateView(_ size: CGFloat) {
@ -123,20 +121,40 @@
} }
func updateAccessibilityLabel() { func updateAccessibilityLabel() {
if let accessoryView = accessoryView { let hasHeart = !(horizontalStack.stackModel?.molecules[1].gone ?? true)
// Both caret and heart. if let accessoryView = accessoryView,
hasHeart {
// Both accessory and heart actions.
isAccessibilityElement = false isAccessibilityElement = false
accessoryView.accessibilityLabel = getAccessibilityMessage() accessoryView.accessibilityLabel = getAccessibilityMessage()
accessibilityElements = [accessoryView, heart] accessibilityElements = [accessoryView, heart]
} else { } else {
// Make whole cell focusable if no action. // Make whole cell focusable if no action.
isAccessibilityElement = true isAccessibilityElement = true
if let message = getAccessibilityMessage(), var message = getAccessibilityMessage()
let heartLabel = heart.accessibilityLabel { if hasHeart {
accessibilityLabel = message + ", " + heartLabel accessibilityHint = heart.accessibilityHint
if let heartLabel = heart.accessibilityLabel {
message = (message ?? "") + ", " + heartLabel
}
} else { } else {
accessibilityLabel = getAccessibilityMessage() accessibilityHint = nil
} }
accessibilityLabel = message
} }
} }
// Ensures voice over does not read "selected" after user triggers action on cell.
override public var accessibilityTraits: UIAccessibilityTraits {
get {
if (accessoryView != nil) {
return .button
} else if (!(horizontalStack.stackModel?.molecules[1].gone ?? true)) {
return heart.accessibilityTraits
} else {
return .none
}
}
set {}
}
} }

View File

@ -12,7 +12,7 @@ public class ListStoreLocatorModel: ListItemModel, MoleculeModelProtocol {
//-------------------------------------------------- //--------------------------------------------------
public static var identifier = "listStoreLocator" public static var identifier = "listStoreLocator"
public var heart: HeartModel public var heart: HeartModel?
public var leftHeadline: LabelModel public var leftHeadline: LabelModel
public var leftBody: LabelModel public var leftBody: LabelModel
public var leftSubBody: LabelModel public var leftSubBody: LabelModel
@ -22,7 +22,7 @@ public class ListStoreLocatorModel: ListItemModel, MoleculeModelProtocol {
// MARK: - Initializer // MARK: - Initializer
//-------------------------------------------------- //--------------------------------------------------
public init(heart: HeartModel, leftHeadline: LabelModel, leftBody: LabelModel, leftSubBody: LabelModel, rightLabel: LabelModel) { public init(heart: HeartModel?, leftHeadline: LabelModel, leftBody: LabelModel, leftSubBody: LabelModel, rightLabel: LabelModel) {
self.heart = heart self.heart = heart
self.leftHeadline = leftHeadline self.leftHeadline = leftHeadline
self.leftBody = leftBody self.leftBody = leftBody
@ -59,7 +59,7 @@ public class ListStoreLocatorModel: ListItemModel, MoleculeModelProtocol {
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)
heart = try typeContainer.decode(HeartModel.self, forKey:.heart) heart = try typeContainer.decodeIfPresent(HeartModel.self, forKey:.heart)
leftHeadline = try typeContainer.decode(LabelModel.self, forKey: .leftHeadline) leftHeadline = try typeContainer.decode(LabelModel.self, forKey: .leftHeadline)
leftBody = try typeContainer.decode(LabelModel.self, forKey: .leftBody) leftBody = try typeContainer.decode(LabelModel.self, forKey: .leftBody)
leftSubBody = try typeContainer.decode(LabelModel.self, forKey: .leftSubBody) leftSubBody = try typeContainer.decode(LabelModel.self, forKey: .leftSubBody)
@ -71,7 +71,7 @@ public class ListStoreLocatorModel: ListItemModel, MoleculeModelProtocol {
try super.encode(to: encoder) try super.encode(to: encoder)
var container = encoder.container(keyedBy: CodingKeys.self) var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(moleculeName, forKey: .moleculeName) try container.encode(moleculeName, forKey: .moleculeName)
try container.encode(heart, forKey: .heart) try container.encodeIfPresent(heart, forKey: .heart)
try container.encode(leftHeadline, forKey: .leftHeadline) try container.encode(leftHeadline, forKey: .leftHeadline)
try container.encode(leftBody, forKey: .leftBody) try container.encode(leftBody, forKey: .leftBody)
try container.encode(leftSubBody, forKey: .leftSubBody) try container.encode(leftSubBody, forKey: .leftSubBody)

View File

@ -9,12 +9,12 @@
import Foundation import Foundation
@objcMembers public class CarouselItemModel: MoleculeCollectionItemModel, CarouselItemModelProtocol { @objcMembers open class CarouselItemModel: MoleculeCollectionItemModel, CarouselItemModelProtocol {
//-------------------------------------------------- //--------------------------------------------------
// MARK: - Properties // MARK: - Properties
//-------------------------------------------------- //--------------------------------------------------
public override class var identifier: String { open override class var identifier: String {
return "carouselItem" return "carouselItem"
} }
@ -44,7 +44,7 @@ import Foundation
try super.init(from: decoder) try super.init(from: decoder)
} }
public override func encode(to encoder: Encoder) throws { open override func encode(to encoder: Encoder) throws {
try super.encode(to: encoder) try super.encode(to: encoder)
var container = encoder.container(keyedBy: CodingKeys.self) var container = encoder.container(keyedBy: CodingKeys.self)
try container.encodeIfPresent(peakingUI, forKey: .peakingUI) try container.encodeIfPresent(peakingUI, forKey: .peakingUI)

View File

@ -9,7 +9,7 @@
import Foundation import Foundation
/// A model for a collection item that is a container for any molecule. /// A model for a collection item that is a container for any molecule.
@objcMembers public class MoleculeCollectionItemModel: MoleculeContainerModel, CollectionItemModelProtocol { @objcMembers open class MoleculeCollectionItemModel: MoleculeContainerModel, CollectionItemModelProtocol {
open override class var identifier: String { open override class var identifier: String {
return "collectionItem" return "collectionItem"
} }

View File

@ -13,6 +13,7 @@ public class NavigationImageButtonModel: NavigationButtonModelProtocol, Molecule
public var image: String public var image: String
public var action: ActionModelProtocol public var action: ActionModelProtocol
public var accessibilityText: String?
public init(with image: String, action: ActionModelProtocol) { public init(with image: String, action: ActionModelProtocol) {
self.image = image self.image = image
@ -23,12 +24,14 @@ public class NavigationImageButtonModel: NavigationButtonModelProtocol, Molecule
case image case image
case action case action
case moleculeName case moleculeName
case accessibilityText
} }
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)
image = try typeContainer.decode(String.self, forKey: .image) image = try typeContainer.decode(String.self, forKey: .image)
action = try typeContainer.decodeModel(codingKey: .action) action = try typeContainer.decodeModel(codingKey: .action)
accessibilityText = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityText)
} }
open func encode(to encoder: Encoder) throws { open func encode(to encoder: Encoder) throws {
@ -36,11 +39,17 @@ public class NavigationImageButtonModel: NavigationButtonModelProtocol, Molecule
try container.encode(image, forKey: .image) try container.encode(image, forKey: .image)
try container.encode(moleculeName, forKey: .moleculeName) try container.encode(moleculeName, forKey: .moleculeName)
try container.encodeModel(action, forKey: .action) try container.encodeModel(action, forKey: .action)
try container.encodeIfPresent(accessibilityText, forKey: .accessibilityText)
} }
/// Convenience function that creates a BarButtonItem for the model. /// Convenience function that creates a BarButtonItem for the model.
public func createNavigationItemButton(delegateObject: MVMCoreUIDelegateObject? = nil, additionalData: [AnyHashable: Any]? = nil) -> UIBarButtonItem { public func createNavigationItemButton(delegateObject: MVMCoreUIDelegateObject? = nil, additionalData: [AnyHashable: Any]? = nil) -> UIBarButtonItem {
let uiImage = MVMCoreCache.shared()?.getImageFromRegisteredBundles(image) let uiImage = MVMCoreCache.shared()?.getImageFromRegisteredBundles(image)
return ImageBarButtonItem.create(with: uiImage, actionModel: action, delegateObject: delegateObject, additionalData: additionalData) let navigationImageButton = ImageBarButtonItem.create(with: uiImage, actionModel: action, delegateObject: delegateObject, additionalData: additionalData)
if let accessibilityString = accessibilityText {
navigationImageButton.accessibilityLabel = accessibilityString
navigationImageButton.isAccessibilityElement = true
}
return navigationImageButton
} }
} }

View File

@ -12,21 +12,24 @@ import Foundation
public override class var identifier: String { public override class var identifier: String {
return "numberedList" return "numberedList"
} }
public var numberColor: Color
private enum CodingKeys: String, CodingKey { private enum CodingKeys: String, CodingKey {
case moleculeName case moleculeName
case backgroundColor case backgroundColor
case list case list
case numberColor
} }
// Numbered list model comes in the from of list = [MoleculeModelProtocol] // Numbered list model comes in the from of list = [MoleculeModelProtocol]
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)
numberColor = try typeContainer.decodeIfPresent(Color.self, forKey: .numberColor) ?? Color(uiColor: .mvmBlack)
let list: [MoleculeModelProtocol] = try typeContainer.decodeModels(codingKey: .list) let list: [MoleculeModelProtocol] = try typeContainer.decodeModels(codingKey: .list)
var models: [MoleculeStackItemModel] = [] var models: [MoleculeStackItemModel] = []
for (index, molecule) in list.enumerated() { for (index, molecule) in list.enumerated() {
models.append(MoleculeStackItemModel(with: StringAndMoleculeModel(string: "\(index+1).", molecule: molecule))) models.append(MoleculeStackItemModel(with: StringAndMoleculeModel(string: "\(index+1).", molecule: molecule, stringColor: numberColor)))
} }
super.init(molecules: models, spacing: 0) super.init(molecules: models, spacing: 0)
} }
@ -41,6 +44,7 @@ import Foundation
models.append(((molecule as! MoleculeStackItemModel).molecule as! StringAndMoleculeModel).molecule) models.append(((molecule as! MoleculeStackItemModel).molecule as! StringAndMoleculeModel).molecule)
} }
try container.encodeModels(models, forKey: .list) try container.encodeModels(models, forKey: .list)
try container.encode(numberColor, forKey: .numberColor)
} }
} }

View File

@ -13,10 +13,12 @@ public class StringAndMoleculeModel: MoleculeModelProtocol {
public var backgroundColor: Color? public var backgroundColor: Color?
public var string: String public var string: String
public var molecule: MoleculeModelProtocol public var molecule: MoleculeModelProtocol
public var stringColor: Color
public init(string: String, molecule: MoleculeModelProtocol) {
public init(string: String, molecule: MoleculeModelProtocol, stringColor: Color = Color(uiColor: .mvmBlack)) {
self.string = string self.string = string
self.molecule = molecule self.molecule = molecule
self.stringColor = stringColor
} }
private enum CodingKeys: String, CodingKey { private enum CodingKeys: String, CodingKey {
@ -24,6 +26,7 @@ public class StringAndMoleculeModel: MoleculeModelProtocol {
case backgroundColor case backgroundColor
case string case string
case molecule case molecule
case stringColor
} }
public required init(from decoder: Decoder) throws { public required init(from decoder: Decoder) throws {
@ -31,6 +34,7 @@ public class StringAndMoleculeModel: MoleculeModelProtocol {
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
string = try typeContainer.decode(String.self, forKey: .string) string = try typeContainer.decode(String.self, forKey: .string)
molecule = try typeContainer.decodeModel(codingKey: .molecule) molecule = try typeContainer.decodeModel(codingKey: .molecule)
stringColor = try typeContainer.decodeIfPresent(Color.self, forKey: .stringColor) ?? Color(uiColor: .mvmBlack)
} }
public func encode(to encoder: Encoder) throws { public func encode(to encoder: Encoder) throws {
@ -39,5 +43,6 @@ public class StringAndMoleculeModel: MoleculeModelProtocol {
try container.encode(string, forKey: .string) try container.encode(string, forKey: .string)
try container.encodeModel(molecule, forKey: .molecule) try container.encodeModel(molecule, forKey: .molecule)
try container.encode(moleculeName, forKey: .moleculeName) try container.encode(moleculeName, forKey: .moleculeName)
try container.encode(stringColor, forKey: .stringColor)
} }
} }

View File

@ -84,6 +84,7 @@ open class StringAndMoleculeView: View {
super.set(with: model, delegateObject, additionalData) super.set(with: model, delegateObject, additionalData)
guard let model = model as? StringAndMoleculeModel else { return } guard let model = model as? StringAndMoleculeModel else { return }
label.text = model.string label.text = model.string
label.textColor = model.stringColor.uiColor
molecule.set(with: model.molecule, delegateObject, additionalData) molecule.set(with: model.molecule, delegateObject, additionalData)
} }

View File

@ -13,12 +13,14 @@ import Foundation
return "unOrderedList" return "unOrderedList"
} }
public var bulletChar = "" public var bulletChar = ""
public var bulletColor: Color
private enum CodingKeys: String, CodingKey { private enum CodingKeys: String, CodingKey {
case moleculeName case moleculeName
case backgroundColor case backgroundColor
case list case list
case bulletChar case bulletChar
case bulletColor
} }
// Numbered list model comes in the from of list = [MoleculeModelProtocol] // Numbered list model comes in the from of list = [MoleculeModelProtocol]
@ -28,10 +30,11 @@ import Foundation
self.bulletChar = bulletChar self.bulletChar = bulletChar
} }
bulletColor = try typeContainer.decodeIfPresent(Color.self, forKey: .bulletColor) ?? Color(uiColor: .mvmBlack)
let list: [MoleculeModelProtocol] = try typeContainer.decodeModels(codingKey: .list) let list: [MoleculeModelProtocol] = try typeContainer.decodeModels(codingKey: .list)
var models: [MoleculeStackItemModel] = [] var models: [MoleculeStackItemModel] = []
for molecule in list { for molecule in list {
models.append(MoleculeStackItemModel(with: StringAndMoleculeModel(string: bulletChar, molecule: molecule))) models.append(MoleculeStackItemModel(with: StringAndMoleculeModel(string: bulletChar, molecule: molecule, stringColor: bulletColor)))
} }
super.init(molecules: models, spacing: 0) super.init(molecules: models, spacing: 0)
} }
@ -47,5 +50,6 @@ import Foundation
models.append(((molecule as! MoleculeStackItemModel).molecule as! StringAndMoleculeModel).molecule) models.append(((molecule as! MoleculeStackItemModel).molecule as! StringAndMoleculeModel).molecule)
} }
try container.encodeModels(models, forKey: .list) try container.encodeModels(models, forKey: .list)
try container.encode(bulletColor, forKey: .bulletColor)
} }
} }

View File

@ -67,7 +67,7 @@ import Foundation
var container = encoder.container(keyedBy: CodingKeys.self) var container = encoder.container(keyedBy: CodingKeys.self)
try container.encodeModelsIfPresent(molecules, forKey: .molecules) try container.encodeModelsIfPresent(molecules, forKey: .molecules)
try container.encode(line, forKey: .line) try container.encode(line, forKey: .line)
try container.encode(scrollToRowIndex, forKey: .scrollToRowIndex) try container.encodeIfPresent(scrollToRowIndex, forKey: .scrollToRowIndex)
} }
} }

View File

@ -9,8 +9,8 @@
import Foundation import Foundation
class UICollectionViewLeftAlignedLayout: UICollectionViewFlowLayout { public class UICollectionViewLeftAlignedLayout: UICollectionViewFlowLayout {
override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? { public override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
guard let attributes = super.layoutAttributesForElements(in: rect) else { return nil } guard let attributes = super.layoutAttributesForElements(in: rect) else { return nil }
var newAttributesForElementsInRect = [UICollectionViewLayoutAttributes]() var newAttributesForElementsInRect = [UICollectionViewLayoutAttributes]()
for attribute in attributes { for attribute in attributes {

View File

@ -15,9 +15,9 @@ open class Container: View, ContainerProtocol {
//-------------------------------------------------- //--------------------------------------------------
public var view: UIView? public var view: UIView?
let containerHelper = ContainerHelper() public let containerHelper = ContainerHelper()
var containerModel: ContainerModelProtocol? { public var containerModel: ContainerModelProtocol? {
get { return model as? ContainerModelProtocol } get { return model as? ContainerModelProtocol }
} }

View File

@ -15,23 +15,23 @@ open class ContainerHelper: NSObject {
// MARK: - Constraints // MARK: - Constraints
//-------------------------------------------------- //--------------------------------------------------
var leftConstraint: NSLayoutConstraint? open var leftConstraint: NSLayoutConstraint?
var topConstraint: NSLayoutConstraint? open var topConstraint: NSLayoutConstraint?
var bottomConstraint: NSLayoutConstraint? open var bottomConstraint: NSLayoutConstraint?
var rightConstraint: NSLayoutConstraint? open var rightConstraint: NSLayoutConstraint?
var alignCenterHorizontalConstraint: NSLayoutConstraint? open var alignCenterHorizontalConstraint: NSLayoutConstraint?
var alignCenterLeftConstraint: NSLayoutConstraint? open var alignCenterLeftConstraint: NSLayoutConstraint?
var alignCenterRightConstraint: NSLayoutConstraint? open var alignCenterRightConstraint: NSLayoutConstraint?
var alignCenterVerticalConstraint: NSLayoutConstraint? open var alignCenterVerticalConstraint: NSLayoutConstraint?
var alignCenterTopConstraint: NSLayoutConstraint? open var alignCenterTopConstraint: NSLayoutConstraint?
var alignCenterBottomConstraint: NSLayoutConstraint? open var alignCenterBottomConstraint: NSLayoutConstraint?
var leftLowConstraint: NSLayoutConstraint? open var leftLowConstraint: NSLayoutConstraint?
var topLowConstraint: NSLayoutConstraint? open var topLowConstraint: NSLayoutConstraint?
var bottomLowConstraint: NSLayoutConstraint? open var bottomLowConstraint: NSLayoutConstraint?
var rightLowConstraint: NSLayoutConstraint? open var rightLowConstraint: NSLayoutConstraint?
//-------------------------------------------------- //--------------------------------------------------
// MARK: - Methods // MARK: - Methods

View File

@ -24,6 +24,9 @@ NS_ASSUME_NONNULL_BEGIN
// Collapses the current top notification // Collapses the current top notification
- (void)collapseNotificationAction:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData delegateObject:(nullable DelegateObject *)delegateObject; - (void)collapseNotificationAction:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData delegateObject:(nullable DelegateObject *)delegateObject;
// Shows a topnotification new molecular
- (void)topNotificationAction:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData delegateObject:(nullable DelegateObject *)delegateObject;
#pragma mark - Deprecated #pragma mark - Deprecated
// Shows a popup // Shows a popup
@ -32,6 +35,9 @@ NS_ASSUME_NONNULL_BEGIN
// Shows a top alert // Shows a top alert
- (void)topAlertAction:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData delegate:(nullable NSObject <MVMCoreLoadDelegateProtocol, MVMCorePresentationDelegateProtocol,MVMCoreActionDelegateProtocol>*)delegate __deprecated; - (void)topAlertAction:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData delegate:(nullable NSObject <MVMCoreLoadDelegateProtocol, MVMCorePresentationDelegateProtocol,MVMCoreActionDelegateProtocol>*)delegate __deprecated;
// Shows a molecular top alert
- (void)topNotificationAction:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData delegate:(nullable NSObject <MVMCoreLoadDelegateProtocol, MVMCorePresentationDelegateProtocol,MVMCoreActionDelegateProtocol>*)delegate __deprecated;
// Collapses the current top notification // Collapses the current top notification
- (void)collapseNotificationAction:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData delegate:(nullable NSObject <MVMCoreLoadDelegateProtocol, MVMCorePresentationDelegateProtocol,MVMCoreActionDelegateProtocol>*)delegate __deprecated; - (void)collapseNotificationAction:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData delegate:(nullable NSObject <MVMCoreLoadDelegateProtocol, MVMCorePresentationDelegateProtocol,MVMCoreActionDelegateProtocol>*)delegate __deprecated;

View File

@ -31,6 +31,9 @@
} else if ([actionType isEqualToString:KeyActionTypeAlert]) { } else if ([actionType isEqualToString:KeyActionTypeAlert]) {
[self showAlert:actionInformation additionalData:additionalData delegateObject:delegateObject]; [self showAlert:actionInformation additionalData:additionalData delegateObject:delegateObject];
return YES; return YES;
} else if ([actionType isEqualToString:KeyActionTypeTopNotification]) {
[self topNotificationAction:actionInformation additionalData:additionalData delegateObject:delegateObject];
return YES;
} }
return NO; return NO;
} }
@ -102,6 +105,11 @@
} }
} }
- (void)topNotificationAction:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData delegateObject:(nullable DelegateObject *)delegateObject {
//Handle molecular topnotification
[[MVMCoreUITopAlertView sharedGlobal] showTopAlertWith:[actionInformation dict:@"topNotification"] ?: @{}];
}
- (void)defaultHandleActionError:(nonnull MVMCoreErrorObject *)error additionalData:(nullable NSDictionary *)additionalData { - (void)defaultHandleActionError:(nonnull MVMCoreErrorObject *)error additionalData:(nullable NSDictionary *)additionalData {
[super defaultHandleActionError:error additionalData:additionalData]; [super defaultHandleActionError:error additionalData:additionalData];
if (!error.silentError) { if (!error.silentError) {
@ -119,12 +127,16 @@
- (BOOL)handleOtherActions:(nullable NSString *)actionType actionInformation:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData delegate:(nullable NSObject <MVMCoreLoadDelegateProtocol, MVMCorePresentationDelegateProtocol,MVMCoreActionDelegateProtocol>*)delegate { - (BOOL)handleOtherActions:(nullable NSString *)actionType actionInformation:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData delegate:(nullable NSObject <MVMCoreLoadDelegateProtocol, MVMCorePresentationDelegateProtocol,MVMCoreActionDelegateProtocol>*)delegate {
if ([actionType isEqualToString:KeyActionTypePopup]) { if ([actionType isEqualToString:KeyActionTypePopup]) {
[self popupAction:actionInformation additionalData:additionalData delegate:delegate]; [self popupAction:actionInformation additionalData:additionalData delegate:delegate];
return YES;
} else if ([actionType isEqualToString:KeyActionTypeTopAlert]) { } else if ([actionType isEqualToString:KeyActionTypeTopAlert]) {
[self topAlertAction:actionInformation additionalData:additionalData delegate:delegate]; [self topAlertAction:actionInformation additionalData:additionalData delegate:delegate];
return YES; return YES;
} else if ([actionType isEqualToString:KeyActionTypeCollapseNotification]) { } else if ([actionType isEqualToString:KeyActionTypeCollapseNotification]) {
[self collapseNotificationAction:actionInformation additionalData:additionalData delegate:delegate]; [self collapseNotificationAction:actionInformation additionalData:additionalData delegate:delegate];
return YES; return YES;
} else if ([actionType isEqualToString:KeyActionTypeTopNotification]) {
[self topNotificationAction:actionInformation additionalData:additionalData delegate:delegate];
return YES;
} }
return NO; return NO;
} }
@ -171,4 +183,9 @@
} }
} }
- (void)topNotificationAction:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData delegate:(nullable NSObject <MVMCoreLoadDelegateProtocol, MVMCorePresentationDelegateProtocol,MVMCoreActionDelegateProtocol>*)delegate {
//Handle molecular topnotification
[[MVMCoreUITopAlertView sharedGlobal] showTopAlertWith:[actionInformation dict:@"topNotification"] ?: @{}];
}
@end @end

View File

@ -1104,7 +1104,7 @@ CGFloat const LabelWithInternalButtonLineSpace = 2;
} }
+ (nonnull NSAttributedString *)styleGetRegularMicroAttributedString:(nullable NSString *)string { + (nonnull NSAttributedString *)styleGetRegularMicroAttributedString:(nullable NSString *)string {
return [MFStyler styleGetRegularBodySmallAttributedString:string genericScaling:YES]; return [MFStyler styleGetRegularMicroAttributedString:string genericScaling:YES];
} }
+ (nonnull NSAttributedString *)styleGetRegularMicroAttributedString:(nullable NSString *)string genericScaling:(BOOL)genericScaling { + (nonnull NSAttributedString *)styleGetRegularMicroAttributedString:(nullable NSString *)string genericScaling:(BOOL)genericScaling {

View File

@ -28,13 +28,13 @@ open class Styler {
// Legacy Fonts // Legacy Fonts
case H1 case H1
case H2
case H3
case H32 case H32
case H2
case B20
case H3
case B1 case B1
case B2 case B2
case B3 case B3
case B20
/// Returns the font size of the current enum case. /// Returns the font size of the current enum case.
public func pointSize() -> CGFloat { public func pointSize() -> CGFloat {
@ -45,8 +45,7 @@ open class Styler {
case .Title2XLarge: case .Title2XLarge:
return 36 return 36
case .TitleXLarge, case .TitleXLarge, .H32:
.H32:
return 32 return 32
case .H2: case .H2:
@ -57,8 +56,7 @@ open class Styler {
return 24 return 24
case .BoldTitleMedium, case .BoldTitleMedium,
.RegularTitleMedium, .RegularTitleMedium, .B20:
.B20:
return 20 return 20
case .H3: case .H3:
@ -68,15 +66,12 @@ open class Styler {
.RegularBodyLarge: .RegularBodyLarge:
return 16 return 16
case .BoldBodySmall, case .BoldBodySmall, .B1,
.RegularBodySmall, .RegularBodySmall, .B2:
.B1,
.B2:
return 13 return 13
case .BoldMicro, case .BoldMicro,
.RegularMicro, .RegularMicro, .B3:
.B3:
return 11 return 11
} }
} }
@ -96,27 +91,22 @@ open class Styler {
switch self { switch self {
case .RegularTitleLarge, case .RegularTitleLarge,
.RegularTitleMedium, .RegularTitleMedium, .B20,
.RegularBodyLarge, .RegularBodyLarge,
.RegularBodySmall, .RegularBodySmall, .B2,
.RegularMicro, .RegularMicro, .B3:
.B2,
.B3,
.B20:
return false return false
case .Title2XLarge, case .H1,
.TitleXLarge, .Title2XLarge,
.TitleXLarge, .H32,
.H2,
.BoldTitleLarge, .BoldTitleLarge,
.BoldTitleMedium, .BoldTitleMedium,
.BoldBodyLarge,
.BoldBodySmall,
.BoldMicro,
.H1,
.H2,
.H3, .H3,
.H32, .BoldBodyLarge,
.B1: .BoldBodySmall, .B1,
.BoldMicro:
return true return true
} }
} }
@ -140,9 +130,9 @@ open class Styler {
return false return false
case .H1, case .H1,
.H32,
.H2, .H2,
.H3, .H3,
.H32,
.B1, .B1,
.B2, .B2,
.B3, .B3,

View File

@ -61,6 +61,12 @@ public extension MVMCoreUITopAlertView {
MVMCoreAlertHandler.shared()?.add(operation) MVMCoreAlertHandler.shared()?.add(operation)
} }
/// Shows the top alert with the json.
@objc func showTopAlert(with json: [AnyHashable: Any]) {
guard let model = decodeTopNotification(with: json, delegateObject: getDelegateObject()) else { return }
showTopAlert(with: model)
}
/// Checks for existing top alert object of same type and updates it. Only happens for molecular top alerts. Returns true if we updated. /// Checks for existing top alert object of same type and updates it. Only happens for molecular top alerts. Returns true if we updated.
private func checkAndUpdateExisting(with topAlertObject: MVMCoreTopAlertObject) -> Bool { private func checkAndUpdateExisting(with topAlertObject: MVMCoreTopAlertObject) -> Bool {
guard let queue = MVMCoreAlertHandler.shared()?.topAlertQueue.operations else { return false } guard let queue = MVMCoreAlertHandler.shared()?.topAlertQueue.operations else { return false }

View File

@ -118,6 +118,10 @@ static const CGFloat VertialShadowOffset = 6;
NSLocale *locale = [NSLocale currentLocale]; NSLocale *locale = [NSLocale currentLocale];
datePicker.locale = locale; datePicker.locale = locale;
datePicker.calendar = [locale objectForKey:NSLocaleCalendar]; datePicker.calendar = [locale objectForKey:NSLocaleCalendar];
//To handle new style in ios 13.4 and above
if (@available(iOS 13.4, *)) {
[datePicker setPreferredDatePickerStyle:UIDatePickerStyleWheels];
}
datePicker = datePicker; datePicker = datePicker;
textField.inputView = datePicker; textField.inputView = datePicker;
return datePicker; return datePicker;
@ -128,6 +132,10 @@ static const CGFloat VertialShadowOffset = 6;
datePicker.backgroundColor = [UIColor whiteColor]; datePicker.backgroundColor = [UIColor whiteColor];
datePicker.datePickerMode = UIDatePickerModeTime; datePicker.datePickerMode = UIDatePickerModeTime;
datePicker = datePicker; datePicker = datePicker;
//To handle new style in ios 13.4 and above
if (@available(iOS 13.4, *)) {
[datePicker setPreferredDatePickerStyle:UIDatePickerStyleWheels];
}
textField.inputView = datePicker; textField.inputView = datePicker;
return datePicker; return datePicker;

View File

@ -48,6 +48,7 @@ extern NSString * const KeyActionTypePopup;
extern NSString * const KeyActionTypeAlert; extern NSString * const KeyActionTypeAlert;
extern NSString * const KeyActionTypeTopAlert; extern NSString * const KeyActionTypeTopAlert;
extern NSString * const KeyActionTypeCollapseNotification; extern NSString * const KeyActionTypeCollapseNotification;
extern NSString * const KeyActionTypeTopNotification;
/// Key for molecular top notification architecture. /// Key for molecular top notification architecture.
extern NSString * const KeyTopAlert; extern NSString * const KeyTopAlert;

View File

@ -47,6 +47,7 @@ NSString * const KeyActionTypeAlert = @"alert";
NSString * const KeyActionTypeTopAlert = @"topAlert"; NSString * const KeyActionTypeTopAlert = @"topAlert";
NSString * const KeyActionTypeCollapseNotification = @"collapseNotification"; NSString * const KeyActionTypeCollapseNotification = @"collapseNotification";
NSString * const KeyActionTypeTopNotification = @"topNotification";
NSString * const KeyTopAlert = @"TopNotification"; NSString * const KeyTopAlert = @"TopNotification";
#pragma mark - Values #pragma mark - Values