merging
This commit is contained in:
commit
ddd8cc2f07
@ -80,8 +80,6 @@ import UIKit
|
||||
heightConstraint = heightAnchor.constraint(equalTo: widthAnchor, multiplier: 1)
|
||||
heightConstraint?.isActive = true
|
||||
isAccessibilityElement = true
|
||||
accessibilityTraits = .button
|
||||
updateAccessibilityLabel()
|
||||
}
|
||||
|
||||
public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
||||
@ -91,6 +89,8 @@ import UIKit
|
||||
guard let model = model as? HeartModel else { return }
|
||||
accessibilityIdentifier = model.accessibilityIdentifier
|
||||
isSelected = model.isActive
|
||||
isEnabled = model.enabled
|
||||
updateAccessibilityLabel()
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
@ -98,11 +98,13 @@ import UIKit
|
||||
//--------------------------------------------------
|
||||
/// Adjust accessibility label based on selection of Heart.
|
||||
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")
|
||||
}
|
||||
|
||||
func tapAction() {
|
||||
guard isEnabled else { return }
|
||||
isSelected = !isSelected
|
||||
if let heartModel = heartModel {
|
||||
Button.performButtonAction(with: heartModel.action, button: self, delegateObject: delegateObject, additionalData: additionalData, sourceModel: heartModel)
|
||||
|
||||
@ -7,7 +7,8 @@
|
||||
//
|
||||
|
||||
|
||||
open class HeartModel: MoleculeModelProtocol {
|
||||
open class HeartModel: MoleculeModelProtocol, EnableableModelProtocol {
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Properties
|
||||
//--------------------------------------------------
|
||||
@ -19,6 +20,7 @@ open class HeartModel: MoleculeModelProtocol {
|
||||
public var activeColor: Color = Color(uiColor: .mvmRed)
|
||||
public var inActiveColor: Color = Color(uiColor: .clear)
|
||||
public var action: ActionModelProtocol = ActionNoopModel()
|
||||
public var enabled: Bool = true
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Keys
|
||||
@ -32,6 +34,7 @@ open class HeartModel: MoleculeModelProtocol {
|
||||
case activeColor
|
||||
case inActiveColor
|
||||
case action
|
||||
case enabled
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
@ -58,6 +61,9 @@ open class HeartModel: MoleculeModelProtocol {
|
||||
if let action: ActionModelProtocol = try typeContainer.decodeModelIfPresent(codingKey: .action) {
|
||||
self.action = action
|
||||
}
|
||||
if let enabled = try typeContainer.decodeIfPresent(Bool.self, forKey: .enabled) {
|
||||
self.enabled = enabled
|
||||
}
|
||||
}
|
||||
|
||||
public func encode(to encoder: Encoder) throws {
|
||||
@ -69,5 +75,6 @@ open class HeartModel: MoleculeModelProtocol {
|
||||
try container.encode(activeColor, forKey: .activeColor)
|
||||
try container.encode(inActiveColor, forKey: .inActiveColor)
|
||||
try container.encodeModel(action, forKey: .action)
|
||||
try container.encode(enabled, forKey: .enabled)
|
||||
}
|
||||
}
|
||||
|
||||
@ -42,8 +42,6 @@
|
||||
addMolecule(stack)
|
||||
stack.restack()
|
||||
horizontalStack.restack()
|
||||
accessibilityHint = heart.accessibilityHint
|
||||
accessibilityTraits = heart.accessibilityTraits
|
||||
}
|
||||
|
||||
public override func updateView(_ size: CGFloat) {
|
||||
@ -123,20 +121,40 @@
|
||||
}
|
||||
|
||||
func updateAccessibilityLabel() {
|
||||
if let accessoryView = accessoryView {
|
||||
// Both caret and heart.
|
||||
let hasHeart = !(horizontalStack.stackModel?.molecules[1].gone ?? true)
|
||||
if let accessoryView = accessoryView,
|
||||
hasHeart {
|
||||
// Both accessory and heart actions.
|
||||
isAccessibilityElement = false
|
||||
accessoryView.accessibilityLabel = getAccessibilityMessage()
|
||||
accessibilityElements = [accessoryView, heart]
|
||||
} else {
|
||||
// Make whole cell focusable if no action.
|
||||
isAccessibilityElement = true
|
||||
if let message = getAccessibilityMessage(),
|
||||
let heartLabel = heart.accessibilityLabel {
|
||||
accessibilityLabel = message + ", " + heartLabel
|
||||
var message = getAccessibilityMessage()
|
||||
if hasHeart {
|
||||
accessibilityHint = heart.accessibilityHint
|
||||
if let heartLabel = heart.accessibilityLabel {
|
||||
message = (message ?? "") + ", " + heartLabel
|
||||
}
|
||||
} 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 {}
|
||||
}
|
||||
}
|
||||
|
||||
@ -12,7 +12,7 @@ public class ListStoreLocatorModel: ListItemModel, MoleculeModelProtocol {
|
||||
//--------------------------------------------------
|
||||
|
||||
public static var identifier = "listStoreLocator"
|
||||
public var heart: HeartModel
|
||||
public var heart: HeartModel?
|
||||
public var leftHeadline: LabelModel
|
||||
public var leftBody: LabelModel
|
||||
public var leftSubBody: LabelModel
|
||||
@ -22,7 +22,7 @@ public class ListStoreLocatorModel: ListItemModel, MoleculeModelProtocol {
|
||||
// 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.leftHeadline = leftHeadline
|
||||
self.leftBody = leftBody
|
||||
@ -59,7 +59,7 @@ public class ListStoreLocatorModel: ListItemModel, MoleculeModelProtocol {
|
||||
|
||||
public required init(from decoder: Decoder) throws {
|
||||
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)
|
||||
leftBody = try typeContainer.decode(LabelModel.self, forKey: .leftBody)
|
||||
leftSubBody = try typeContainer.decode(LabelModel.self, forKey: .leftSubBody)
|
||||
@ -71,7 +71,7 @@ public class ListStoreLocatorModel: ListItemModel, MoleculeModelProtocol {
|
||||
try super.encode(to: encoder)
|
||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||
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(leftBody, forKey: .leftBody)
|
||||
try container.encode(leftSubBody, forKey: .leftSubBody)
|
||||
|
||||
@ -16,6 +16,7 @@ public class NavigationImageButtonModel: NavigationButtonModelProtocol, Molecule
|
||||
public static var identifier: String = "navigationImageButton"
|
||||
public var image: String
|
||||
public var action: ActionModelProtocol
|
||||
public var accessibilityText: String?
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Initializer
|
||||
@ -35,6 +36,7 @@ public class NavigationImageButtonModel: NavigationButtonModelProtocol, Molecule
|
||||
case action
|
||||
case accessibilityIdentifier
|
||||
case moleculeName
|
||||
case accessibilityText
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
@ -46,6 +48,7 @@ public class NavigationImageButtonModel: NavigationButtonModelProtocol, Molecule
|
||||
accessibilityIdentifier = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityIdentifier)
|
||||
image = try typeContainer.decode(String.self, forKey: .image)
|
||||
action = try typeContainer.decodeModel(codingKey: .action)
|
||||
accessibilityText = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityText)
|
||||
}
|
||||
|
||||
open func encode(to encoder: Encoder) throws {
|
||||
@ -54,6 +57,7 @@ public class NavigationImageButtonModel: NavigationButtonModelProtocol, Molecule
|
||||
try container.encodeIfPresent(accessibilityIdentifier, forKey: .accessibilityIdentifier)
|
||||
try container.encode(moleculeName, forKey: .moleculeName)
|
||||
try container.encodeModel(action, forKey: .action)
|
||||
try container.encodeIfPresent(accessibilityText, forKey: .accessibilityText)
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
@ -65,6 +69,11 @@ public class NavigationImageButtonModel: NavigationButtonModelProtocol, Molecule
|
||||
let uiImage = MVMCoreCache.shared()?.getImageFromRegisteredBundles(image)
|
||||
let buttonItem = ImageBarButtonItem.create(with: uiImage, actionModel: action, delegateObject: delegateObject, additionalData: additionalData)
|
||||
buttonItem.accessibilityIdentifier = accessibilityIdentifier ?? image
|
||||
if let accessibilityString = accessibilityText {
|
||||
buttonItem.accessibilityLabel = accessibilityString
|
||||
buttonItem.isAccessibilityElement = true
|
||||
}
|
||||
|
||||
return buttonItem
|
||||
}
|
||||
}
|
||||
|
||||
@ -12,21 +12,24 @@ import Foundation
|
||||
public override class var identifier: String {
|
||||
return "numberedList"
|
||||
}
|
||||
public var numberColor: Color
|
||||
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case moleculeName
|
||||
case backgroundColor
|
||||
case list
|
||||
case numberColor
|
||||
}
|
||||
|
||||
// Numbered list model comes in the from of list = [MoleculeModelProtocol]
|
||||
public required init(from decoder: Decoder) throws {
|
||||
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)
|
||||
var models: [MoleculeStackItemModel] = []
|
||||
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)
|
||||
}
|
||||
@ -41,6 +44,7 @@ import Foundation
|
||||
models.append(((molecule as! MoleculeStackItemModel).molecule as! StringAndMoleculeModel).molecule)
|
||||
}
|
||||
try container.encodeModels(models, forKey: .list)
|
||||
try container.encode(numberColor, forKey: .numberColor)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -13,10 +13,12 @@ public class StringAndMoleculeModel: MoleculeModelProtocol {
|
||||
public var backgroundColor: Color?
|
||||
public var string: String
|
||||
public var molecule: MoleculeModelProtocol
|
||||
|
||||
public init(string: String, molecule: MoleculeModelProtocol) {
|
||||
public var stringColor: Color
|
||||
|
||||
public init(string: String, molecule: MoleculeModelProtocol, stringColor: Color = Color(uiColor: .mvmBlack)) {
|
||||
self.string = string
|
||||
self.molecule = molecule
|
||||
self.stringColor = stringColor
|
||||
}
|
||||
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
@ -24,6 +26,7 @@ public class StringAndMoleculeModel: MoleculeModelProtocol {
|
||||
case backgroundColor
|
||||
case string
|
||||
case molecule
|
||||
case stringColor
|
||||
}
|
||||
|
||||
public required init(from decoder: Decoder) throws {
|
||||
@ -31,6 +34,7 @@ public class StringAndMoleculeModel: MoleculeModelProtocol {
|
||||
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
|
||||
string = try typeContainer.decode(String.self, forKey: .string)
|
||||
molecule = try typeContainer.decodeModel(codingKey: .molecule)
|
||||
stringColor = try typeContainer.decodeIfPresent(Color.self, forKey: .stringColor) ?? Color(uiColor: .mvmBlack)
|
||||
}
|
||||
|
||||
public func encode(to encoder: Encoder) throws {
|
||||
@ -39,5 +43,6 @@ public class StringAndMoleculeModel: MoleculeModelProtocol {
|
||||
try container.encode(string, forKey: .string)
|
||||
try container.encodeModel(molecule, forKey: .molecule)
|
||||
try container.encode(moleculeName, forKey: .moleculeName)
|
||||
try container.encode(stringColor, forKey: .stringColor)
|
||||
}
|
||||
}
|
||||
|
||||
@ -84,6 +84,7 @@ open class StringAndMoleculeView: View {
|
||||
super.set(with: model, delegateObject, additionalData)
|
||||
guard let model = model as? StringAndMoleculeModel else { return }
|
||||
label.text = model.string
|
||||
label.textColor = model.stringColor.uiColor
|
||||
molecule.set(with: model.molecule, delegateObject, additionalData)
|
||||
}
|
||||
|
||||
|
||||
@ -13,12 +13,14 @@ import Foundation
|
||||
return "unOrderedList"
|
||||
}
|
||||
public var bulletChar = "•"
|
||||
|
||||
public var bulletColor: Color
|
||||
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case moleculeName
|
||||
case backgroundColor
|
||||
case list
|
||||
case bulletChar
|
||||
case bulletColor
|
||||
}
|
||||
|
||||
// Numbered list model comes in the from of list = [MoleculeModelProtocol]
|
||||
@ -28,10 +30,11 @@ import Foundation
|
||||
self.bulletChar = bulletChar
|
||||
}
|
||||
|
||||
bulletColor = try typeContainer.decodeIfPresent(Color.self, forKey: .bulletColor) ?? Color(uiColor: .mvmBlack)
|
||||
let list: [MoleculeModelProtocol] = try typeContainer.decodeModels(codingKey: .list)
|
||||
var models: [MoleculeStackItemModel] = []
|
||||
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)
|
||||
}
|
||||
@ -47,5 +50,6 @@ import Foundation
|
||||
models.append(((molecule as! MoleculeStackItemModel).molecule as! StringAndMoleculeModel).molecule)
|
||||
}
|
||||
try container.encodeModels(models, forKey: .list)
|
||||
try container.encode(bulletColor, forKey: .bulletColor)
|
||||
}
|
||||
}
|
||||
|
||||
@ -28,13 +28,13 @@ open class Styler {
|
||||
|
||||
// Legacy Fonts
|
||||
case H1
|
||||
case H2
|
||||
case H3
|
||||
case H32
|
||||
case H2
|
||||
case B20
|
||||
case H3
|
||||
case B1
|
||||
case B2
|
||||
case B3
|
||||
case B20
|
||||
|
||||
/// Returns the font size of the current enum case.
|
||||
public func pointSize() -> CGFloat {
|
||||
@ -45,8 +45,7 @@ open class Styler {
|
||||
case .Title2XLarge:
|
||||
return 36
|
||||
|
||||
case .TitleXLarge,
|
||||
.H32:
|
||||
case .TitleXLarge, .H32:
|
||||
return 32
|
||||
|
||||
case .H2:
|
||||
@ -57,8 +56,7 @@ open class Styler {
|
||||
return 24
|
||||
|
||||
case .BoldTitleMedium,
|
||||
.RegularTitleMedium,
|
||||
.B20:
|
||||
.RegularTitleMedium, .B20:
|
||||
return 20
|
||||
|
||||
case .H3:
|
||||
@ -68,15 +66,12 @@ open class Styler {
|
||||
.RegularBodyLarge:
|
||||
return 16
|
||||
|
||||
case .BoldBodySmall,
|
||||
.RegularBodySmall,
|
||||
.B1,
|
||||
.B2:
|
||||
case .BoldBodySmall, .B1,
|
||||
.RegularBodySmall, .B2:
|
||||
return 13
|
||||
|
||||
case .BoldMicro,
|
||||
.RegularMicro,
|
||||
.B3:
|
||||
.RegularMicro, .B3:
|
||||
return 11
|
||||
}
|
||||
}
|
||||
@ -96,27 +91,22 @@ open class Styler {
|
||||
|
||||
switch self {
|
||||
case .RegularTitleLarge,
|
||||
.RegularTitleMedium,
|
||||
.RegularTitleMedium, .B20,
|
||||
.RegularBodyLarge,
|
||||
.RegularBodySmall,
|
||||
.RegularMicro,
|
||||
.B2,
|
||||
.B3,
|
||||
.B20:
|
||||
.RegularBodySmall, .B2,
|
||||
.RegularMicro, .B3:
|
||||
return false
|
||||
|
||||
case .Title2XLarge,
|
||||
.TitleXLarge,
|
||||
case .H1,
|
||||
.Title2XLarge,
|
||||
.TitleXLarge, .H32,
|
||||
.H2,
|
||||
.BoldTitleLarge,
|
||||
.BoldTitleMedium,
|
||||
.BoldBodyLarge,
|
||||
.BoldBodySmall,
|
||||
.BoldMicro,
|
||||
.H1,
|
||||
.H2,
|
||||
.H3,
|
||||
.H32,
|
||||
.B1:
|
||||
.BoldBodyLarge,
|
||||
.BoldBodySmall, .B1,
|
||||
.BoldMicro:
|
||||
return true
|
||||
}
|
||||
}
|
||||
@ -140,9 +130,9 @@ open class Styler {
|
||||
return false
|
||||
|
||||
case .H1,
|
||||
.H32,
|
||||
.H2,
|
||||
.H3,
|
||||
.H32,
|
||||
.B1,
|
||||
.B2,
|
||||
.B3,
|
||||
|
||||
Loading…
Reference in New Issue
Block a user