From 04bbf58e6ae936e095dccda4203b2d38f09216d3 Mon Sep 17 00:00:00 2001 From: Lekshmi S Date: Tue, 8 Sep 2020 13:13:43 +0530 Subject: [PATCH 1/7] Heart atom initial commit. --- MVMCoreUI.xcodeproj/project.pbxproj | 8 ++ MVMCoreUI/Atomic/Atoms/Selectors/Heart.swift | 84 +++++++++++++++++++ .../Atomic/Atoms/Selectors/HeartModel.swift | 61 ++++++++++++++ MVMCoreUI/Atomic/MoleculeObjectMapping.swift | 2 +- 4 files changed, 154 insertions(+), 1 deletion(-) create mode 100644 MVMCoreUI/Atomic/Atoms/Selectors/Heart.swift create mode 100644 MVMCoreUI/Atomic/Atoms/Selectors/HeartModel.swift diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index b61c3aa1..133e099b 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -236,6 +236,8 @@ AA997252247530B100FC7472 /* ListLeftVariableIconAllTextLinks.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA997251247530B100FC7472 /* ListLeftVariableIconAllTextLinks.swift */; }; AAA74A172410C04600080241 /* HeadersH2NoButtonsBodyText.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAA74A162410C04600080241 /* HeadersH2NoButtonsBodyText.swift */; }; AAA74A192410C05800080241 /* HeadersH2NoButtonsBodyTextModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAA74A182410C05800080241 /* HeadersH2NoButtonsBodyTextModel.swift */; }; + AAA7CD69250641F90045B959 /* HeartModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAA7CD68250641F90045B959 /* HeartModel.swift */; }; + AAA7CD6B250642080045B959 /* Heart.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAA7CD6A250642080045B959 /* Heart.swift */; }; AAA905DF24D1758700D1EFAB /* ListThreeColumnBillHistoryModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAA905DE24D1758700D1EFAB /* ListThreeColumnBillHistoryModel.swift */; }; AAA905E124D1759A00D1EFAB /* ListThreeColumnBillHistory.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAA905E024D1759A00D1EFAB /* ListThreeColumnBillHistory.swift */; }; AAB7EDEF246ADA1600E54929 /* ListProgressBarThinModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAB7EDEE246ADA1600E54929 /* ListProgressBarThinModel.swift */; }; @@ -717,6 +719,8 @@ AA997251247530B100FC7472 /* ListLeftVariableIconAllTextLinks.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListLeftVariableIconAllTextLinks.swift; sourceTree = ""; }; AAA74A162410C04600080241 /* HeadersH2NoButtonsBodyText.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeadersH2NoButtonsBodyText.swift; sourceTree = ""; }; AAA74A182410C05800080241 /* HeadersH2NoButtonsBodyTextModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeadersH2NoButtonsBodyTextModel.swift; sourceTree = ""; }; + AAA7CD68250641F90045B959 /* HeartModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeartModel.swift; sourceTree = ""; }; + AAA7CD6A250642080045B959 /* Heart.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Heart.swift; sourceTree = ""; }; AAA905DE24D1758700D1EFAB /* ListThreeColumnBillHistoryModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListThreeColumnBillHistoryModel.swift; sourceTree = ""; }; AAA905E024D1759A00D1EFAB /* ListThreeColumnBillHistory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListThreeColumnBillHistory.swift; sourceTree = ""; }; AAB7EDEE246ADA1600E54929 /* ListProgressBarThinModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListProgressBarThinModel.swift; sourceTree = ""; }; @@ -1564,6 +1568,8 @@ D2092348244A51D40044AD09 /* RadioSwatchModel.swift */, AAB9C109243496DD00151545 /* RadioSwatch.swift */, AA85236B244435A20059CC1E /* RadioSwatchCollectionViewCell.swift */, + AAA7CD68250641F90045B959 /* HeartModel.swift */, + AAA7CD6A250642080045B959 /* Heart.swift */, ); path = Selectors; sourceTree = ""; @@ -2187,6 +2193,7 @@ 943784F5236B77BB006A1E82 /* Wheel.swift in Sources */, 31BE15CC23D8924D00452370 /* CheckboxModel.swift in Sources */, 8D3BA9BF2433789900D341BA /* ListThreeColumnInternationalDataDivider.swift in Sources */, + AAA7CD6B250642080045B959 /* Heart.swift in Sources */, 94C661DA23CCF4FB00D9FE5B /* UIColor+Extension.swift in Sources */, D28A838123CCB0D800DFE4FC /* AccordionListItemModel.swift in Sources */, D2509ED62472EE2F001BFB9D /* NavigationImageButtonModel.swift in Sources */, @@ -2205,6 +2212,7 @@ BBC0C4FF24811DCA0087C44F /* TagModel.swift in Sources */, 0A7BAD74232A8DC700FB8E22 /* HeadlineBodyButton.swift in Sources */, 3265B30424BCA749000D154B /* HeadersH1NoButtonsBodyText.swift in Sources */, + AAA7CD69250641F90045B959 /* HeartModel.swift in Sources */, D2FB151D23A40F1500C20E10 /* MoleculeStackItem.swift in Sources */, D28BA7452481652D00B75CB8 /* TabBarProtocol.swift in Sources */, AA11A41F23F15D3100D7962F /* ListRightVariablePayments.swift in Sources */, diff --git a/MVMCoreUI/Atomic/Atoms/Selectors/Heart.swift b/MVMCoreUI/Atomic/Atoms/Selectors/Heart.swift new file mode 100644 index 00000000..33625303 --- /dev/null +++ b/MVMCoreUI/Atomic/Atoms/Selectors/Heart.swift @@ -0,0 +1,84 @@ +// +// Heart.swift +// MVMCoreUI +// +// Created by Lekshmi S on 07/09/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import UIKit + +open class Heart: Control { + //-------------------------------------------------- + // MARK: - Properties + //-------------------------------------------------- + private var heartLayer: CAShapeLayer? + @objc public override var isSelected: Bool { + didSet { + heartModel?.isActive = isSelected + } + } + public var delegateObject: MVMCoreUIDelegateObject? + public var heartModel: HeartModel? { + return model as? HeartModel + } + + //-------------------------------------------------- + // MARK: - Lifecycle + //-------------------------------------------------- + open override func draw(_ layer: CALayer, in ctx: CGContext) { + //Draw the heart + heartLayer?.removeFromSuperlayer() + let heart = drawHeart() + layer.addSublayer(heart) + heartLayer = heart + } + + func drawHeart() -> CAShapeLayer { + let heart = CAShapeLayer() + let rect = CGRect(x: 0, y: 0, width: 22, height: 22) + let leftArc = rect.width * 0.4 + let rightArc = rect.height * 0.3 + let arcRadius = sqrt(leftArc*leftArc + rightArc*rightArc)/2 + let heartPath = UIBezierPath() + //Left Hand Curve + heartPath.addArc(withCenter: CGPoint(x: rect.width * 0.3, y: rect.height * 0.35), radius: arcRadius, startAngle: 135.degreesToRadians, endAngle: 315.degreesToRadians, clockwise: true) + //Top Centre Dip + heartPath.addLine(to: CGPoint(x: rect.width/2, y: rect.height * 0.2)) + //Right Hand Curve + heartPath.addArc(withCenter: CGPoint(x: rect.width * 0.7, y: rect.height * 0.35), radius: arcRadius, startAngle: 225.degreesToRadians, endAngle: 45.degreesToRadians, clockwise: true) + //Right Bottom Line + heartPath.addLine(to: CGPoint(x: rect.width * 0.5, y: rect.height * 0.95)) + //Left Bottom Line + heartPath.close() + heart.path = heartPath.cgPath + heart.fillColor = isSelected ? heartModel?.activeColor.cgColor : heartModel?.inActiveColor.cgColor + heart.opacity = 1.0 + heart.lineWidth = 1 + heart.strokeColor = isSelected ? UIColor.clear.cgColor : UIColor.mvmBlack.cgColor + return heart + } + + //-------------------------------------------------- + // MARK: - MVMViewProtocol + //-------------------------------------------------- + open override func setupView() { + super.setupView() + } + + open override func updateView(_ size: CGFloat) { + super.updateView(size) + layer.setNeedsDisplay() + } + + public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { + super.set(with: model, delegateObject, additionalData) + self.delegateObject = delegateObject + guard let model = model as? HeartModel else { return } + isSelected = model.isActive + } +} + +extension Int { + var degreesToRadians: CGFloat { return CGFloat(self) * .pi / 180 } +} diff --git a/MVMCoreUI/Atomic/Atoms/Selectors/HeartModel.swift b/MVMCoreUI/Atomic/Atoms/Selectors/HeartModel.swift new file mode 100644 index 00000000..469dc4d9 --- /dev/null +++ b/MVMCoreUI/Atomic/Atoms/Selectors/HeartModel.swift @@ -0,0 +1,61 @@ +// +// HeartModel.swift +// MVMCoreUI +// +// Created by Lekshmi S on 07/09/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import Foundation + +open class HeartModel: MoleculeModelProtocol { + //-------------------------------------------------- + // MARK: - Properties + //-------------------------------------------------- + + public static var identifier: String = "heart" + public var backgroundColor: Color? + public var isActive: Bool = false + public var activeColor: Color = Color(uiColor: .mvmRed) + public var inActiveColor: Color = Color(uiColor: .clear) + + //-------------------------------------------------- + // MARK: - Keys + //-------------------------------------------------- + + private enum CodingKeys: String, CodingKey { + case moleculeName + case backgroundColor + case isActive + case activeColor + case inActiveColor + } + + //-------------------------------------------------- + // MARK: - Codec + //-------------------------------------------------- + + required public init(from decoder: Decoder) throws { + let typeContainer = try decoder.container(keyedBy: CodingKeys.self) + + if let isActive = try typeContainer.decodeIfPresent(Bool.self, forKey: .isActive) { + self.isActive = isActive + } + backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) + if let activeColor = try typeContainer.decodeIfPresent(Color.self, forKey: .activeColor) { + self.activeColor = activeColor + } + if let inActiveColor = try typeContainer.decodeIfPresent(Color.self, forKey: .inActiveColor) { + self.inActiveColor = inActiveColor + } + } + + public func encode(to encoder: Encoder) throws { + var container = encoder.container(keyedBy: CodingKeys.self) + try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor) + try container.encode(moleculeName, forKey: .moleculeName) + try container.encodeIfPresent(isActive, forKey: .isActive) + try container.encodeIfPresent(activeColor, forKey: .activeColor) + try container.encodeIfPresent(inActiveColor, forKey: .inActiveColor) + } +} diff --git a/MVMCoreUI/Atomic/MoleculeObjectMapping.swift b/MVMCoreUI/Atomic/MoleculeObjectMapping.swift index a08347c7..4016ec8a 100644 --- a/MVMCoreUI/Atomic/MoleculeObjectMapping.swift +++ b/MVMCoreUI/Atomic/MoleculeObjectMapping.swift @@ -87,7 +87,7 @@ import Foundation MoleculeObjectMapping.shared()?.register(viewClass: RadioSwatches.self, viewModelClass: RadioSwatchesModel.self) MoleculeObjectMapping.shared()?.register(viewClass: Tags.self, viewModelClass: TagsModel.self) MoleculeObjectMapping.shared()?.register(viewClass: Tag.self, viewModelClass: TagModel.self) - + MoleculeObjectMapping.shared()?.register(viewClass: Heart.self, viewModelClass: HeartModel.self) // MARK:- Other Atoms From 06df235fb293b059193b62c63793e0e1c611710f Mon Sep 17 00:00:00 2001 From: Lekshmi S Date: Tue, 8 Sep 2020 20:25:46 +0530 Subject: [PATCH 2/7] Code fixes and added accessibility. --- MVMCoreUI/Atomic/Atoms/Selectors/Heart.swift | 48 +++++++++++++++---- .../Strings/en.lproj/Localizable.strings | 5 ++ .../Strings/es-MX.lproj/Localizable.strings | 4 ++ .../Strings/es.lproj/Localizable.strings | 6 +++ 4 files changed, 53 insertions(+), 10 deletions(-) diff --git a/MVMCoreUI/Atomic/Atoms/Selectors/Heart.swift b/MVMCoreUI/Atomic/Atoms/Selectors/Heart.swift index 33625303..46435614 100644 --- a/MVMCoreUI/Atomic/Atoms/Selectors/Heart.swift +++ b/MVMCoreUI/Atomic/Atoms/Selectors/Heart.swift @@ -8,7 +8,8 @@ import UIKit -open class Heart: Control { +@objcMembers open class Heart: Control { + //-------------------------------------------------- // MARK: - Properties //-------------------------------------------------- @@ -16,6 +17,7 @@ open class Heart: Control { @objc public override var isSelected: Bool { didSet { heartModel?.isActive = isSelected + updateAccessibilityLabel() } } public var delegateObject: MVMCoreUIDelegateObject? @@ -24,9 +26,15 @@ open class Heart: Control { } //-------------------------------------------------- - // MARK: - Lifecycle + // MARK: - Constraints //-------------------------------------------------- - open override func draw(_ layer: CALayer, in ctx: CGContext) { + public var widthConstraint: NSLayoutConstraint? + public var heightConstraint: NSLayoutConstraint? + + //------------------------------------------------------ + // MARK: - State Handling + //------------------------------------------------------ + open override func draw(_ rect: CGRect) { //Draw the heart heartLayer?.removeFromSuperlayer() let heart = drawHeart() @@ -36,7 +44,7 @@ open class Heart: Control { func drawHeart() -> CAShapeLayer { let heart = CAShapeLayer() - let rect = CGRect(x: 0, y: 0, width: 22, height: 22) + let rect = CGRect(x: 0, y: 0, width: 10, height: 10) let leftArc = rect.width * 0.4 let rightArc = rect.height * 0.3 let arcRadius = sqrt(leftArc*leftArc + rightArc*rightArc)/2 @@ -60,15 +68,19 @@ open class Heart: Control { } //-------------------------------------------------- - // MARK: - MVMViewProtocol + // MARK: - Lifecycle //-------------------------------------------------- open override func setupView() { super.setupView() - } - - open override func updateView(_ size: CGFloat) { - super.updateView(size) - layer.setNeedsDisplay() + addTarget(self, action: #selector(tapAction), for: .touchUpInside) + widthConstraint = widthAnchor.constraint(equalToConstant: 10) + widthConstraint?.isActive = true + heightConstraint = heightAnchor.constraint(equalTo: widthAnchor, multiplier: 1) + heightConstraint?.isActive = true + isAccessibilityElement = true + accessibilityHint = MVMCoreUIUtility.hardcodedString(withKey: "heart_action_hint") + accessibilityTraits = .button + updateAccessibilityLabel() } public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { @@ -77,6 +89,22 @@ open class Heart: Control { guard let model = model as? HeartModel else { return } isSelected = model.isActive } + + //-------------------------------------------------- + // MARK: - Methods + //-------------------------------------------------- + /// Adjust accessibility label based on selection of Heart. + func updateAccessibilityLabel() { + if let message = MVMCoreUIUtility.hardcodedString(withKey: "heart"), + let selectedState = MVMCoreUIUtility.hardcodedString(withKey: isSelected ? "heart_selected_state" : "heart_not_selected_state") { + accessibilityLabel = message + selectedState + } + } + + func tapAction() { + isSelected = !isSelected + setNeedsDisplay() + } } extension Int { diff --git a/MVMCoreUI/SupportingFiles/Strings/en.lproj/Localizable.strings b/MVMCoreUI/SupportingFiles/Strings/en.lproj/Localizable.strings index c280b737..2f8b642b 100644 --- a/MVMCoreUI/SupportingFiles/Strings/en.lproj/Localizable.strings +++ b/MVMCoreUI/SupportingFiles/Strings/en.lproj/Localizable.strings @@ -67,6 +67,11 @@ "AccOff" = "off"; "AccToggleHint" = "double tap to toggle"; +// MARK: Heart +"heart" = "Heart"; +"heart_action_hint" = "Double tap to select"; +"heart_selected_state" = "Selected"; +"heart_not_selected_state" = "Not Selected"; // MARK: Carousel "MVMCoreUIPageControl_currentpage_index" = "page %@ of %d"; diff --git a/MVMCoreUI/SupportingFiles/Strings/es-MX.lproj/Localizable.strings b/MVMCoreUI/SupportingFiles/Strings/es-MX.lproj/Localizable.strings index f21df078..4917f6ee 100644 --- a/MVMCoreUI/SupportingFiles/Strings/es-MX.lproj/Localizable.strings +++ b/MVMCoreUI/SupportingFiles/Strings/es-MX.lproj/Localizable.strings @@ -49,6 +49,10 @@ "AccOn" = "encendido"; "AccOff" = "apagado"; "AccToggleHint" = "toca dos veces para alternar"; +// Heart +"heart_action_hint" = "Toca dos veces para seleccionar."; +"heart_selected_state" = "Seleccionado"; +"heart_not_selected_state" = "No Seleccionado"; // Carousel "MVMCoreUIPageControl_currentpage_index" = "página %@ de %d"; "MVMCoreUIPageControlslides_currentpage_index" = "diapositiva %@ of %d"; diff --git a/MVMCoreUI/SupportingFiles/Strings/es.lproj/Localizable.strings b/MVMCoreUI/SupportingFiles/Strings/es.lproj/Localizable.strings index 47d124a9..5bf02ca0 100644 --- a/MVMCoreUI/SupportingFiles/Strings/es.lproj/Localizable.strings +++ b/MVMCoreUI/SupportingFiles/Strings/es.lproj/Localizable.strings @@ -51,6 +51,12 @@ "AccOn" = "encendido"; "AccOff" = "apagado"; "AccToggleHint" = "toca dos veces para alternar"; + +// Heart +"heart_action_hint" = "Toca dos veces para seleccionar."; +"heart_selected_state" = "Seleccionado"; +"heart_not_selected_state" = "No Seleccionado"; + // Carousel "MVMCoreUIPageControl_currentpage_index" = "página %@ de %d"; "MVMCoreUIPageControlslides_currentpage_index" = "diapositiva %@ of %d"; From 884f2ad69fac5f33ec1dd9a5f8cb41b39e3dd0d9 Mon Sep 17 00:00:00 2001 From: Lekshmi S Date: Mon, 14 Sep 2020 17:38:20 +0530 Subject: [PATCH 3/7] Added action key. --- MVMCoreUI/Atomic/Atoms/Selectors/Heart.swift | 4 ++-- MVMCoreUI/Atomic/Atoms/Selectors/HeartModel.swift | 8 +++++--- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/MVMCoreUI/Atomic/Atoms/Selectors/Heart.swift b/MVMCoreUI/Atomic/Atoms/Selectors/Heart.swift index 46435614..5270fa62 100644 --- a/MVMCoreUI/Atomic/Atoms/Selectors/Heart.swift +++ b/MVMCoreUI/Atomic/Atoms/Selectors/Heart.swift @@ -44,7 +44,7 @@ import UIKit func drawHeart() -> CAShapeLayer { let heart = CAShapeLayer() - let rect = CGRect(x: 0, y: 0, width: 10, height: 10) + let rect = self.bounds let leftArc = rect.width * 0.4 let rightArc = rect.height * 0.3 let arcRadius = sqrt(leftArc*leftArc + rightArc*rightArc)/2 @@ -73,7 +73,7 @@ import UIKit open override func setupView() { super.setupView() addTarget(self, action: #selector(tapAction), for: .touchUpInside) - widthConstraint = widthAnchor.constraint(equalToConstant: 10) + widthConstraint = widthAnchor.constraint(equalToConstant: 22) widthConstraint?.isActive = true heightConstraint = heightAnchor.constraint(equalTo: widthAnchor, multiplier: 1) heightConstraint?.isActive = true diff --git a/MVMCoreUI/Atomic/Atoms/Selectors/HeartModel.swift b/MVMCoreUI/Atomic/Atoms/Selectors/HeartModel.swift index 469dc4d9..3fe696f8 100644 --- a/MVMCoreUI/Atomic/Atoms/Selectors/HeartModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Selectors/HeartModel.swift @@ -9,32 +9,32 @@ import Foundation open class HeartModel: MoleculeModelProtocol { + //-------------------------------------------------- // MARK: - Properties //-------------------------------------------------- - public static var identifier: String = "heart" public var backgroundColor: Color? public var isActive: Bool = false public var activeColor: Color = Color(uiColor: .mvmRed) public var inActiveColor: Color = Color(uiColor: .clear) + public var action: ActionModelProtocol? //-------------------------------------------------- // MARK: - Keys //-------------------------------------------------- - private enum CodingKeys: String, CodingKey { case moleculeName case backgroundColor case isActive case activeColor case inActiveColor + case action } //-------------------------------------------------- // MARK: - Codec //-------------------------------------------------- - required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) @@ -48,6 +48,7 @@ open class HeartModel: MoleculeModelProtocol { if let inActiveColor = try typeContainer.decodeIfPresent(Color.self, forKey: .inActiveColor) { self.inActiveColor = inActiveColor } + action = try typeContainer.decodeModelIfPresent(codingKey: .action) } public func encode(to encoder: Encoder) throws { @@ -57,5 +58,6 @@ open class HeartModel: MoleculeModelProtocol { try container.encodeIfPresent(isActive, forKey: .isActive) try container.encodeIfPresent(activeColor, forKey: .activeColor) try container.encodeIfPresent(inActiveColor, forKey: .inActiveColor) + try container.encodeModelIfPresent(action, forKey: .action) } } From 7c4c9ea43a6e09f4b56a3b53c6df8711af974681 Mon Sep 17 00:00:00 2001 From: Lekshmi S Date: Tue, 29 Sep 2020 17:39:16 +0530 Subject: [PATCH 4/7] Code changes based on review comments and added default action noop. --- MVMCoreUI/Atomic/Atoms/Selectors/Heart.swift | 7 ++++++- MVMCoreUI/Atomic/Atoms/Selectors/HeartModel.swift | 12 +++++++----- .../Strings/en.lproj/Localizable.strings | 2 +- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/MVMCoreUI/Atomic/Atoms/Selectors/Heart.swift b/MVMCoreUI/Atomic/Atoms/Selectors/Heart.swift index 5270fa62..0cdc1f6d 100644 --- a/MVMCoreUI/Atomic/Atoms/Selectors/Heart.swift +++ b/MVMCoreUI/Atomic/Atoms/Selectors/Heart.swift @@ -8,7 +8,7 @@ import UIKit -@objcMembers open class Heart: Control { +@objcMembers open class Heart: Control, MFButtonProtocol { //-------------------------------------------------- // MARK: - Properties @@ -24,6 +24,7 @@ import UIKit public var heartModel: HeartModel? { return model as? HeartModel } + var additionalData: [AnyHashable: Any]? //-------------------------------------------------- // MARK: - Constraints @@ -86,6 +87,7 @@ import UIKit public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { super.set(with: model, delegateObject, additionalData) self.delegateObject = delegateObject + self.additionalData = additionalData guard let model = model as? HeartModel else { return } isSelected = model.isActive } @@ -103,6 +105,9 @@ import UIKit func tapAction() { isSelected = !isSelected + if let heartModel = heartModel { + Button.performButtonAction(with: heartModel.action, button: self, delegateObject: delegateObject, additionalData: additionalData, sourceModel: heartModel) + } setNeedsDisplay() } } diff --git a/MVMCoreUI/Atomic/Atoms/Selectors/HeartModel.swift b/MVMCoreUI/Atomic/Atoms/Selectors/HeartModel.swift index 3fe696f8..b3d168ef 100644 --- a/MVMCoreUI/Atomic/Atoms/Selectors/HeartModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Selectors/HeartModel.swift @@ -18,7 +18,7 @@ open class HeartModel: MoleculeModelProtocol { public var isActive: Bool = false public var activeColor: Color = Color(uiColor: .mvmRed) public var inActiveColor: Color = Color(uiColor: .clear) - public var action: ActionModelProtocol? + public var action: ActionModelProtocol = ActionNoopModel() //-------------------------------------------------- // MARK: - Keys @@ -48,16 +48,18 @@ open class HeartModel: MoleculeModelProtocol { if let inActiveColor = try typeContainer.decodeIfPresent(Color.self, forKey: .inActiveColor) { self.inActiveColor = inActiveColor } - action = try typeContainer.decodeModelIfPresent(codingKey: .action) + if let action: ActionModelProtocol = try typeContainer.decodeModelIfPresent(codingKey: .action) { + self.action = action + } } public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor) try container.encode(moleculeName, forKey: .moleculeName) - try container.encodeIfPresent(isActive, forKey: .isActive) - try container.encodeIfPresent(activeColor, forKey: .activeColor) - try container.encodeIfPresent(inActiveColor, forKey: .inActiveColor) + try container.encode(isActive, forKey: .isActive) + try container.encode(activeColor, forKey: .activeColor) + try container.encode(inActiveColor, forKey: .inActiveColor) try container.encodeModelIfPresent(action, forKey: .action) } } diff --git a/MVMCoreUI/SupportingFiles/Strings/en.lproj/Localizable.strings b/MVMCoreUI/SupportingFiles/Strings/en.lproj/Localizable.strings index 2f8b642b..8cf3e21e 100644 --- a/MVMCoreUI/SupportingFiles/Strings/en.lproj/Localizable.strings +++ b/MVMCoreUI/SupportingFiles/Strings/en.lproj/Localizable.strings @@ -68,7 +68,7 @@ "AccToggleHint" = "double tap to toggle"; // MARK: Heart -"heart" = "Heart"; +"heart" = "Favorite"; "heart_action_hint" = "Double tap to select"; "heart_selected_state" = "Selected"; "heart_not_selected_state" = "Not Selected"; From 223757ab0fae7b0dadf2418c919195a485a483ae Mon Sep 17 00:00:00 2001 From: Lekshmi S Date: Wed, 30 Sep 2020 12:16:04 +0530 Subject: [PATCH 5/7] Changed accessibility text for heart. --- MVMCoreUI/Atomic/Atoms/Selectors/Heart.swift | 2 +- .../SupportingFiles/Strings/en.lproj/Localizable.strings | 6 +++--- .../SupportingFiles/Strings/es-MX.lproj/Localizable.strings | 6 +++--- .../SupportingFiles/Strings/es.lproj/Localizable.strings | 6 +++--- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/MVMCoreUI/Atomic/Atoms/Selectors/Heart.swift b/MVMCoreUI/Atomic/Atoms/Selectors/Heart.swift index 0cdc1f6d..eeda08af 100644 --- a/MVMCoreUI/Atomic/Atoms/Selectors/Heart.swift +++ b/MVMCoreUI/Atomic/Atoms/Selectors/Heart.swift @@ -45,7 +45,7 @@ import UIKit func drawHeart() -> CAShapeLayer { let heart = CAShapeLayer() - let rect = self.bounds + let rect = bounds let leftArc = rect.width * 0.4 let rightArc = rect.height * 0.3 let arcRadius = sqrt(leftArc*leftArc + rightArc*rightArc)/2 diff --git a/MVMCoreUI/SupportingFiles/Strings/en.lproj/Localizable.strings b/MVMCoreUI/SupportingFiles/Strings/en.lproj/Localizable.strings index 8cf3e21e..db90b9b7 100644 --- a/MVMCoreUI/SupportingFiles/Strings/en.lproj/Localizable.strings +++ b/MVMCoreUI/SupportingFiles/Strings/en.lproj/Localizable.strings @@ -69,9 +69,9 @@ // MARK: Heart "heart" = "Favorite"; -"heart_action_hint" = "Double tap to select"; -"heart_selected_state" = "Selected"; -"heart_not_selected_state" = "Not Selected"; +"heart_action_hint" = "Double tap to favorite"; +"heart_selected_state" = "Favorited"; +"heart_not_selected_state" = "Unfavorited"; // MARK: Carousel "MVMCoreUIPageControl_currentpage_index" = "page %@ of %d"; diff --git a/MVMCoreUI/SupportingFiles/Strings/es-MX.lproj/Localizable.strings b/MVMCoreUI/SupportingFiles/Strings/es-MX.lproj/Localizable.strings index 4917f6ee..d6bfb89c 100644 --- a/MVMCoreUI/SupportingFiles/Strings/es-MX.lproj/Localizable.strings +++ b/MVMCoreUI/SupportingFiles/Strings/es-MX.lproj/Localizable.strings @@ -50,9 +50,9 @@ "AccOff" = "apagado"; "AccToggleHint" = "toca dos veces para alternar"; // Heart -"heart_action_hint" = "Toca dos veces para seleccionar."; -"heart_selected_state" = "Seleccionado"; -"heart_not_selected_state" = "No Seleccionado"; +"heart_action_hint" = "Toca dos veces en favorito"; +"heart_selected_state" = "Favoritos"; +"heart_not_selected_state" = "No favorito"; // Carousel "MVMCoreUIPageControl_currentpage_index" = "página %@ de %d"; "MVMCoreUIPageControlslides_currentpage_index" = "diapositiva %@ of %d"; diff --git a/MVMCoreUI/SupportingFiles/Strings/es.lproj/Localizable.strings b/MVMCoreUI/SupportingFiles/Strings/es.lproj/Localizable.strings index 5bf02ca0..b06c972b 100644 --- a/MVMCoreUI/SupportingFiles/Strings/es.lproj/Localizable.strings +++ b/MVMCoreUI/SupportingFiles/Strings/es.lproj/Localizable.strings @@ -53,9 +53,9 @@ "AccToggleHint" = "toca dos veces para alternar"; // Heart -"heart_action_hint" = "Toca dos veces para seleccionar."; -"heart_selected_state" = "Seleccionado"; -"heart_not_selected_state" = "No Seleccionado"; +"heart_action_hint" = "Toca dos veces en favorito"; +"heart_selected_state" = "Favoritos"; +"heart_not_selected_state" = "No favorito"; // Carousel "MVMCoreUIPageControl_currentpage_index" = "página %@ de %d"; From 1bf75c99292bd8472b06ac445657f1b48f7a5c5a Mon Sep 17 00:00:00 2001 From: Lekshmi S Date: Tue, 6 Oct 2020 16:13:02 +0530 Subject: [PATCH 6/7] Accessibility label changes for heart. --- MVMCoreUI/Atomic/Atoms/Selectors/Heart.swift | 7 ++----- MVMCoreUI/Atomic/Atoms/Selectors/HeartModel.swift | 2 +- .../SupportingFiles/Strings/en.lproj/Localizable.strings | 4 ++-- .../Strings/es-MX.lproj/Localizable.strings | 3 ++- .../SupportingFiles/Strings/es.lproj/Localizable.strings | 3 ++- 5 files changed, 9 insertions(+), 10 deletions(-) diff --git a/MVMCoreUI/Atomic/Atoms/Selectors/Heart.swift b/MVMCoreUI/Atomic/Atoms/Selectors/Heart.swift index eeda08af..796bf617 100644 --- a/MVMCoreUI/Atomic/Atoms/Selectors/Heart.swift +++ b/MVMCoreUI/Atomic/Atoms/Selectors/Heart.swift @@ -79,7 +79,6 @@ import UIKit heightConstraint = heightAnchor.constraint(equalTo: widthAnchor, multiplier: 1) heightConstraint?.isActive = true isAccessibilityElement = true - accessibilityHint = MVMCoreUIUtility.hardcodedString(withKey: "heart_action_hint") accessibilityTraits = .button updateAccessibilityLabel() } @@ -97,10 +96,8 @@ import UIKit //-------------------------------------------------- /// Adjust accessibility label based on selection of Heart. func updateAccessibilityLabel() { - if let message = MVMCoreUIUtility.hardcodedString(withKey: "heart"), - let selectedState = MVMCoreUIUtility.hardcodedString(withKey: isSelected ? "heart_selected_state" : "heart_not_selected_state") { - accessibilityLabel = message + selectedState - } + accessibilityHint = MVMCoreUIUtility.hardcodedString(withKey: isSelected ? "heart_unfavorite_action_hint" : "heart_favorite_action_hint") + accessibilityLabel = MVMCoreUIUtility.hardcodedString(withKey: isSelected ? "heart_selected_state" : "heart_not_selected_state") } func tapAction() { diff --git a/MVMCoreUI/Atomic/Atoms/Selectors/HeartModel.swift b/MVMCoreUI/Atomic/Atoms/Selectors/HeartModel.swift index b3d168ef..8001ddd5 100644 --- a/MVMCoreUI/Atomic/Atoms/Selectors/HeartModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Selectors/HeartModel.swift @@ -60,6 +60,6 @@ open class HeartModel: MoleculeModelProtocol { try container.encode(isActive, forKey: .isActive) try container.encode(activeColor, forKey: .activeColor) try container.encode(inActiveColor, forKey: .inActiveColor) - try container.encodeModelIfPresent(action, forKey: .action) + try container.encodeModel(action, forKey: .action) } } diff --git a/MVMCoreUI/SupportingFiles/Strings/en.lproj/Localizable.strings b/MVMCoreUI/SupportingFiles/Strings/en.lproj/Localizable.strings index db90b9b7..bbeadbdb 100644 --- a/MVMCoreUI/SupportingFiles/Strings/en.lproj/Localizable.strings +++ b/MVMCoreUI/SupportingFiles/Strings/en.lproj/Localizable.strings @@ -68,8 +68,8 @@ "AccToggleHint" = "double tap to toggle"; // MARK: Heart -"heart" = "Favorite"; -"heart_action_hint" = "Double tap to favorite"; +"heart_favorite_action_hint" = "Double tap to favorite"; +"heart_unfavorite_action_hint" = "Double tap to unfavorite"; "heart_selected_state" = "Favorited"; "heart_not_selected_state" = "Unfavorited"; diff --git a/MVMCoreUI/SupportingFiles/Strings/es-MX.lproj/Localizable.strings b/MVMCoreUI/SupportingFiles/Strings/es-MX.lproj/Localizable.strings index d6bfb89c..0a37e1a5 100644 --- a/MVMCoreUI/SupportingFiles/Strings/es-MX.lproj/Localizable.strings +++ b/MVMCoreUI/SupportingFiles/Strings/es-MX.lproj/Localizable.strings @@ -50,7 +50,8 @@ "AccOff" = "apagado"; "AccToggleHint" = "toca dos veces para alternar"; // Heart -"heart_action_hint" = "Toca dos veces en favorito"; +"heart_favorite_action_hint" = "Toca dos veces en favorito"; +"heart_unfavorite_action_hint" = "Toca dos veces para dejar de marcar como favorito"; "heart_selected_state" = "Favoritos"; "heart_not_selected_state" = "No favorito"; // Carousel diff --git a/MVMCoreUI/SupportingFiles/Strings/es.lproj/Localizable.strings b/MVMCoreUI/SupportingFiles/Strings/es.lproj/Localizable.strings index b06c972b..a64c3915 100644 --- a/MVMCoreUI/SupportingFiles/Strings/es.lproj/Localizable.strings +++ b/MVMCoreUI/SupportingFiles/Strings/es.lproj/Localizable.strings @@ -53,7 +53,8 @@ "AccToggleHint" = "toca dos veces para alternar"; // Heart -"heart_action_hint" = "Toca dos veces en favorito"; +"heart_favorite_action_hint" = "Toca dos veces en favorito"; +"heart_unfavorite_action_hint" = "Toca dos veces para dejar de marcar como favorito"; "heart_selected_state" = "Favoritos"; "heart_not_selected_state" = "No favorito"; From 35468f592e4956275642e2aef2c6bd6d638a7f9d Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Fri, 9 Oct 2020 14:19:56 -0400 Subject: [PATCH 7/7] accessibility adjustment --- MVMCoreUI/SupportingFiles/Strings/en.lproj/Localizable.strings | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MVMCoreUI/SupportingFiles/Strings/en.lproj/Localizable.strings b/MVMCoreUI/SupportingFiles/Strings/en.lproj/Localizable.strings index bbeadbdb..ee0b1849 100644 --- a/MVMCoreUI/SupportingFiles/Strings/en.lproj/Localizable.strings +++ b/MVMCoreUI/SupportingFiles/Strings/en.lproj/Localizable.strings @@ -71,7 +71,7 @@ "heart_favorite_action_hint" = "Double tap to favorite"; "heart_unfavorite_action_hint" = "Double tap to unfavorite"; "heart_selected_state" = "Favorited"; -"heart_not_selected_state" = "Unfavorited"; +"heart_not_selected_state" = "Un-favorited"; // MARK: Carousel "MVMCoreUIPageControl_currentpage_index" = "page %@ of %d";