insert molecule transformation hooks into the list template
This commit is contained in:
parent
da646a29a6
commit
bd9e8cf7ad
@ -128,6 +128,7 @@
|
|||||||
0AF60F0926B3316E00AC3DB4 /* MVMCoreUIUtility+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AF60F0826B3316E00AC3DB4 /* MVMCoreUIUtility+Extension.swift */; };
|
0AF60F0926B3316E00AC3DB4 /* MVMCoreUIUtility+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AF60F0826B3316E00AC3DB4 /* MVMCoreUIUtility+Extension.swift */; };
|
||||||
1D6D258826899B0C00DEBB08 /* ImageButtonModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D6D258626899B0B00DEBB08 /* ImageButtonModel.swift */; };
|
1D6D258826899B0C00DEBB08 /* ImageButtonModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D6D258626899B0B00DEBB08 /* ImageButtonModel.swift */; };
|
||||||
1D6D258926899B0C00DEBB08 /* ImageButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D6D258726899B0B00DEBB08 /* ImageButton.swift */; };
|
1D6D258926899B0C00DEBB08 /* ImageButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D6D258726899B0B00DEBB08 /* ImageButton.swift */; };
|
||||||
|
27559EFC27D691D3000836C1 /* ViewMaskingProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 27559EFB27D691D3000836C1 /* ViewMaskingProtocol.swift */; };
|
||||||
279B1569242BBC2F00921D6C /* ActionModelAdapter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 279B1568242BBC2F00921D6C /* ActionModelAdapter.swift */; };
|
279B1569242BBC2F00921D6C /* ActionModelAdapter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 279B1568242BBC2F00921D6C /* ActionModelAdapter.swift */; };
|
||||||
27F6B08826051831008529AA /* MoleculeTreeTraversalProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 27F6B08726051831008529AA /* MoleculeTreeTraversalProtocol.swift */; };
|
27F6B08826051831008529AA /* MoleculeTreeTraversalProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 27F6B08726051831008529AA /* MoleculeTreeTraversalProtocol.swift */; };
|
||||||
27F6B08C26052AFF008529AA /* ParentMoleculeModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 27F6B08B26052AFF008529AA /* ParentMoleculeModelProtocol.swift */; };
|
27F6B08C26052AFF008529AA /* ParentMoleculeModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 27F6B08B26052AFF008529AA /* ParentMoleculeModelProtocol.swift */; };
|
||||||
@ -711,6 +712,7 @@
|
|||||||
0AF60F0826B3316E00AC3DB4 /* MVMCoreUIUtility+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MVMCoreUIUtility+Extension.swift"; sourceTree = "<group>"; };
|
0AF60F0826B3316E00AC3DB4 /* MVMCoreUIUtility+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MVMCoreUIUtility+Extension.swift"; sourceTree = "<group>"; };
|
||||||
1D6D258626899B0B00DEBB08 /* ImageButtonModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = ImageButtonModel.swift; path = MVMCoreUI/Atomic/Atoms/Buttons/ImageButtonModel.swift; sourceTree = SOURCE_ROOT; };
|
1D6D258626899B0B00DEBB08 /* ImageButtonModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = ImageButtonModel.swift; path = MVMCoreUI/Atomic/Atoms/Buttons/ImageButtonModel.swift; sourceTree = SOURCE_ROOT; };
|
||||||
1D6D258726899B0B00DEBB08 /* ImageButton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = ImageButton.swift; path = MVMCoreUI/Atomic/Atoms/Buttons/ImageButton.swift; sourceTree = SOURCE_ROOT; };
|
1D6D258726899B0B00DEBB08 /* ImageButton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = ImageButton.swift; path = MVMCoreUI/Atomic/Atoms/Buttons/ImageButton.swift; sourceTree = SOURCE_ROOT; };
|
||||||
|
27559EFB27D691D3000836C1 /* ViewMaskingProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewMaskingProtocol.swift; sourceTree = "<group>"; };
|
||||||
279B1568242BBC2F00921D6C /* ActionModelAdapter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActionModelAdapter.swift; sourceTree = "<group>"; };
|
279B1568242BBC2F00921D6C /* ActionModelAdapter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActionModelAdapter.swift; sourceTree = "<group>"; };
|
||||||
27F6B08726051831008529AA /* MoleculeTreeTraversalProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MoleculeTreeTraversalProtocol.swift; sourceTree = "<group>"; };
|
27F6B08726051831008529AA /* MoleculeTreeTraversalProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MoleculeTreeTraversalProtocol.swift; sourceTree = "<group>"; };
|
||||||
27F6B08B26052AFF008529AA /* ParentMoleculeModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ParentMoleculeModelProtocol.swift; sourceTree = "<group>"; };
|
27F6B08B26052AFF008529AA /* ParentMoleculeModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ParentMoleculeModelProtocol.swift; sourceTree = "<group>"; };
|
||||||
@ -2389,6 +2391,7 @@
|
|||||||
D28BA7442481652D00B75CB8 /* TabBarProtocol.swift */,
|
D28BA7442481652D00B75CB8 /* TabBarProtocol.swift */,
|
||||||
D2B9D0E3265EEE9D0084735C /* MoleculeListProtocol.swift */,
|
D2B9D0E3265EEE9D0084735C /* MoleculeListProtocol.swift */,
|
||||||
011B58EE23A2AA850085F53C /* ModelProtocols */,
|
011B58EE23A2AA850085F53C /* ModelProtocols */,
|
||||||
|
27559EFB27D691D3000836C1 /* ViewMaskingProtocol.swift */,
|
||||||
);
|
);
|
||||||
path = Protocols;
|
path = Protocols;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -2854,6 +2857,7 @@
|
|||||||
D23EA800247EBD6C00D60C34 /* LabelBarButtonItem.swift in Sources */,
|
D23EA800247EBD6C00D60C34 /* LabelBarButtonItem.swift in Sources */,
|
||||||
01EB368F23609801006832FA /* LabelModel.swift in Sources */,
|
01EB368F23609801006832FA /* LabelModel.swift in Sources */,
|
||||||
0A6682AC243531C300AD3CA1 /* Padding.swift in Sources */,
|
0A6682AC243531C300AD3CA1 /* Padding.swift in Sources */,
|
||||||
|
27559EFC27D691D3000836C1 /* ViewMaskingProtocol.swift in Sources */,
|
||||||
AA1EC59924373994003D6F50 /* ListThreeColumnSpeedTestDivider.swift in Sources */,
|
AA1EC59924373994003D6F50 /* ListThreeColumnSpeedTestDivider.swift in Sources */,
|
||||||
AA37CBD52519072F0027344C /* Stars.swift in Sources */,
|
AA37CBD52519072F0027344C /* Stars.swift in Sources */,
|
||||||
942C378E2412F5B60066E45E /* ModalMoleculeStackTemplate.swift in Sources */,
|
942C378E2412F5B60066E45E /* ModalMoleculeStackTemplate.swift in Sources */,
|
||||||
|
|||||||
@ -42,6 +42,7 @@ import Foundation
|
|||||||
public var wasInitiallySelected: Bool = false
|
public var wasInitiallySelected: Bool = false
|
||||||
public var title: String?
|
public var title: String?
|
||||||
public var feedback: String?
|
public var feedback: String?
|
||||||
|
public var shouldMaskRecordedView: Bool = true
|
||||||
|
|
||||||
//used to drive the EntryFieldView UI
|
//used to drive the EntryFieldView UI
|
||||||
public var titleStateLabel: FormLabelModel
|
public var titleStateLabel: FormLabelModel
|
||||||
@ -79,6 +80,7 @@ import Foundation
|
|||||||
case fieldKey
|
case fieldKey
|
||||||
case groupName
|
case groupName
|
||||||
case required
|
case required
|
||||||
|
case shouldMaskRecordedView
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -143,6 +145,7 @@ import Foundation
|
|||||||
hideBorders = try typeContainer.decodeIfPresent(Bool.self, forKey: .hideBorders) ?? false
|
hideBorders = try typeContainer.decodeIfPresent(Bool.self, forKey: .hideBorders) ?? false
|
||||||
baseValue = text
|
baseValue = text
|
||||||
fieldKey = try typeContainer.decodeIfPresent(String.self, forKey: .fieldKey)
|
fieldKey = try typeContainer.decodeIfPresent(String.self, forKey: .fieldKey)
|
||||||
|
shouldMaskRecordedView = try typeContainer.decode(Bool.self, forKey: .shouldMaskRecordedView)
|
||||||
if let groupName = try typeContainer.decodeIfPresent(String.self, forKey: .groupName) {
|
if let groupName = try typeContainer.decodeIfPresent(String.self, forKey: .groupName) {
|
||||||
self.groupName = groupName
|
self.groupName = groupName
|
||||||
}
|
}
|
||||||
@ -172,5 +175,6 @@ import Foundation
|
|||||||
try container.encode(enabled, forKey: .enabled)
|
try container.encode(enabled, forKey: .enabled)
|
||||||
try container.encode(required, forKey: .required)
|
try container.encode(required, forKey: .required)
|
||||||
try container.encode(hideBorders, forKey: .hideBorders)
|
try container.encode(hideBorders, forKey: .hideBorders)
|
||||||
|
try container.encode(shouldMaskRecordedView, forKey: .shouldMaskRecordedView)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -338,12 +338,16 @@ import UIKit
|
|||||||
text = model.text
|
text = model.text
|
||||||
placeholder = model.placeholder
|
placeholder = model.placeholder
|
||||||
|
|
||||||
|
textField.shouldMaskWhileRecording = model.shouldMaskRecordedView
|
||||||
|
|
||||||
switch model.type {
|
switch model.type {
|
||||||
case .password, .secure:
|
case .password, .secure:
|
||||||
textField.isSecureTextEntry = true
|
textField.isSecureTextEntry = true
|
||||||
|
textField.shouldMaskWhileRecording = true
|
||||||
|
|
||||||
case .numberSecure:
|
case .numberSecure:
|
||||||
textField.isSecureTextEntry = true
|
textField.isSecureTextEntry = true
|
||||||
|
textField.shouldMaskWhileRecording = true
|
||||||
textField.keyboardType = .numberPad
|
textField.keyboardType = .numberPad
|
||||||
|
|
||||||
case .number:
|
case .number:
|
||||||
|
|||||||
@ -22,6 +22,7 @@
|
|||||||
public var baseValue: AnyHashable?
|
public var baseValue: AnyHashable?
|
||||||
public var enabled: Bool = true
|
public var enabled: Bool = true
|
||||||
public var readOnly: Bool = false
|
public var readOnly: Bool = false
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Methods
|
// MARK: - Methods
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
|
|||||||
@ -12,7 +12,8 @@ import MVMCore
|
|||||||
public typealias ActionBlock = () -> ()
|
public typealias ActionBlock = () -> ()
|
||||||
|
|
||||||
|
|
||||||
@objcMembers open class Label: UILabel, MVMCoreViewProtocol, MoleculeViewProtocol, MVMCoreUIViewConstrainingProtocol, MFButtonProtocol {
|
@objcMembers open class Label: UILabel, MVMCoreViewProtocol, MoleculeViewProtocol, MVMCoreUIViewConstrainingProtocol, MFButtonProtocol, ViewMaskingProtocol {
|
||||||
|
|
||||||
//------------------------------------------------------
|
//------------------------------------------------------
|
||||||
// MARK: - Properties
|
// MARK: - Properties
|
||||||
//------------------------------------------------------
|
//------------------------------------------------------
|
||||||
@ -41,6 +42,8 @@ public typealias ActionBlock = () -> ()
|
|||||||
NSRange(location: 0, length: text?.count ?? 0)
|
NSRange(location: 0, length: text?.count ?? 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public var shouldMaskWhileRecording: Bool = false
|
||||||
|
|
||||||
//------------------------------------------------------
|
//------------------------------------------------------
|
||||||
// MARK: - Multi-Action Text
|
// MARK: - Multi-Action Text
|
||||||
//------------------------------------------------------
|
//------------------------------------------------------
|
||||||
@ -244,6 +247,7 @@ public typealias ActionBlock = () -> ()
|
|||||||
text = nil
|
text = nil
|
||||||
attributedText = nil
|
attributedText = nil
|
||||||
originalAttributedString = nil
|
originalAttributedString = nil
|
||||||
|
shouldMaskWhileRecording = model.shouldMaskRecordedView
|
||||||
|
|
||||||
guard let labelModel = model as? LabelModel else { return }
|
guard let labelModel = model as? LabelModel else { return }
|
||||||
|
|
||||||
|
|||||||
@ -26,6 +26,7 @@
|
|||||||
public var hero: Int?
|
public var hero: Int?
|
||||||
public var makeWholeViewClickable: Bool?
|
public var makeWholeViewClickable: Bool?
|
||||||
public var numberOfLines: Int?
|
public var numberOfLines: Int?
|
||||||
|
public var shouldMaskRecordedView: Bool = false
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Keys
|
// MARK: - Keys
|
||||||
@ -46,6 +47,7 @@
|
|||||||
case hero
|
case hero
|
||||||
case makeWholeViewClickable
|
case makeWholeViewClickable
|
||||||
case numberOfLines
|
case numberOfLines
|
||||||
|
case shouldMaskRecordedView
|
||||||
}
|
}
|
||||||
|
|
||||||
enum AttributeTypeKey: String, CodingKey {
|
enum AttributeTypeKey: String, CodingKey {
|
||||||
@ -79,6 +81,7 @@
|
|||||||
hero = try typeContainer.decodeIfPresent(Int.self, forKey: .hero)
|
hero = try typeContainer.decodeIfPresent(Int.self, forKey: .hero)
|
||||||
makeWholeViewClickable = try typeContainer.decodeIfPresent(Bool.self, forKey: .makeWholeViewClickable)
|
makeWholeViewClickable = try typeContainer.decodeIfPresent(Bool.self, forKey: .makeWholeViewClickable)
|
||||||
numberOfLines = try typeContainer.decodeIfPresent(Int.self, forKey: .numberOfLines)
|
numberOfLines = try typeContainer.decodeIfPresent(Int.self, forKey: .numberOfLines)
|
||||||
|
shouldMaskRecordedView = try typeContainer.decodeIfPresent(Bool.self, forKey: .shouldMaskRecordedView) ?? false
|
||||||
}
|
}
|
||||||
|
|
||||||
open func encode(to encoder: Encoder) throws {
|
open func encode(to encoder: Encoder) throws {
|
||||||
@ -97,5 +100,6 @@
|
|||||||
try container.encodeIfPresent(hero, forKey: .hero)
|
try container.encodeIfPresent(hero, forKey: .hero)
|
||||||
try container.encodeIfPresent(makeWholeViewClickable, forKey: .makeWholeViewClickable)
|
try container.encodeIfPresent(makeWholeViewClickable, forKey: .makeWholeViewClickable)
|
||||||
try container.encodeIfPresent(numberOfLines, forKey: .numberOfLines)
|
try container.encodeIfPresent(numberOfLines, forKey: .numberOfLines)
|
||||||
|
try container.encodeIfPresent(shouldMaskRecordedView, forKey: .shouldMaskRecordedView)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,6 +8,7 @@ public enum MolecularError: Swift.Error {
|
|||||||
public protocol MoleculeModelProtocol: ModelProtocol, AccessibilityModelProtocol, MoleculeTreeTraversalProtocol {
|
public protocol MoleculeModelProtocol: ModelProtocol, AccessibilityModelProtocol, MoleculeTreeTraversalProtocol {
|
||||||
var moleculeName: String { get }
|
var moleculeName: String { get }
|
||||||
var backgroundColor: Color? { get set }
|
var backgroundColor: Color? { get set }
|
||||||
|
var shouldMaskRecordedView: Bool { get }
|
||||||
}
|
}
|
||||||
|
|
||||||
public extension MoleculeModelProtocol {
|
public extension MoleculeModelProtocol {
|
||||||
@ -17,6 +18,8 @@ public extension MoleculeModelProtocol {
|
|||||||
static var categoryName: String { "\(MoleculeModelProtocol.self)" }
|
static var categoryName: String { "\(MoleculeModelProtocol.self)" }
|
||||||
|
|
||||||
static var categoryCodingKey: String { "moleculeName" }
|
static var categoryCodingKey: String { "moleculeName" }
|
||||||
|
|
||||||
|
var shouldMaskRecordedView: Bool { return false }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -13,4 +13,5 @@ public protocol PageModelProtocol {
|
|||||||
var screenHeading: String? { get set }
|
var screenHeading: String? { get set }
|
||||||
var backgroundColor: Color? { get set }
|
var backgroundColor: Color? { get set }
|
||||||
var navigationBar: (NavigationItemModelProtocol & MoleculeModelProtocol)? { get set }
|
var navigationBar: (NavigationItemModelProtocol & MoleculeModelProtocol)? { get set }
|
||||||
|
var shouldMaskScreenWhileRecording: Bool { get }
|
||||||
}
|
}
|
||||||
|
|||||||
@ -28,6 +28,7 @@ public extension TemplateProtocol where Self: ViewController {
|
|||||||
traverseAndAddRequiredBehaviors()
|
traverseAndAddRequiredBehaviors()
|
||||||
var behaviorHandler = self
|
var behaviorHandler = self
|
||||||
behaviorHandler.createBehaviors(for: model, delegateObject: delegateObjectIVar)
|
behaviorHandler.createBehaviors(for: model, delegateObject: delegateObjectIVar)
|
||||||
|
MVMCoreUISession.sharedGlobal()?.applyGlobalBehaviors(to: self)
|
||||||
}
|
}
|
||||||
|
|
||||||
func decodeTemplate(using decoder: JSONDecoder, from data: Data) throws -> TemplateModel {
|
func decodeTemplate(using decoder: JSONDecoder, from data: Data) throws -> TemplateModel {
|
||||||
|
|||||||
21
MVMCoreUI/Atomic/Protocols/ViewMaskingProtocol.swift
Normal file
21
MVMCoreUI/Atomic/Protocols/ViewMaskingProtocol.swift
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
//
|
||||||
|
// ViewMaskingProtocol.swift
|
||||||
|
// MVMCoreUI
|
||||||
|
//
|
||||||
|
// Created by Kyle on 3/7/22.
|
||||||
|
// Copyright © 2022 Verizon Wireless. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
public protocol ViewMaskingProtocol: UIView {
|
||||||
|
|
||||||
|
var shouldMaskWhileRecording: Bool { get }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public protocol ViewMaskingContainerProtocol {
|
||||||
|
|
||||||
|
var maskedViewsWhileRecording: [UIView] { get }
|
||||||
|
|
||||||
|
}
|
||||||
@ -60,7 +60,7 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol
|
|||||||
|
|
||||||
open override func viewForTop() -> UIView {
|
open override func viewForTop() -> UIView {
|
||||||
guard let headerModel = templateModel?.header,
|
guard let headerModel = templateModel?.header,
|
||||||
let molecule = ModelRegistry.createMolecule(headerModel, delegateObject: delegateObjectIVar)
|
let molecule = generateMoleculeView(from: headerModel)
|
||||||
else { return super.viewForTop() }
|
else { return super.viewForTop() }
|
||||||
|
|
||||||
// Temporary, Default the horizontal padding
|
// Temporary, Default the horizontal padding
|
||||||
@ -73,7 +73,7 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol
|
|||||||
|
|
||||||
override open func viewForBottom() -> UIView {
|
override open func viewForBottom() -> UIView {
|
||||||
guard let footerModel = templateModel?.footer,
|
guard let footerModel = templateModel?.footer,
|
||||||
let molecule = ModelRegistry.createMolecule(footerModel, delegateObject: delegateObjectIVar)
|
let molecule = generateMoleculeView(from: footerModel)
|
||||||
else { return super.viewForBottom() }
|
else { return super.viewForBottom() }
|
||||||
|
|
||||||
return molecule
|
return molecule
|
||||||
@ -142,7 +142,9 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol
|
|||||||
|
|
||||||
(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)
|
||||||
(cell as? MoleculeViewProtocol)?.set(with: moleculeInfo.molecule, delegateObjectIVar, nil)
|
if let moleculeView = cell as? MoleculeViewProtocol {
|
||||||
|
updateMoleculeView(moleculeView, from: moleculeInfo.molecule)
|
||||||
|
}
|
||||||
(cell as? MVMCoreViewProtocol)?.updateView(tableView.bounds.width)
|
(cell as? MVMCoreViewProtocol)?.updateView(tableView.bounds.width)
|
||||||
// Neded to fix an apple defect where the cell is not the correct size on certain devices for certain cells
|
// Neded to fix an apple defect where the cell is not the correct size on certain devices for certain cells
|
||||||
cell.layoutIfNeeded()
|
cell.layoutIfNeeded()
|
||||||
|
|||||||
@ -10,6 +10,7 @@ import Foundation
|
|||||||
|
|
||||||
|
|
||||||
@objcMembers open class TemplateModel: MVMControllerModelProtocol, TabPageModelProtocol {
|
@objcMembers open class TemplateModel: MVMControllerModelProtocol, TabPageModelProtocol {
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Properties
|
// MARK: - Properties
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -31,6 +32,9 @@ import Foundation
|
|||||||
public var tabBarHidden: Bool = false
|
public var tabBarHidden: Bool = false
|
||||||
public var tabBarIndex: Int?
|
public var tabBarIndex: Int?
|
||||||
|
|
||||||
|
// By default we mask until the server unlocks the page.
|
||||||
|
public var shouldMaskScreenWhileRecording: Bool = false
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Initializer
|
// MARK: - Initializer
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -53,6 +57,7 @@ import Foundation
|
|||||||
case navigationBar
|
case navigationBar
|
||||||
case tabBarHidden
|
case tabBarHidden
|
||||||
case tabBarIndex
|
case tabBarIndex
|
||||||
|
case shouldMaskScreenWhileRecording
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -77,6 +82,7 @@ import Foundation
|
|||||||
self.tabBarHidden = tabBarHidden
|
self.tabBarHidden = tabBarHidden
|
||||||
}
|
}
|
||||||
tabBarIndex = try typeContainer.decodeIfPresent(Int.self, forKey: .tabBarIndex)
|
tabBarIndex = try typeContainer.decodeIfPresent(Int.self, forKey: .tabBarIndex)
|
||||||
|
shouldMaskScreenWhileRecording = try typeContainer.decodeIfPresent(Bool.self, forKey: .shouldMaskScreenWhileRecording) ?? shouldMaskScreenWhileRecording
|
||||||
}
|
}
|
||||||
|
|
||||||
open func encode(to encoder: Encoder) throws {
|
open func encode(to encoder: Encoder) throws {
|
||||||
@ -89,5 +95,6 @@ import Foundation
|
|||||||
try container.encodeModelIfPresent(navigationBar, forKey: .navigationBar)
|
try container.encodeModelIfPresent(navigationBar, forKey: .navigationBar)
|
||||||
try container.encode(tabBarHidden, forKey: .tabBarHidden)
|
try container.encode(tabBarHidden, forKey: .tabBarHidden)
|
||||||
try container.encodeIfPresent(tabBarIndex, forKey: .tabBarIndex)
|
try container.encodeIfPresent(tabBarIndex, forKey: .tabBarIndex)
|
||||||
|
try container.encode(shouldMaskScreenWhileRecording, forKey: .shouldMaskScreenWhileRecording)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,12 +8,13 @@
|
|||||||
|
|
||||||
import UIKit
|
import UIKit
|
||||||
|
|
||||||
public protocol TextInputDidDeleteProtocol: class {
|
public protocol TextInputDidDeleteProtocol: AnyObject {
|
||||||
func textInputDidDelete()
|
func textInputDidDelete()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@objcMembers open class TextField: UITextField {
|
@objcMembers open class TextField: UITextField, ViewMaskingProtocol {
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Properties
|
// MARK: - Properties
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -23,6 +24,8 @@ public protocol TextInputDidDeleteProtocol: class {
|
|||||||
/// Set to true to hide the blinking textField cursor.
|
/// Set to true to hide the blinking textField cursor.
|
||||||
public var hideBlinkingCaret = false
|
public var hideBlinkingCaret = false
|
||||||
|
|
||||||
|
public var shouldMaskWhileRecording: Bool = true
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Delegate
|
// MARK: - Delegate
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -97,6 +100,8 @@ extension TextField: MoleculeViewProtocol {
|
|||||||
if let accessibilityIdentifier = model.accessibilityIdentifier {
|
if let accessibilityIdentifier = model.accessibilityIdentifier {
|
||||||
self.accessibilityIdentifier = accessibilityIdentifier
|
self.accessibilityIdentifier = accessibilityIdentifier
|
||||||
}
|
}
|
||||||
|
|
||||||
|
shouldMaskWhileRecording = model.shouldMaskRecordedView
|
||||||
}
|
}
|
||||||
|
|
||||||
open func reset() {
|
open func reset() {
|
||||||
|
|||||||
@ -9,7 +9,8 @@
|
|||||||
import UIKit
|
import UIKit
|
||||||
|
|
||||||
|
|
||||||
@objcMembers open class View: UIView, MoleculeViewProtocol {
|
@objcMembers open class View: UIView, MoleculeViewProtocol, ViewMaskingProtocol {
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Properties
|
// MARK: - Properties
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -18,6 +19,10 @@ import UIKit
|
|||||||
|
|
||||||
private var initialSetupPerformed = false
|
private var initialSetupPerformed = false
|
||||||
|
|
||||||
|
public var shouldMaskWhileRecording: Bool {
|
||||||
|
return model?.shouldMaskRecordedView ?? false
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Initialization
|
// MARK: - Initialization
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
|
|||||||
@ -230,7 +230,7 @@ import UIKit
|
|||||||
let navigationItem = createDefaultLegacyNavigationModel()
|
let navigationItem = createDefaultLegacyNavigationModel()
|
||||||
model?.navigationBar = navigationItem
|
model?.navigationBar = navigationItem
|
||||||
}
|
}
|
||||||
|
self.model?.template
|
||||||
executeBehaviors { (behavior: PageMoleculeTransformationBehavior) in
|
executeBehaviors { (behavior: PageMoleculeTransformationBehavior) in
|
||||||
behavior.onPageNew(rootMolecules: getRootMolecules(), delegateObjectIVar)
|
behavior.onPageNew(rootMolecules: getRootMolecules(), delegateObjectIVar)
|
||||||
}
|
}
|
||||||
@ -254,6 +254,27 @@ import UIKit
|
|||||||
manager?.newDataReceived?(in: self)
|
manager?.newDataReceived?(in: self)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public func generateMoleculeView(from model: MoleculeModelProtocol) -> MoleculeViewProtocol? {
|
||||||
|
executeBehaviors { (behavior: PageMoleculeTransformationBehavior) in
|
||||||
|
behavior.willSetupMolecule(with: model, updating: nil)
|
||||||
|
}
|
||||||
|
guard let moleculeView = ModelRegistry.createMolecule(model, delegateObject: delegateObjectIVar) else { return nil }
|
||||||
|
executeBehaviors { (behavior: PageMoleculeTransformationBehavior) in
|
||||||
|
behavior.didSetupMolecule(view: moleculeView, withModel: model)
|
||||||
|
}
|
||||||
|
return moleculeView
|
||||||
|
}
|
||||||
|
|
||||||
|
public func updateMoleculeView(_ view: MoleculeViewProtocol, from model: MoleculeModelProtocol) {
|
||||||
|
executeBehaviors { (behavior: PageMoleculeTransformationBehavior) in
|
||||||
|
behavior.willSetupMolecule(with: model, updating: view)
|
||||||
|
}
|
||||||
|
view.set(with: model, delegateObjectIVar, nil)
|
||||||
|
executeBehaviors { (behavior: PageMoleculeTransformationBehavior) in
|
||||||
|
behavior.didSetupMolecule(view: view, withModel: model)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Navigation Item
|
// MARK: - Navigation Item
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
|
|||||||
@ -15,7 +15,6 @@ public extension PageBehaviorHandlerProtocol {
|
|||||||
/// Creates the behaviors and sets the variable.
|
/// Creates the behaviors and sets the variable.
|
||||||
mutating func createBehaviors(for model: PageBehaviorHandlerModelProtocol, delegateObject: MVMCoreUIDelegateObject?) {
|
mutating func createBehaviors(for model: PageBehaviorHandlerModelProtocol, delegateObject: MVMCoreUIDelegateObject?) {
|
||||||
guard let behaviorModels = model.behaviors else {
|
guard let behaviorModels = model.behaviors else {
|
||||||
behaviors = nil
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -32,6 +31,9 @@ public extension PageBehaviorHandlerProtocol {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.behaviors = behaviors.count > 0 ? behaviors : nil
|
|
||||||
|
if behaviors.count > 0 {
|
||||||
|
self.behaviors = behaviors + (self.behaviors ?? [])
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -20,6 +20,15 @@ public protocol PageBehaviorProtocol: ModelHandlerProtocol {
|
|||||||
public protocol PageMoleculeTransformationBehavior: PageBehaviorProtocol {
|
public protocol PageMoleculeTransformationBehavior: PageBehaviorProtocol {
|
||||||
|
|
||||||
func onPageNew(rootMolecules: [MoleculeModelProtocol], _ delegateObject: MVMCoreUIDelegateObject)
|
func onPageNew(rootMolecules: [MoleculeModelProtocol], _ delegateObject: MVMCoreUIDelegateObject)
|
||||||
|
func willSetupMolecule(with model: MoleculeModelProtocol, updating view: MoleculeViewProtocol?)
|
||||||
|
func didSetupMolecule(view: MoleculeViewProtocol, withModel: MoleculeModelProtocol)
|
||||||
|
}
|
||||||
|
|
||||||
|
public extension PageMoleculeTransformationBehavior {
|
||||||
|
// All optional.
|
||||||
|
func onPageNew(rootMolecules: [MoleculeModelProtocol], _ delegateObject: MVMCoreUIDelegateObject) {}
|
||||||
|
func willSetupMolecule(with model: MoleculeModelProtocol, updating view: MoleculeViewProtocol?) {}
|
||||||
|
func didSetupMolecule(view: MoleculeViewProtocol, withModel: MoleculeModelProtocol) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
public protocol PageVisibilityBehavior: PageBehaviorProtocol {
|
public protocol PageVisibilityBehavior: PageBehaviorProtocol {
|
||||||
|
|||||||
@ -13,6 +13,7 @@
|
|||||||
@class MFViewController;
|
@class MFViewController;
|
||||||
@class MFLoadingViewController;
|
@class MFLoadingViewController;
|
||||||
@class NavigationController;
|
@class NavigationController;
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_BEGIN
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
@interface MVMCoreUISession : MVMCoreSessionObject
|
@interface MVMCoreUISession : MVMCoreSessionObject
|
||||||
@ -25,18 +26,21 @@ NS_ASSUME_NONNULL_BEGIN
|
|||||||
/// Tracks the current page type the user is currently viewing. KVO compliant.
|
/// Tracks the current page type the user is currently viewing. KVO compliant.
|
||||||
@property (nonatomic, strong, nullable) NSString *currentPageType;
|
@property (nonatomic, strong, nullable) NSString *currentPageType;
|
||||||
|
|
||||||
// for handscroll Animation on subclasses of MFScrollingViewController
|
/// for handscroll Animation on subclasses of MFScrollingViewController
|
||||||
@property (assign, nonatomic) BOOL enableHandScrollAnimation;
|
@property (assign, nonatomic) BOOL enableHandScrollAnimation;
|
||||||
|
|
||||||
//indicates if the app launched successfully
|
/// indicates if the app launched successfully
|
||||||
@property (assign, nonatomic) BOOL launchAppLoadedSuccessfully;
|
@property (assign, nonatomic) BOOL launchAppLoadedSuccessfully;
|
||||||
|
|
||||||
// Allows a global overload of the title view of navigation item.
|
/// Allows a global overload of the title view of navigation item.
|
||||||
- (nullable UIView *)titleViewForController:(nonnull MFViewController *)controller;
|
- (nullable UIView *)titleViewForController:(nonnull MFViewController *)controller;
|
||||||
|
|
||||||
// Sets up the session as delegate for standard load view controller. Pass the view controller that will be used to present and will be disabled when load view is presented.
|
/// Sets up the session as delegate for standard load view controller. Pass the view controller that will be used to present and will be disabled when load view is presented.
|
||||||
- (void)setupAsStandardLoadViewDelegate:(nonnull UIViewController *)mainViewController;
|
- (void)setupAsStandardLoadViewDelegate:(nonnull UIViewController *)mainViewController;
|
||||||
|
|
||||||
|
/// Applies additional behaviors to a controller according to the session. Allows for packages to add additional cross cutting concerns.
|
||||||
|
- (void)applyGlobalBehaviorsToController:(nonnull UIViewController *)viewController;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_END
|
NS_ASSUME_NONNULL_END
|
||||||
|
|||||||
@ -62,4 +62,8 @@
|
|||||||
self.mainViewController.view.userInteractionEnabled = YES;
|
self.mainViewController.view.userInteractionEnabled = YES;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)applyGlobalBehaviorsToController:(nonnull UIViewController *)viewController {
|
||||||
|
// Allow extending frameworks to apply behaviors to add cross cutting concerns to the base controllers.
|
||||||
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user