Merge remote-tracking branch 'refs/remotes/origin/develop'
This commit is contained in:
commit
6354174857
@ -307,6 +307,9 @@
|
|||||||
AFA4932229E5EF2E001A9663 /* NotificationHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = AFA4932129E5EF2E001A9663 /* NotificationHandler.swift */; };
|
AFA4932229E5EF2E001A9663 /* NotificationHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = AFA4932129E5EF2E001A9663 /* NotificationHandler.swift */; };
|
||||||
AFA4933F29E874F0001A9663 /* MVMCoreUILoggingDelegateProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = AFA4933E29E874F0001A9663 /* MVMCoreUILoggingDelegateProtocol.swift */; };
|
AFA4933F29E874F0001A9663 /* MVMCoreUILoggingDelegateProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = AFA4933E29E874F0001A9663 /* MVMCoreUILoggingDelegateProtocol.swift */; };
|
||||||
AFA4935729EE3DCC001A9663 /* AlertDelegateProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = AFA4935629EE3DCC001A9663 /* AlertDelegateProtocol.swift */; };
|
AFA4935729EE3DCC001A9663 /* AlertDelegateProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = AFA4935629EE3DCC001A9663 /* AlertDelegateProtocol.swift */; };
|
||||||
|
AFB6336E2C65166E00791221 /* GoneableProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = AFB6336D2C65166E00791221 /* GoneableProtocol.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 */; };
|
AFE4A1D627DFBB6F00C458D0 /* UINavigationController+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = AFE4A1D527DFBB6F00C458D0 /* UINavigationController+Extension.swift */; };
|
||||||
B4CC8FBD29DF34680005D28B /* Badge.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4CC8FBC29DF34680005D28B /* Badge.swift */; };
|
B4CC8FBD29DF34680005D28B /* Badge.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4CC8FBC29DF34680005D28B /* Badge.swift */; };
|
||||||
B4CC8FBF29DF34730005D28B /* BadgeModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4CC8FBE29DF34730005D28B /* BadgeModel.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 = "<group>"; };
|
AFA4932129E5EF2E001A9663 /* NotificationHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationHandler.swift; sourceTree = "<group>"; };
|
||||||
AFA4933E29E874F0001A9663 /* MVMCoreUILoggingDelegateProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MVMCoreUILoggingDelegateProtocol.swift; sourceTree = "<group>"; };
|
AFA4933E29E874F0001A9663 /* MVMCoreUILoggingDelegateProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MVMCoreUILoggingDelegateProtocol.swift; sourceTree = "<group>"; };
|
||||||
AFA4935629EE3DCC001A9663 /* AlertDelegateProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlertDelegateProtocol.swift; sourceTree = "<group>"; };
|
AFA4935629EE3DCC001A9663 /* AlertDelegateProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlertDelegateProtocol.swift; sourceTree = "<group>"; };
|
||||||
|
AFB6336D2C65166E00791221 /* GoneableProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GoneableProtocol.swift; sourceTree = "<group>"; };
|
||||||
|
AFB6336F2C65175800791221 /* ActionUpdateVisibility.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActionUpdateVisibility.swift; sourceTree = "<group>"; };
|
||||||
|
AFB633712C653C0900791221 /* ActionUpdateVisibilityModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActionUpdateVisibilityModel.swift; sourceTree = "<group>"; };
|
||||||
AFE4A1D527DFBB6F00C458D0 /* UINavigationController+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UINavigationController+Extension.swift"; sourceTree = "<group>"; };
|
AFE4A1D527DFBB6F00C458D0 /* UINavigationController+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UINavigationController+Extension.swift"; sourceTree = "<group>"; };
|
||||||
B4CC8FBC29DF34680005D28B /* Badge.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Badge.swift; sourceTree = "<group>"; };
|
B4CC8FBC29DF34680005D28B /* Badge.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Badge.swift; sourceTree = "<group>"; };
|
||||||
B4CC8FBE29DF34730005D28B /* BadgeModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BadgeModel.swift; sourceTree = "<group>"; };
|
B4CC8FBE29DF34730005D28B /* BadgeModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BadgeModel.swift; sourceTree = "<group>"; };
|
||||||
@ -1287,6 +1293,7 @@
|
|||||||
27F6B08B26052AFF008529AA /* ParentMoleculeModelProtocol.swift */,
|
27F6B08B26052AFF008529AA /* ParentMoleculeModelProtocol.swift */,
|
||||||
27577DCC286CA959001EC47E /* MoleculeMaskingProtocol.swift */,
|
27577DCC286CA959001EC47E /* MoleculeMaskingProtocol.swift */,
|
||||||
58E7561C2BE04C320088BB5D /* MoleculeComparisonProtocol.swift */,
|
58E7561C2BE04C320088BB5D /* MoleculeComparisonProtocol.swift */,
|
||||||
|
AFB6336D2C65166E00791221 /* GoneableProtocol.swift */,
|
||||||
);
|
);
|
||||||
path = ModelProtocols;
|
path = ModelProtocols;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -1598,6 +1605,8 @@
|
|||||||
AF1C33722885D481006B1001 /* MVMCoreUIActionOpenPageHandler.swift */,
|
AF1C33722885D481006B1001 /* MVMCoreUIActionOpenPageHandler.swift */,
|
||||||
AF60A7F52892D2E300919EEB /* ActionDismissNotificationModel.swift */,
|
AF60A7F52892D2E300919EEB /* ActionDismissNotificationModel.swift */,
|
||||||
AF60A7F72892D34D00919EEB /* ActionDismissNotificationHandler.swift */,
|
AF60A7F72892D34D00919EEB /* ActionDismissNotificationHandler.swift */,
|
||||||
|
AFB633712C653C0900791221 /* ActionUpdateVisibilityModel.swift */,
|
||||||
|
AFB6336F2C65175800791221 /* ActionUpdateVisibility.swift */,
|
||||||
);
|
);
|
||||||
path = Actions;
|
path = Actions;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -2844,6 +2853,7 @@
|
|||||||
D2E2A99423D8CCBC000B42E6 /* HeadlineBodyLinkModel.swift in Sources */,
|
D2E2A99423D8CCBC000B42E6 /* HeadlineBodyLinkModel.swift in Sources */,
|
||||||
01004F3022721C3800991ECC /* RadioButton.swift in Sources */,
|
01004F3022721C3800991ECC /* RadioButton.swift in Sources */,
|
||||||
D268C70E238C22D7007F2C1C /* DropDownFilterTableViewCell.swift in Sources */,
|
D268C70E238C22D7007F2C1C /* DropDownFilterTableViewCell.swift in Sources */,
|
||||||
|
AFB633702C65175800791221 /* ActionUpdateVisibility.swift in Sources */,
|
||||||
D236E5B7242007C500C38625 /* MVMControllerModelProtocol.swift in Sources */,
|
D236E5B7242007C500C38625 /* MVMControllerModelProtocol.swift in Sources */,
|
||||||
AA71AD4024A32FE700ACA76F /* HeadersH2Link.swift in Sources */,
|
AA71AD4024A32FE700ACA76F /* HeadersH2Link.swift in Sources */,
|
||||||
D29DF11721E6805F003B2FB9 /* UIColor+MFConvenience.m in Sources */,
|
D29DF11721E6805F003B2FB9 /* UIColor+MFConvenience.m in Sources */,
|
||||||
@ -2893,6 +2903,7 @@
|
|||||||
D2E2A99D23DA3217000B42E6 /* UIStackViewAlignment+Extension.swift in Sources */,
|
D2E2A99D23DA3217000B42E6 /* UIStackViewAlignment+Extension.swift in Sources */,
|
||||||
01EB369423609801006832FA /* HeadlineBodyModel.swift in Sources */,
|
01EB369423609801006832FA /* HeadlineBodyModel.swift in Sources */,
|
||||||
D2A92884241ACB25004E01C6 /* ProgrammaticScrollViewController.swift in Sources */,
|
D2A92884241ACB25004E01C6 /* ProgrammaticScrollViewController.swift in Sources */,
|
||||||
|
AFB633722C653C0900791221 /* ActionUpdateVisibilityModel.swift in Sources */,
|
||||||
EA985C3E2970938F00F2FF2E /* Tilelet.swift in Sources */,
|
EA985C3E2970938F00F2FF2E /* Tilelet.swift in Sources */,
|
||||||
D23A90002612347A007E14CE /* PageBehaviorContainerModelProtocol.swift in Sources */,
|
D23A90002612347A007E14CE /* PageBehaviorContainerModelProtocol.swift in Sources */,
|
||||||
EAA78020290081320057DFDF /* VDSMoleculeViewProtocol.swift in Sources */,
|
EAA78020290081320057DFDF /* VDSMoleculeViewProtocol.swift in Sources */,
|
||||||
@ -3176,6 +3187,7 @@
|
|||||||
D2092355244FA0FD0044AD09 /* ThreeLayerTemplateModelProtocol.swift in Sources */,
|
D2092355244FA0FD0044AD09 /* ThreeLayerTemplateModelProtocol.swift in Sources */,
|
||||||
0AE14F64238315D2005417F8 /* TextField.swift in Sources */,
|
0AE14F64238315D2005417F8 /* TextField.swift in Sources */,
|
||||||
0A51F3E22475CB73002E08B6 /* LoadingSpinnerModel.swift in Sources */,
|
0A51F3E22475CB73002E08B6 /* LoadingSpinnerModel.swift in Sources */,
|
||||||
|
AFB6336E2C65166E00791221 /* GoneableProtocol.swift in Sources */,
|
||||||
D2169303251E53D9002A6324 /* SectionListTemplateModel.swift in Sources */,
|
D2169303251E53D9002A6324 /* SectionListTemplateModel.swift in Sources */,
|
||||||
EA6642932BCDA97D00D81DC4 /* TileContainerModel.swift in Sources */,
|
EA6642932BCDA97D00D81DC4 /* TileContainerModel.swift in Sources */,
|
||||||
AF7E509929E477C1009DC2AD /* AlertController.swift in Sources */,
|
AF7E509929E477C1009DC2AD /* AlertController.swift in Sources */,
|
||||||
|
|||||||
47
MVMCoreUI/Atomic/Actions/ActionUpdateVisibility.swift
Normal file
47
MVMCoreUI/Atomic/Actions/ActionUpdateVisibility.swift
Normal file
@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
42
MVMCoreUI/Atomic/Actions/ActionUpdateVisibilityModel.swift
Normal file
42
MVMCoreUI/Atomic/Actions/ActionUpdateVisibilityModel.swift
Normal file
@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -17,7 +17,7 @@ import VDS
|
|||||||
public var options: [String] = []
|
public var options: [String] = []
|
||||||
public var selectedIndex: Int?
|
public var selectedIndex: Int?
|
||||||
public var showInlineLabel: Bool = false
|
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) {
|
public init(with options: [String], selectedIndex: Int? = nil) {
|
||||||
self.options = options
|
self.options = options
|
||||||
|
|||||||
@ -31,29 +31,38 @@ import VDS
|
|||||||
isAccessibilityElement = false
|
isAccessibilityElement = false
|
||||||
addSubview(buttonGroup)
|
addSubview(buttonGroup)
|
||||||
buttonGroup.pinToSuperView()
|
buttonGroup.pinToSuperView()
|
||||||
|
heightConstraint = height(constant: VDS.Button.Size.large.height, priority: .required)
|
||||||
|
}
|
||||||
|
|
||||||
|
open override func setDefaults() {
|
||||||
|
super.setDefaults()
|
||||||
buttonGroup.alignment = .center
|
buttonGroup.alignment = .center
|
||||||
buttonGroup.rowQuantityPhone = 2
|
buttonGroup.rowQuantityPhone = 2
|
||||||
buttonGroup.rowQuantityTablet = 2
|
buttonGroup.rowQuantityTablet = 2
|
||||||
heightConstraint = height(constant: VDS.Button.Size.large.height, priority: .required)
|
}
|
||||||
|
|
||||||
|
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()
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - MoleculeViewProtocol
|
// MARK: - MoleculeViewProtocol
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
|
|
||||||
open override func reset() {
|
|
||||||
super.reset()
|
|
||||||
buttonGroup.reset()
|
|
||||||
}
|
|
||||||
|
|
||||||
public static func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? {
|
public static func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? {
|
||||||
guard let model = model as? TwoButtonViewModel,
|
guard let model = model as? TwoButtonViewModel,
|
||||||
let buttonModel = model.primaryButton ?? model.secondaryButton
|
let buttonModel = model.primaryButton ?? model.secondaryButton
|
||||||
else { return 0 }
|
else { return 0 }
|
||||||
|
|
||||||
return PillButton.estimatedHeight(with: buttonModel, delegateObject)
|
return PillButton.estimatedHeight(with: buttonModel, delegateObject)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - VDSMoleculeViewProtocol
|
||||||
|
//--------------------------------------------------
|
||||||
public func viewModelDidUpdate() {
|
public func viewModelDidUpdate() {
|
||||||
var buttons = [PillButton]()
|
var buttons = [PillButton]()
|
||||||
if let secondaryModel = viewModel.secondaryButton {
|
if let secondaryModel = viewModel.secondaryButton {
|
||||||
@ -87,7 +96,5 @@ import VDS
|
|||||||
// MARK: - MVMCoreViewProtocol
|
// MARK: - MVMCoreViewProtocol
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
|
|
||||||
public func updateView(_ size: CGFloat) {
|
public func updateView(_ size: CGFloat) {}
|
||||||
setNeedsUpdate()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -32,21 +32,22 @@ import VDS
|
|||||||
isAccessibilityElement = false
|
isAccessibilityElement = false
|
||||||
addSubview(buttonGroup)
|
addSubview(buttonGroup)
|
||||||
buttonGroup.pinToSuperView()
|
buttonGroup.pinToSuperView()
|
||||||
|
}
|
||||||
|
|
||||||
|
open override func setDefaults() {
|
||||||
|
super.setDefaults()
|
||||||
buttonGroup.alignment = .center
|
buttonGroup.alignment = .center
|
||||||
buttonGroup.rowQuantityPhone = 2
|
buttonGroup.rowQuantityPhone = 2
|
||||||
buttonGroup.rowQuantityTablet = 2
|
buttonGroup.rowQuantityTablet = 2
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------
|
|
||||||
// MARK: - MVMCoreViewProtocol
|
|
||||||
//--------------------------------------------------
|
|
||||||
open override func reset() {
|
open override func reset() {
|
||||||
super.reset()
|
//we want to reset() all local views/controls first before calling
|
||||||
|
//super since super.reset() calls setDefaults().
|
||||||
buttonGroup.reset()
|
buttonGroup.reset()
|
||||||
|
super.reset()
|
||||||
}
|
}
|
||||||
|
|
||||||
open func updateView(_ size: CGFloat) { }
|
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Stack Manipulation
|
// MARK: - Stack Manipulation
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -90,6 +91,7 @@ import VDS
|
|||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - MoleculeViewProtocol
|
// MARK: - MoleculeViewProtocol
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
|
open func updateView(_ size: CGFloat) { }
|
||||||
|
|
||||||
public static func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? {
|
public static func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? {
|
||||||
guard let model = model as? TwoButtonViewModel,
|
guard let model = model as? TwoButtonViewModel,
|
||||||
@ -99,6 +101,9 @@ import VDS
|
|||||||
return PillButton.estimatedHeight(with: buttonModel, delegateObject)
|
return PillButton.estimatedHeight(with: buttonModel, delegateObject)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - VDSMoleculeViewProtocol
|
||||||
|
//--------------------------------------------------
|
||||||
public func viewModelDidUpdate() {
|
public func viewModelDidUpdate() {
|
||||||
buttons.removeAll()
|
buttons.removeAll()
|
||||||
|
|
||||||
|
|||||||
@ -7,8 +7,7 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
|
|
||||||
public protocol StackItemModelProtocol {
|
public protocol StackItemModelProtocol: GoneableProtocol {
|
||||||
var spacing: CGFloat? { get set }
|
var spacing: CGFloat? { get set }
|
||||||
var percent: Int? { get set }
|
var percent: Int? { get set }
|
||||||
var gone: Bool { get set }
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,9 +7,8 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
|
|
||||||
public protocol CarouselItemModelProtocol: FormFieldProtocol, ContainerModelProtocol {
|
public protocol CarouselItemModelProtocol: FormFieldProtocol, ContainerModelProtocol, GoneableProtocol {
|
||||||
var analyticsData: JSONValueDictionary? { get set }
|
var analyticsData: JSONValueDictionary? { get set }
|
||||||
var gone: Bool { get set }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public extension CarouselItemModelProtocol {
|
public extension CarouselItemModelProtocol {
|
||||||
|
|||||||
@ -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 }
|
||||||
|
}
|
||||||
@ -15,12 +15,11 @@ public enum ListItemStyle: String, Codable {
|
|||||||
case none
|
case none
|
||||||
}
|
}
|
||||||
|
|
||||||
public protocol ListItemModelProtocol: ContainerModelProtocol, AccessibilityModelProtocol {
|
public protocol ListItemModelProtocol: ContainerModelProtocol, AccessibilityModelProtocol, GoneableProtocol {
|
||||||
var line: LineModel? { get set }
|
var line: LineModel? { get set }
|
||||||
var action: ActionModelProtocol? { get set }
|
var action: ActionModelProtocol? { get set }
|
||||||
var hideArrow: Bool? { get set }
|
var hideArrow: Bool? { get set }
|
||||||
var style: ListItemStyle? { get set }
|
var style: ListItemStyle? { get set }
|
||||||
var gone: Bool { get set }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Not a strict requirement.
|
// Not a strict requirement.
|
||||||
|
|||||||
@ -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.
|
/// 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
|
func moleculeLayoutUpdated(_ molecule: MoleculeViewProtocol) //optional
|
||||||
|
|
||||||
|
/// Updates the UI for the updated models.
|
||||||
|
@MainActor
|
||||||
|
func updateUI(for molecules: [MoleculeModelProtocol]?)
|
||||||
}
|
}
|
||||||
|
|
||||||
extension MoleculeDelegateProtocol {
|
extension MoleculeDelegateProtocol {
|
||||||
|
|||||||
@ -148,7 +148,7 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol
|
|||||||
}
|
}
|
||||||
|
|
||||||
open func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
|
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 {
|
open func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
|
||||||
@ -168,7 +168,7 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol
|
|||||||
guard let moleculeInfo = getMoleculeInfo(for: indexPath),
|
guard let moleculeInfo = getMoleculeInfo(for: indexPath),
|
||||||
let cell = tableView.dequeueReusableCell(withIdentifier: moleculeInfo.identifier)
|
let cell = tableView.dequeueReusableCell(withIdentifier: moleculeInfo.identifier)
|
||||||
else { return UITableViewCell() }
|
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? MoleculeViewProtocol)?.reset()
|
||||||
(cell as? MoleculeListCellProtocol)?.setLines(with: templateModel?.line, delegateObject: delegateObjectIVar, additionalData: nil, indexPath: indexPath)
|
(cell as? MoleculeListCellProtocol)?.setLines(with: templateModel?.line, delegateObject: delegateObjectIVar, additionalData: nil, indexPath: indexPath)
|
||||||
if let moleculeView = cell as? MoleculeViewProtocol {
|
if let moleculeView = cell as? MoleculeViewProtocol {
|
||||||
@ -282,6 +282,9 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol
|
|||||||
if let selectedIndex = selectedIndex {
|
if let selectedIndex = selectedIndex {
|
||||||
tableView.selectRow(at: selectedIndex, animated: false, scrollPosition: .none)
|
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
|
///Helper functions to update header/footer view
|
||||||
|
|||||||
@ -33,6 +33,9 @@
|
|||||||
- (void)showArrow;
|
- (void)showArrow;
|
||||||
- (void)hideArrow;
|
- (void)hideArrow;
|
||||||
|
|
||||||
|
/// Orientation supported by the panel.
|
||||||
|
- (UIInterfaceOrientationMask)supportedInterface;
|
||||||
|
|
||||||
/// The width to use if the panel is automatically extended when the screen is big enough.
|
/// The width to use if the panel is automatically extended when the screen is big enough.
|
||||||
- (CGFloat)panelExtendedWidth;
|
- (CGFloat)panelExtendedWidth;
|
||||||
|
|
||||||
|
|||||||
@ -59,6 +59,13 @@ typedef NS_ENUM(NSInteger, MFNumberOfDrawers) {
|
|||||||
|
|
||||||
@property (nullable, strong, nonatomic) NSSet *cancellables;
|
@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
|
// Convenience getter
|
||||||
+ (nullable instancetype)mainSplitViewController;
|
+ (nullable instancetype)mainSplitViewController;
|
||||||
|
|
||||||
@ -131,6 +138,8 @@ typedef NS_ENUM(NSInteger, MFNumberOfDrawers) {
|
|||||||
|
|
||||||
/// Returns true if a panel is showing.
|
/// Returns true if a panel is showing.
|
||||||
- (BOOL)isAPanelShowing;
|
- (BOOL)isAPanelShowing;
|
||||||
|
- (BOOL)isLeftPanelShowing;
|
||||||
|
- (BOOL)isRightPanelShowing;
|
||||||
|
|
||||||
#pragma mark - Main Subclassables
|
#pragma mark - Main Subclassables
|
||||||
|
|
||||||
|
|||||||
@ -679,6 +679,11 @@ CGFloat const PanelAnimationDuration = 0.2;
|
|||||||
[protocolController panelDidAppear:panel];
|
[protocolController panelDidAppear:panel];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (@available(iOS 16.0, *)) {
|
||||||
|
if ([panel respondsToSelector:@selector(supportedInterface)]) {
|
||||||
|
[controller setNeedsUpdateOfSupportedInterfaceOrientations];
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)panelWillDisappear:(UIViewController <MVMCoreUIPanelProtocol> *)panel animated:(BOOL)animated {
|
- (void)panelWillDisappear:(UIViewController <MVMCoreUIPanelProtocol> *)panel animated:(BOOL)animated {
|
||||||
@ -709,6 +714,11 @@ CGFloat const PanelAnimationDuration = 0.2;
|
|||||||
[protocolController panelDidDisappear:panel];
|
[protocolController panelDidDisappear:panel];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (@available(iOS 16.0, *)) {
|
||||||
|
if ([panel respondsToSelector:@selector(supportedInterface)]) {
|
||||||
|
[controller setNeedsUpdateOfSupportedInterfaceOrientations];
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)addPanel:(nonnull UIViewController <MVMCoreUIPanelProtocol> *)panel {
|
- (void)addPanel:(nonnull UIViewController <MVMCoreUIPanelProtocol> *)panel {
|
||||||
@ -999,7 +1009,9 @@ CGFloat const PanelAnimationDuration = 0.2;
|
|||||||
|
|
||||||
CGFloat leftPanelExtendedWidth = [self leftPanelExtendedWidth];
|
CGFloat leftPanelExtendedWidth = [self leftPanelExtendedWidth];
|
||||||
CGFloat leftPanelMaxWidth = [self leftPanelMaxWidth];
|
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;
|
self.leftPanelWidth.constant = leftPanelExtendedWidth;
|
||||||
} else if (viewWidth > leftPanelMaxWidth) {
|
} else if (viewWidth > leftPanelMaxWidth) {
|
||||||
self.leftPanelWidth.constant = leftPanelMaxWidth;
|
self.leftPanelWidth.constant = leftPanelMaxWidth;
|
||||||
@ -1009,7 +1021,9 @@ CGFloat const PanelAnimationDuration = 0.2;
|
|||||||
|
|
||||||
CGFloat rightPanelExtendedWidth = [self rightPanelExtendedWidth];
|
CGFloat rightPanelExtendedWidth = [self rightPanelExtendedWidth];
|
||||||
CGFloat rightPanelMaxWidth = [self rightPanelMaxWidth];
|
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;
|
self.rightPanelWidth.constant = rightPanelExtendedWidth;
|
||||||
} else if (viewWidth > rightPanelMaxWidth) {
|
} else if (viewWidth > rightPanelMaxWidth) {
|
||||||
self.rightPanelWidth.constant = rightPanelMaxWidth;
|
self.rightPanelWidth.constant = rightPanelMaxWidth;
|
||||||
@ -1063,6 +1077,14 @@ CGFloat const PanelAnimationDuration = 0.2;
|
|||||||
return fabs(self.mainViewLeading.constant) > 1;
|
return fabs(self.mainViewLeading.constant) > 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (BOOL)isLeftPanelShowing {
|
||||||
|
return !self.leftView.isHidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL)isRightPanelShowing {
|
||||||
|
return !self.rightView.isHidden;
|
||||||
|
}
|
||||||
|
|
||||||
#pragma mark - Getters
|
#pragma mark - Getters
|
||||||
|
|
||||||
// Returns the desired view or falls back. Hot fix until we can get away from using these functions...
|
// Returns the desired view or falls back. Hot fix until we can get away from using these functions...
|
||||||
|
|||||||
@ -249,6 +249,7 @@ open class CoreUIModelMapping: ModelMapping {
|
|||||||
ModelRegistry.register(handler: ActionOpenPanelHandler.self, for: ActionOpenPanelModel.self)
|
ModelRegistry.register(handler: ActionOpenPanelHandler.self, for: ActionOpenPanelModel.self)
|
||||||
ModelRegistry.register(handler: ActionTopNotificationHandler.self, for: ActionTopNotificationModel.self)
|
ModelRegistry.register(handler: ActionTopNotificationHandler.self, for: ActionTopNotificationModel.self)
|
||||||
ModelRegistry.register(handler: MVMCoreUIActionOpenPageHandler.self, for: ActionOpenPageModel.self, allowsReplace: true)
|
ModelRegistry.register(handler: MVMCoreUIActionOpenPageHandler.self, for: ActionOpenPageModel.self, allowsReplace: true)
|
||||||
|
ModelRegistry.register(handler: ActionUpdateVisibility.self, for: ActionUpdateVisibilityModel.self)
|
||||||
}
|
}
|
||||||
|
|
||||||
open class func registerRules() {
|
open class func registerRules() {
|
||||||
|
|||||||
@ -102,4 +102,22 @@ public extension MVMCoreUIUtility {
|
|||||||
return nil
|
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()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user