Merge branch 'develop' into bugfix/layout_accessibility_fx
This commit is contained in:
commit
f53526508c
@ -199,6 +199,8 @@
|
||||
94CA227D24058534002D6750 /* VerizonNHGeDS-Regular.otf in Resources */ = {isa = PBXBuildFile; fileRef = 94CA227924058533002D6750 /* VerizonNHGeDS-Regular.otf */; };
|
||||
94CA227E24058534002D6750 /* VerizonNHGeDS-Bold.otf in Resources */ = {isa = PBXBuildFile; fileRef = 94CA227A24058533002D6750 /* VerizonNHGeDS-Bold.otf */; };
|
||||
94F6516D2437954100631BF9 /* Tabs.swift in Sources */ = {isa = PBXBuildFile; fileRef = 94F6516C2437954100631BF9 /* Tabs.swift */; };
|
||||
AA07EA912510A442009A2AE3 /* StarModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA07EA902510A442009A2AE3 /* StarModel.swift */; };
|
||||
AA07EA932510A451009A2AE3 /* Star.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA07EA922510A451009A2AE3 /* Star.swift */; };
|
||||
AA0A257824766C8A00862F64 /* ListLeftVariableIconWithRightCaretBodyTextModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA0A257724766C8A00862F64 /* ListLeftVariableIconWithRightCaretBodyTextModel.swift */; };
|
||||
AA0A257A24766CA200862F64 /* ListLeftVariableIconWithRightCaretBodyText.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA0A257924766CA200862F64 /* ListLeftVariableIconWithRightCaretBodyText.swift */; };
|
||||
AA104AC724472DB0004D2810 /* HeadersH1Button.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA104AC624472DB0004D2810 /* HeadersH1Button.swift */; };
|
||||
@ -217,6 +219,8 @@
|
||||
AA2AD118244EE48C00BBFFE3 /* ListDeviceComplexLinkMediumModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA2AD117244EE48C00BBFFE3 /* ListDeviceComplexLinkMediumModel.swift */; };
|
||||
AA3561AC24C9684400452EB1 /* ListRightVariableRightCaretAllTextAndLinksModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA3561AB24C9684400452EB1 /* ListRightVariableRightCaretAllTextAndLinksModel.swift */; };
|
||||
AA3561AE24C96B9000452EB1 /* ListRightVariableRightCaretAllTextAndLinks.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA3561AD24C96B9000452EB1 /* ListRightVariableRightCaretAllTextAndLinks.swift */; };
|
||||
AA37CBD3251907200027344C /* StarsModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA37CBD2251907200027344C /* StarsModel.swift */; };
|
||||
AA37CBD52519072F0027344C /* Stars.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA37CBD42519072F0027344C /* Stars.swift */; };
|
||||
AA45AA0B24BF0263007A6EA7 /* LockUpsPlanNamesModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA45AA0A24BF0263007A6EA7 /* LockUpsPlanNamesModel.swift */; };
|
||||
AA45AA0D24BF0276007A6EA7 /* LockUpsPlanNames.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA45AA0C24BF0276007A6EA7 /* LockUpsPlanNames.swift */; };
|
||||
AA56A20F243C5EE900303286 /* ListTwoColumnSubsectionDividerModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA56A20E243C5EE900303286 /* ListTwoColumnSubsectionDividerModel.swift */; };
|
||||
@ -705,6 +709,8 @@
|
||||
94CA227A24058533002D6750 /* VerizonNHGeDS-Bold.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "VerizonNHGeDS-Bold.otf"; sourceTree = "<group>"; };
|
||||
94CA227B24058533002D6750 /* VerizonNHGeTX-Regular.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "VerizonNHGeTX-Regular.otf"; sourceTree = "<group>"; };
|
||||
94F6516C2437954100631BF9 /* Tabs.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Tabs.swift; sourceTree = "<group>"; };
|
||||
AA07EA902510A442009A2AE3 /* StarModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StarModel.swift; sourceTree = "<group>"; };
|
||||
AA07EA922510A451009A2AE3 /* Star.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Star.swift; sourceTree = "<group>"; };
|
||||
AA0A257724766C8A00862F64 /* ListLeftVariableIconWithRightCaretBodyTextModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListLeftVariableIconWithRightCaretBodyTextModel.swift; sourceTree = "<group>"; };
|
||||
AA0A257924766CA200862F64 /* ListLeftVariableIconWithRightCaretBodyText.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListLeftVariableIconWithRightCaretBodyText.swift; sourceTree = "<group>"; };
|
||||
AA104AC624472DB0004D2810 /* HeadersH1Button.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeadersH1Button.swift; sourceTree = "<group>"; };
|
||||
@ -723,6 +729,8 @@
|
||||
AA2AD117244EE48C00BBFFE3 /* ListDeviceComplexLinkMediumModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListDeviceComplexLinkMediumModel.swift; sourceTree = "<group>"; };
|
||||
AA3561AB24C9684400452EB1 /* ListRightVariableRightCaretAllTextAndLinksModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListRightVariableRightCaretAllTextAndLinksModel.swift; sourceTree = "<group>"; };
|
||||
AA3561AD24C96B9000452EB1 /* ListRightVariableRightCaretAllTextAndLinks.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListRightVariableRightCaretAllTextAndLinks.swift; sourceTree = "<group>"; };
|
||||
AA37CBD2251907200027344C /* StarsModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StarsModel.swift; sourceTree = "<group>"; };
|
||||
AA37CBD42519072F0027344C /* Stars.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Stars.swift; sourceTree = "<group>"; };
|
||||
AA45AA0A24BF0263007A6EA7 /* LockUpsPlanNamesModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LockUpsPlanNamesModel.swift; sourceTree = "<group>"; };
|
||||
AA45AA0C24BF0276007A6EA7 /* LockUpsPlanNames.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LockUpsPlanNames.swift; sourceTree = "<group>"; };
|
||||
AA56A20E243C5EE900303286 /* ListTwoColumnSubsectionDividerModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListTwoColumnSubsectionDividerModel.swift; sourceTree = "<group>"; };
|
||||
@ -1913,6 +1921,10 @@
|
||||
D20492A524329CE200A5EED6 /* LoadImageView.swift */,
|
||||
0A51F3E02475CB73002E08B6 /* LoadingSpinnerModel.swift */,
|
||||
0A51F3E12475CB73002E08B6 /* LoadingSpinner.swift */,
|
||||
AA37CBD2251907200027344C /* StarsModel.swift */,
|
||||
AA37CBD42519072F0027344C /* Stars.swift */,
|
||||
AA07EA902510A442009A2AE3 /* StarModel.swift */,
|
||||
AA07EA922510A451009A2AE3 /* Star.swift */,
|
||||
);
|
||||
path = Views;
|
||||
sourceTree = "<group>";
|
||||
@ -2372,6 +2384,7 @@
|
||||
AA1EC59724373985003D6F50 /* ListThreeColumnSpeedTestDividerModel.swift in Sources */,
|
||||
BB1D17E0244EAA30001D2002 /* ListDeviceComplexButtonMediumModel.swift in Sources */,
|
||||
D2CAC7D3251105A700C75681 /* MVMCoreUITopAlertExpandableView+Extension.swift in Sources */,
|
||||
AA07EA932510A451009A2AE3 /* Star.swift in Sources */,
|
||||
D29DF2CF21E7C104003B2FB9 /* MFLoadingViewController.m in Sources */,
|
||||
D28A837B23C928DA00DFE4FC /* MoleculeListCellProtocol.swift in Sources */,
|
||||
D28BA74D248589C800B75CB8 /* TabPageModelProtocol.swift in Sources */,
|
||||
@ -2397,6 +2410,7 @@
|
||||
D2E2A99A23D8D6B4000B42E6 /* HeadlineBodyButtonModel.swift in Sources */,
|
||||
D202AFE6242A6A9C00E5BEDF /* UICollectionViewScrollPosition+Extension.swift in Sources */,
|
||||
D20F3B44252E00E4004B3F56 /* PageProtocol.swift in Sources */,
|
||||
AA37CBD3251907200027344C /* StarsModel.swift in Sources */,
|
||||
8D084AD22410BF7600951227 /* ListOneColumnFullWidthTextBodyText.swift in Sources */,
|
||||
94C0150C2421564A005811A9 /* ActionCollapseNotificationModel.swift in Sources */,
|
||||
D2CAC7CB251104E100C75681 /* NotificationXButtonModel.swift in Sources */,
|
||||
@ -2496,6 +2510,7 @@
|
||||
01EB368F23609801006832FA /* LabelModel.swift in Sources */,
|
||||
0A6682AC243531C300AD3CA1 /* Padding.swift in Sources */,
|
||||
AA1EC59924373994003D6F50 /* ListThreeColumnSpeedTestDivider.swift in Sources */,
|
||||
AA37CBD52519072F0027344C /* Stars.swift in Sources */,
|
||||
942C378E2412F5B60066E45E /* ModalMoleculeStackTemplate.swift in Sources */,
|
||||
8D8067D32444473A00203BE8 /* ListRightVariablePriceChangeAllTextAndLinks.swift in Sources */,
|
||||
8D4687E4242E2DF300802879 /* ListFourColumnDataUsageListItem.swift in Sources */,
|
||||
@ -2645,6 +2660,7 @@
|
||||
BB2BF0EC2452A9D5001D0FC2 /* ListDeviceComplexButtonSmallModel.swift in Sources */,
|
||||
943784F6236B77BB006A1E82 /* WheelAnimationHandler.swift in Sources */,
|
||||
011D95A1240453D0000E3791 /* RuleEqualsModel.swift in Sources */,
|
||||
AA07EA912510A442009A2AE3 /* StarModel.swift in Sources */,
|
||||
D29DF2AA21E7B2F9003B2FB9 /* MVMCoreUIConstants.m in Sources */,
|
||||
011D95892404249B000E3791 /* FormHolderModelProtocol.swift in Sources */,
|
||||
BB54C5202434D92F0038326C /* ListRightVariableButtonAllTextAndLinks.swift in Sources */,
|
||||
|
||||
@ -74,23 +74,6 @@ import UIKit
|
||||
private weak var widthConstraint: NSLayoutConstraint?
|
||||
private weak var heightConstraint: NSLayoutConstraint?
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Initializers
|
||||
//--------------------------------------------------
|
||||
|
||||
@objc public override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
}
|
||||
|
||||
@objc public convenience init() {
|
||||
self.init(frame: .zero)
|
||||
}
|
||||
|
||||
@objc required public init?(coder: NSCoder) {
|
||||
super.init(coder: coder)
|
||||
fatalError("DigitBox does not support xibs.")
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Lifecycle
|
||||
//--------------------------------------------------
|
||||
|
||||
@ -81,7 +81,9 @@ open class ItemDropdownEntryField: BaseDropdownEntryField {
|
||||
guard !pickerData.isEmpty else { return }
|
||||
|
||||
if setInitialValueInTextField, let pickerIndex = pickerView?.selectedRow(inComponent: 0) {
|
||||
observeDropdownChange?(text ?? "", pickerData[pickerIndex])
|
||||
text = pickerData[pickerIndex]
|
||||
itemDropdownEntryFieldModel?.selectedIndex = pickerIndex
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -79,18 +79,6 @@ open class Arrow: View {
|
||||
widthConstraint?.isActive = true
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Initializers
|
||||
//--------------------------------------------------
|
||||
|
||||
public override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
}
|
||||
|
||||
public required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Lifecycle
|
||||
//--------------------------------------------------
|
||||
|
||||
@ -73,30 +73,6 @@
|
||||
layoutIfNeeded()
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Initializers
|
||||
//--------------------------------------------------
|
||||
|
||||
public override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
setupView()
|
||||
}
|
||||
|
||||
public convenience init() {
|
||||
self.init(frame: .zero)
|
||||
}
|
||||
|
||||
public convenience init(position: CheckboxPosition) {
|
||||
self.init(frame: .zero)
|
||||
|
||||
alignCheckbox(position)
|
||||
}
|
||||
|
||||
required public init?(coder: NSCoder) {
|
||||
super.init(coder: coder)
|
||||
fatalError("xib file is not implemented for CheckboxLabel")
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Methods
|
||||
//--------------------------------------------------
|
||||
|
||||
@ -24,22 +24,6 @@ open class DashLine: View {
|
||||
|
||||
@objc private var dashLayer: CAShapeLayer?
|
||||
|
||||
//------------------------------------------------------
|
||||
// MARK: - Initializer
|
||||
//------------------------------------------------------
|
||||
|
||||
public override init(frame: CGRect) {
|
||||
super.init(frame: .zero)
|
||||
}
|
||||
|
||||
public convenience init() {
|
||||
self.init(frame: .zero)
|
||||
}
|
||||
|
||||
required public init?(coder: NSCoder) {
|
||||
super.init(coder: coder)
|
||||
}
|
||||
|
||||
//------------------------------------------------------
|
||||
// MARK: - Lifecycle
|
||||
//------------------------------------------------------
|
||||
|
||||
@ -46,22 +46,6 @@
|
||||
rightTextLabelLeading?.isActive = false
|
||||
}
|
||||
|
||||
//------------------------------------------------------
|
||||
// MARK: - Initialization
|
||||
//------------------------------------------------------
|
||||
|
||||
public convenience init() {
|
||||
self.init(frame: .zero)
|
||||
}
|
||||
|
||||
public override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
}
|
||||
|
||||
required public init?(coder aDecoder: NSCoder) {
|
||||
super.init(coder: aDecoder)
|
||||
}
|
||||
|
||||
override open func setupView() {
|
||||
super.setupView()
|
||||
|
||||
|
||||
160
MVMCoreUI/Atomic/Atoms/Views/Star.swift
Normal file
160
MVMCoreUI/Atomic/Atoms/Views/Star.swift
Normal file
@ -0,0 +1,160 @@
|
||||
//
|
||||
// Star.swift
|
||||
// MVMCoreUI
|
||||
//
|
||||
// Created by Lekshmi S on 15/09/20.
|
||||
// Copyright © 2020 Verizon Wireless. All rights reserved.
|
||||
//
|
||||
|
||||
@objcMembers open class Star: View {
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Properties
|
||||
//--------------------------------------------------
|
||||
private var starLayer: CAShapeLayer?
|
||||
private var progressLayer: CAShapeLayer?
|
||||
private let maskLayer = CAShapeLayer()
|
||||
public var starModel: StarModel? {
|
||||
return model as? StarModel
|
||||
}
|
||||
@Percent public var percent = 0 {
|
||||
didSet {
|
||||
updateAccessibilityLabel()
|
||||
setNeedsDisplay()
|
||||
}
|
||||
}
|
||||
public var size: CGFloat = 30 {
|
||||
didSet {
|
||||
widthConstraint?.constant = size
|
||||
setNeedsDisplay()
|
||||
}
|
||||
}
|
||||
public var fillColor = UIColor.mvmBlack {
|
||||
didSet {
|
||||
setNeedsDisplay()
|
||||
}
|
||||
}
|
||||
public var borderColor: CGColor = UIColor.mvmBlack.cgColor {
|
||||
didSet {
|
||||
setNeedsDisplay()
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Constraints
|
||||
//--------------------------------------------------
|
||||
public var widthConstraint: NSLayoutConstraint?
|
||||
public var heightConstraint: NSLayoutConstraint?
|
||||
|
||||
//------------------------------------------------------
|
||||
// MARK: - State Handling
|
||||
//------------------------------------------------------
|
||||
open override func draw(_ rect: CGRect) {
|
||||
//Draw progress
|
||||
progressLayer?.removeFromSuperlayer()
|
||||
let progress = drawProgress()
|
||||
layer.addSublayer(progress)
|
||||
progressLayer = progress
|
||||
|
||||
//Draw the star
|
||||
starLayer?.removeFromSuperlayer()
|
||||
let star = drawStar()
|
||||
layer.addSublayer(star)
|
||||
starLayer = star
|
||||
|
||||
//Mask the star
|
||||
maskLayer.removeFromSuperlayer()
|
||||
maskLayer.path = star.path
|
||||
layer.mask = maskLayer
|
||||
}
|
||||
|
||||
func drawProgress() -> CAShapeLayer {
|
||||
let shapeLayer = CAShapeLayer()
|
||||
let width = bounds.size.width * percent / 100.0
|
||||
shapeLayer.path = UIBezierPath(rect: CGRect(x: 0, y: 0, width: width, height: bounds.height)).cgPath
|
||||
shapeLayer.fillColor = fillColor.cgColor
|
||||
return shapeLayer
|
||||
}
|
||||
|
||||
func drawStar() -> CAShapeLayer {
|
||||
let shapeLayer = CAShapeLayer()
|
||||
shapeLayer.frame = bounds
|
||||
let starPath = UIBezierPath()
|
||||
let center = shapeLayer.position
|
||||
let theta = .pi / CGFloat(5.0)
|
||||
let outerRadius = center.x * 1.039
|
||||
let excessRadius = outerRadius - center.x
|
||||
let innerRadius = CGFloat(outerRadius * 0.382)
|
||||
let leftEdgePointX = (center.x + cos(4.0 * theta) * outerRadius) + excessRadius
|
||||
let horizontalOffset = leftEdgePointX / 2.0
|
||||
let offsetCenter = CGPoint(x: center.x - horizontalOffset, y: center.y)
|
||||
for i in 0 ..< 10 {
|
||||
let radius = i % 2 == 0 ? outerRadius : innerRadius
|
||||
let pointX = offsetCenter.x + cos(CGFloat(i) * theta) * radius
|
||||
let pointY = offsetCenter.y + sin(CGFloat(i) * theta) * radius
|
||||
let point = CGPoint(x: pointX, y: pointY)
|
||||
if i == 0 {
|
||||
starPath.move(to: point)
|
||||
} else {
|
||||
starPath.addLine(to: point)
|
||||
}
|
||||
}
|
||||
starPath.close()
|
||||
// Rotate the path so the star points up as expected
|
||||
var pathTransform = CGAffineTransform.identity
|
||||
pathTransform = pathTransform.translatedBy(x: center.x, y: center.y)
|
||||
pathTransform = pathTransform.rotated(by: CGFloat(-.pi / 2.0))
|
||||
pathTransform = pathTransform.translatedBy(x: -center.x, y: -center.y)
|
||||
starPath.apply(pathTransform)
|
||||
shapeLayer.path = starPath.cgPath
|
||||
shapeLayer.fillColor = UIColor.clear.cgColor
|
||||
shapeLayer.opacity = 1.0
|
||||
shapeLayer.lineWidth = 1
|
||||
shapeLayer.strokeColor = borderColor
|
||||
return shapeLayer
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - MoleculeViewProtocol
|
||||
//--------------------------------------------------
|
||||
open override func reset() {
|
||||
super.reset()
|
||||
borderColor = UIColor.mvmBlack.cgColor
|
||||
fillColor = .mvmBlack
|
||||
percent = 0
|
||||
}
|
||||
|
||||
public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
||||
super.set(with: model, delegateObject, additionalData)
|
||||
guard let model = model as? StarModel else { return }
|
||||
percent = model.percent
|
||||
if let fillColor = model.fillColor?.uiColor {
|
||||
self.fillColor = fillColor
|
||||
}
|
||||
if let borderColor = model.borderColor?.cgColor {
|
||||
self.borderColor = borderColor
|
||||
}
|
||||
size = model.size
|
||||
updateAccessibilityLabel()
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - MVMCoreViewProtocol
|
||||
//--------------------------------------------------
|
||||
open override func setupView() {
|
||||
super.setupView()
|
||||
backgroundColor = .clear
|
||||
widthConstraint = widthAnchor.constraint(equalToConstant: 30)
|
||||
widthConstraint?.isActive = true
|
||||
heightConstraint = heightAnchor.constraint(equalTo: widthAnchor, multiplier: 1)
|
||||
heightConstraint?.isActive = true
|
||||
isAccessibilityElement = true
|
||||
updateAccessibilityLabel()
|
||||
}
|
||||
|
||||
// MARK: - Accessibility
|
||||
func updateAccessibilityLabel() {
|
||||
accessibilityLabel = MVMCoreUIUtility.hardcodedString(withKey: "star")
|
||||
accessibilityValue = String(format: MVMCoreUIUtility.hardcodedString(withKey: "star_percent") ?? "", Int(percent))
|
||||
}
|
||||
}
|
||||
59
MVMCoreUI/Atomic/Atoms/Views/StarModel.swift
Normal file
59
MVMCoreUI/Atomic/Atoms/Views/StarModel.swift
Normal file
@ -0,0 +1,59 @@
|
||||
//
|
||||
// StarModel.swift
|
||||
// MVMCoreUI
|
||||
//
|
||||
// Created by Lekshmi S on 15/09/20.
|
||||
// Copyright © 2020 Verizon Wireless. All rights reserved.
|
||||
//
|
||||
|
||||
open class StarModel: MoleculeModelProtocol {
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Properties
|
||||
//--------------------------------------------------
|
||||
public static var identifier: String = "star"
|
||||
public var backgroundColor: Color?
|
||||
@Percent public var percent: CGFloat = 0
|
||||
public var borderColor: Color?
|
||||
public var fillColor: Color?
|
||||
public var size: CGFloat = 30.0
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Keys
|
||||
//--------------------------------------------------
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case moleculeName
|
||||
case backgroundColor
|
||||
case percent
|
||||
case borderColor
|
||||
case fillColor
|
||||
case size
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Codec
|
||||
//--------------------------------------------------
|
||||
required public init(from decoder: Decoder) throws {
|
||||
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||
|
||||
if let percent = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .percent) {
|
||||
self.percent = percent
|
||||
}
|
||||
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
|
||||
borderColor = try typeContainer.decodeIfPresent(Color.self, forKey: .borderColor)
|
||||
fillColor = try typeContainer.decodeIfPresent(Color.self, forKey: .fillColor)
|
||||
if let size = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .size) {
|
||||
self.size = size
|
||||
}
|
||||
}
|
||||
|
||||
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.encode(percent, forKey: .percent)
|
||||
try container.encodeIfPresent(borderColor, forKey: .borderColor)
|
||||
try container.encodeIfPresent(fillColor, forKey: .fillColor)
|
||||
try container.encode(size, forKey: .size)
|
||||
}
|
||||
}
|
||||
108
MVMCoreUI/Atomic/Atoms/Views/Stars.swift
Normal file
108
MVMCoreUI/Atomic/Atoms/Views/Stars.swift
Normal file
@ -0,0 +1,108 @@
|
||||
//
|
||||
// Stars.swift
|
||||
// MVMCoreUI
|
||||
//
|
||||
// Created by Lekshmi S on 21/09/20.
|
||||
// Copyright © 2020 Verizon Wireless. All rights reserved.
|
||||
//
|
||||
|
||||
open class Stars: View {
|
||||
//--------------------------------------------------
|
||||
// MARK: - Properties
|
||||
//--------------------------------------------------
|
||||
private var stack = UIStackView()
|
||||
public var starsModel: StarsModel? {
|
||||
return model as? StarsModel
|
||||
}
|
||||
private var delegateObject: MVMCoreUIDelegateObject?
|
||||
private let itemSpacing: CGFloat = 3.0
|
||||
private var heightConstraint: NSLayoutConstraint?
|
||||
private var starsFilledValue: Float = 0
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - MVMCoreViewProtocol
|
||||
//--------------------------------------------------
|
||||
open override func setupView() {
|
||||
super.setupView()
|
||||
stack.translatesAutoresizingMaskIntoConstraints = false
|
||||
stack.axis = .horizontal
|
||||
stack.spacing = itemSpacing
|
||||
addSubview(stack)
|
||||
NSLayoutConstraint.constraintPinSubview(toSuperview: stack)
|
||||
heightConstraint = heightAnchor.constraint(equalToConstant: 30)
|
||||
heightConstraint?.isActive = true
|
||||
isAccessibilityElement = true
|
||||
updateAccessibilityLabel()
|
||||
}
|
||||
|
||||
@objc override open func updateView(_ size: CGFloat) {
|
||||
super.updateView(size)
|
||||
stack.updateView(size)
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - MoleculeViewProtocol
|
||||
//--------------------------------------------------
|
||||
open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
||||
super.set(with: model, delegateObject, additionalData)
|
||||
self.delegateObject = delegateObject
|
||||
createStars()
|
||||
updateStars()
|
||||
updateAccessibilityLabel()
|
||||
}
|
||||
|
||||
public override func reset() {
|
||||
stack.subviews.forEach({$0.removeFromSuperview()})
|
||||
super.reset()
|
||||
}
|
||||
|
||||
//------------------------------------------------------
|
||||
// MARK: - Methods
|
||||
//------------------------------------------------------
|
||||
func createStars() {
|
||||
guard let starsModel = starsModel else { return }
|
||||
for starModel in starsModel.stars {
|
||||
let star = Star(model: starModel, delegateObject, nil)
|
||||
star.isAccessibilityElement = false
|
||||
stack.addArrangedSubview(star)
|
||||
}
|
||||
heightConstraint?.constant = starsModel.size
|
||||
}
|
||||
|
||||
func updateStars() {
|
||||
guard let starsModel = starsModel else { return }
|
||||
let percentRequiredToFillStarFully = CGFloat(100/(stack.arrangedSubviews.count))
|
||||
let numberOfFilledStars = Int(starsModel.percent/percentRequiredToFillStarFully)
|
||||
starsFilledValue = Float(numberOfFilledStars)
|
||||
for case let (index, star as Star) in stack.arrangedSubviews.enumerated() {
|
||||
//Star model colors should take priority over stars.
|
||||
if let borderColor = starsModel.borderColor?.cgColor, star.starModel?.borderColor == nil {
|
||||
star.borderColor = borderColor
|
||||
}
|
||||
if let fillColor = starsModel.fillColor?.uiColor, star.starModel?.fillColor == nil {
|
||||
star.fillColor = fillColor
|
||||
}
|
||||
if let backgroundColor = starsModel.starBackgroundColor?.uiColor, star.starModel?.backgroundColor == nil {
|
||||
star.backgroundColor = backgroundColor
|
||||
}
|
||||
|
||||
//Fill the stars based on percentage. Ex: if there were 4 stars, 75 percent is 3 full stars
|
||||
if index < numberOfFilledStars {
|
||||
star.percent = 100
|
||||
} else if index == numberOfFilledStars {
|
||||
let remainingProgress = (starsModel.percent).truncatingRemainder(dividingBy: percentRequiredToFillStarFully)
|
||||
let fillPercent = remainingProgress/percentRequiredToFillStarFully
|
||||
starsFilledValue += Float(fillPercent)
|
||||
star.percent = fillPercent * 100
|
||||
} else {
|
||||
star.percent = 0
|
||||
}
|
||||
star.size = starsModel.size
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Accessibility
|
||||
func updateAccessibilityLabel() {
|
||||
accessibilityLabel = String(format: MVMCoreUIUtility.hardcodedString(withKey: "stars_filled") ?? "", starsFilledValue, stack.arrangedSubviews.count)
|
||||
}
|
||||
}
|
||||
66
MVMCoreUI/Atomic/Atoms/Views/StarsModel.swift
Normal file
66
MVMCoreUI/Atomic/Atoms/Views/StarsModel.swift
Normal file
@ -0,0 +1,66 @@
|
||||
//
|
||||
// StarsModel.swift
|
||||
// MVMCoreUI
|
||||
//
|
||||
// Created by Lekshmi S on 21/09/20.
|
||||
// Copyright © 2020 Verizon Wireless. All rights reserved.
|
||||
//
|
||||
|
||||
@objcMembers public class StarsModel: MoleculeModelProtocol {
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Properties
|
||||
//--------------------------------------------------
|
||||
public static var identifier: String = "stars"
|
||||
public var backgroundColor: Color?
|
||||
public var starBackgroundColor: Color?
|
||||
public var stars: [StarModel]
|
||||
@Percent public var percent: CGFloat = 0
|
||||
public var borderColor: Color?
|
||||
public var fillColor: Color?
|
||||
public var size: CGFloat = 30.0
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Keys
|
||||
//--------------------------------------------------
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case moleculeName
|
||||
case backgroundColor
|
||||
case starBackgroundColor
|
||||
case stars
|
||||
case percent
|
||||
case borderColor
|
||||
case fillColor
|
||||
case size
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Codec
|
||||
//--------------------------------------------------
|
||||
required public init(from decoder: Decoder) throws {
|
||||
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||
stars = try typeContainer.decode([StarModel].self, forKey: .stars)
|
||||
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
|
||||
starBackgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .starBackgroundColor)
|
||||
if let percent = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .percent) {
|
||||
self.percent = percent
|
||||
}
|
||||
borderColor = try typeContainer.decodeIfPresent(Color.self, forKey: .borderColor)
|
||||
fillColor = try typeContainer.decodeIfPresent(Color.self, forKey: .fillColor)
|
||||
if let size = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .size) {
|
||||
self.size = size
|
||||
}
|
||||
}
|
||||
|
||||
public func encode(to encoder: Encoder) throws {
|
||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||
try container.encode(moleculeName, forKey: .moleculeName)
|
||||
try container.encode(stars, forKey: .stars)
|
||||
try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor)
|
||||
try container.encodeIfPresent(starBackgroundColor, forKey: .starBackgroundColor)
|
||||
try container.encodeIfPresent(borderColor, forKey: .borderColor)
|
||||
try container.encodeIfPresent(fillColor, forKey: .fillColor)
|
||||
try container.encode(percent, forKey: .percent)
|
||||
try container.encode(size, forKey: .size)
|
||||
}
|
||||
}
|
||||
@ -88,6 +88,8 @@ import Foundation
|
||||
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)
|
||||
MoleculeObjectMapping.shared()?.register(viewClass: Stars.self, viewModelClass: StarsModel.self)
|
||||
MoleculeObjectMapping.shared()?.register(viewClass: Star.self, viewModelClass: StarModel.self)
|
||||
|
||||
|
||||
// MARK:- Other Atoms
|
||||
|
||||
@ -14,19 +14,9 @@ import Foundation
|
||||
//--------------------------------------------------
|
||||
public let headlineBody = HeadlineBody(frame: .zero)
|
||||
public let buttons = TwoButtonView(frame: .zero)
|
||||
public let stack: Stack<StackModel>
|
||||
|
||||
//-------------------------------------------------------
|
||||
// MARK: - Initializers
|
||||
//-------------------------------------------------------
|
||||
public override init(frame: CGRect) {
|
||||
stack = Stack<StackModel>.createStack(with: [headlineBody, buttons], spacing: Padding.Eighteen)
|
||||
super.init(frame: frame)
|
||||
}
|
||||
|
||||
public required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
public lazy var stack: Stack<StackModel> = {
|
||||
return Stack<StackModel>.createStack(with: [headlineBody, buttons], spacing: Padding.Eighteen)
|
||||
}()
|
||||
|
||||
//-------------------------------------------------------
|
||||
// MARK: - View Lifecycle
|
||||
|
||||
@ -16,20 +16,9 @@ import Foundation
|
||||
|
||||
public let headlineBody = HeadlineBody()
|
||||
public let buttons = TwoButtonView()
|
||||
public let stack: Stack<StackModel>
|
||||
|
||||
//-------------------------------------------------------
|
||||
// MARK: - Initializers
|
||||
//-------------------------------------------------------
|
||||
|
||||
public override init(frame: CGRect) {
|
||||
stack = Stack<StackModel>.createStack(with: [headlineBody, buttons], spacing: PaddingDefaultVerticalSpacing3)
|
||||
super.init(frame: frame)
|
||||
}
|
||||
|
||||
public required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
public lazy var stack: Stack<StackModel> = {
|
||||
return Stack<StackModel>.createStack(with: [headlineBody, buttons], spacing: PaddingDefaultVerticalSpacing3)
|
||||
}()
|
||||
|
||||
//-------------------------------------------------------
|
||||
// MARK: - Lifecycle
|
||||
|
||||
@ -13,19 +13,9 @@ import Foundation
|
||||
//--------------------------------------------------
|
||||
public let headlineBody = HeadlineBody()
|
||||
public let caretLink = CaretLink()
|
||||
public let stack: Stack<StackModel>
|
||||
|
||||
//-------------------------------------------------------
|
||||
// MARK: - Initializers
|
||||
//-------------------------------------------------------
|
||||
public override init(frame: CGRect) {
|
||||
stack = Stack<StackModel>.createStack(with: [headlineBody, caretLink])
|
||||
super.init(frame: frame)
|
||||
}
|
||||
|
||||
public required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
public lazy var stack: Stack<StackModel> = {
|
||||
return Stack<StackModel>.createStack(with: [headlineBody, caretLink])
|
||||
}()
|
||||
|
||||
//-------------------------------------------------------
|
||||
// MARK: - Lifecycle
|
||||
|
||||
@ -14,19 +14,9 @@ import Foundation
|
||||
//--------------------------------------------------
|
||||
public let headlineBody = HeadlineBody()
|
||||
public let link = Link()
|
||||
public let stack: Stack<StackModel>
|
||||
|
||||
//-------------------------------------------------------
|
||||
// MARK: - Initializers
|
||||
//-------------------------------------------------------
|
||||
public override init(frame: CGRect) {
|
||||
stack = Stack<StackModel>.createStack(with: [headlineBody, link])
|
||||
super.init(frame: frame)
|
||||
}
|
||||
|
||||
public required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
public lazy var stack: Stack<StackModel> = {
|
||||
return Stack<StackModel>.createStack(with: [headlineBody, link])
|
||||
}()
|
||||
|
||||
//-------------------------------------------------------
|
||||
// MARK: - Lifecycle
|
||||
|
||||
@ -21,31 +21,26 @@ import Foundation
|
||||
public let subBody3 = Label(fontStyle: .RegularMicro)
|
||||
public let verticalLine1 = Line()
|
||||
public let verticalLine2 = Line()
|
||||
public let verticalStack1: Stack<StackModel>
|
||||
public let verticalStack2: Stack<StackModel>
|
||||
public let verticalStack3: Stack<StackModel>
|
||||
public let horizontalStack: Stack<StackModel>
|
||||
public let stack: Stack<StackModel>
|
||||
|
||||
//-------------------------------------------------------
|
||||
// MARK: - Initializers
|
||||
//-------------------------------------------------------
|
||||
public override init(frame: CGRect) {
|
||||
verticalStack1 = Stack<StackModel>.createStack(with: [body, subBody], spacing: 0)
|
||||
verticalStack2 = Stack<StackModel>.createStack(with: [body2, subBody2], spacing: 0)
|
||||
verticalStack3 = Stack<StackModel>.createStack(with: [body3, subBody3], spacing: 0)
|
||||
horizontalStack = Stack<StackModel>.createStack(with: [(view: verticalStack1, model: StackItemModel(percent: 29, verticalAlignment: .top)), (view: verticalLine1, model: StackItemModel(verticalAlignment: .top)),
|
||||
(view: verticalStack2, model: StackItemModel(horizontalAlignment: .leading, verticalAlignment: .top)),
|
||||
(view: verticalLine2, model: StackItemModel(verticalAlignment: .top)),
|
||||
(view: verticalStack3, model: StackItemModel(percent: 32, verticalAlignment: .top))],
|
||||
axis: .horizontal)
|
||||
stack = Stack<StackModel>.createStack(with: [headline, horizontalStack], spacing: 8)
|
||||
super.init(frame: frame)
|
||||
}
|
||||
|
||||
public required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
public lazy var verticalStack1: Stack<StackModel> = {
|
||||
return Stack<StackModel>.createStack(with: [body, subBody], spacing: 0)
|
||||
}()
|
||||
public lazy var verticalStack2: Stack<StackModel> = {
|
||||
return Stack<StackModel>.createStack(with: [body2, subBody2], spacing: 0)
|
||||
}()
|
||||
public lazy var verticalStack3: Stack<StackModel> = {
|
||||
return Stack<StackModel>.createStack(with: [body3, subBody3], spacing: 0)
|
||||
}()
|
||||
public lazy var horizontalStack: Stack<StackModel> = {
|
||||
return Stack<StackModel>.createStack(with: [(view: verticalStack1, model: StackItemModel(percent: 29, verticalAlignment: .top)),
|
||||
(view: verticalLine1, model: StackItemModel(verticalAlignment: .top)),
|
||||
(view: verticalStack2, model: StackItemModel(horizontalAlignment: .leading, verticalAlignment: .top)),
|
||||
(view: verticalLine2, model: StackItemModel(verticalAlignment: .top)),
|
||||
(view: verticalStack3, model: StackItemModel(percent: 32, verticalAlignment: .top))],
|
||||
axis: .horizontal)
|
||||
}()
|
||||
public lazy var stack: Stack<StackModel> = {
|
||||
return Stack<StackModel>.createStack(with: [headline, horizontalStack], spacing: 8)
|
||||
}()
|
||||
|
||||
//-------------------------------------------------------
|
||||
// MARK: - Lifecycle
|
||||
|
||||
@ -16,22 +16,11 @@ import Foundation
|
||||
|
||||
public let headlineBody = HeadlineBody()
|
||||
public let button = PillButton()
|
||||
public let stack: Stack<StackModel>
|
||||
|
||||
//-------------------------------------------------------
|
||||
// MARK: - Initializers
|
||||
//-------------------------------------------------------
|
||||
|
||||
public override init(frame: CGRect) {
|
||||
stack = Stack<StackModel>.createStack(with: [(view: headlineBody, model: StackItemModel(horizontalAlignment: .fill)),
|
||||
(view: button, model: StackItemModel(spacing: spacingBetwenHeadlineBodyAndButton, horizontalAlignment: .leading))],
|
||||
axis: .vertical)
|
||||
super.init(frame: frame)
|
||||
}
|
||||
|
||||
public required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
public lazy var stack: Stack<StackModel> = {
|
||||
return Stack<StackModel>.createStack(with: [(view: headlineBody, model: StackItemModel(horizontalAlignment: .fill)),
|
||||
(view: button, model: StackItemModel(spacing: spacingBetwenHeadlineBodyAndButton, horizontalAlignment: .leading))],
|
||||
axis: .vertical)
|
||||
}()
|
||||
|
||||
//------------------------------------------------------
|
||||
// MARK: - Constants
|
||||
|
||||
@ -15,21 +15,11 @@ import Foundation
|
||||
public let headline = Label(fontStyle: .Title2XLarge)
|
||||
public let subHeadline = Label(fontStyle: .RegularTitleLarge)
|
||||
public let body = Label(fontStyle: .RegularBodySmall)
|
||||
public let stack: Stack<StackModel>
|
||||
|
||||
//-------------------------------------------------------
|
||||
// MARK: - Initializers
|
||||
//-------------------------------------------------------
|
||||
public override init(frame: CGRect) {
|
||||
stack = Stack<StackModel>.createStack(with: [(view: headline, model: StackItemModel()),
|
||||
(view: subHeadline, model: StackItemModel(spacing: 16)),
|
||||
(view: body, model: StackItemModel(spacing: 8))])
|
||||
super.init(frame: frame)
|
||||
}
|
||||
|
||||
public required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
public lazy var stack: Stack<StackModel> = {
|
||||
return Stack<StackModel>.createStack(with: [(view: headline, model: StackItemModel()),
|
||||
(view: subHeadline, model: StackItemModel(spacing: 16)),
|
||||
(view: body, model: StackItemModel(spacing: 8))])
|
||||
}()
|
||||
|
||||
//-------------------------------------------------------
|
||||
// MARK: - Lifecycle
|
||||
|
||||
@ -16,26 +16,17 @@ import Foundation
|
||||
public let headline = Label(fontStyle: .BoldTitleLarge)
|
||||
public let subHeadline = Label(fontStyle: .RegularTitleLarge)
|
||||
public let body = Label(fontStyle: .RegularBodySmall)
|
||||
public let verticalStack: Stack<StackModel>
|
||||
public var stack: Stack<StackModel>
|
||||
|
||||
//-------------------------------------------------------
|
||||
// MARK: - Initializers
|
||||
//-------------------------------------------------------
|
||||
public override init(frame: CGRect) {
|
||||
verticalStack = Stack<StackModel>.createStack(with: [(view: headline, model: StackItemModel()),
|
||||
(view: subHeadline, model: StackItemModel()),
|
||||
(view: body, model: StackItemModel(horizontalAlignment: .fill))],
|
||||
axis: .vertical, spacing: 0)
|
||||
stack = Stack<StackModel>.createStack(with: [(view: planLabel, model: StackItemModel(horizontalAlignment: .fill, verticalAlignment: .leading)),
|
||||
(view: verticalStack, model: StackItemModel(horizontalAlignment: .fill, verticalAlignment: .leading))],
|
||||
axis: .horizontal)
|
||||
super.init(frame: frame)
|
||||
}
|
||||
|
||||
public required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
public lazy var verticalStack: Stack<StackModel> = {
|
||||
return Stack<StackModel>.createStack(with: [(view: headline, model: StackItemModel()),
|
||||
(view: subHeadline, model: StackItemModel()),
|
||||
(view: body, model: StackItemModel(horizontalAlignment: .fill))],
|
||||
axis: .vertical, spacing: 0)
|
||||
}()
|
||||
public lazy var stack: Stack<StackModel> = {
|
||||
return Stack<StackModel>.createStack(with: [(view: planLabel, model: StackItemModel(horizontalAlignment: .fill, verticalAlignment: .leading)),
|
||||
(view: verticalStack, model: StackItemModel(horizontalAlignment: .fill, verticalAlignment: .leading))],
|
||||
axis: .horizontal)
|
||||
}()
|
||||
|
||||
//-------------------------------------------------------
|
||||
// MARK: - Lifecycle
|
||||
|
||||
@ -49,22 +49,6 @@ open class DoughnutChart: View {
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Initializers
|
||||
//--------------------------------------------------
|
||||
|
||||
public override init(frame: CGRect) {
|
||||
super.init(frame: .zero)
|
||||
}
|
||||
|
||||
public convenience init() {
|
||||
self.init(frame: .zero)
|
||||
}
|
||||
|
||||
public required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Lifecycle
|
||||
//--------------------------------------------------
|
||||
|
||||
@ -15,19 +15,6 @@ import UIKit
|
||||
var delegateObject: MVMCoreUIDelegateObject?
|
||||
let label = Label()
|
||||
|
||||
// MARK: - Inits
|
||||
public init() {
|
||||
super.init(frame: .zero)
|
||||
}
|
||||
|
||||
public override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
}
|
||||
|
||||
required public init?(coder aDecoder: NSCoder) {
|
||||
super.init(coder: aDecoder)
|
||||
}
|
||||
|
||||
public override func updateView(_ size: CGFloat) {
|
||||
super.updateView(size)
|
||||
radioButton.updateView(size)
|
||||
|
||||
@ -24,22 +24,6 @@ import UIKit
|
||||
|
||||
private var equalWidthConstraint: NSLayoutConstraint?
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Initializers
|
||||
//--------------------------------------------------
|
||||
|
||||
public init() {
|
||||
super.init(frame: .zero)
|
||||
}
|
||||
|
||||
required public init?(coder aDecoder: NSCoder) {
|
||||
super.init(coder: aDecoder)
|
||||
}
|
||||
|
||||
public override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Lifecycle
|
||||
//--------------------------------------------------
|
||||
|
||||
@ -17,22 +17,6 @@ import Foundation
|
||||
open var leftLink = Link()
|
||||
open var rightLink = Link()
|
||||
private var stack = UIStackView()
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Initializers
|
||||
//--------------------------------------------------
|
||||
|
||||
public init() {
|
||||
super.init(frame: .zero)
|
||||
}
|
||||
|
||||
required public init?(coder aDecoder: NSCoder) {
|
||||
super.init(coder: aDecoder)
|
||||
}
|
||||
|
||||
public override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - MVMCoreViewProtocol
|
||||
|
||||
@ -29,22 +29,6 @@ import UIKit
|
||||
|
||||
var imageLeadingConstraint: NSLayoutConstraint?
|
||||
|
||||
//------------------------------------------------------
|
||||
// MARK: - Initialization
|
||||
//------------------------------------------------------
|
||||
|
||||
public init() {
|
||||
super.init(frame: .zero)
|
||||
}
|
||||
|
||||
public override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
}
|
||||
|
||||
required public init?(coder aDecoder: NSCoder) {
|
||||
super.init(coder: aDecoder)
|
||||
}
|
||||
|
||||
//------------------------------------------------------
|
||||
// MARK: - View Lifecycle
|
||||
//------------------------------------------------------
|
||||
|
||||
@ -27,22 +27,6 @@
|
||||
|
||||
var buttonTopConstraint: NSLayoutConstraint?
|
||||
|
||||
//------------------------------------------------------
|
||||
// MARK: - Initialization
|
||||
//------------------------------------------------------
|
||||
|
||||
public convenience init() {
|
||||
self.init(frame: .zero)
|
||||
}
|
||||
|
||||
public override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
}
|
||||
|
||||
required public init?(coder aDecoder: NSCoder) {
|
||||
super.init(coder: aDecoder)
|
||||
}
|
||||
|
||||
//------------------------------------------------------
|
||||
// MARK: - View Lifecycle
|
||||
//------------------------------------------------------
|
||||
|
||||
@ -36,6 +36,13 @@ open class StringAndMoleculeView: View {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
public required init(model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) {
|
||||
let moleculeModel = model as? StringAndMoleculeModel
|
||||
label.text = moleculeModel?.string
|
||||
self.molecule = moleculeModel?.molecule as! MoleculeViewProtocol
|
||||
super.init(model: model, delegateObject, additionalData)
|
||||
}
|
||||
|
||||
override public func setupView() {
|
||||
super.setupView()
|
||||
|
||||
|
||||
@ -18,22 +18,6 @@ open class ThreeHeadlineBodyLink: View {
|
||||
public let body = Label(fontStyle: .RegularBodySmall)
|
||||
public let link = Link()
|
||||
|
||||
//------------------------------------------------------
|
||||
// MARK: - Initialization
|
||||
//------------------------------------------------------
|
||||
|
||||
public convenience init() {
|
||||
self.init(frame: .zero)
|
||||
}
|
||||
|
||||
public override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
}
|
||||
|
||||
required public init?(coder aDecoder: NSCoder) {
|
||||
super.init(coder: aDecoder)
|
||||
}
|
||||
|
||||
//------------------------------------------------------
|
||||
// MARK: - Lifecycle
|
||||
//------------------------------------------------------
|
||||
|
||||
@ -115,6 +115,11 @@ open class Stack<T>: Container where T: (StackModelProtocol & MoleculeModelProto
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
public required init(model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
||||
super.init(frame: .zero)
|
||||
set(with: model, delegateObject, additionalData)
|
||||
}
|
||||
|
||||
/// Returns a Stack created with a StackModel and StackItems containing the passed in views.
|
||||
public static func createStack(with views: [UIView], axis: NSLayoutConstraint.Axis? = nil, spacing: CGFloat? = nil) -> Stack<StackModel> {
|
||||
|
||||
|
||||
@ -43,6 +43,12 @@ import UIKit
|
||||
}
|
||||
}
|
||||
|
||||
public required init(model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
||||
super.init(frame: .zero)
|
||||
initialSetup()
|
||||
set(with: model, delegateObject, additionalData)
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - MoleculeViewProtocol
|
||||
//--------------------------------------------------
|
||||
|
||||
@ -17,7 +17,7 @@
|
||||
- (BOOL)panelAvailable;
|
||||
|
||||
// Notified when it is appearing and disappearing. Called by the container.
|
||||
- (void)willOpenWithActionInformation:(nullable NSDictionary *)actionInformation;
|
||||
- (void)willOpenWithActionInformation:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData;
|
||||
- (void)willAppear:(BOOL)animated;
|
||||
- (void)didAppear:(BOOL)animated;
|
||||
- (void)willDisappear:(BOOL)animated;
|
||||
|
||||
@ -878,7 +878,7 @@ CGFloat const PanelAnimationDuration = 0.2;
|
||||
// Create bottom progress bar
|
||||
UIProgressView *progressView = [[UIProgressView alloc] initWithProgressViewStyle:UIProgressViewStyleDefault];
|
||||
progressView.translatesAutoresizingMaskIntoConstraints = NO;
|
||||
progressView.tintColor = [UIColor mfTomatoRed];
|
||||
progressView.progressTintColor = [UIColor mfTomatoRed];
|
||||
[self.view addSubview:progressView];
|
||||
self.bottomProgressBar = progressView;
|
||||
[NSLayoutConstraint constraintWithItem:progressView attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:mainView attribute:NSLayoutAttributeLeft multiplier:1.0 constant:0].active = YES;
|
||||
|
||||
@ -87,3 +87,8 @@
|
||||
"CountDownHours" = " hours";
|
||||
"CountDownMins" = " mins";
|
||||
"CountDownSecs" = " secs";
|
||||
|
||||
// MARK: Star
|
||||
"star" = "Star";
|
||||
"star_percent" = "%d percent progress";
|
||||
"stars_filled" = "%.1f out of %d stars";
|
||||
|
||||
@ -66,3 +66,7 @@
|
||||
"CountDownHours" = " horas";
|
||||
"CountDownMins" = " min";
|
||||
"CountDownSecs" = " seg";
|
||||
// Star
|
||||
"star" = "Estrella";
|
||||
"star_percent" = "%@ porcentaje de progreso";
|
||||
"stars_filled" = "%.1f de %d estrellas";
|
||||
|
||||
@ -70,3 +70,8 @@
|
||||
"CountDownHours" = " horas";
|
||||
"CountDownMins" = " min";
|
||||
"CountDownSecs" = " seg";
|
||||
|
||||
// Star
|
||||
"star" = "Estrella";
|
||||
"star_percent" = "%@ porcentaje de progreso";
|
||||
"stars_filled" = "%.1f de %d estrellas";
|
||||
|
||||
@ -21,13 +21,13 @@ public extension MVMCoreUITopAlertView {
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(viewControllerChanged(notification:)), name: NSNotification.Name(rawValue: MVMCoreNotificationViewControllerChanged), object: nil)
|
||||
}
|
||||
|
||||
@objc func getDelegateObject() -> MVMCoreUIDelegateObject {
|
||||
private func getDelegateObject() -> MVMCoreUIDelegateObject {
|
||||
// TODO: Top alert view is current delegate. Should move to current view controller eventually?
|
||||
return MVMCoreUIDelegateObject.create(withDelegateForAll: self)
|
||||
}
|
||||
|
||||
/// Checks for new top alert json
|
||||
@objc func responseJSONUpdated(notification: Notification) {
|
||||
@objc private func responseJSONUpdated(notification: Notification) {
|
||||
guard let responseJSON = (notification.userInfo?[String(describing: MVMCoreLoadObject.self)] as? MVMCoreLoadObject)?.responseJSON,
|
||||
let json = responseJSON.optionalDictionaryForKey("TopNotification"),
|
||||
let model = decodeTopNotification(with: json, delegateObject: getDelegateObject()) else { return }
|
||||
@ -35,13 +35,43 @@ public extension MVMCoreUITopAlertView {
|
||||
}
|
||||
|
||||
/// When a detail page changes, check top alerts.
|
||||
@objc func viewControllerChanged(notification: Notification) {
|
||||
@objc private func viewControllerChanged(notification: Notification) {
|
||||
guard let controller = MVMCoreUISplitViewController.main()?.getCurrentDetailViewController() as? MVMCoreViewControllerProtocol else { return }
|
||||
MVMCoreAlertHandler.shared()?.checkPagesDependency(for: controller.pageType)
|
||||
MVMCoreAlertHandler.shared()?.handleAllPagesDependency(for: controller.pageType)
|
||||
reevalutePriority()
|
||||
}
|
||||
|
||||
/// Re-evaluates the queue priority
|
||||
private func reevalutePriority() {
|
||||
guard let operations = MVMCoreAlertHandler.shared()?.topAlertQueue.operations else { return }
|
||||
var highestReadyOperation: Operation?
|
||||
var executingOperation: Operation?
|
||||
for operation in operations {
|
||||
guard !operation.isCancelled,
|
||||
!operation.isFinished else {
|
||||
continue
|
||||
}
|
||||
if operation.isReady,
|
||||
highestReadyOperation == nil || operation.queuePriority.rawValue > highestReadyOperation!.queuePriority.rawValue {
|
||||
highestReadyOperation = operation
|
||||
}
|
||||
if operation.isExecuting {
|
||||
executingOperation = operation
|
||||
}
|
||||
}
|
||||
|
||||
// If the highest priority operation is not executing, and the executing operation is persistent, cancel it.
|
||||
if let newOperation = highestReadyOperation,
|
||||
let currentOperation = executingOperation as? MVMCoreTopAlertOperation,
|
||||
currentOperation != newOperation,
|
||||
currentOperation.topAlertObject.persistent {
|
||||
currentOperation.reAddAfterCancel = true
|
||||
currentOperation.cancel()
|
||||
}
|
||||
}
|
||||
|
||||
/// Decodes the json into a TopNotificationModel
|
||||
func decodeTopNotification(with json: [AnyHashable: Any], delegateObject: MVMCoreUIDelegateObject?) -> TopNotificationModel? {
|
||||
private func decodeTopNotification(with json: [AnyHashable: Any], delegateObject: MVMCoreUIDelegateObject?) -> TopNotificationModel? {
|
||||
do {
|
||||
return try TopNotificationModel.decode(json: json, delegateObject: delegateObject)
|
||||
} catch {
|
||||
@ -55,7 +85,26 @@ public extension MVMCoreUITopAlertView {
|
||||
/// Shows the top alert with the model.
|
||||
func showTopAlert(with model: TopNotificationModel) {
|
||||
let object = model.createTopAlertObject()
|
||||
MVMCoreAlertHandler.shared()?.showTopAlert(with: object)
|
||||
guard !checkAndUpdateExisting(with: object),
|
||||
let operation = MVMCoreTopAlertOperation(topAlertObject: object) else { return }
|
||||
MVMCoreAlertHandler.shared()?.addPagesDependency(to: operation)
|
||||
MVMCoreAlertHandler.shared()?.handlePageDependency(for: operation, with: (MVMCoreUISplitViewController.main()?.getCurrentDetailViewController() as? MVMCoreViewControllerProtocol)?.pageType)
|
||||
MVMCoreAlertHandler.shared()?.add(operation)
|
||||
}
|
||||
|
||||
/// 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 {
|
||||
guard let queue = MVMCoreAlertHandler.shared()?.topAlertQueue.operations else { return false }
|
||||
for case let operation as MVMCoreTopAlertOperation in queue {
|
||||
guard topAlertObject.json != nil,
|
||||
operation.topAlertObject.type == topAlertObject.type else { continue }
|
||||
operation.update(with: topAlertObject)
|
||||
MVMCoreAlertHandler.shared()?.updatePages(for: operation, with: topAlertObject)
|
||||
MVMCoreAlertHandler.shared()?.handlePageDependency(for: operation, with: (MVMCoreUISplitViewController.main()?.getCurrentDetailViewController() as? MVMCoreViewControllerProtocol)?.pageType)
|
||||
reevalutePriority()
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
/// Updates the current top alert molecule with the new object
|
||||
|
||||
Loading…
Reference in New Issue
Block a user