From e13e8ca5ab90fd8a158c013678dcd68879b859a0 Mon Sep 17 00:00:00 2001 From: Scott Pfeil Date: Mon, 5 Aug 2024 13:59:59 -0400 Subject: [PATCH 01/10] Digital PCT265 story MVAPCT-213 - Allow for panels to override the supported orientation. Force chatbot panel to be full screen width on non tablet devices. --- .../MVMCoreUIPanelProtocol.h | 3 +++ .../MVMCoreUISplitViewController.h | 9 +++++++ .../MVMCoreUISplitViewController.m | 26 +++++++++++++++++-- 3 files changed, 36 insertions(+), 2 deletions(-) diff --git a/MVMCoreUI/Containers/SplitViewController/MVMCoreUIPanelProtocol.h b/MVMCoreUI/Containers/SplitViewController/MVMCoreUIPanelProtocol.h index 8d381b76..bb151cc7 100644 --- a/MVMCoreUI/Containers/SplitViewController/MVMCoreUIPanelProtocol.h +++ b/MVMCoreUI/Containers/SplitViewController/MVMCoreUIPanelProtocol.h @@ -33,6 +33,9 @@ - (void)showArrow; - (void)hideArrow; +/// Orientation supported by the panel. +- (UIInterfaceOrientationMask)supportedInterfac; + /// The width to use if the panel is automatically extended when the screen is big enough. - (CGFloat)panelExtendedWidth; diff --git a/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController.h b/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController.h index ac057f10..915b832a 100644 --- a/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController.h +++ b/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController.h @@ -59,6 +59,13 @@ typedef NS_ENUM(NSInteger, MFNumberOfDrawers) { @property (nullable, strong, nonatomic) NSSet *cancellables; +/// When set to true, the panel will always be full width of the split. +@property (nonatomic) BOOL leftPanelFullWidth; + +/// When set to true, the panel will always be full width of the split. +@property (nonatomic) BOOL rightPanelFullWidth; + + // Convenience getter + (nullable instancetype)mainSplitViewController; @@ -131,6 +138,8 @@ typedef NS_ENUM(NSInteger, MFNumberOfDrawers) { /// Returns true if a panel is showing. - (BOOL)isAPanelShowing; +- (BOOL)isLeftPanelShowing; +- (BOOL)isRightPanelShowing; #pragma mark - Main Subclassables diff --git a/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController.m b/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController.m index 4d865830..78d5ef5a 100644 --- a/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController.m +++ b/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController.m @@ -679,6 +679,11 @@ CGFloat const PanelAnimationDuration = 0.2; [protocolController panelDidAppear:panel]; } } + if (@available(iOS 16.0, *)) { + if ([panel respondsToSelector:@selector(supportedInterfac)]) { + [controller setNeedsUpdateOfSupportedInterfaceOrientations]; + } + } } - (void)panelWillDisappear:(UIViewController *)panel animated:(BOOL)animated { @@ -709,6 +714,11 @@ CGFloat const PanelAnimationDuration = 0.2; [protocolController panelDidDisappear:panel]; } } + if (@available(iOS 16.0, *)) { + if ([panel respondsToSelector:@selector(supportedInterfac)]) { + [controller setNeedsUpdateOfSupportedInterfaceOrientations]; + } + } } - (void)addPanel:(nonnull UIViewController *)panel { @@ -999,7 +1009,9 @@ CGFloat const PanelAnimationDuration = 0.2; CGFloat leftPanelExtendedWidth = [self leftPanelExtendedWidth]; CGFloat leftPanelMaxWidth = [self leftPanelMaxWidth]; - if ([self shouldExtendLeftPanel:numberOfDrawers] && viewWidth > leftPanelExtendedWidth) { + if (self.leftPanelFullWidth) { + self.leftPanelWidth.constant = viewWidth; + } else if ([self shouldExtendLeftPanel:numberOfDrawers] && viewWidth > leftPanelExtendedWidth) { self.leftPanelWidth.constant = leftPanelExtendedWidth; } else if (viewWidth > leftPanelMaxWidth) { self.leftPanelWidth.constant = leftPanelMaxWidth; @@ -1009,7 +1021,9 @@ CGFloat const PanelAnimationDuration = 0.2; CGFloat rightPanelExtendedWidth = [self rightPanelExtendedWidth]; CGFloat rightPanelMaxWidth = [self rightPanelMaxWidth]; - if ([self shouldExtendRightPanel:numberOfDrawers] && viewWidth > rightPanelExtendedWidth) { + if (self.rightPanelFullWidth) { + self.rightPanelWidth.constant = viewWidth; + } else if ([self shouldExtendRightPanel:numberOfDrawers] && viewWidth > rightPanelExtendedWidth) { self.rightPanelWidth.constant = rightPanelExtendedWidth; } else if (viewWidth > rightPanelMaxWidth) { self.rightPanelWidth.constant = rightPanelMaxWidth; @@ -1063,6 +1077,14 @@ CGFloat const PanelAnimationDuration = 0.2; return fabs(self.mainViewLeading.constant) > 1; } +- (BOOL)isLeftPanelShowing { + return !self.leftView.isHidden; +} + +- (BOOL)isRightPanelShowing { + return !self.rightView.isHidden; +} + #pragma mark - Getters // Returns the desired view or falls back. Hot fix until we can get away from using these functions... From 1d2defeabbd0bf46afc848adf25599cc6fef1eb7 Mon Sep 17 00:00:00 2001 From: Scott Pfeil Date: Tue, 6 Aug 2024 09:53:59 -0400 Subject: [PATCH 02/10] Digital PCT265 story MVAPCT-213 - Add Helper to update the orientation. --- .../Utility/MVMCoreUIUtility+Extension.swift | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/MVMCoreUI/Utility/MVMCoreUIUtility+Extension.swift b/MVMCoreUI/Utility/MVMCoreUIUtility+Extension.swift index 5b70412e..18578682 100644 --- a/MVMCoreUI/Utility/MVMCoreUIUtility+Extension.swift +++ b/MVMCoreUI/Utility/MVMCoreUIUtility+Extension.swift @@ -102,4 +102,22 @@ public extension MVMCoreUIUtility { return nil } } + + @available(iOS 16.0, *) + @objc @MainActor + static func setNeedsUpdateOfSupportedInterfaceOrientations() { + var viewController = NavigationHandler.shared().getViewControllerToPresentOn() + while let presentedController = viewController?.presentedViewController, + !presentedController.isBeingDismissed { + viewController = presentedController + } + if let navigationController = viewController as? UINavigationController { + viewController = navigationController.topViewController + } + if let viewController = viewController { + viewController.setNeedsUpdateOfSupportedInterfaceOrientations() + } else if let viewController = MVMCoreUISession.sharedGlobal()?.navigationController?.topViewController { + viewController.setNeedsUpdateOfSupportedInterfaceOrientations() + } + } } From dfbb53f5453eb69f24a98692b95438d95e544464 Mon Sep 17 00:00:00 2001 From: Scott Pfeil Date: Tue, 6 Aug 2024 10:31:18 -0400 Subject: [PATCH 03/10] Digital PCT265 story MVAPCT-213 - Function name update --- .../Containers/SplitViewController/MVMCoreUIPanelProtocol.h | 2 +- .../SplitViewController/MVMCoreUISplitViewController.m | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/MVMCoreUI/Containers/SplitViewController/MVMCoreUIPanelProtocol.h b/MVMCoreUI/Containers/SplitViewController/MVMCoreUIPanelProtocol.h index bb151cc7..589dd5f3 100644 --- a/MVMCoreUI/Containers/SplitViewController/MVMCoreUIPanelProtocol.h +++ b/MVMCoreUI/Containers/SplitViewController/MVMCoreUIPanelProtocol.h @@ -34,7 +34,7 @@ - (void)hideArrow; /// Orientation supported by the panel. -- (UIInterfaceOrientationMask)supportedInterfac; +- (UIInterfaceOrientationMask)supportedInterface; /// The width to use if the panel is automatically extended when the screen is big enough. - (CGFloat)panelExtendedWidth; diff --git a/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController.m b/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController.m index 78d5ef5a..ec2e7d27 100644 --- a/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController.m +++ b/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController.m @@ -680,7 +680,7 @@ CGFloat const PanelAnimationDuration = 0.2; } } if (@available(iOS 16.0, *)) { - if ([panel respondsToSelector:@selector(supportedInterfac)]) { + if ([panel respondsToSelector:@selector(supportedInterface)]) { [controller setNeedsUpdateOfSupportedInterfaceOrientations]; } } @@ -715,7 +715,7 @@ CGFloat const PanelAnimationDuration = 0.2; } } if (@available(iOS 16.0, *)) { - if ([panel respondsToSelector:@selector(supportedInterfac)]) { + if ([panel respondsToSelector:@selector(supportedInterface)]) { [controller setNeedsUpdateOfSupportedInterfaceOrientations]; } } From f412fd70e1c5b9b5a9887a3170592809af581e70 Mon Sep 17 00:00:00 2001 From: Scott Pfeil Date: Thu, 8 Aug 2024 14:02:21 -0400 Subject: [PATCH 04/10] Digital PCT265 story VZWYZDG-1866 - Added action for negating the gone property on molecules. --- MVMCoreUI.xcodeproj/project.pbxproj | 12 ++++++ .../Atomic/Actions/ActionNegateGone.swift | 38 +++++++++++++++++++ .../Actions/ActionNegateGoneModel.swift | 24 ++++++++++++ .../Items/StackItemModelProtocol.swift | 3 +- .../CarouselItemModelProtocol.swift | 3 +- .../ModelProtocols/GoneableProtocol.swift | 13 +++++++ .../ListItemModelProtocol.swift | 3 +- .../Protocols/MoleculeDelegateProtocol.swift | 4 ++ .../Templates/MoleculeListTemplate.swift | 4 +- .../OtherHandlers/CoreUIModelMapping.swift | 1 + 10 files changed, 97 insertions(+), 8 deletions(-) create mode 100644 MVMCoreUI/Atomic/Actions/ActionNegateGone.swift create mode 100644 MVMCoreUI/Atomic/Actions/ActionNegateGoneModel.swift create mode 100644 MVMCoreUI/Atomic/Protocols/ModelProtocols/GoneableProtocol.swift diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index dc37ca12..ac0a84ed 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -307,6 +307,9 @@ AFA4932229E5EF2E001A9663 /* NotificationHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = AFA4932129E5EF2E001A9663 /* NotificationHandler.swift */; }; AFA4933F29E874F0001A9663 /* MVMCoreUILoggingDelegateProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = AFA4933E29E874F0001A9663 /* MVMCoreUILoggingDelegateProtocol.swift */; }; AFA4935729EE3DCC001A9663 /* AlertDelegateProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = AFA4935629EE3DCC001A9663 /* AlertDelegateProtocol.swift */; }; + AFB6336E2C65166E00791221 /* GoneableProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = AFB6336D2C65166E00791221 /* GoneableProtocol.swift */; }; + AFB633702C65175800791221 /* ActionNegateGone.swift in Sources */ = {isa = PBXBuildFile; fileRef = AFB6336F2C65175800791221 /* ActionNegateGone.swift */; }; + AFB633722C653C0900791221 /* ActionNegateGoneModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AFB633712C653C0900791221 /* ActionNegateGoneModel.swift */; }; AFE4A1D627DFBB6F00C458D0 /* UINavigationController+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = AFE4A1D527DFBB6F00C458D0 /* UINavigationController+Extension.swift */; }; B4CC8FBD29DF34680005D28B /* Badge.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4CC8FBC29DF34680005D28B /* Badge.swift */; }; B4CC8FBF29DF34730005D28B /* BadgeModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4CC8FBE29DF34730005D28B /* BadgeModel.swift */; }; @@ -931,6 +934,9 @@ AFA4932129E5EF2E001A9663 /* NotificationHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationHandler.swift; sourceTree = ""; }; AFA4933E29E874F0001A9663 /* MVMCoreUILoggingDelegateProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MVMCoreUILoggingDelegateProtocol.swift; sourceTree = ""; }; AFA4935629EE3DCC001A9663 /* AlertDelegateProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlertDelegateProtocol.swift; sourceTree = ""; }; + AFB6336D2C65166E00791221 /* GoneableProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GoneableProtocol.swift; sourceTree = ""; }; + AFB6336F2C65175800791221 /* ActionNegateGone.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActionNegateGone.swift; sourceTree = ""; }; + AFB633712C653C0900791221 /* ActionNegateGoneModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActionNegateGoneModel.swift; sourceTree = ""; }; AFE4A1D527DFBB6F00C458D0 /* UINavigationController+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UINavigationController+Extension.swift"; sourceTree = ""; }; B4CC8FBC29DF34680005D28B /* Badge.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Badge.swift; sourceTree = ""; }; B4CC8FBE29DF34730005D28B /* BadgeModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BadgeModel.swift; sourceTree = ""; }; @@ -1287,6 +1293,7 @@ 27F6B08B26052AFF008529AA /* ParentMoleculeModelProtocol.swift */, 27577DCC286CA959001EC47E /* MoleculeMaskingProtocol.swift */, 58E7561C2BE04C320088BB5D /* MoleculeComparisonProtocol.swift */, + AFB6336D2C65166E00791221 /* GoneableProtocol.swift */, ); path = ModelProtocols; sourceTree = ""; @@ -1598,6 +1605,8 @@ AF1C33722885D481006B1001 /* MVMCoreUIActionOpenPageHandler.swift */, AF60A7F52892D2E300919EEB /* ActionDismissNotificationModel.swift */, AF60A7F72892D34D00919EEB /* ActionDismissNotificationHandler.swift */, + AFB633712C653C0900791221 /* ActionNegateGoneModel.swift */, + AFB6336F2C65175800791221 /* ActionNegateGone.swift */, ); path = Actions; sourceTree = ""; @@ -2844,6 +2853,7 @@ D2E2A99423D8CCBC000B42E6 /* HeadlineBodyLinkModel.swift in Sources */, 01004F3022721C3800991ECC /* RadioButton.swift in Sources */, D268C70E238C22D7007F2C1C /* DropDownFilterTableViewCell.swift in Sources */, + AFB633702C65175800791221 /* ActionNegateGone.swift in Sources */, D236E5B7242007C500C38625 /* MVMControllerModelProtocol.swift in Sources */, AA71AD4024A32FE700ACA76F /* HeadersH2Link.swift in Sources */, D29DF11721E6805F003B2FB9 /* UIColor+MFConvenience.m in Sources */, @@ -2893,6 +2903,7 @@ D2E2A99D23DA3217000B42E6 /* UIStackViewAlignment+Extension.swift in Sources */, 01EB369423609801006832FA /* HeadlineBodyModel.swift in Sources */, D2A92884241ACB25004E01C6 /* ProgrammaticScrollViewController.swift in Sources */, + AFB633722C653C0900791221 /* ActionNegateGoneModel.swift in Sources */, EA985C3E2970938F00F2FF2E /* Tilelet.swift in Sources */, D23A90002612347A007E14CE /* PageBehaviorContainerModelProtocol.swift in Sources */, EAA78020290081320057DFDF /* VDSMoleculeViewProtocol.swift in Sources */, @@ -3176,6 +3187,7 @@ D2092355244FA0FD0044AD09 /* ThreeLayerTemplateModelProtocol.swift in Sources */, 0AE14F64238315D2005417F8 /* TextField.swift in Sources */, 0A51F3E22475CB73002E08B6 /* LoadingSpinnerModel.swift in Sources */, + AFB6336E2C65166E00791221 /* GoneableProtocol.swift in Sources */, D2169303251E53D9002A6324 /* SectionListTemplateModel.swift in Sources */, EA6642932BCDA97D00D81DC4 /* TileContainerModel.swift in Sources */, AF7E509929E477C1009DC2AD /* AlertController.swift in Sources */, diff --git a/MVMCoreUI/Atomic/Actions/ActionNegateGone.swift b/MVMCoreUI/Atomic/Actions/ActionNegateGone.swift new file mode 100644 index 00000000..cc964c8b --- /dev/null +++ b/MVMCoreUI/Atomic/Actions/ActionNegateGone.swift @@ -0,0 +1,38 @@ +// +// ActionToggleGone.swift +// MVMCoreUI +// +// Created by Scott Pfeil on 8/8/24. +// Copyright © 2024 Verizon Wireless. All rights reserved. +// + +import Foundation +import MVMCore + +public struct ActionNegateGone: MVMCoreActionHandlerProtocol { + + public enum ActionNegateGoneError: MVMError { + case moleculeNotFound(id: String) + } + + public init() {} + + public func execute(with model: any MVMCore.ActionModelProtocol, delegateObject: MVMCore.DelegateObject?, additionalData: [AnyHashable : Any]?) async throws { + guard let model = model as? ActionNegateGoneModel else { return } + guard let goneableModels: [GoneableProtocol & MoleculeModelProtocol] = (delegateObject as? MVMCoreUIDelegateObject)?.moleculeDelegate?.getRootMolecules().allMoleculesOfType(), + var goneableModel = goneableModels.first(where: { goneableModel in + goneableModel.id == model.id + }) else { throw ActionNegateGoneError.moleculeNotFound(id: model.id) } + goneableModel.gone = !goneableModel.gone + await (delegateObject as? MVMCoreUIDelegateObject)?.moleculeDelegate?.updateUI(for: [goneableModel]) + } +} + +extension ActionNegateGone.ActionNegateGoneError: CustomStringConvertible { + public var description: String { + switch self { + case .moleculeNotFound(id: let id): + "Unable to negate gone for molecule with id: \(id)" + } + } +} diff --git a/MVMCoreUI/Atomic/Actions/ActionNegateGoneModel.swift b/MVMCoreUI/Atomic/Actions/ActionNegateGoneModel.swift new file mode 100644 index 00000000..8bb28548 --- /dev/null +++ b/MVMCoreUI/Atomic/Actions/ActionNegateGoneModel.swift @@ -0,0 +1,24 @@ +// +// ActionToggleGoneModel.swift +// MVMCoreUI +// +// Created by Scott Pfeil on 8/8/24. +// Copyright © 2024 Verizon Wireless. All rights reserved. +// + +import Foundation +import MVMCore + +public struct ActionNegateGoneModel: ActionModelProtocol { + public static var identifier: String = "toggleGone" + public var actionType: String = ActionNegateGoneModel.identifier + public var extraParameters: JSONValueDictionary? + public var analyticsData: JSONValueDictionary? + public var id: String + + public init(id: String, extraParameters: JSONValueDictionary? = nil, analyticsData: JSONValueDictionary? = nil) { + self.id = id + self.extraParameters = extraParameters + self.analyticsData = analyticsData + } +} diff --git a/MVMCoreUI/Atomic/Molecules/Items/StackItemModelProtocol.swift b/MVMCoreUI/Atomic/Molecules/Items/StackItemModelProtocol.swift index c3670c20..542cf134 100644 --- a/MVMCoreUI/Atomic/Molecules/Items/StackItemModelProtocol.swift +++ b/MVMCoreUI/Atomic/Molecules/Items/StackItemModelProtocol.swift @@ -7,8 +7,7 @@ // -public protocol StackItemModelProtocol { +public protocol StackItemModelProtocol: GoneableProtocol { var spacing: CGFloat? { get set } var percent: Int? { get set } - var gone: Bool { get set } } diff --git a/MVMCoreUI/Atomic/Protocols/ModelProtocols/CarouselItemModelProtocol.swift b/MVMCoreUI/Atomic/Protocols/ModelProtocols/CarouselItemModelProtocol.swift index 24a0bb02..52013830 100644 --- a/MVMCoreUI/Atomic/Protocols/ModelProtocols/CarouselItemModelProtocol.swift +++ b/MVMCoreUI/Atomic/Protocols/ModelProtocols/CarouselItemModelProtocol.swift @@ -7,9 +7,8 @@ // -public protocol CarouselItemModelProtocol: FormFieldProtocol, ContainerModelProtocol { +public protocol CarouselItemModelProtocol: FormFieldProtocol, ContainerModelProtocol, GoneableProtocol { var analyticsData: JSONValueDictionary? { get set } - var gone: Bool { get set } } public extension CarouselItemModelProtocol { diff --git a/MVMCoreUI/Atomic/Protocols/ModelProtocols/GoneableProtocol.swift b/MVMCoreUI/Atomic/Protocols/ModelProtocols/GoneableProtocol.swift new file mode 100644 index 00000000..03593831 --- /dev/null +++ b/MVMCoreUI/Atomic/Protocols/ModelProtocols/GoneableProtocol.swift @@ -0,0 +1,13 @@ +// +// GoneableProtocol.swift +// MVMCoreUI +// +// Created by Scott Pfeil on 8/8/24. +// Copyright © 2024 Verizon Wireless. All rights reserved. +// + +import Foundation + +public protocol GoneableProtocol { + var gone: Bool { get set } +} diff --git a/MVMCoreUI/Atomic/Protocols/ModelProtocols/ListItemModelProtocol.swift b/MVMCoreUI/Atomic/Protocols/ModelProtocols/ListItemModelProtocol.swift index 74d6e3fe..2e18c92b 100644 --- a/MVMCoreUI/Atomic/Protocols/ModelProtocols/ListItemModelProtocol.swift +++ b/MVMCoreUI/Atomic/Protocols/ModelProtocols/ListItemModelProtocol.swift @@ -15,12 +15,11 @@ public enum ListItemStyle: String, Codable { case none } -public protocol ListItemModelProtocol: ContainerModelProtocol, AccessibilityModelProtocol { +public protocol ListItemModelProtocol: ContainerModelProtocol, AccessibilityModelProtocol, GoneableProtocol { var line: LineModel? { get set } var action: ActionModelProtocol? { get set } var hideArrow: Bool? { get set } var style: ListItemStyle? { get set } - var gone: Bool { get set } } // Not a strict requirement. diff --git a/MVMCoreUI/Atomic/Protocols/MoleculeDelegateProtocol.swift b/MVMCoreUI/Atomic/Protocols/MoleculeDelegateProtocol.swift index e78c0b1b..d44edf4b 100644 --- a/MVMCoreUI/Atomic/Protocols/MoleculeDelegateProtocol.swift +++ b/MVMCoreUI/Atomic/Protocols/MoleculeDelegateProtocol.swift @@ -21,6 +21,10 @@ public protocol MoleculeDelegateProtocol: AnyObject { /// Notifies the delegate that the molecule layout update. Should be called when the layout may change due to an async method. Mainly used for list or collections. func moleculeLayoutUpdated(_ molecule: MoleculeViewProtocol) //optional + + /// Updates the UI for the updated models. + @MainActor + func updateUI(for molecules: [MoleculeModelProtocol]?) } extension MoleculeDelegateProtocol { diff --git a/MVMCoreUI/Atomic/Templates/MoleculeListTemplate.swift b/MVMCoreUI/Atomic/Templates/MoleculeListTemplate.swift index 40bcd134..218c1eeb 100644 --- a/MVMCoreUI/Atomic/Templates/MoleculeListTemplate.swift +++ b/MVMCoreUI/Atomic/Templates/MoleculeListTemplate.swift @@ -148,7 +148,7 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol } open func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { - return (getMoleculeInfo(for: indexPath)?.molecule as? ListItemModelProtocol)?.gone == true ? 0 : UITableView.automaticDimension + return (getMoleculeInfo(for: indexPath)?.molecule as? GoneableProtocol)?.gone == true ? 0 : UITableView.automaticDimension } open func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat { @@ -168,7 +168,7 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol guard let moleculeInfo = getMoleculeInfo(for: indexPath), let cell = tableView.dequeueReusableCell(withIdentifier: moleculeInfo.identifier) else { return UITableViewCell() } - cell.isHidden = (getMoleculeInfo(for: indexPath)?.molecule as? ListItemModelProtocol)?.gone == true + cell.isHidden = (getMoleculeInfo(for: indexPath)?.molecule as? GoneableProtocol)?.gone == true (cell as? MoleculeViewProtocol)?.reset() (cell as? MoleculeListCellProtocol)?.setLines(with: templateModel?.line, delegateObject: delegateObjectIVar, additionalData: nil, indexPath: indexPath) if let moleculeView = cell as? MoleculeViewProtocol { diff --git a/MVMCoreUI/OtherHandlers/CoreUIModelMapping.swift b/MVMCoreUI/OtherHandlers/CoreUIModelMapping.swift index 9524c116..1c6dffc5 100644 --- a/MVMCoreUI/OtherHandlers/CoreUIModelMapping.swift +++ b/MVMCoreUI/OtherHandlers/CoreUIModelMapping.swift @@ -249,6 +249,7 @@ open class CoreUIModelMapping: ModelMapping { ModelRegistry.register(handler: ActionOpenPanelHandler.self, for: ActionOpenPanelModel.self) ModelRegistry.register(handler: ActionTopNotificationHandler.self, for: ActionTopNotificationModel.self) ModelRegistry.register(handler: MVMCoreUIActionOpenPageHandler.self, for: ActionOpenPageModel.self, allowsReplace: true) + ModelRegistry.register(handler: ActionNegateGone.self, for: ActionNegateGoneModel.self) } open class func registerRules() { From a691f8d71347df6bedb9e4c67120b615d363e44c Mon Sep 17 00:00:00 2001 From: Scott Pfeil Date: Thu, 8 Aug 2024 14:14:03 -0400 Subject: [PATCH 05/10] Digital PCT265 story VZWYZDG-1866 - Update name to proper jargon. --- MVMCoreUI/Atomic/Actions/ActionNegateGoneModel.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MVMCoreUI/Atomic/Actions/ActionNegateGoneModel.swift b/MVMCoreUI/Atomic/Actions/ActionNegateGoneModel.swift index 8bb28548..c7b5a661 100644 --- a/MVMCoreUI/Atomic/Actions/ActionNegateGoneModel.swift +++ b/MVMCoreUI/Atomic/Actions/ActionNegateGoneModel.swift @@ -10,7 +10,7 @@ import Foundation import MVMCore public struct ActionNegateGoneModel: ActionModelProtocol { - public static var identifier: String = "toggleGone" + public static var identifier: String = "negateGone" public var actionType: String = ActionNegateGoneModel.identifier public var extraParameters: JSONValueDictionary? public var analyticsData: JSONValueDictionary? From 715a911ee4e4169b72a59d5ed8be5ed5e7d13cdd Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Sat, 10 Aug 2024 11:30:47 -0500 Subject: [PATCH 06/10] fixed issue with vds refactor --- .../Item Dropdown/ItemDropdownEntryFieldModel.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/Dropdown Fields/Item Dropdown/ItemDropdownEntryFieldModel.swift b/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/Dropdown Fields/Item Dropdown/ItemDropdownEntryFieldModel.swift index f6f20b9f..04d880ae 100644 --- a/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/Dropdown Fields/Item Dropdown/ItemDropdownEntryFieldModel.swift +++ b/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/Dropdown Fields/Item Dropdown/ItemDropdownEntryFieldModel.swift @@ -17,7 +17,7 @@ import VDS public var options: [String] = [] public var selectedIndex: Int? public var showInlineLabel: Bool = false - public var feedbackTextPlacement: VDS.EntryFieldBase.HelperTextPlacement = .bottom + public var feedbackTextPlacement: VDS.DropdownSelect.HelperTextPlacement = .bottom public init(with options: [String], selectedIndex: Int? = nil) { self.options = options From 4921d7d8dbbd069c2302df7faf87dedbc871118a Mon Sep 17 00:00:00 2001 From: Scott Pfeil Date: Wed, 14 Aug 2024 11:33:40 -0400 Subject: [PATCH 07/10] Digital PCT265 story VZWYZDG-1866 - Updating format per code review. --- MVMCoreUI.xcodeproj/project.pbxproj | 16 +++---- .../Atomic/Actions/ActionNegateGone.swift | 38 --------------- .../Actions/ActionNegateGoneModel.swift | 24 ---------- .../Actions/ActionUpdateVisibility.swift | 47 +++++++++++++++++++ .../Actions/ActionUpdateVisibilityModel.swift | 42 +++++++++++++++++ .../OtherHandlers/CoreUIModelMapping.swift | 2 +- 6 files changed, 98 insertions(+), 71 deletions(-) delete mode 100644 MVMCoreUI/Atomic/Actions/ActionNegateGone.swift delete mode 100644 MVMCoreUI/Atomic/Actions/ActionNegateGoneModel.swift create mode 100644 MVMCoreUI/Atomic/Actions/ActionUpdateVisibility.swift create mode 100644 MVMCoreUI/Atomic/Actions/ActionUpdateVisibilityModel.swift diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index ac0a84ed..f7f5870b 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -308,8 +308,8 @@ AFA4933F29E874F0001A9663 /* MVMCoreUILoggingDelegateProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = AFA4933E29E874F0001A9663 /* MVMCoreUILoggingDelegateProtocol.swift */; }; AFA4935729EE3DCC001A9663 /* AlertDelegateProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = AFA4935629EE3DCC001A9663 /* AlertDelegateProtocol.swift */; }; AFB6336E2C65166E00791221 /* GoneableProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = AFB6336D2C65166E00791221 /* GoneableProtocol.swift */; }; - AFB633702C65175800791221 /* ActionNegateGone.swift in Sources */ = {isa = PBXBuildFile; fileRef = AFB6336F2C65175800791221 /* ActionNegateGone.swift */; }; - AFB633722C653C0900791221 /* ActionNegateGoneModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AFB633712C653C0900791221 /* ActionNegateGoneModel.swift */; }; + AFB633702C65175800791221 /* ActionUpdateVisibility.swift in Sources */ = {isa = PBXBuildFile; fileRef = AFB6336F2C65175800791221 /* ActionUpdateVisibility.swift */; }; + AFB633722C653C0900791221 /* ActionUpdateVisibilityModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AFB633712C653C0900791221 /* ActionUpdateVisibilityModel.swift */; }; AFE4A1D627DFBB6F00C458D0 /* UINavigationController+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = AFE4A1D527DFBB6F00C458D0 /* UINavigationController+Extension.swift */; }; B4CC8FBD29DF34680005D28B /* Badge.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4CC8FBC29DF34680005D28B /* Badge.swift */; }; B4CC8FBF29DF34730005D28B /* BadgeModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4CC8FBE29DF34730005D28B /* BadgeModel.swift */; }; @@ -935,8 +935,8 @@ AFA4933E29E874F0001A9663 /* MVMCoreUILoggingDelegateProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MVMCoreUILoggingDelegateProtocol.swift; sourceTree = ""; }; AFA4935629EE3DCC001A9663 /* AlertDelegateProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlertDelegateProtocol.swift; sourceTree = ""; }; AFB6336D2C65166E00791221 /* GoneableProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GoneableProtocol.swift; sourceTree = ""; }; - AFB6336F2C65175800791221 /* ActionNegateGone.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActionNegateGone.swift; sourceTree = ""; }; - AFB633712C653C0900791221 /* ActionNegateGoneModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActionNegateGoneModel.swift; sourceTree = ""; }; + AFB6336F2C65175800791221 /* ActionUpdateVisibility.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActionUpdateVisibility.swift; sourceTree = ""; }; + AFB633712C653C0900791221 /* ActionUpdateVisibilityModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActionUpdateVisibilityModel.swift; sourceTree = ""; }; AFE4A1D527DFBB6F00C458D0 /* UINavigationController+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UINavigationController+Extension.swift"; sourceTree = ""; }; B4CC8FBC29DF34680005D28B /* Badge.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Badge.swift; sourceTree = ""; }; B4CC8FBE29DF34730005D28B /* BadgeModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BadgeModel.swift; sourceTree = ""; }; @@ -1605,8 +1605,8 @@ AF1C33722885D481006B1001 /* MVMCoreUIActionOpenPageHandler.swift */, AF60A7F52892D2E300919EEB /* ActionDismissNotificationModel.swift */, AF60A7F72892D34D00919EEB /* ActionDismissNotificationHandler.swift */, - AFB633712C653C0900791221 /* ActionNegateGoneModel.swift */, - AFB6336F2C65175800791221 /* ActionNegateGone.swift */, + AFB633712C653C0900791221 /* ActionUpdateVisibilityModel.swift */, + AFB6336F2C65175800791221 /* ActionUpdateVisibility.swift */, ); path = Actions; sourceTree = ""; @@ -2853,7 +2853,7 @@ D2E2A99423D8CCBC000B42E6 /* HeadlineBodyLinkModel.swift in Sources */, 01004F3022721C3800991ECC /* RadioButton.swift in Sources */, D268C70E238C22D7007F2C1C /* DropDownFilterTableViewCell.swift in Sources */, - AFB633702C65175800791221 /* ActionNegateGone.swift in Sources */, + AFB633702C65175800791221 /* ActionUpdateVisibility.swift in Sources */, D236E5B7242007C500C38625 /* MVMControllerModelProtocol.swift in Sources */, AA71AD4024A32FE700ACA76F /* HeadersH2Link.swift in Sources */, D29DF11721E6805F003B2FB9 /* UIColor+MFConvenience.m in Sources */, @@ -2903,7 +2903,7 @@ D2E2A99D23DA3217000B42E6 /* UIStackViewAlignment+Extension.swift in Sources */, 01EB369423609801006832FA /* HeadlineBodyModel.swift in Sources */, D2A92884241ACB25004E01C6 /* ProgrammaticScrollViewController.swift in Sources */, - AFB633722C653C0900791221 /* ActionNegateGoneModel.swift in Sources */, + AFB633722C653C0900791221 /* ActionUpdateVisibilityModel.swift in Sources */, EA985C3E2970938F00F2FF2E /* Tilelet.swift in Sources */, D23A90002612347A007E14CE /* PageBehaviorContainerModelProtocol.swift in Sources */, EAA78020290081320057DFDF /* VDSMoleculeViewProtocol.swift in Sources */, diff --git a/MVMCoreUI/Atomic/Actions/ActionNegateGone.swift b/MVMCoreUI/Atomic/Actions/ActionNegateGone.swift deleted file mode 100644 index cc964c8b..00000000 --- a/MVMCoreUI/Atomic/Actions/ActionNegateGone.swift +++ /dev/null @@ -1,38 +0,0 @@ -// -// ActionToggleGone.swift -// MVMCoreUI -// -// Created by Scott Pfeil on 8/8/24. -// Copyright © 2024 Verizon Wireless. All rights reserved. -// - -import Foundation -import MVMCore - -public struct ActionNegateGone: MVMCoreActionHandlerProtocol { - - public enum ActionNegateGoneError: MVMError { - case moleculeNotFound(id: String) - } - - public init() {} - - public func execute(with model: any MVMCore.ActionModelProtocol, delegateObject: MVMCore.DelegateObject?, additionalData: [AnyHashable : Any]?) async throws { - guard let model = model as? ActionNegateGoneModel else { return } - guard let goneableModels: [GoneableProtocol & MoleculeModelProtocol] = (delegateObject as? MVMCoreUIDelegateObject)?.moleculeDelegate?.getRootMolecules().allMoleculesOfType(), - var goneableModel = goneableModels.first(where: { goneableModel in - goneableModel.id == model.id - }) else { throw ActionNegateGoneError.moleculeNotFound(id: model.id) } - goneableModel.gone = !goneableModel.gone - await (delegateObject as? MVMCoreUIDelegateObject)?.moleculeDelegate?.updateUI(for: [goneableModel]) - } -} - -extension ActionNegateGone.ActionNegateGoneError: CustomStringConvertible { - public var description: String { - switch self { - case .moleculeNotFound(id: let id): - "Unable to negate gone for molecule with id: \(id)" - } - } -} diff --git a/MVMCoreUI/Atomic/Actions/ActionNegateGoneModel.swift b/MVMCoreUI/Atomic/Actions/ActionNegateGoneModel.swift deleted file mode 100644 index c7b5a661..00000000 --- a/MVMCoreUI/Atomic/Actions/ActionNegateGoneModel.swift +++ /dev/null @@ -1,24 +0,0 @@ -// -// ActionToggleGoneModel.swift -// MVMCoreUI -// -// Created by Scott Pfeil on 8/8/24. -// Copyright © 2024 Verizon Wireless. All rights reserved. -// - -import Foundation -import MVMCore - -public struct ActionNegateGoneModel: ActionModelProtocol { - public static var identifier: String = "negateGone" - public var actionType: String = ActionNegateGoneModel.identifier - public var extraParameters: JSONValueDictionary? - public var analyticsData: JSONValueDictionary? - public var id: String - - public init(id: String, extraParameters: JSONValueDictionary? = nil, analyticsData: JSONValueDictionary? = nil) { - self.id = id - self.extraParameters = extraParameters - self.analyticsData = analyticsData - } -} diff --git a/MVMCoreUI/Atomic/Actions/ActionUpdateVisibility.swift b/MVMCoreUI/Atomic/Actions/ActionUpdateVisibility.swift new file mode 100644 index 00000000..315c3a38 --- /dev/null +++ b/MVMCoreUI/Atomic/Actions/ActionUpdateVisibility.swift @@ -0,0 +1,47 @@ +// +// ActionToggleGone.swift +// MVMCoreUI +// +// Created by Scott Pfeil on 8/8/24. +// Copyright © 2024 Verizon Wireless. All rights reserved. +// + +import Foundation +import MVMCore + +public struct ActionUpdateVisibility: MVMCoreActionHandlerProtocol { + + public init() {} + + public func execute(with model: any MVMCore.ActionModelProtocol, delegateObject: MVMCore.DelegateObject?, additionalData: [AnyHashable : Any]?) async throws { + guard let model = model as? ActionUpdateVisibilityModel, + let delegate = (delegateObject as? MVMCoreUIDelegateObject)?.moleculeDelegate else { return } + + let stateMap = model.targets.reduce(into: [String: ActionUpdateVisibilityModel.VisibilityTarget.VisibilityState]()) { + $0[$1.id] = $1.state + } + + let updatedModels: [MoleculeModelProtocol] = delegate.getRootMolecules().reduceDepthFirstTraverse(options: .parentFirst, depth: 0, initialResult: [], nextPartialResult: { accumulator, model, depth in + guard var model = model as? (GoneableProtocol & MoleculeModelProtocol), + let state = stateMap[model.id] else { return accumulator } + model.updateVisibility(state) + return accumulator + [model] + }) + + guard updatedModels.count > 0 else { return } + await delegate.updateUI(for: updatedModels) + } +} + +extension GoneableProtocol { + mutating func updateVisibility(_ state: ActionUpdateVisibilityModel.VisibilityTarget.VisibilityState) { + switch state { + case .true: + gone = false + case .false: + gone = true + case .inverted: + gone = !gone + } + } +} diff --git a/MVMCoreUI/Atomic/Actions/ActionUpdateVisibilityModel.swift b/MVMCoreUI/Atomic/Actions/ActionUpdateVisibilityModel.swift new file mode 100644 index 00000000..323e9a2d --- /dev/null +++ b/MVMCoreUI/Atomic/Actions/ActionUpdateVisibilityModel.swift @@ -0,0 +1,42 @@ +// +// ActionToggleGoneModel.swift +// MVMCoreUI +// +// Created by Scott Pfeil on 8/8/24. +// Copyright © 2024 Verizon Wireless. All rights reserved. +// + +import Foundation +import MVMCore + +public struct ActionUpdateVisibilityModel: ActionModelProtocol { + + public static var identifier: String = "updateVisibility" + public var actionType: String = ActionUpdateVisibilityModel.identifier + public var extraParameters: JSONValueDictionary? + public var analyticsData: JSONValueDictionary? + public var targets: [VisibilityTarget] + + public struct VisibilityTarget: Codable { + + public enum VisibilityState: String, Codable { + case `true` + case `false` + case inverted + } + + public var id: String + public var state: VisibilityState + + public init(id: String, state: VisibilityState) { + self.id = id + self.state = state + } + } + + public init(targets: [VisibilityTarget], extraParameters: JSONValueDictionary? = nil, analyticsData: JSONValueDictionary? = nil) { + self.targets = targets + self.extraParameters = extraParameters + self.analyticsData = analyticsData + } +} diff --git a/MVMCoreUI/OtherHandlers/CoreUIModelMapping.swift b/MVMCoreUI/OtherHandlers/CoreUIModelMapping.swift index 1c6dffc5..c45936cf 100644 --- a/MVMCoreUI/OtherHandlers/CoreUIModelMapping.swift +++ b/MVMCoreUI/OtherHandlers/CoreUIModelMapping.swift @@ -249,7 +249,7 @@ open class CoreUIModelMapping: ModelMapping { ModelRegistry.register(handler: ActionOpenPanelHandler.self, for: ActionOpenPanelModel.self) ModelRegistry.register(handler: ActionTopNotificationHandler.self, for: ActionTopNotificationModel.self) ModelRegistry.register(handler: MVMCoreUIActionOpenPageHandler.self, for: ActionOpenPageModel.self, allowsReplace: true) - ModelRegistry.register(handler: ActionNegateGone.self, for: ActionNegateGoneModel.self) + ModelRegistry.register(handler: ActionUpdateVisibility.self, for: ActionUpdateVisibilityModel.self) } open class func registerRules() { From 17a94e2f040748841c0138a3fa9cc60a840f75a0 Mon Sep 17 00:00:00 2001 From: Scott Pfeil Date: Wed, 14 Aug 2024 12:32:50 -0400 Subject: [PATCH 08/10] Digital PCT265 story VZWYZDG-1866 - Ensure the footer stays at the bottom. --- MVMCoreUI/Atomic/Templates/MoleculeListTemplate.swift | 3 +++ 1 file changed, 3 insertions(+) diff --git a/MVMCoreUI/Atomic/Templates/MoleculeListTemplate.swift b/MVMCoreUI/Atomic/Templates/MoleculeListTemplate.swift index 218c1eeb..3e78dc86 100644 --- a/MVMCoreUI/Atomic/Templates/MoleculeListTemplate.swift +++ b/MVMCoreUI/Atomic/Templates/MoleculeListTemplate.swift @@ -282,6 +282,9 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol if let selectedIndex = selectedIndex { tableView.selectRow(at: selectedIndex, animated: false, scrollPosition: .none) } + + // If the height of the cells change, we need to update the constraints. + view.setNeedsUpdateConstraints() } ///Helper functions to update header/footer view From 33dc411743ca02e5597dde80e5f1eda21df51e93 Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Thu, 15 Aug 2024 11:08:25 -0500 Subject: [PATCH 09/10] Fix for the reset() issue with default properties being reset for buttonGroup Signed-off-by: Matt Bruce --- .../TwoButtonView.swift | 37 +++++++++++-------- .../TwoLinkView.swift | 19 ++++++---- 2 files changed, 32 insertions(+), 24 deletions(-) diff --git a/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TwoButtonView.swift b/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TwoButtonView.swift index 536bc16b..6610a04e 100644 --- a/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TwoButtonView.swift +++ b/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TwoButtonView.swift @@ -10,7 +10,7 @@ import UIKit import VDS @objcMembers open class TwoButtonView: VDS.View, VDSMoleculeViewProtocol { - + //-------------------------------------------------- // MARK: - Properties //-------------------------------------------------- @@ -31,29 +31,36 @@ import VDS isAccessibilityElement = false addSubview(buttonGroup) buttonGroup.pinToSuperView() + heightConstraint = height(constant: VDS.Button.Size.large.height, priority: .required) + } + + open override func setDefaults() { + super.setDefaults() buttonGroup.alignment = .center buttonGroup.rowQuantityPhone = 2 buttonGroup.rowQuantityTablet = 2 - heightConstraint = height(constant: VDS.Button.Size.large.height, priority: .required) } - + + open override func reset() { + buttonGroup.reset() + super.reset() + } + //-------------------------------------------------- // MARK: - MoleculeViewProtocol //-------------------------------------------------- - open override func reset() { - super.reset() - buttonGroup.reset() - } - public static func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { guard let model = model as? TwoButtonViewModel, - let buttonModel = model.primaryButton ?? model.secondaryButton - else { return 0 } + let buttonModel = model.primaryButton ?? model.secondaryButton + else { return 0 } return PillButton.estimatedHeight(with: buttonModel, delegateObject) } - + + //-------------------------------------------------- + // MARK: - VDSMoleculeViewProtocol + //-------------------------------------------------- public func viewModelDidUpdate() { var buttons = [PillButton]() if let secondaryModel = viewModel.secondaryButton { @@ -65,7 +72,7 @@ import VDS primaryButton.set(with: primaryModel, delegateObject, additionalData) buttons.append(primaryButton) } - + buttonGroup.childWidth = viewModel.fillContainer ? .percentage(100) : nil if buttons.count != buttonGroup.buttons.count { @@ -74,7 +81,7 @@ import VDS heightConstraint?.constant = primaryButton.size == .small || secondaryButton.size == .small ? VDS.Button.Size.small.height : VDS.Button.Size.large.height } - + //-------------------------------------------------- // MARK: - MVMCoreUIViewConstrainingProtocol //-------------------------------------------------- @@ -87,7 +94,5 @@ import VDS // MARK: - MVMCoreViewProtocol //-------------------------------------------------- - public func updateView(_ size: CGFloat) { - setNeedsUpdate() - } + public func updateView(_ size: CGFloat) {} } diff --git a/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TwoLinkView.swift b/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TwoLinkView.swift index 32c546f9..1fdf5658 100644 --- a/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TwoLinkView.swift +++ b/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TwoLinkView.swift @@ -32,21 +32,20 @@ import VDS isAccessibilityElement = false addSubview(buttonGroup) buttonGroup.pinToSuperView() + } + + open override func setDefaults() { + super.setDefaults() buttonGroup.alignment = .center buttonGroup.rowQuantityPhone = 2 buttonGroup.rowQuantityTablet = 2 } - - //-------------------------------------------------- - // MARK: - MVMCoreViewProtocol - //-------------------------------------------------- + open override func reset() { - super.reset() buttonGroup.reset() + super.reset() } - open func updateView(_ size: CGFloat) { } - //-------------------------------------------------- // MARK: - Stack Manipulation //-------------------------------------------------- @@ -90,7 +89,8 @@ import VDS //-------------------------------------------------- // MARK: - MoleculeViewProtocol //-------------------------------------------------- - + open func updateView(_ size: CGFloat) { } + public static func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { guard let model = model as? TwoButtonViewModel, let buttonModel = model.primaryButton ?? model.secondaryButton @@ -99,6 +99,9 @@ import VDS return PillButton.estimatedHeight(with: buttonModel, delegateObject) } + //-------------------------------------------------- + // MARK: - VDSMoleculeViewProtocol + //-------------------------------------------------- public func viewModelDidUpdate() { buttons.removeAll() From e89272a3cdb73bee3279c82399ed956444ede935 Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Thu, 15 Aug 2024 12:31:50 -0500 Subject: [PATCH 10/10] comments on the order of operations in reset() Signed-off-by: Matt Bruce --- .../Molecules/HorizontalCombinationViews/TwoButtonView.swift | 2 ++ .../Molecules/HorizontalCombinationViews/TwoLinkView.swift | 2 ++ 2 files changed, 4 insertions(+) diff --git a/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TwoButtonView.swift b/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TwoButtonView.swift index 6610a04e..f57c5801 100644 --- a/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TwoButtonView.swift +++ b/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TwoButtonView.swift @@ -42,6 +42,8 @@ import VDS } open override func reset() { + //we want to reset() all local views/controls first before calling + //super since super.reset() calls setDefaults(). buttonGroup.reset() super.reset() } diff --git a/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TwoLinkView.swift b/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TwoLinkView.swift index 1fdf5658..a9890618 100644 --- a/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TwoLinkView.swift +++ b/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TwoLinkView.swift @@ -42,6 +42,8 @@ import VDS } open override func reset() { + //we want to reset() all local views/controls first before calling + //super since super.reset() calls setDefaults(). buttonGroup.reset() super.reset() }