From 44adc76dcbdc48ef7331ef2d6763d60421ed1cb9 Mon Sep 17 00:00:00 2001 From: Scott Pfeil Date: Thu, 17 Oct 2024 09:04:31 -0400 Subject: [PATCH 1/2] 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. --- MVMCoreUI/Atomic/Atoms/Views/Spacer.swift | 8 +++++ .../Atomic/Atoms/Views/SpacerModel.swift | 8 +++++ .../CollapsableNotification.swift | 7 +++- .../Atomic/Organisms/Carousel/Carousel.swift | 2 +- .../ContainerModelProtocol.swift | 6 ++++ .../Templates/ThreeLayerModelBase.swift | 4 +++ .../Atomic/Templates/ThreeLayerTemplate.swift | 15 ++++++++ MVMCoreUI/BaseClasses/CollectionView.swift | 2 +- .../BaseClasses/CollectionViewCell.swift | 1 + MVMCoreUI/BaseClasses/TableViewCell.swift | 2 ++ .../ThreeLayerViewController.swift | 4 +++ ...MCoreUISplitViewController+Extension.swift | 6 ++-- .../MVMCoreUISplitViewController.h | 9 ----- .../MVMCoreUISplitViewController.m | 36 ++----------------- MVMCoreUI/Containers/Views/Container.swift | 1 + .../Containers/Views/ContainerModel.swift | 5 +++ .../NotificationContainerView.swift | 9 ++++- 17 files changed, 76 insertions(+), 49 deletions(-) create mode 100644 MVMCoreUI/Atomic/Atoms/Views/Spacer.swift create mode 100644 MVMCoreUI/Atomic/Atoms/Views/SpacerModel.swift diff --git a/MVMCoreUI/Atomic/Atoms/Views/Spacer.swift b/MVMCoreUI/Atomic/Atoms/Views/Spacer.swift new file mode 100644 index 00000000..5687fc01 --- /dev/null +++ b/MVMCoreUI/Atomic/Atoms/Views/Spacer.swift @@ -0,0 +1,8 @@ +// +// Untitled.swift +// MVMCoreUI +// +// Created by Scott Pfeil on 10/16/24. +// Copyright © 2024 Verizon Wireless. All rights reserved. +// + diff --git a/MVMCoreUI/Atomic/Atoms/Views/SpacerModel.swift b/MVMCoreUI/Atomic/Atoms/Views/SpacerModel.swift new file mode 100644 index 00000000..158b27c6 --- /dev/null +++ b/MVMCoreUI/Atomic/Atoms/Views/SpacerModel.swift @@ -0,0 +1,8 @@ +// +// SpacerMdoel.swift +// MVMCoreUI +// +// Created by Scott Pfeil on 10/16/24. +// Copyright © 2024 Verizon Wireless. All rights reserved. +// + diff --git a/MVMCoreUI/Atomic/Molecules/TopNotification/CollapsableNotification.swift b/MVMCoreUI/Atomic/Molecules/TopNotification/CollapsableNotification.swift index 5691390a..c7c5414e 100644 --- a/MVMCoreUI/Atomic/Molecules/TopNotification/CollapsableNotification.swift +++ b/MVMCoreUI/Atomic/Molecules/TopNotification/CollapsableNotification.swift @@ -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 { diff --git a/MVMCoreUI/Atomic/Organisms/Carousel/Carousel.swift b/MVMCoreUI/Atomic/Organisms/Carousel/Carousel.swift index 6476e8fa..58ad2280 100644 --- a/MVMCoreUI/Atomic/Organisms/Carousel/Carousel.swift +++ b/MVMCoreUI/Atomic/Organisms/Carousel/Carousel.swift @@ -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) diff --git a/MVMCoreUI/Atomic/Protocols/ModelProtocols/ContainerModelProtocol.swift b/MVMCoreUI/Atomic/Protocols/ModelProtocols/ContainerModelProtocol.swift index 29e25903..40c5aba4 100644 --- a/MVMCoreUI/Atomic/Protocols/ModelProtocols/ContainerModelProtocol.swift +++ b/MVMCoreUI/Atomic/Protocols/ModelProtocols/ContainerModelProtocol.swift @@ -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 {} } } diff --git a/MVMCoreUI/Atomic/Templates/ThreeLayerModelBase.swift b/MVMCoreUI/Atomic/Templates/ThreeLayerModelBase.swift index 481f8cad..380eec1d 100644 --- a/MVMCoreUI/Atomic/Templates/ThreeLayerModelBase.swift +++ b/MVMCoreUI/Atomic/Templates/ThreeLayerModelBase.swift @@ -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 { diff --git a/MVMCoreUI/Atomic/Templates/ThreeLayerTemplate.swift b/MVMCoreUI/Atomic/Templates/ThreeLayerTemplate.swift index b4af2ed4..811e87e6 100644 --- a/MVMCoreUI/Atomic/Templates/ThreeLayerTemplate.swift +++ b/MVMCoreUI/Atomic/Templates/ThreeLayerTemplate.swift @@ -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) } diff --git a/MVMCoreUI/BaseClasses/CollectionView.swift b/MVMCoreUI/BaseClasses/CollectionView.swift index 4b034462..196b8bf8 100644 --- a/MVMCoreUI/BaseClasses/CollectionView.swift +++ b/MVMCoreUI/BaseClasses/CollectionView.swift @@ -55,6 +55,6 @@ open class CollectionView: UICollectionView, MVMCoreViewProtocol { showsVerticalScrollIndicator = false backgroundColor = .clear isAccessibilityElement = false - contentInsetAdjustmentBehavior = .always + contentInsetAdjustmentBehavior = .never } } diff --git a/MVMCoreUI/BaseClasses/CollectionViewCell.swift b/MVMCoreUI/BaseClasses/CollectionViewCell.swift index 0507bd5c..5f632f6b 100644 --- a/MVMCoreUI/BaseClasses/CollectionViewCell.swift +++ b/MVMCoreUI/BaseClasses/CollectionViewCell.swift @@ -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) } diff --git a/MVMCoreUI/BaseClasses/TableViewCell.swift b/MVMCoreUI/BaseClasses/TableViewCell.swift index e18c3497..6ab77500 100644 --- a/MVMCoreUI/BaseClasses/TableViewCell.swift +++ b/MVMCoreUI/BaseClasses/TableViewCell.swift @@ -116,6 +116,8 @@ import UIKit } else { contentView.directionalLayoutMargins = directionalLayoutMargins } + + contentView.insetsLayoutMarginsFromSafeArea = listItemModel?.useSafeAreaInsets == true topSeparatorView?.updateView(size) bottomSeparatorView?.updateView(size) diff --git a/MVMCoreUI/BaseControllers/ThreeLayerViewController.swift b/MVMCoreUI/BaseControllers/ThreeLayerViewController.swift index 837d19c7..402c8703 100644 --- a/MVMCoreUI/BaseControllers/ThreeLayerViewController.swift +++ b/MVMCoreUI/BaseControllers/ThreeLayerViewController.swift @@ -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) diff --git a/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController+Extension.swift b/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController+Extension.swift index 11e33458..b5da1369 100644 --- a/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController+Extension.swift +++ b/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController+Extension.swift @@ -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) diff --git a/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController.h b/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController.h index 915b832a..c708b132 100644 --- a/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController.h +++ b/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController.h @@ -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 diff --git a/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController.m b/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController.m index ec2e7d27..cc832b97 100644 --- a/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController.m +++ b/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController.m @@ -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. diff --git a/MVMCoreUI/Containers/Views/Container.swift b/MVMCoreUI/Containers/Views/Container.swift index 281f8d1b..537c61f1 100644 --- a/MVMCoreUI/Containers/Views/Container.swift +++ b/MVMCoreUI/Containers/Views/Container.swift @@ -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. diff --git a/MVMCoreUI/Containers/Views/ContainerModel.swift b/MVMCoreUI/Containers/Views/ContainerModel.swift index fca6834e..289c6827 100644 --- a/MVMCoreUI/Containers/Views/ContainerModel.swift +++ b/MVMCoreUI/Containers/Views/ContainerModel.swift @@ -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 { diff --git a/MVMCoreUI/Notification/NotificationContainerView.swift b/MVMCoreUI/Notification/NotificationContainerView.swift index 0fee99e0..17d209fe 100644 --- a/MVMCoreUI/Notification/NotificationContainerView.swift +++ b/MVMCoreUI/Notification/NotificationContainerView.swift @@ -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 { From a210b8da9b2aea8d4162c8cdcfb09e4104c84205 Mon Sep 17 00:00:00 2001 From: Scott Pfeil Date: Thu, 17 Oct 2024 09:34:50 -0400 Subject: [PATCH 2/2] Remove Spacer --- MVMCoreUI/Atomic/Atoms/Views/Spacer.swift | 8 -------- MVMCoreUI/Atomic/Atoms/Views/SpacerModel.swift | 8 -------- 2 files changed, 16 deletions(-) delete mode 100644 MVMCoreUI/Atomic/Atoms/Views/Spacer.swift delete mode 100644 MVMCoreUI/Atomic/Atoms/Views/SpacerModel.swift diff --git a/MVMCoreUI/Atomic/Atoms/Views/Spacer.swift b/MVMCoreUI/Atomic/Atoms/Views/Spacer.swift deleted file mode 100644 index 5687fc01..00000000 --- a/MVMCoreUI/Atomic/Atoms/Views/Spacer.swift +++ /dev/null @@ -1,8 +0,0 @@ -// -// Untitled.swift -// MVMCoreUI -// -// Created by Scott Pfeil on 10/16/24. -// Copyright © 2024 Verizon Wireless. All rights reserved. -// - diff --git a/MVMCoreUI/Atomic/Atoms/Views/SpacerModel.swift b/MVMCoreUI/Atomic/Atoms/Views/SpacerModel.swift deleted file mode 100644 index 158b27c6..00000000 --- a/MVMCoreUI/Atomic/Atoms/Views/SpacerModel.swift +++ /dev/null @@ -1,8 +0,0 @@ -// -// SpacerMdoel.swift -// MVMCoreUI -// -// Created by Scott Pfeil on 10/16/24. -// Copyright © 2024 Verizon Wireless. All rights reserved. -// -