Compare commits
14 Commits
f3e97ecfd4
...
8212d7146c
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8212d7146c | ||
|
|
5c280b7922 | ||
|
|
1eed9ebb76 | ||
|
|
a210b8da9b | ||
|
|
44adc76dcb | ||
|
|
eb4f741f1a | ||
|
|
928c8c5b54 | ||
|
|
2dd3a7dca8 | ||
|
|
7bed914dca | ||
|
|
fe5bd4a9ac | ||
|
|
7eb1a4ff4b | ||
|
|
76b58ec88a | ||
|
|
4487f9b03b | ||
|
|
3a06f7b43e |
@ -31,10 +31,10 @@ open class Badge: VDS.Badge, VDSMoleculeViewProtocol {
|
|||||||
self.accessibilityIdentifier = accessibilityIdentifier
|
self.accessibilityIdentifier = accessibilityIdentifier
|
||||||
}
|
}
|
||||||
text = viewModel.text
|
text = viewModel.text
|
||||||
textColor = viewModel.textColor
|
textColor = viewModel.textColorStyle
|
||||||
maxWidth = viewModel.maxWidth
|
maxWidth = viewModel.maxWidth
|
||||||
numberOfLines = viewModel.numberOfLines
|
numberOfLines = viewModel.numberOfLines
|
||||||
fillColor = viewModel.fillColor
|
fillColor = viewModel.fillColorStyle
|
||||||
surface = viewModel.surface
|
surface = viewModel.surface
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -22,15 +22,18 @@ open class BadgeModel: MoleculeModelProtocol {
|
|||||||
// MARK: - VDS Properties
|
// MARK: - VDS Properties
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
public var text: String = ""
|
public var text: String = ""
|
||||||
public var textColor: Badge.TextColor? = nil
|
public var textColorStyle: Badge.TextColor? = nil
|
||||||
public var accessibilityText: String?
|
public var accessibilityText: String?
|
||||||
public var maxWidth: CGFloat?
|
public var maxWidth: CGFloat?
|
||||||
public var numberOfLines: Int = 1
|
public var numberOfLines: Int = 1
|
||||||
public var fillColor = Badge.FillColor.red
|
public var fillColorStyle = Badge.FillColor.red
|
||||||
public var surface: Surface = .light
|
public var surface: Surface = .light
|
||||||
|
|
||||||
private enum CodingKeys: String, CodingKey {
|
private enum CodingKeys: String, CodingKey {
|
||||||
case id, accessibilityIdentifier, text, textColor, accessibilityText, fillColor, surface, numberOfLines, maxWidth
|
case id, accessibilityIdentifier, accessibilityText
|
||||||
|
case surface, numberOfLines, maxWidth
|
||||||
|
case text, textColor
|
||||||
|
case fillColor, fillColorStyle
|
||||||
}
|
}
|
||||||
|
|
||||||
required public convenience init(from decoder: Decoder) throws {
|
required public convenience init(from decoder: Decoder) throws {
|
||||||
@ -39,11 +42,20 @@ open class BadgeModel: MoleculeModelProtocol {
|
|||||||
id = try container.decodeIfPresent(String.self, forKey: .id) ?? UUID().uuidString
|
id = try container.decodeIfPresent(String.self, forKey: .id) ?? UUID().uuidString
|
||||||
accessibilityIdentifier = try container.decodeIfPresent(String.self, forKey: .accessibilityIdentifier)
|
accessibilityIdentifier = try container.decodeIfPresent(String.self, forKey: .accessibilityIdentifier)
|
||||||
text = try container.decode(String.self, forKey: .text)
|
text = try container.decode(String.self, forKey: .text)
|
||||||
if let foundTextColor = try container.decodeIfPresent(Color.self, forKey: .textColor) {
|
|
||||||
textColor = .custom(foundTextColor.uiColor)
|
|
||||||
}
|
|
||||||
accessibilityText = try container.decodeIfPresent(String.self, forKey: .accessibilityText)
|
accessibilityText = try container.decodeIfPresent(String.self, forKey: .accessibilityText)
|
||||||
fillColor = try container.decodeIfPresent(Badge.FillColor.self, forKey: .fillColor) ?? .red
|
|
||||||
|
//look for a textColor
|
||||||
|
if let textColor = try container.decodeIfPresent(Color.self, forKey: .textColor) {
|
||||||
|
textColorStyle = .custom(textColor.uiColor)
|
||||||
|
}
|
||||||
|
|
||||||
|
//look for a style
|
||||||
|
fillColorStyle = try container.decodeIfPresent(Badge.FillColor.self, forKey: .fillColorStyle) ?? .red
|
||||||
|
|
||||||
|
//look for a color and set the style
|
||||||
|
if let fillColor = try container.decodeIfPresent(Color.self, forKey: .fillColor) {
|
||||||
|
fillColorStyle = .custom(fillColor.uiColor)
|
||||||
|
}
|
||||||
surface = try container.decodeIfPresent(Surface.self, forKey: .surface) ?? .light
|
surface = try container.decodeIfPresent(Surface.self, forKey: .surface) ?? .light
|
||||||
numberOfLines = try container.decodeIfPresent(Int.self, forKey: .numberOfLines) ?? 1
|
numberOfLines = try container.decodeIfPresent(Int.self, forKey: .numberOfLines) ?? 1
|
||||||
maxWidth = try container.decodeIfPresent(CGFloat.self, forKey: .maxWidth)
|
maxWidth = try container.decodeIfPresent(CGFloat.self, forKey: .maxWidth)
|
||||||
@ -55,11 +67,11 @@ open class BadgeModel: MoleculeModelProtocol {
|
|||||||
try container.encode(text, forKey: .text)
|
try container.encode(text, forKey: .text)
|
||||||
try container.encode(accessibilityText, forKey: .accessibilityText)
|
try container.encode(accessibilityText, forKey: .accessibilityText)
|
||||||
try container.encodeIfPresent(accessibilityIdentifier, forKey: .accessibilityIdentifier)
|
try container.encodeIfPresent(accessibilityIdentifier, forKey: .accessibilityIdentifier)
|
||||||
try container.encode(fillColor, forKey: .fillColor)
|
|
||||||
try container.encode(surface, forKey: .surface)
|
try container.encode(surface, forKey: .surface)
|
||||||
try container.encode(numberOfLines, forKey: .numberOfLines)
|
try container.encode(numberOfLines, forKey: .numberOfLines)
|
||||||
try container.encodeIfPresent(maxWidth, forKey: .maxWidth)
|
try container.encodeIfPresent(maxWidth, forKey: .maxWidth)
|
||||||
switch textColor {
|
try container.encode(fillColorStyle, forKey: .fillColorStyle)
|
||||||
|
switch textColorStyle {
|
||||||
case .custom(let color):
|
case .custom(let color):
|
||||||
try container.encode(Color(uiColor: color), forKey: .textColor)
|
try container.encode(Color(uiColor: color), forKey: .textColor)
|
||||||
default:
|
default:
|
||||||
@ -70,7 +82,8 @@ open class BadgeModel: MoleculeModelProtocol {
|
|||||||
public func isEqual(to model: any ModelComparisonProtocol) -> Bool {
|
public func isEqual(to model: any ModelComparisonProtocol) -> Bool {
|
||||||
guard let model = model as? BadgeModel else { return false }
|
guard let model = model as? BadgeModel else { return false }
|
||||||
return self.backgroundColor == model.backgroundColor
|
return self.backgroundColor == model.backgroundColor
|
||||||
&& self.fillColor == model.fillColor
|
&& self.fillColorStyle == model.fillColorStyle
|
||||||
|
&& self.textColorStyle == model.textColorStyle
|
||||||
&& self.numberOfLines == model.numberOfLines
|
&& self.numberOfLines == model.numberOfLines
|
||||||
&& self.text == model.text
|
&& self.text == model.text
|
||||||
&& self.surface == model.surface
|
&& self.surface == model.surface
|
||||||
|
|||||||
@ -107,15 +107,15 @@ import UIKit
|
|||||||
// configure attributed string for progress percentage.
|
// configure attributed string for progress percentage.
|
||||||
let attributedString = NSMutableAttributedString(string: String(percent) + "%")
|
let attributedString = NSMutableAttributedString(string: String(percent) + "%")
|
||||||
// percent value
|
// percent value
|
||||||
attributedString.setAttributes([NSAttributedString.Key.font: MFStyler.fontBoldTitleLarge()], range: NSMakeRange(0, percentLen))
|
attributedString.setAttributes([NSAttributedString.Key.font: Styler.Font.BoldTitleXLarge], range: NSMakeRange(0, percentLen))
|
||||||
// % symbol
|
// % symbol
|
||||||
attributedString.setAttributes([NSAttributedString.Key.font: MFStyler.fontBoldBodyLarge()], range: NSMakeRange(percentLen, 1))
|
attributedString.setAttributes([NSAttributedString.Key.font: Styler.Font.RegularMicro], range: NSMakeRange(percentLen, 1))
|
||||||
|
|
||||||
// show progress percentage in a text layer
|
// show progress percentage in a text layer
|
||||||
let width = viewWidth
|
let width = viewWidth
|
||||||
let height = width
|
let height = width
|
||||||
labelLayer.string = attributedString
|
labelLayer.string = attributedString
|
||||||
labelLayer.frame = CGRectMake((width - CGFloat(percentLen * 20))/2, (height - 30)/2, 60, 30)
|
labelLayer.frame = CGRectMake((width - CGFloat(percentLen * 20))/2, (height - 40)/2, 80, 40)
|
||||||
self.layer.addSublayer(labelLayer)
|
self.layer.addSublayer(labelLayer)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -94,8 +94,8 @@ open class TileletModel: TileContainerBaseModel<Tilelet.Padding, Tilelet>, Molec
|
|||||||
public func badgeModel() -> Tilelet.BadgeModel? {
|
public func badgeModel() -> Tilelet.BadgeModel? {
|
||||||
guard let badge else { return nil }
|
guard let badge else { return nil }
|
||||||
return .init(text: badge.text,
|
return .init(text: badge.text,
|
||||||
textColor: badge.textColor,
|
textColor: badge.textColorStyle,
|
||||||
fillColor: badge.fillColor,
|
fillColor: badge.fillColorStyle,
|
||||||
surface: badge.surface,
|
surface: badge.surface,
|
||||||
numberOfLines: badge.numberOfLines,
|
numberOfLines: badge.numberOfLines,
|
||||||
maxWidth: badge.maxWidth
|
maxWidth: badge.maxWidth
|
||||||
|
|||||||
@ -294,49 +294,40 @@ extension VDS.TitleLockup.TextColor: Codable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
extension VDS.Badge.FillColor: Codable {
|
extension VDS.Badge.FillColor: Codable {
|
||||||
enum CodingKeys: String, CodingKey {
|
|
||||||
case type
|
|
||||||
case color
|
|
||||||
}
|
|
||||||
|
|
||||||
enum CustomColorType: String, Codable {
|
|
||||||
case red, yellow, green, orange, blue, black, white
|
|
||||||
case custom
|
|
||||||
}
|
|
||||||
|
|
||||||
public init(from decoder: Decoder) throws {
|
public init(from decoder: Decoder) throws {
|
||||||
let container = try decoder.container(keyedBy: CodingKeys.self)
|
let container = try decoder.singleValueContainer()
|
||||||
let type = try container.decode(CustomColorType.self, forKey: .type)
|
let type = try container.decode(String.self)
|
||||||
|
|
||||||
switch type {
|
switch type {
|
||||||
case .red:
|
case "red":
|
||||||
self = .red
|
self = .red
|
||||||
case .yellow:
|
case "yellow":
|
||||||
self = .yellow
|
self = .yellow
|
||||||
case .green:
|
case "green":
|
||||||
self = .green
|
self = .green
|
||||||
case .orange:
|
case "orange":
|
||||||
self = .orange
|
self = .orange
|
||||||
case .blue:
|
case "blue":
|
||||||
self = .blue
|
self = .blue
|
||||||
case .black:
|
case "black":
|
||||||
self = .black
|
self = .black
|
||||||
case .white:
|
case "white":
|
||||||
self = .white
|
self = .white
|
||||||
case .custom:
|
default:
|
||||||
let color = try container.decode(Color.self, forKey: .color)
|
if let color = try? Color(from: decoder) {
|
||||||
self = .custom(color.uiColor)
|
self = .custom(color.uiColor)
|
||||||
|
} else {
|
||||||
|
self = .custom(UIColor(hexString: type))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func encode(to encoder: Encoder) throws {
|
public func encode(to encoder: Encoder) throws {
|
||||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
var container = encoder.singleValueContainer()
|
||||||
switch self {
|
switch self {
|
||||||
case .custom(let color):
|
case .custom(let value):
|
||||||
try container.encode(CustomColorType.custom.rawValue, forKey: .type)
|
try container.encode(Color(uiColor: value))
|
||||||
try container.encode(Color(uiColor: color), forKey: .color)
|
|
||||||
default:
|
default:
|
||||||
try container.encode("\(self)", forKey: .type)
|
try container.encode(String(reflecting: self))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -52,6 +52,9 @@ public class HeadersH1ButtonModel: HeaderModel, MoleculeModelProtocol, ParentMol
|
|||||||
if titleLockup.subTitle?.fontStyle == nil {
|
if titleLockup.subTitle?.fontStyle == nil {
|
||||||
titleLockup.subTitle?.fontStyle = Styler.Font.RegularTitleMedium
|
titleLockup.subTitle?.fontStyle = Styler.Font.RegularTitleMedium
|
||||||
}
|
}
|
||||||
|
if titleLockup.title.accessibilityTraits == nil {
|
||||||
|
titleLockup.title.accessibilityTraits = [.header]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
|
|||||||
@ -31,6 +31,9 @@ public class HeadersH1NoButtonsBodyTextModel: HeaderModel, MoleculeModelProtocol
|
|||||||
if titleLockup.subTitle?.fontStyle == nil {
|
if titleLockup.subTitle?.fontStyle == nil {
|
||||||
titleLockup.subTitle?.fontStyle = Styler.Font.RegularTitleMedium
|
titleLockup.subTitle?.fontStyle = Styler.Font.RegularTitleMedium
|
||||||
}
|
}
|
||||||
|
if titleLockup.title.accessibilityTraits == nil {
|
||||||
|
titleLockup.title.accessibilityTraits = [.header]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
|
|||||||
@ -47,18 +47,15 @@ public class HeadersH2ButtonsModel: HeaderModel, MoleculeModelProtocol, ParentMo
|
|||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
|
|
||||||
public override func setDefaults() {
|
public override func setDefaults() {
|
||||||
if topPadding == nil {
|
|
||||||
topPadding = Padding.Component.VerticalMarginSpacing
|
|
||||||
}
|
|
||||||
if bottomPadding == nil {
|
|
||||||
bottomPadding = Padding.Component.VerticalMarginSpacing
|
|
||||||
}
|
|
||||||
if titleLockup.title.fontStyle == nil {
|
if titleLockup.title.fontStyle == nil {
|
||||||
titleLockup.title.fontStyle = Styler.Font.RegularTitleXLarge
|
titleLockup.title.fontStyle = Styler.Font.RegularTitleXLarge
|
||||||
}
|
}
|
||||||
if titleLockup.subTitle?.fontStyle == nil {
|
if titleLockup.subTitle?.fontStyle == nil {
|
||||||
titleLockup.subTitle?.fontStyle = Styler.Font.RegularTitleMedium
|
titleLockup.subTitle?.fontStyle = Styler.Font.RegularTitleMedium
|
||||||
}
|
}
|
||||||
|
if titleLockup.title.accessibilityTraits == nil {
|
||||||
|
titleLockup.title.accessibilityTraits = [.header]
|
||||||
|
}
|
||||||
super.setDefaults()
|
super.setDefaults()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -42,18 +42,15 @@ public class HeadersH2CaretLinkModel: HeaderModel, MoleculeModelProtocol, Parent
|
|||||||
// MARK: - Methods
|
// MARK: - Methods
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
public override func setDefaults() {
|
public override func setDefaults() {
|
||||||
if topPadding == nil {
|
|
||||||
topPadding = Padding.Component.VerticalMarginSpacing
|
|
||||||
}
|
|
||||||
if bottomPadding == nil {
|
|
||||||
bottomPadding = Padding.Component.VerticalMarginSpacing
|
|
||||||
}
|
|
||||||
if titleLockup.title.fontStyle == nil {
|
if titleLockup.title.fontStyle == nil {
|
||||||
titleLockup.title.fontStyle = Styler.Font.RegularTitleXLarge
|
titleLockup.title.fontStyle = Styler.Font.RegularTitleXLarge
|
||||||
}
|
}
|
||||||
if titleLockup.subTitle?.fontStyle == nil {
|
if titleLockup.subTitle?.fontStyle == nil {
|
||||||
titleLockup.subTitle?.fontStyle = Styler.Font.RegularTitleMedium
|
titleLockup.subTitle?.fontStyle = Styler.Font.RegularTitleMedium
|
||||||
}
|
}
|
||||||
|
if titleLockup.title.accessibilityTraits == nil {
|
||||||
|
titleLockup.title.accessibilityTraits = [.header]
|
||||||
|
}
|
||||||
super.setDefaults()
|
super.setDefaults()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -46,18 +46,15 @@ public class HeadersH2LinkModel: HeaderModel, ParentMoleculeModelProtocol {
|
|||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
|
|
||||||
public override func setDefaults() {
|
public override func setDefaults() {
|
||||||
if topPadding == nil {
|
if titleLockup.title.fontStyle == nil {
|
||||||
topPadding = Padding.Component.VerticalMarginSpacing
|
|
||||||
}
|
|
||||||
if bottomPadding == nil {
|
|
||||||
bottomPadding = Padding.Component.VerticalMarginSpacing
|
|
||||||
}
|
|
||||||
if titleLockup.title.fontStyle == nil {
|
|
||||||
titleLockup.title.fontStyle = Styler.Font.RegularTitleXLarge
|
titleLockup.title.fontStyle = Styler.Font.RegularTitleXLarge
|
||||||
}
|
}
|
||||||
if titleLockup.subTitle?.fontStyle == nil {
|
if titleLockup.subTitle?.fontStyle == nil {
|
||||||
titleLockup.subTitle?.fontStyle = Styler.Font.RegularTitleMedium
|
titleLockup.subTitle?.fontStyle = Styler.Font.RegularTitleMedium
|
||||||
}
|
}
|
||||||
|
if titleLockup.title.accessibilityTraits == nil {
|
||||||
|
titleLockup.title.accessibilityTraits = [.header]
|
||||||
|
}
|
||||||
super.setDefaults()
|
super.setDefaults()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -36,18 +36,15 @@ public class HeadersH2NoButtonsBodyTextModel: HeaderModel, MoleculeModelProtocol
|
|||||||
}
|
}
|
||||||
|
|
||||||
public override func setDefaults() {
|
public override func setDefaults() {
|
||||||
if topPadding == nil {
|
|
||||||
topPadding = Padding.Component.VerticalMarginSpacing
|
|
||||||
}
|
|
||||||
if bottomPadding == nil {
|
|
||||||
bottomPadding = Padding.Component.VerticalMarginSpacing
|
|
||||||
}
|
|
||||||
if titleLockup.title.fontStyle == nil {
|
if titleLockup.title.fontStyle == nil {
|
||||||
titleLockup.title.fontStyle = Styler.Font.RegularTitleXLarge
|
titleLockup.title.fontStyle = Styler.Font.RegularTitleXLarge
|
||||||
}
|
}
|
||||||
if titleLockup.subTitle?.fontStyle == nil {
|
if titleLockup.subTitle?.fontStyle == nil {
|
||||||
titleLockup.subTitle?.fontStyle = Styler.Font.RegularTitleMedium
|
titleLockup.subTitle?.fontStyle = Styler.Font.RegularTitleMedium
|
||||||
}
|
}
|
||||||
|
if titleLockup.title.accessibilityTraits == nil {
|
||||||
|
titleLockup.title.accessibilityTraits = [.header]
|
||||||
|
}
|
||||||
super.setDefaults()
|
super.setDefaults()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -57,12 +57,6 @@ public class HeadersH2PricingTwoRowsModel: HeaderModel, MoleculeModelProtocol, P
|
|||||||
// MARK: - Methods
|
// MARK: - Methods
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
public override func setDefaults() {
|
public override func setDefaults() {
|
||||||
if topPadding == nil {
|
|
||||||
topPadding = Padding.Component.VerticalMarginSpacing
|
|
||||||
}
|
|
||||||
if bottomPadding == nil {
|
|
||||||
bottomPadding = Padding.Component.VerticalMarginSpacing
|
|
||||||
}
|
|
||||||
if headline.accessibilityTraits == nil {
|
if headline.accessibilityTraits == nil {
|
||||||
headline.accessibilityTraits = .header
|
headline.accessibilityTraits = .header
|
||||||
}
|
}
|
||||||
|
|||||||
@ -47,18 +47,15 @@ public class HeadersH2TinyButtonModel: HeaderModel, MoleculeModelProtocol, Paren
|
|||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
|
|
||||||
public override func setDefaults() {
|
public override func setDefaults() {
|
||||||
if topPadding == nil {
|
|
||||||
topPadding = Padding.Component.VerticalMarginSpacing
|
|
||||||
}
|
|
||||||
if bottomPadding == nil {
|
|
||||||
bottomPadding = Padding.Component.VerticalMarginSpacing
|
|
||||||
}
|
|
||||||
if titleLockup.title.fontStyle == nil {
|
if titleLockup.title.fontStyle == nil {
|
||||||
titleLockup.title.fontStyle = Styler.Font.RegularTitleXLarge
|
titleLockup.title.fontStyle = Styler.Font.RegularTitleXLarge
|
||||||
}
|
}
|
||||||
if titleLockup.subTitle?.fontStyle == nil {
|
if titleLockup.subTitle?.fontStyle == nil {
|
||||||
titleLockup.subTitle?.fontStyle = Styler.Font.RegularTitleMedium
|
titleLockup.subTitle?.fontStyle = Styler.Font.RegularTitleMedium
|
||||||
}
|
}
|
||||||
|
if titleLockup.title.accessibilityTraits == nil {
|
||||||
|
titleLockup.title.accessibilityTraits = [.header]
|
||||||
|
}
|
||||||
super.setDefaults()
|
super.setDefaults()
|
||||||
button.style = .secondary
|
button.style = .secondary
|
||||||
button.size = .small
|
button.size = .small
|
||||||
|
|||||||
@ -15,7 +15,7 @@ import Foundation
|
|||||||
//-----------------------------------------------------
|
//-----------------------------------------------------
|
||||||
|
|
||||||
public var stack: Stack<StackModel>
|
public var stack: Stack<StackModel>
|
||||||
public let headline = Label(fontStyle: .BoldTitleMedium)
|
public let headline = Label(fontStyle: .BoldTitleLarge)
|
||||||
public let body = Label(fontStyle: .RegularBodySmall)
|
public let body = Label(fontStyle: .RegularBodySmall)
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -24,7 +24,7 @@ import Foundation
|
|||||||
|
|
||||||
public override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
|
public override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
|
||||||
stack = Stack<StackModel>.createStack(with: [(view: headline, model: StackItemModel(horizontalAlignment: .leading)),
|
stack = Stack<StackModel>.createStack(with: [(view: headline, model: StackItemModel(horizontalAlignment: .leading)),
|
||||||
(view: body, model: StackItemModel(spacing: 0, horizontalAlignment: .leading))],
|
(view: body, model: StackItemModel(spacing: 8, horizontalAlignment: .leading))],
|
||||||
axis: .vertical)
|
axis: .vertical)
|
||||||
super.init(style: style, reuseIdentifier: reuseIdentifier)
|
super.init(style: style, reuseIdentifier: reuseIdentifier)
|
||||||
}
|
}
|
||||||
@ -63,7 +63,7 @@ import Foundation
|
|||||||
|
|
||||||
open override func reset() {
|
open override func reset() {
|
||||||
super.reset()
|
super.reset()
|
||||||
headline.setFontStyle(.BoldTitleMedium)
|
headline.setFontStyle(.BoldTitleLarge)
|
||||||
body.setFontStyle(.RegularBodySmall)
|
body.setFontStyle(.RegularBodySmall)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -47,6 +47,9 @@ public class ListOneColumnTextWithWhitespaceDividerShortModel: ListItemModel, Mo
|
|||||||
|
|
||||||
override public func setDefaults() {
|
override public func setDefaults() {
|
||||||
style = .shortDivider
|
style = .shortDivider
|
||||||
|
if headline.accessibilityTraits == nil {
|
||||||
|
headline.accessibilityTraits = [.header]
|
||||||
|
}
|
||||||
super.setDefaults()
|
super.setDefaults()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -15,7 +15,7 @@ import Foundation
|
|||||||
//-----------------------------------------------------
|
//-----------------------------------------------------
|
||||||
|
|
||||||
public var stack: Stack<StackModel>
|
public var stack: Stack<StackModel>
|
||||||
public let headline = Label(fontStyle: .BoldTitleMedium)
|
public let headline = Label(fontStyle: .BoldTitleLarge)
|
||||||
public let body = Label(fontStyle: .RegularBodySmall)
|
public let body = Label(fontStyle: .RegularBodySmall)
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -24,7 +24,7 @@ import Foundation
|
|||||||
|
|
||||||
public override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
|
public override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
|
||||||
stack = Stack<StackModel>.createStack(with: [(view: headline, model: StackItemModel(horizontalAlignment: .leading)),
|
stack = Stack<StackModel>.createStack(with: [(view: headline, model: StackItemModel(horizontalAlignment: .leading)),
|
||||||
(view: body, model: StackItemModel(spacing: 0, horizontalAlignment: .leading))],
|
(view: body, model: StackItemModel(spacing: 8, horizontalAlignment: .leading))],
|
||||||
axis: .vertical)
|
axis: .vertical)
|
||||||
super.init(style: style, reuseIdentifier: reuseIdentifier)
|
super.init(style: style, reuseIdentifier: reuseIdentifier)
|
||||||
}
|
}
|
||||||
@ -62,7 +62,7 @@ import Foundation
|
|||||||
|
|
||||||
open override func reset() {
|
open override func reset() {
|
||||||
super.reset()
|
super.reset()
|
||||||
headline.setFontStyle(.BoldTitleMedium)
|
headline.setFontStyle(.BoldTitleLarge)
|
||||||
body.setFontStyle(.RegularBodySmall)
|
body.setFontStyle(.RegularBodySmall)
|
||||||
accessibilityLabel = nil
|
accessibilityLabel = nil
|
||||||
}
|
}
|
||||||
|
|||||||
@ -47,6 +47,9 @@ public class ListOneColumnTextWithWhitespaceDividerTallModel: ListItemModel, Mol
|
|||||||
|
|
||||||
override public func setDefaults() {
|
override public func setDefaults() {
|
||||||
style = .tallDivider
|
style = .tallDivider
|
||||||
|
if headline.accessibilityTraits == nil {
|
||||||
|
headline.accessibilityTraits = [.header]
|
||||||
|
}
|
||||||
super.setDefaults()
|
super.setDefaults()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -72,9 +72,9 @@ import MVMCore
|
|||||||
case .standard:
|
case .standard:
|
||||||
set(topPadding: Padding.Component.VerticalMarginSpacing, bottomPadding: Padding.Component.VerticalMarginSpacing)
|
set(topPadding: Padding.Component.VerticalMarginSpacing, bottomPadding: Padding.Component.VerticalMarginSpacing)
|
||||||
case .shortDivider:
|
case .shortDivider:
|
||||||
set(topPadding: Padding.Component.LargeVerticalMarginSpacing, bottomPadding: Padding.Four)
|
set(topPadding: Padding.Component.LargeVerticalMarginSpacing, bottomPadding: Padding.Five)
|
||||||
case .tallDivider:
|
case .tallDivider:
|
||||||
set(topPadding: Padding.Twelve, bottomPadding: Padding.Four)
|
set(topPadding: Padding.Twelve, bottomPadding: Padding.Five)
|
||||||
case .sectionFooter:
|
case .sectionFooter:
|
||||||
set(topPadding: Padding.Component.VerticalMarginSpacing, bottomPadding: 0)
|
set(topPadding: Padding.Component.VerticalMarginSpacing, bottomPadding: 0)
|
||||||
case ListItemStyle.none:
|
case ListItemStyle.none:
|
||||||
|
|||||||
@ -37,7 +37,8 @@ import VDSCoreTokens
|
|||||||
verticalStack.alignment = .fill
|
verticalStack.alignment = .fill
|
||||||
verticalStack.distribution = .fill
|
verticalStack.distribution = .fill
|
||||||
addSubview(verticalStack)
|
addSubview(verticalStack)
|
||||||
NSLayoutConstraint.constraintPinSubview(verticalStack, pinTop: true, topConstant: 0, pinBottom: true, bottomConstant: 0, pinLeft: true, leftConstant: 0, pinRight: true, rightConstant: 0)
|
verticalStack.topAnchor.constraint(equalTo: safeAreaLayoutGuide.topAnchor).isActive = true
|
||||||
|
NSLayoutConstraint.constraintPinSubview(verticalStack, pinTop: false, topConstant: 0, pinBottom: true, bottomConstant: 0, pinLeft: true, leftConstant: 0, pinRight: true, rightConstant: 0)
|
||||||
|
|
||||||
reset()
|
reset()
|
||||||
subscribeForNotifications()
|
subscribeForNotifications()
|
||||||
@ -223,6 +224,10 @@ extension CollapsableNotification: StatusBarUI {
|
|||||||
topView.label.textColor.getWhite(&greyScale, alpha: nil)
|
topView.label.textColor.getWhite(&greyScale, alpha: nil)
|
||||||
return (color, greyScale > 0.5 ? .lightContent : .default)
|
return (color, greyScale > 0.5 ? .lightContent : .default)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public func shouldUseSafeAreaLayoutGuide() -> Bool {
|
||||||
|
return false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension CollapsableNotification: AccessibilityProtocol {
|
extension CollapsableNotification: AccessibilityProtocol {
|
||||||
|
|||||||
@ -332,7 +332,7 @@ open class Carousel: View {
|
|||||||
|
|
||||||
addSubview(pagingView)
|
addSubview(pagingView)
|
||||||
pagingView.centerXAnchor.constraint(equalTo: collectionView.centerXAnchor).isActive = true
|
pagingView.centerXAnchor.constraint(equalTo: collectionView.centerXAnchor).isActive = true
|
||||||
collectionView.bottomAnchor.constraint(equalTo: pagingView.centerYAnchor, constant: position).isActive = true
|
collectionView.safeAreaLayoutGuide.bottomAnchor.constraint(equalTo: pagingView.centerYAnchor, constant: position).isActive = true
|
||||||
pagingBottomPin = bottomAnchor.constraint(greaterThanOrEqualTo: pagingView.bottomAnchor)
|
pagingBottomPin = bottomAnchor.constraint(greaterThanOrEqualTo: pagingView.bottomAnchor)
|
||||||
pagingBottomPin?.isActive = true
|
pagingBottomPin?.isActive = true
|
||||||
bottomPin = bottomAnchor.constraint(equalTo: collectionView.bottomAnchor)
|
bottomPin = bottomAnchor.constraint(equalTo: collectionView.bottomAnchor)
|
||||||
|
|||||||
@ -19,4 +19,10 @@ public protocol ContainerModelProtocol {
|
|||||||
var useVerticalMargins: Bool? { get set }
|
var useVerticalMargins: Bool? { get set }
|
||||||
var topPadding: CGFloat? { get set }
|
var topPadding: CGFloat? { get set }
|
||||||
var bottomPadding: CGFloat? { get set }
|
var bottomPadding: CGFloat? { get set }
|
||||||
|
|
||||||
|
var useSafeAreaInsets: Bool? { get set }
|
||||||
|
}
|
||||||
|
|
||||||
|
public extension ContainerModelProtocol {
|
||||||
|
var useSafeAreaInsets: Bool? { get { return nil } set {} }
|
||||||
}
|
}
|
||||||
|
|||||||
@ -16,6 +16,7 @@
|
|||||||
public var header: MoleculeModelProtocol?
|
public var header: MoleculeModelProtocol?
|
||||||
public var anchorFooter: Bool = false
|
public var anchorFooter: Bool = false
|
||||||
public var footer: MoleculeModelProtocol?
|
public var footer: MoleculeModelProtocol?
|
||||||
|
public var fullScreen: Bool = false
|
||||||
|
|
||||||
public override var rootMolecules: [MoleculeModelProtocol] {
|
public override var rootMolecules: [MoleculeModelProtocol] {
|
||||||
[navigationBar, header, footer].compactMap { $0 }
|
[navigationBar, header, footer].compactMap { $0 }
|
||||||
@ -50,6 +51,7 @@
|
|||||||
case header
|
case header
|
||||||
case anchorFooter
|
case anchorFooter
|
||||||
case footer
|
case footer
|
||||||
|
case fullScreen
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -66,6 +68,7 @@
|
|||||||
anchorFooter = anchor
|
anchorFooter = anchor
|
||||||
}
|
}
|
||||||
footer = try typeContainer.decodeModelIfPresent(codingKey: .footer)
|
footer = try typeContainer.decodeModelIfPresent(codingKey: .footer)
|
||||||
|
fullScreen = try typeContainer.decodeIfPresent(Bool.self, forKey: .fullScreen) ?? false
|
||||||
try super.init(from: decoder)
|
try super.init(from: decoder)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -76,6 +79,7 @@
|
|||||||
try container.encodeModelIfPresent(header, forKey: .header)
|
try container.encodeModelIfPresent(header, forKey: .header)
|
||||||
try container.encodeIfPresent(anchorFooter, forKey: .anchorFooter)
|
try container.encodeIfPresent(anchorFooter, forKey: .anchorFooter)
|
||||||
try container.encodeModelIfPresent(footer, forKey: .footer)
|
try container.encodeModelIfPresent(footer, forKey: .footer)
|
||||||
|
try container.encodeIfPresent(fullScreen, forKey: .fullScreen)
|
||||||
}
|
}
|
||||||
|
|
||||||
public override func isEqual(to model: any ModelComparisonProtocol) -> Bool {
|
public override func isEqual(to model: any ModelComparisonProtocol) -> Bool {
|
||||||
|
|||||||
@ -18,9 +18,24 @@ import UIKit
|
|||||||
return try parseTemplate(loadObject: loadObject)
|
return try parseTemplate(loadObject: loadObject)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
open override func setContentHeightConstraint() {
|
||||||
|
// The height is used to keep the bottom view at the bottom.
|
||||||
|
if let contentView = contentView, let scrollView = scrollView {
|
||||||
|
let anchor = templateModel?.fullScreen == true ? scrollView.heightAnchor : scrollView.safeAreaLayoutGuide.heightAnchor
|
||||||
|
heightConstraint = contentView.heightAnchor.constraint(equalTo: anchor, multiplier: 1.0)
|
||||||
|
heightConstraint?.priority = UILayoutPriority.defaultLow
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
open override func updateUI(for molecules: [MoleculeModelProtocol]? = nil) {
|
open override func updateUI(for molecules: [MoleculeModelProtocol]? = nil) {
|
||||||
topViewOutsideOfScroll = templateModel?.anchorHeader ?? false
|
topViewOutsideOfScroll = templateModel?.anchorHeader ?? false
|
||||||
bottomViewOutsideOfScroll = templateModel?.anchorFooter ?? false
|
bottomViewOutsideOfScroll = templateModel?.anchorFooter ?? false
|
||||||
|
|
||||||
|
// Check if we are respecting the safe areas or not.
|
||||||
|
scrollView.contentInsetAdjustmentBehavior = templateModel?.fullScreen == true ? .never : .automatic
|
||||||
|
heightConstraint?.isActive = false
|
||||||
|
setContentHeightConstraint()
|
||||||
|
|
||||||
super.updateUI(for: molecules)
|
super.updateUI(for: molecules)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -55,6 +55,6 @@ open class CollectionView: UICollectionView, MVMCoreViewProtocol {
|
|||||||
showsVerticalScrollIndicator = false
|
showsVerticalScrollIndicator = false
|
||||||
backgroundColor = .clear
|
backgroundColor = .clear
|
||||||
isAccessibilityElement = false
|
isAccessibilityElement = false
|
||||||
contentInsetAdjustmentBehavior = .always
|
contentInsetAdjustmentBehavior = .never
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -65,6 +65,7 @@ open class CollectionViewCell: UICollectionViewCell, MoleculeViewProtocol, MVMCo
|
|||||||
open func updateView(_ size: CGFloat) {
|
open func updateView(_ size: CGFloat) {
|
||||||
if let model = model as? ContainerModelProtocol {
|
if let model = model as? ContainerModelProtocol {
|
||||||
containerHelper.updateViewMargins(contentView, model: model, size: size)
|
containerHelper.updateViewMargins(contentView, model: model, size: size)
|
||||||
|
contentView.insetsLayoutMarginsFromSafeArea = model.useSafeAreaInsets == true
|
||||||
}
|
}
|
||||||
(molecule as? MVMCoreViewProtocol)?.updateView(size)
|
(molecule as? MVMCoreViewProtocol)?.updateView(size)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -117,6 +117,8 @@ import UIKit
|
|||||||
contentView.directionalLayoutMargins = directionalLayoutMargins
|
contentView.directionalLayoutMargins = directionalLayoutMargins
|
||||||
}
|
}
|
||||||
|
|
||||||
|
contentView.insetsLayoutMarginsFromSafeArea = listItemModel?.useSafeAreaInsets == true
|
||||||
|
|
||||||
topSeparatorView?.updateView(size)
|
topSeparatorView?.updateView(size)
|
||||||
bottomSeparatorView?.updateView(size)
|
bottomSeparatorView?.updateView(size)
|
||||||
(molecule as? MVMCoreViewProtocol)?.updateView(size)
|
(molecule as? MVMCoreViewProtocol)?.updateView(size)
|
||||||
|
|||||||
@ -42,6 +42,10 @@ open class ThreeLayerViewController: ProgrammaticScrollViewController, RotorView
|
|||||||
|
|
||||||
open override func loadView() {
|
open override func loadView() {
|
||||||
super.loadView()
|
super.loadView()
|
||||||
|
setContentHeightConstraint()
|
||||||
|
}
|
||||||
|
|
||||||
|
open func setContentHeightConstraint() {
|
||||||
// The height is used to keep the bottom view at the bottom.
|
// The height is used to keep the bottom view at the bottom.
|
||||||
if let contentView = contentView, let scrollView = scrollView {
|
if let contentView = contentView, let scrollView = scrollView {
|
||||||
heightConstraint = contentView.heightAnchor.constraint(equalTo: scrollView.safeAreaLayoutGuide.heightAnchor, multiplier: 1.0)
|
heightConstraint = contentView.heightAnchor.constraint(equalTo: scrollView.safeAreaLayoutGuide.heightAnchor, multiplier: 1.0)
|
||||||
|
|||||||
@ -15,6 +15,9 @@ import MVMCore
|
|||||||
public protocol StatusBarUI {
|
public protocol StatusBarUI {
|
||||||
/// Returns the background color of the status bar view and the style of the status bar.
|
/// Returns the background color of the status bar view and the style of the status bar.
|
||||||
func getStatusBarUI() -> (color: UIColor, style: UIStatusBarStyle)
|
func getStatusBarUI() -> (color: UIColor, style: UIStatusBarStyle)
|
||||||
|
|
||||||
|
/// Returns if this view should use the safe area layout guide or not (be below the status bar or behind the status bar)
|
||||||
|
func shouldUseSafeAreaLayoutGuide() -> Bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// Navigation bar update functions
|
// Navigation bar update functions
|
||||||
@ -230,8 +233,7 @@ public extension MVMCoreUISplitViewController {
|
|||||||
func setStatusBar(for viewController: UIViewController?) {
|
func setStatusBar(for viewController: UIViewController?) {
|
||||||
let viewController = viewController as? MVMCoreUIDetailViewProtocol
|
let viewController = viewController as? MVMCoreUIDetailViewProtocol
|
||||||
let backgroundColor = viewController?.defaultStatusBarBackgroundColor?() ??
|
let backgroundColor = viewController?.defaultStatusBarBackgroundColor?() ??
|
||||||
navigationController?.navigationBar.standardAppearance.backgroundColor ??
|
navigationController?.navigationBar.standardAppearance.backgroundColor
|
||||||
statusBarView?.backgroundColor
|
|
||||||
|
|
||||||
let style = viewController?.defaultStatusBarStyle?() ??
|
let style = viewController?.defaultStatusBarStyle?() ??
|
||||||
getStatusBarStyle(for: backgroundColor)
|
getStatusBarStyle(for: backgroundColor)
|
||||||
|
|||||||
@ -43,9 +43,6 @@ typedef NS_ENUM(NSInteger, MFNumberOfDrawers) {
|
|||||||
// Reference to the top alert view
|
// Reference to the top alert view
|
||||||
@property (nullable, weak, nonatomic) UIView *topAlertView;
|
@property (nullable, weak, nonatomic) UIView *topAlertView;
|
||||||
|
|
||||||
// Reference to the status bar view
|
|
||||||
@property (nullable, weak, nonatomic) UIView *statusBarView;
|
|
||||||
|
|
||||||
// References to the current navigation item settings.
|
// References to the current navigation item settings.
|
||||||
@property (nonatomic, readonly) BOOL leftPanelIsAccessible;
|
@property (nonatomic, readonly) BOOL leftPanelIsAccessible;
|
||||||
@property (nonatomic, readonly) BOOL rightPanelIsAccessible;
|
@property (nonatomic, readonly) BOOL rightPanelIsAccessible;
|
||||||
@ -183,10 +180,4 @@ typedef NS_ENUM(NSInteger, MFNumberOfDrawers) {
|
|||||||
/// Updates the status bar with the given style and background color
|
/// Updates the status bar with the given style and background color
|
||||||
- (void)setStatusBarBackgroundColor:(nullable UIColor *)backgroundColor style:(UIStatusBarStyle)style;
|
- (void)setStatusBarBackgroundColor:(nullable UIColor *)backgroundColor style:(UIStatusBarStyle)style;
|
||||||
|
|
||||||
/// Shows the view under the status bar.
|
|
||||||
- (void)expandStatusBarView;
|
|
||||||
|
|
||||||
/// Hides the view under the status bar.
|
|
||||||
- (void)collapseStatusBarView;
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
@ -63,8 +63,6 @@ typedef NS_OPTIONS(NSInteger, MFExtendedDrawer) {
|
|||||||
@property (strong, nonatomic) NSNumber *transitionWidth;
|
@property (strong, nonatomic) NSNumber *transitionWidth;
|
||||||
|
|
||||||
@property (nonatomic) UIStatusBarStyle statusBarStyle;
|
@property (nonatomic) UIStatusBarStyle statusBarStyle;
|
||||||
@property (strong, nonatomic) NSLayoutConstraint *statusBarHeightConstraint;
|
|
||||||
@property (strong, nonatomic) NSLayoutConstraint *statusBarBottomConstraint;
|
|
||||||
|
|
||||||
// Dismisses any panel
|
// Dismisses any panel
|
||||||
- (void)dismissPanels:(id)sender;
|
- (void)dismissPanels:(id)sender;
|
||||||
@ -865,7 +863,6 @@ CGFloat const PanelAnimationDuration = 0.2;
|
|||||||
#pragma mark - Status Bar
|
#pragma mark - Status Bar
|
||||||
|
|
||||||
- (void)setStatusBarBackgroundColor:(UIColor *)backgroundColor style:(UIStatusBarStyle)style {
|
- (void)setStatusBarBackgroundColor:(UIColor *)backgroundColor style:(UIStatusBarStyle)style {
|
||||||
self.statusBarView.backgroundColor = backgroundColor;
|
|
||||||
self.statusBarStyle = style;
|
self.statusBarStyle = style;
|
||||||
|
|
||||||
// Triggers preferredStatusBarStyle
|
// Triggers preferredStatusBarStyle
|
||||||
@ -876,24 +873,6 @@ CGFloat const PanelAnimationDuration = 0.2;
|
|||||||
return self.statusBarStyle;
|
return self.statusBarStyle;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)expandStatusBarView {
|
|
||||||
__weak typeof(self) weakSelf = self;
|
|
||||||
[MVMCoreDispatchUtility performBlockOnMainThread:^{
|
|
||||||
weakSelf.statusBarBottomConstraint.active = YES;
|
|
||||||
weakSelf.statusBarHeightConstraint.active = NO;
|
|
||||||
[weakSelf.view layoutIfNeeded];
|
|
||||||
}];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)collapseStatusBarView {
|
|
||||||
__weak typeof(self) weakSelf = self;
|
|
||||||
[MVMCoreDispatchUtility performBlockOnMainThread:^{
|
|
||||||
weakSelf.statusBarBottomConstraint.active = NO;
|
|
||||||
weakSelf.statusBarHeightConstraint.active = YES;
|
|
||||||
[weakSelf.view layoutIfNeeded];
|
|
||||||
}];
|
|
||||||
}
|
|
||||||
|
|
||||||
#pragma mark - View Cyle
|
#pragma mark - View Cyle
|
||||||
|
|
||||||
- (void)loadView {
|
- (void)loadView {
|
||||||
@ -902,17 +881,6 @@ CGFloat const PanelAnimationDuration = 0.2;
|
|||||||
view.translatesAutoresizingMaskIntoConstraints = NO;
|
view.translatesAutoresizingMaskIntoConstraints = NO;
|
||||||
self.view = view;
|
self.view = view;
|
||||||
|
|
||||||
// Status bar
|
|
||||||
UIView *statusBarView = [MVMCoreUICommonViewsUtility commonView];
|
|
||||||
statusBarView.backgroundColor = [UIColor whiteColor];
|
|
||||||
[self.view addSubview:statusBarView];
|
|
||||||
[NSLayoutConstraint activateConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-0-[statusBarView]-0-|" options:NSLayoutFormatDirectionLeadingToTrailing metrics:nil views:NSDictionaryOfVariableBindings(statusBarView)]];
|
|
||||||
id topGuide = view.safeAreaLayoutGuide;
|
|
||||||
self.statusBarBottomConstraint = [NSLayoutConstraint constraintWithItem:statusBarView attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:topGuide attribute:NSLayoutAttributeTop multiplier:1.0 constant:0];
|
|
||||||
self.statusBarBottomConstraint.active = YES;
|
|
||||||
self.statusBarHeightConstraint = [statusBarView.heightAnchor constraintEqualToConstant:0];
|
|
||||||
self.statusBarView = statusBarView;
|
|
||||||
|
|
||||||
// Top Alert
|
// Top Alert
|
||||||
if (self.topAlertView) {
|
if (self.topAlertView) {
|
||||||
[self.view addSubview:self.topAlertView];
|
[self.view addSubview:self.topAlertView];
|
||||||
@ -954,9 +922,9 @@ CGFloat const PanelAnimationDuration = 0.2;
|
|||||||
|
|
||||||
if (self.topAlertView) {
|
if (self.topAlertView) {
|
||||||
UIView *topAlertView = self.topAlertView;
|
UIView *topAlertView = self.topAlertView;
|
||||||
[NSLayoutConstraint activateConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-0-[statusBarView]-0-[topAlertView]-0-[mainView]-0-[progressView]" options:NSLayoutFormatDirectionLeadingToTrailing metrics:nil views:NSDictionaryOfVariableBindings(statusBarView,topAlertView, mainView, progressView)]];
|
[NSLayoutConstraint activateConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-0-[topAlertView]-0-[mainView]-0-[progressView]" options:NSLayoutFormatDirectionLeadingToTrailing metrics:nil views:NSDictionaryOfVariableBindings(topAlertView, mainView, progressView)]];
|
||||||
} else {
|
} else {
|
||||||
[NSLayoutConstraint activateConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-0-[statusBarView]-0-[mainView]-0-[progressView]" options:NSLayoutFormatDirectionLeadingToTrailing metrics:nil views:NSDictionaryOfVariableBindings(statusBarView,mainView, progressView)]];
|
[NSLayoutConstraint activateConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-0-[mainView]-0-[progressView]" options:NSLayoutFormatDirectionLeadingToTrailing metrics:nil views:NSDictionaryOfVariableBindings(mainView, progressView)]];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add tabbar if we have it.
|
// Add tabbar if we have it.
|
||||||
|
|||||||
@ -64,6 +64,7 @@ open class Container: View, ContainerProtocol {
|
|||||||
super.updateView(size)
|
super.updateView(size)
|
||||||
(view as? MVMCoreViewProtocol)?.updateView(size)
|
(view as? MVMCoreViewProtocol)?.updateView(size)
|
||||||
containerHelper.updateViewMargins(self, model: containerModel, size: size)
|
containerHelper.updateViewMargins(self, model: containerModel, size: size)
|
||||||
|
insetsLayoutMarginsFromSafeArea = containerModel?.useSafeAreaInsets == true
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Will be called only once.
|
/// Will be called only once.
|
||||||
|
|||||||
@ -30,6 +30,8 @@ open class ContainerModel: ContainerModelProtocol, Codable, ModelComparisonProto
|
|||||||
|
|
||||||
public var cornerRadius: CGFloat?
|
public var cornerRadius: CGFloat?
|
||||||
|
|
||||||
|
public var useSafeAreaInsets: Bool?
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Keys
|
// MARK: - Keys
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -46,6 +48,7 @@ open class ContainerModel: ContainerModelProtocol, Codable, ModelComparisonProto
|
|||||||
case topPadding
|
case topPadding
|
||||||
case bottomPadding
|
case bottomPadding
|
||||||
case cornerRadius
|
case cornerRadius
|
||||||
|
case useSafeAreaInsets
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -101,6 +104,7 @@ open class ContainerModel: ContainerModelProtocol, Codable, ModelComparisonProto
|
|||||||
topPadding = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .topPadding)
|
topPadding = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .topPadding)
|
||||||
bottomPadding = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .bottomPadding)
|
bottomPadding = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .bottomPadding)
|
||||||
cornerRadius = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .cornerRadius)
|
cornerRadius = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .cornerRadius)
|
||||||
|
useSafeAreaInsets = try typeContainer.decodeIfPresent(Bool.self, forKey: .useSafeAreaInsets)
|
||||||
setDefaults()
|
setDefaults()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -117,6 +121,7 @@ open class ContainerModel: ContainerModelProtocol, Codable, ModelComparisonProto
|
|||||||
try container.encodeIfPresent(topPadding, forKey: .topPadding)
|
try container.encodeIfPresent(topPadding, forKey: .topPadding)
|
||||||
try container.encodeIfPresent(bottomPadding, forKey: .bottomPadding)
|
try container.encodeIfPresent(bottomPadding, forKey: .bottomPadding)
|
||||||
try container.encodeIfPresent(cornerRadius, forKey: .cornerRadius)
|
try container.encodeIfPresent(cornerRadius, forKey: .cornerRadius)
|
||||||
|
try container.encodeIfPresent(useSafeAreaInsets, forKey: .useSafeAreaInsets)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func isEqual(to model: any ModelComparisonProtocol) -> Bool {
|
public func isEqual(to model: any ModelComparisonProtocol) -> Bool {
|
||||||
|
|||||||
@ -32,7 +32,14 @@ extension NotificationContainerView: NotificationTransitionDelegateProtocol {
|
|||||||
public func show(notification: UIView) async {
|
public func show(notification: UIView) async {
|
||||||
currentNotificationView?.removeFromSuperview()
|
currentNotificationView?.removeFromSuperview()
|
||||||
addSubview(notification)
|
addSubview(notification)
|
||||||
NSLayoutConstraint.constraintPinSubview(toSuperview: notification)
|
if (notification as? StatusBarUI)?.shouldUseSafeAreaLayoutGuide() ?? true {
|
||||||
|
NSLayoutConstraint.activate([notification.topAnchor.constraint(equalTo: safeAreaLayoutGuide.topAnchor),
|
||||||
|
safeAreaLayoutGuide.bottomAnchor.constraint(equalTo: notification.bottomAnchor),
|
||||||
|
notification.leadingAnchor.constraint(equalTo: leadingAnchor),
|
||||||
|
trailingAnchor.constraint(equalTo: notification.trailingAnchor)])
|
||||||
|
} else {
|
||||||
|
NSLayoutConstraint.constraintPinSubview(toSuperview: notification)
|
||||||
|
}
|
||||||
currentNotificationView = notification
|
currentNotificationView = notification
|
||||||
|
|
||||||
if let conformer = notification as? MVMCoreViewProtocol {
|
if let conformer = notification as? MVMCoreViewProtocol {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user