Compare commits

..

21 Commits

Author SHA1 Message Date
Pfeil, Scott Robert
8212d7146c Merge branch 'bugfix/CXTDT-626224' into 'develop'
CXTDT-626224

### Summary
CXTDT-626224
MVA/iOS: Progress section has visual defects that need to be corrected.
Change :-  Number size should be: (font-size: 32px / line-height: 36px and “%” symbol size should be: font-size: 11px / line-height: 16px

### JIRA Ticket
https://onejira.verizon.com/browse/CXTDT-626224![Screenshot_2024-10-17_at_7.15.02_PM](/uploads/e89f367a09b23c230ab4f461320fc669/Screenshot_2024-10-17_at_7.15.02_PM.png)

![Screenshot_2024-10-17_at_7.15.33_PM](/uploads/a5055585223f4ab2697d1ce79f52d43b/Screenshot_2024-10-17_at_7.15.33_PM.png)

Co-authored-by: rajani kumari  Gupta <rajani.kumari.gupta@verizon.com>

See merge request https://gitlab.verizon.com/BPHV_MIPS/mvm_core_ui/-/merge_requests/1204
2024-10-21 13:10:53 +00:00
rajani kumari Gupta
5c280b7922 Fix comment 2024-10-21 14:28:34 +05:30
Pfeil, Scott Robert
1eed9ebb76 Merge branch 'feature/safe_area_insets' into 'develop'
Digital ACT192 story ONEAPP-11297 - Updating insets to allow for more...

### Summary
Updating insets to allow flexibility with the safe area

### JIRA Ticket
https://onejira.verizon.com/browse/ONEAPP-6673

Co-authored-by: Scott Pfeil <Scott.Pfeil3@verizonwireless.com>

See merge request https://gitlab.verizon.com/BPHV_MIPS/mvm_core_ui/-/merge_requests/1203
2024-10-17 15:30:33 +00:00
Scott Pfeil
a210b8da9b Remove Spacer 2024-10-17 09:34:50 -04:00
Scott Pfeil
44adc76dcb Digital ACT192 story ONEAPP-11297 - Updating insets to allow for more flexibility and edge using. Removing the status bar view because it is no longer used. 2024-10-17 09:04:31 -04:00
rajani kumari Gupta
eb4f741f1a CXTDT-626224
MVA/iOS: Progress section has visual defects that need to be corrected.
issue fixed :- Number size should be: (font-size: 32px / line-height: 36px and “%” symbol size should be: font-size: 11px / line-height: 16px
2024-10-17 17:47:24 +05:30
Bruce, Matt R
928c8c5b54 Merge branch 'bugfix/CXTDT-626309' into 'develop'
Digital ACT191 defect CXTDT-626309 - Updating fonts and spacing

### Summary
Fixes to the header component defaults.
https://docs.google.com/spreadsheets/d/1DqG_ZDxIseuVsEtRaQTVRC5mHME79Ksmhdj067jLNr4/edit?pli=1&gid=0#gid=0

### JIRA Ticket
https://onejira.verizon.com/browse/CXTDT-626309
https://onejira.verizon.com/browse/CXTDT-628092

Co-authored-by: Scott Pfeil <Scott.Pfeil3@verizonwireless.com>

See merge request https://gitlab.verizon.com/BPHV_MIPS/mvm_core_ui/-/merge_requests/1202
2024-10-16 16:34:13 +00:00
Scott Pfeil
2dd3a7dca8 Merge branch 'develop' of https://gitlab.verizon.com/BPHV_MIPS/mvm_core_ui into bugfix/CXTDT-626309 2024-10-16 12:31:28 -04:00
Scott Pfeil
7bed914dca Digital ACT191 defect CXTDT-626309 - Updating fonts and spacing
Digital ACT191 defect CXTDT-628092 - Fixing accessibility trait header default.
2024-10-16 10:53:16 -04:00
Pfeil, Scott Robert
fe5bd4a9ac Merge branch 'feature/CXTDT-624895-Badge-Color-Updates' into 'develop'
refactored badge text/fill color

### Summary
Fixed bug in how fillColor is set.

Co-authored-by: Matt Bruce <matt.bruce@verizon.com>

See merge request https://gitlab.verizon.com/BPHV_MIPS/mvm_core_ui/-/merge_requests/1200
2024-10-16 01:25:12 +00:00
Matt Bruce
7eb1a4ff4b redid the values
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
2024-10-15 16:57:37 -05:00
Matt Bruce
76b58ec88a using type now and not the old way.
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
2024-10-14 15:57:25 -05:00
Matt Bruce
4487f9b03b refactored badge text/fill color
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
2024-10-14 15:53:31 -05:00
Scott Pfeil
3a06f7b43e Digital ACT191 defect CXTDT-626309 - Update to default header h2 padding 2024-10-14 11:03:24 -04:00
Hedden, Kyle Matthew
f3e97ecfd4 Merge branch 'feature/CXTDT-624895-Badge-Color-Updates' into 'develop'
VDS - iOS Badge - Include ability to select custom color for Label and Background

### Summary
CXT - Defect TrackerCXTDT-624895
VDS - iOS Badge - Include ability to select custom color for Label and Background
### JIRA Ticket
https://onejira.verizon.com/browse/CXTDT-624895

Co-authored-by: Matt Bruce <matt.bruce@verizon.com>

See merge request https://gitlab.verizon.com/BPHV_MIPS/mvm_core_ui/-/merge_requests/1199
2024-10-09 13:04:36 +00:00
Matt Bruce
f66dc66818 undid comment
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
2024-10-08 09:18:23 -05:00
Matt Bruce
bf2a3e7e5b removed isDark
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
2024-10-08 09:10:04 -05:00
Matt Bruce
54b50bffd3 added fillColor codable
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
2024-10-08 09:08:30 -05:00
Matt Bruce
3b2dc2d447 updated to use badgeModel
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
2024-10-08 09:08:20 -05:00
Matt Bruce
c737ca1344 added textColor
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
2024-10-08 09:08:05 -05:00
Pfeil, Scott Robert
d2e841c533 Merge branch 'bugfix/FontLabelAttribute-conversion' into 'develop'
added in model conversion to textStyle

### Summary
The size was not being used in the conversion along with the name. 

So now you either pass in a Style or a Name & Size.

Co-authored-by: Matt Bruce <matt.bruce@verizon.com>

See merge request https://gitlab.verizon.com/BPHV_MIPS/mvm_core_ui/-/merge_requests/1197
2024-10-04 17:57:09 +00:00
34 changed files with 182 additions and 107 deletions

View File

@ -31,9 +31,10 @@ open class Badge: VDS.Badge, VDSMoleculeViewProtocol {
self.accessibilityIdentifier = accessibilityIdentifier
}
text = viewModel.text
textColor = viewModel.textColorStyle
maxWidth = viewModel.maxWidth
numberOfLines = viewModel.numberOfLines
fillColor = viewModel.fillColor
fillColor = viewModel.fillColorStyle
surface = viewModel.surface
}

View File

@ -22,14 +22,18 @@ open class BadgeModel: MoleculeModelProtocol {
// MARK: - VDS Properties
//--------------------------------------------------
public var text: String = ""
public var textColorStyle: Badge.TextColor? = nil
public var accessibilityText: String?
public var maxWidth: CGFloat?
public var numberOfLines: Int = 1
public var fillColor = Badge.FillColor.red
public var fillColorStyle = Badge.FillColor.red
public var surface: Surface = .light
private enum CodingKeys: String, CodingKey {
case id, accessibilityIdentifier, text, 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 {
@ -39,7 +43,19 @@ open class BadgeModel: MoleculeModelProtocol {
accessibilityIdentifier = try container.decodeIfPresent(String.self, forKey: .accessibilityIdentifier)
text = try container.decode(String.self, forKey: .text)
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
numberOfLines = try container.decodeIfPresent(Int.self, forKey: .numberOfLines) ?? 1
maxWidth = try container.decodeIfPresent(CGFloat.self, forKey: .maxWidth)
@ -51,16 +67,23 @@ open class BadgeModel: MoleculeModelProtocol {
try container.encode(text, forKey: .text)
try container.encode(accessibilityText, forKey: .accessibilityText)
try container.encodeIfPresent(accessibilityIdentifier, forKey: .accessibilityIdentifier)
try container.encode(fillColor, forKey: .fillColor)
try container.encode(surface, forKey: .surface)
try container.encode(numberOfLines, forKey: .numberOfLines)
try container.encodeIfPresent(maxWidth, forKey: .maxWidth)
try container.encode(fillColorStyle, forKey: .fillColorStyle)
switch textColorStyle {
case .custom(let color):
try container.encode(Color(uiColor: color), forKey: .textColor)
default:
break
}
}
public func isEqual(to model: any ModelComparisonProtocol) -> Bool {
guard let model = model as? BadgeModel else { return false }
return self.backgroundColor == model.backgroundColor
&& self.fillColor == model.fillColor
&& self.fillColorStyle == model.fillColorStyle
&& self.textColorStyle == model.textColorStyle
&& self.numberOfLines == model.numberOfLines
&& self.text == model.text
&& self.surface == model.surface

View File

@ -107,15 +107,15 @@ import UIKit
// configure attributed string for progress percentage.
let attributedString = NSMutableAttributedString(string: String(percent) + "%")
// 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
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
let width = viewWidth
let height = width
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)
}

View File

@ -51,7 +51,7 @@ open class Tilelet: VDS.Tilelet, VDSMoleculeViewProtocol{
eyebrowModel = viewModel.eyebrowModel(delegateObject: delegateObject, additionalData: additionalData)
titleModel = viewModel.titleModel(delegateObject: delegateObject, additionalData: additionalData)
subTitleModel = viewModel.subTitleModel(delegateObject: delegateObject, additionalData: additionalData)
badgeModel = viewModel.badge
badgeModel = viewModel.badgeModel()
descriptiveIconModel = viewModel.descriptiveIcon
directionalIconModel = viewModel.directionalIcon
//setup action

View File

@ -18,7 +18,7 @@ open class TileletModel: TileContainerBaseModel<Tilelet.Padding, Tilelet>, Molec
public var id: String = UUID().uuidString
public var backgroundColor: Color?
public var badge: Tilelet.BadgeModel?
public var badge: BadgeModel?
public var eyebrow: LabelModel?
public var eyebrowColor: TitleLockup.TextColor = .primary
public var title: LabelModel?
@ -49,7 +49,7 @@ open class TileletModel: TileContainerBaseModel<Tilelet.Padding, Tilelet>, Molec
required public init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
id = try container.decodeIfPresent(String.self, forKey: .id) ?? UUID().uuidString
badge = try container.decodeIfPresent(Tilelet.BadgeModel.self, forKey: .badge)
badge = try container.decodeIfPresent(BadgeModel.self, forKey: .badge)
eyebrow = try container.decodeIfPresent(LabelModel.self, forKey: .eyebrow)
title = try container.decodeIfPresent(LabelModel.self, forKey: .title)
subTitle = try container.decodeIfPresent(LabelModel.self, forKey: .subTitle)
@ -91,6 +91,17 @@ open class TileletModel: TileContainerBaseModel<Tilelet.Padding, Tilelet>, Molec
try super.init(from: decoder)
}
public func badgeModel() -> Tilelet.BadgeModel? {
guard let badge else { return nil }
return .init(text: badge.text,
textColor: badge.textColorStyle,
fillColor: badge.fillColorStyle,
surface: badge.surface,
numberOfLines: badge.numberOfLines,
maxWidth: badge.maxWidth
)
}
public func eyebrowModel(delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) -> Tilelet.EyebrowModel? {
guard let eyebrow else { return nil }
let attrs = eyebrow.attributes?.toVDSLabelAttributeModel(delegateObject: delegateObject, additionalData: additionalData)

View File

@ -16,7 +16,6 @@ import MVMCore
//--------------------------------------------------
extension VDS.Surface: Codable {}
extension VDS.Badge.FillColor: Codable {}
extension VDS.BadgeIndicator.FillColor: Codable {}
extension VDS.BadgeIndicator.Kind: Codable {}
extension VDS.BadgeIndicator.MaximumDigits: Codable {}
@ -294,6 +293,45 @@ extension VDS.TitleLockup.TextColor: Codable {
}
}
extension VDS.Badge.FillColor: Codable {
public init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
let type = try container.decode(String.self)
switch type {
case "red":
self = .red
case "yellow":
self = .yellow
case "green":
self = .green
case "orange":
self = .orange
case "blue":
self = .blue
case "black":
self = .black
case "white":
self = .white
default:
if let color = try? Color(from: decoder) {
self = .custom(color.uiColor)
} else {
self = .custom(UIColor(hexString: type))
}
}
}
public func encode(to encoder: Encoder) throws {
var container = encoder.singleValueContainer()
switch self {
case .custom(let value):
try container.encode(Color(uiColor: value))
default:
try container.encode(String(reflecting: self))
}
}
}
extension VDS.TitleLockup.TitleTextColor: Codable {
enum CodingKeys: String, CodingKey {

View File

@ -52,6 +52,9 @@ public class HeadersH1ButtonModel: HeaderModel, MoleculeModelProtocol, ParentMol
if titleLockup.subTitle?.fontStyle == nil {
titleLockup.subTitle?.fontStyle = Styler.Font.RegularTitleMedium
}
if titleLockup.title.accessibilityTraits == nil {
titleLockup.title.accessibilityTraits = [.header]
}
}
//--------------------------------------------------

View File

@ -31,6 +31,9 @@ public class HeadersH1NoButtonsBodyTextModel: HeaderModel, MoleculeModelProtocol
if titleLockup.subTitle?.fontStyle == nil {
titleLockup.subTitle?.fontStyle = Styler.Font.RegularTitleMedium
}
if titleLockup.title.accessibilityTraits == nil {
titleLockup.title.accessibilityTraits = [.header]
}
}
//--------------------------------------------------

View File

@ -47,18 +47,15 @@ public class HeadersH2ButtonsModel: HeaderModel, MoleculeModelProtocol, ParentMo
//--------------------------------------------------
public override func setDefaults() {
if topPadding == nil {
topPadding = Padding.Component.VerticalMarginSpacing
}
if bottomPadding == nil {
bottomPadding = Padding.Component.VerticalMarginSpacing
}
if titleLockup.title.fontStyle == nil {
titleLockup.title.fontStyle = Styler.Font.RegularTitleXLarge
}
if titleLockup.subTitle?.fontStyle == nil {
titleLockup.subTitle?.fontStyle = Styler.Font.RegularTitleMedium
}
if titleLockup.title.accessibilityTraits == nil {
titleLockup.title.accessibilityTraits = [.header]
}
super.setDefaults()
}

View File

@ -42,18 +42,15 @@ public class HeadersH2CaretLinkModel: HeaderModel, MoleculeModelProtocol, Parent
// MARK: - Methods
//--------------------------------------------------
public override func setDefaults() {
if topPadding == nil {
topPadding = Padding.Component.VerticalMarginSpacing
}
if bottomPadding == nil {
bottomPadding = Padding.Component.VerticalMarginSpacing
}
if titleLockup.title.fontStyle == nil {
titleLockup.title.fontStyle = Styler.Font.RegularTitleXLarge
}
if titleLockup.subTitle?.fontStyle == nil {
titleLockup.subTitle?.fontStyle = Styler.Font.RegularTitleMedium
}
if titleLockup.title.accessibilityTraits == nil {
titleLockup.title.accessibilityTraits = [.header]
}
super.setDefaults()
}

View File

@ -46,18 +46,15 @@ public class HeadersH2LinkModel: HeaderModel, ParentMoleculeModelProtocol {
//--------------------------------------------------
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
}
if titleLockup.subTitle?.fontStyle == nil {
titleLockup.subTitle?.fontStyle = Styler.Font.RegularTitleMedium
}
if titleLockup.title.accessibilityTraits == nil {
titleLockup.title.accessibilityTraits = [.header]
}
super.setDefaults()
}

View File

@ -36,18 +36,15 @@ public class HeadersH2NoButtonsBodyTextModel: HeaderModel, MoleculeModelProtocol
}
public override func setDefaults() {
if topPadding == nil {
topPadding = Padding.Component.VerticalMarginSpacing
}
if bottomPadding == nil {
bottomPadding = Padding.Component.VerticalMarginSpacing
}
if titleLockup.title.fontStyle == nil {
titleLockup.title.fontStyle = Styler.Font.RegularTitleXLarge
}
if titleLockup.subTitle?.fontStyle == nil {
titleLockup.subTitle?.fontStyle = Styler.Font.RegularTitleMedium
}
if titleLockup.title.accessibilityTraits == nil {
titleLockup.title.accessibilityTraits = [.header]
}
super.setDefaults()
}

View File

@ -57,12 +57,6 @@ public class HeadersH2PricingTwoRowsModel: HeaderModel, MoleculeModelProtocol, P
// MARK: - Methods
//--------------------------------------------------
public override func setDefaults() {
if topPadding == nil {
topPadding = Padding.Component.VerticalMarginSpacing
}
if bottomPadding == nil {
bottomPadding = Padding.Component.VerticalMarginSpacing
}
if headline.accessibilityTraits == nil {
headline.accessibilityTraits = .header
}

View File

@ -47,18 +47,15 @@ public class HeadersH2TinyButtonModel: HeaderModel, MoleculeModelProtocol, Paren
//--------------------------------------------------
public override func setDefaults() {
if topPadding == nil {
topPadding = Padding.Component.VerticalMarginSpacing
}
if bottomPadding == nil {
bottomPadding = Padding.Component.VerticalMarginSpacing
}
if titleLockup.title.fontStyle == nil {
titleLockup.title.fontStyle = Styler.Font.RegularTitleXLarge
}
if titleLockup.subTitle?.fontStyle == nil {
titleLockup.subTitle?.fontStyle = Styler.Font.RegularTitleMedium
}
if titleLockup.title.accessibilityTraits == nil {
titleLockup.title.accessibilityTraits = [.header]
}
super.setDefaults()
button.style = .secondary
button.size = .small

View File

@ -15,7 +15,7 @@ import Foundation
//-----------------------------------------------------
public var stack: Stack<StackModel>
public let headline = Label(fontStyle: .BoldTitleMedium)
public let headline = Label(fontStyle: .BoldTitleLarge)
public let body = Label(fontStyle: .RegularBodySmall)
//--------------------------------------------------
@ -24,7 +24,7 @@ import Foundation
public override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
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)
super.init(style: style, reuseIdentifier: reuseIdentifier)
}
@ -63,7 +63,7 @@ import Foundation
open override func reset() {
super.reset()
headline.setFontStyle(.BoldTitleMedium)
headline.setFontStyle(.BoldTitleLarge)
body.setFontStyle(.RegularBodySmall)
}

View File

@ -47,6 +47,9 @@ public class ListOneColumnTextWithWhitespaceDividerShortModel: ListItemModel, Mo
override public func setDefaults() {
style = .shortDivider
if headline.accessibilityTraits == nil {
headline.accessibilityTraits = [.header]
}
super.setDefaults()
}

View File

@ -15,7 +15,7 @@ import Foundation
//-----------------------------------------------------
public var stack: Stack<StackModel>
public let headline = Label(fontStyle: .BoldTitleMedium)
public let headline = Label(fontStyle: .BoldTitleLarge)
public let body = Label(fontStyle: .RegularBodySmall)
//--------------------------------------------------
@ -24,7 +24,7 @@ import Foundation
public override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
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)
super.init(style: style, reuseIdentifier: reuseIdentifier)
}
@ -62,7 +62,7 @@ import Foundation
open override func reset() {
super.reset()
headline.setFontStyle(.BoldTitleMedium)
headline.setFontStyle(.BoldTitleLarge)
body.setFontStyle(.RegularBodySmall)
accessibilityLabel = nil
}

View File

@ -47,6 +47,9 @@ public class ListOneColumnTextWithWhitespaceDividerTallModel: ListItemModel, Mol
override public func setDefaults() {
style = .tallDivider
if headline.accessibilityTraits == nil {
headline.accessibilityTraits = [.header]
}
super.setDefaults()
}

View File

@ -72,9 +72,9 @@ import MVMCore
case .standard:
set(topPadding: Padding.Component.VerticalMarginSpacing, bottomPadding: Padding.Component.VerticalMarginSpacing)
case .shortDivider:
set(topPadding: Padding.Component.LargeVerticalMarginSpacing, bottomPadding: Padding.Four)
set(topPadding: Padding.Component.LargeVerticalMarginSpacing, bottomPadding: Padding.Five)
case .tallDivider:
set(topPadding: Padding.Twelve, bottomPadding: Padding.Four)
set(topPadding: Padding.Twelve, bottomPadding: Padding.Five)
case .sectionFooter:
set(topPadding: Padding.Component.VerticalMarginSpacing, bottomPadding: 0)
case ListItemStyle.none:

View File

@ -37,7 +37,8 @@ import VDSCoreTokens
verticalStack.alignment = .fill
verticalStack.distribution = .fill
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()
subscribeForNotifications()
@ -223,6 +224,10 @@ extension CollapsableNotification: StatusBarUI {
topView.label.textColor.getWhite(&greyScale, alpha: nil)
return (color, greyScale > 0.5 ? .lightContent : .default)
}
public func shouldUseSafeAreaLayoutGuide() -> Bool {
return false
}
}
extension CollapsableNotification: AccessibilityProtocol {

View File

@ -332,7 +332,7 @@ open class Carousel: View {
addSubview(pagingView)
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?.isActive = true
bottomPin = bottomAnchor.constraint(equalTo: collectionView.bottomAnchor)

View File

@ -19,4 +19,10 @@ public protocol ContainerModelProtocol {
var useVerticalMargins: Bool? { get set }
var topPadding: CGFloat? { get set }
var bottomPadding: CGFloat? { get set }
var useSafeAreaInsets: Bool? { get set }
}
public extension ContainerModelProtocol {
var useSafeAreaInsets: Bool? { get { return nil } set {} }
}

View File

@ -16,6 +16,7 @@
public var header: MoleculeModelProtocol?
public var anchorFooter: Bool = false
public var footer: MoleculeModelProtocol?
public var fullScreen: Bool = false
public override var rootMolecules: [MoleculeModelProtocol] {
[navigationBar, header, footer].compactMap { $0 }
@ -50,6 +51,7 @@
case header
case anchorFooter
case footer
case fullScreen
}
//--------------------------------------------------
@ -66,6 +68,7 @@
anchorFooter = anchor
}
footer = try typeContainer.decodeModelIfPresent(codingKey: .footer)
fullScreen = try typeContainer.decodeIfPresent(Bool.self, forKey: .fullScreen) ?? false
try super.init(from: decoder)
}
@ -76,6 +79,7 @@
try container.encodeModelIfPresent(header, forKey: .header)
try container.encodeIfPresent(anchorFooter, forKey: .anchorFooter)
try container.encodeModelIfPresent(footer, forKey: .footer)
try container.encodeIfPresent(fullScreen, forKey: .fullScreen)
}
public override func isEqual(to model: any ModelComparisonProtocol) -> Bool {

View File

@ -18,9 +18,24 @@ import UIKit
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) {
topViewOutsideOfScroll = templateModel?.anchorHeader ?? 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)
}

View File

@ -55,6 +55,6 @@ open class CollectionView: UICollectionView, MVMCoreViewProtocol {
showsVerticalScrollIndicator = false
backgroundColor = .clear
isAccessibilityElement = false
contentInsetAdjustmentBehavior = .always
contentInsetAdjustmentBehavior = .never
}
}

View File

@ -65,6 +65,7 @@ open class CollectionViewCell: UICollectionViewCell, MoleculeViewProtocol, MVMCo
open func updateView(_ size: CGFloat) {
if let model = model as? ContainerModelProtocol {
containerHelper.updateViewMargins(contentView, model: model, size: size)
contentView.insetsLayoutMarginsFromSafeArea = model.useSafeAreaInsets == true
}
(molecule as? MVMCoreViewProtocol)?.updateView(size)
}

View File

@ -116,6 +116,8 @@ import UIKit
} else {
contentView.directionalLayoutMargins = directionalLayoutMargins
}
contentView.insetsLayoutMarginsFromSafeArea = listItemModel?.useSafeAreaInsets == true
topSeparatorView?.updateView(size)
bottomSeparatorView?.updateView(size)

View File

@ -42,6 +42,10 @@ open class ThreeLayerViewController: ProgrammaticScrollViewController, RotorView
open override func loadView() {
super.loadView()
setContentHeightConstraint()
}
open func setContentHeightConstraint() {
// The height is used to keep the bottom view at the bottom.
if let contentView = contentView, let scrollView = scrollView {
heightConstraint = contentView.heightAnchor.constraint(equalTo: scrollView.safeAreaLayoutGuide.heightAnchor, multiplier: 1.0)

View File

@ -15,6 +15,9 @@ import MVMCore
public protocol StatusBarUI {
/// Returns the background color of the status bar view and the style of the status bar.
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
@ -230,8 +233,7 @@ public extension MVMCoreUISplitViewController {
func setStatusBar(for viewController: UIViewController?) {
let viewController = viewController as? MVMCoreUIDetailViewProtocol
let backgroundColor = viewController?.defaultStatusBarBackgroundColor?() ??
navigationController?.navigationBar.standardAppearance.backgroundColor ??
statusBarView?.backgroundColor
navigationController?.navigationBar.standardAppearance.backgroundColor
let style = viewController?.defaultStatusBarStyle?() ??
getStatusBarStyle(for: backgroundColor)

View File

@ -43,9 +43,6 @@ typedef NS_ENUM(NSInteger, MFNumberOfDrawers) {
// Reference to the top alert view
@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.
@property (nonatomic, readonly) BOOL leftPanelIsAccessible;
@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
- (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

View File

@ -63,8 +63,6 @@ typedef NS_OPTIONS(NSInteger, MFExtendedDrawer) {
@property (strong, nonatomic) NSNumber *transitionWidth;
@property (nonatomic) UIStatusBarStyle statusBarStyle;
@property (strong, nonatomic) NSLayoutConstraint *statusBarHeightConstraint;
@property (strong, nonatomic) NSLayoutConstraint *statusBarBottomConstraint;
// Dismisses any panel
- (void)dismissPanels:(id)sender;
@ -865,7 +863,6 @@ CGFloat const PanelAnimationDuration = 0.2;
#pragma mark - Status Bar
- (void)setStatusBarBackgroundColor:(UIColor *)backgroundColor style:(UIStatusBarStyle)style {
self.statusBarView.backgroundColor = backgroundColor;
self.statusBarStyle = style;
// Triggers preferredStatusBarStyle
@ -876,24 +873,6 @@ CGFloat const PanelAnimationDuration = 0.2;
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
- (void)loadView {
@ -901,17 +880,6 @@ CGFloat const PanelAnimationDuration = 0.2;
UIView *view = [[UIView alloc] init];
view.translatesAutoresizingMaskIntoConstraints = NO;
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
if (self.topAlertView) {
@ -954,9 +922,9 @@ CGFloat const PanelAnimationDuration = 0.2;
if (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 {
[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.

View File

@ -64,6 +64,7 @@ open class Container: View, ContainerProtocol {
super.updateView(size)
(view as? MVMCoreViewProtocol)?.updateView(size)
containerHelper.updateViewMargins(self, model: containerModel, size: size)
insetsLayoutMarginsFromSafeArea = containerModel?.useSafeAreaInsets == true
}
/// Will be called only once.

View File

@ -30,6 +30,8 @@ open class ContainerModel: ContainerModelProtocol, Codable, ModelComparisonProto
public var cornerRadius: CGFloat?
public var useSafeAreaInsets: Bool?
//--------------------------------------------------
// MARK: - Keys
//--------------------------------------------------
@ -46,6 +48,7 @@ open class ContainerModel: ContainerModelProtocol, Codable, ModelComparisonProto
case topPadding
case bottomPadding
case cornerRadius
case useSafeAreaInsets
}
//--------------------------------------------------
@ -101,6 +104,7 @@ open class ContainerModel: ContainerModelProtocol, Codable, ModelComparisonProto
topPadding = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .topPadding)
bottomPadding = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .bottomPadding)
cornerRadius = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .cornerRadius)
useSafeAreaInsets = try typeContainer.decodeIfPresent(Bool.self, forKey: .useSafeAreaInsets)
setDefaults()
}
@ -117,6 +121,7 @@ open class ContainerModel: ContainerModelProtocol, Codable, ModelComparisonProto
try container.encodeIfPresent(topPadding, forKey: .topPadding)
try container.encodeIfPresent(bottomPadding, forKey: .bottomPadding)
try container.encodeIfPresent(cornerRadius, forKey: .cornerRadius)
try container.encodeIfPresent(useSafeAreaInsets, forKey: .useSafeAreaInsets)
}
public func isEqual(to model: any ModelComparisonProtocol) -> Bool {

View File

@ -32,7 +32,14 @@ extension NotificationContainerView: NotificationTransitionDelegateProtocol {
public func show(notification: UIView) async {
currentNotificationView?.removeFromSuperview()
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
if let conformer = notification as? MVMCoreViewProtocol {