Merge branch 'develop' into feature/models
This commit is contained in:
commit
4111080497
@ -52,6 +52,8 @@
|
||||
0A41BA6E2344FCD400D4C0BC /* CATransaction+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A41BA6D2344FCD400D4C0BC /* CATransaction+Extension.swift */; };
|
||||
0A7BAD74232A8DC700FB8E22 /* HeadlineBodyButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7BAD73232A8DC700FB8E22 /* HeadlineBodyButton.swift */; };
|
||||
0A7BAFA1232BE61800FB8E22 /* Checkbox.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7BAFA0232BE61800FB8E22 /* Checkbox.swift */; };
|
||||
943784F5236B77BB006A1E82 /* GraphView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 943784F3236B77BB006A1E82 /* GraphView.swift */; };
|
||||
943784F6236B77BB006A1E82 /* GraphViewAnimationHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 943784F4236B77BB006A1E82 /* GraphViewAnimationHandler.swift */; };
|
||||
9455B19C234F8A0400A574DB /* MVMAnimationFramework.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9455B19B234F8A0400A574DB /* MVMAnimationFramework.framework */; };
|
||||
948DB67E2326DCD90011F916 /* MultiProgress.swift in Sources */ = {isa = PBXBuildFile; fileRef = 948DB67D2326DCD90011F916 /* MultiProgress.swift */; };
|
||||
D206997721FB8A0B00CAE0DE /* MVMCoreUINavigationController.h in Headers */ = {isa = PBXBuildFile; fileRef = D206997521FB8A0B00CAE0DE /* MVMCoreUINavigationController.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
@ -271,6 +273,8 @@
|
||||
0A7BAD73232A8DC700FB8E22 /* HeadlineBodyButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeadlineBodyButton.swift; sourceTree = "<group>"; };
|
||||
0A7BAFA0232BE61800FB8E22 /* Checkbox.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Checkbox.swift; sourceTree = "<group>"; };
|
||||
0A7BAFA2232BE63400FB8E22 /* CheckboxWithLabelView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CheckboxWithLabelView.swift; sourceTree = "<group>"; };
|
||||
943784F3236B77BB006A1E82 /* GraphView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GraphView.swift; sourceTree = "<group>"; };
|
||||
943784F4236B77BB006A1E82 /* GraphViewAnimationHandler.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GraphViewAnimationHandler.swift; sourceTree = "<group>"; };
|
||||
9455B19B234F8A0400A574DB /* MVMAnimationFramework.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MVMAnimationFramework.framework; path = ../SharedFrameworks/MVMAnimationFramework.framework; sourceTree = "<group>"; };
|
||||
948DB67D2326DCD90011F916 /* MultiProgress.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MultiProgress.swift; sourceTree = "<group>"; };
|
||||
D206997521FB8A0B00CAE0DE /* MVMCoreUINavigationController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MVMCoreUINavigationController.h; sourceTree = "<group>"; };
|
||||
@ -845,6 +849,8 @@
|
||||
0A7BAFA0232BE61800FB8E22 /* Checkbox.swift */,
|
||||
0A7BAFA2232BE63400FB8E22 /* CheckboxWithLabelView.swift */,
|
||||
01004F2F22721C3800991ECC /* RadioButton.swift */,
|
||||
943784F3236B77BB006A1E82 /* GraphView.swift */,
|
||||
943784F4236B77BB006A1E82 /* GraphViewAnimationHandler.swift */,
|
||||
);
|
||||
path = Views;
|
||||
sourceTree = "<group>";
|
||||
@ -1134,6 +1140,7 @@
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
943784F5236B77BB006A1E82 /* GraphView.swift in Sources */,
|
||||
D29DF32121ED0CBA003B2FB9 /* LabelView.m in Sources */,
|
||||
DBC4391822442197001AB423 /* CaretView.swift in Sources */,
|
||||
D29770F221F7C6D600B2F0D0 /* TopLabelsAndBottomButtonsTableViewController.m in Sources */,
|
||||
@ -1240,6 +1247,7 @@
|
||||
D2E1FADF2268B8E700AEFD8C /* ThreeLayerTableViewController.swift in Sources */,
|
||||
D20A9A5E2243D3E300ADE781 /* TwoButtonView.swift in Sources */,
|
||||
D2B1E3E522F37D6A0065F95C /* ImageHeadlineBody.swift in Sources */,
|
||||
943784F6236B77BB006A1E82 /* GraphViewAnimationHandler.swift in Sources */,
|
||||
D29DF2AA21E7B2F9003B2FB9 /* MVMCoreUIConstants.m in Sources */,
|
||||
948DB67E2326DCD90011F916 /* MultiProgress.swift in Sources */,
|
||||
01EB3682236092AE006832FA /* HolderManager.swift in Sources */,
|
||||
|
||||
@ -669,7 +669,7 @@
|
||||
|
||||
- (void)setWithJSON:(NSDictionary *)json delegateObject:(MVMCoreUIDelegateObject *)delegateObject additionalData:(NSDictionary *)additionalData {
|
||||
|
||||
self.validationRequired = [json boolForKey:@"validationRequired"];
|
||||
self.validationRequired = [json boolForKey:@"required"];
|
||||
self.requiredGroupsList = [json array:@"requiredGroups"];
|
||||
[FormValidator setupValidationWithMolecule:self delegate:delegateObject.formValidationProtocol];
|
||||
|
||||
|
||||
@ -19,6 +19,7 @@ import MVMCore
|
||||
// Form Validation
|
||||
var isRequired = false
|
||||
var fieldKey: String?
|
||||
var fieldValue: String?
|
||||
var groupName: String?
|
||||
var delegateObject: MVMCoreUIDelegateObject?
|
||||
|
||||
@ -407,6 +408,7 @@ import MVMCore
|
||||
guard let dictionary = json else { return }
|
||||
|
||||
groupName = dictionary.optionalStringForKey("groupName")
|
||||
fieldValue = dictionary.optionalStringForKey("value")
|
||||
if let fieldKey = dictionary[KeyFieldKey] as? String {
|
||||
self.fieldKey = fieldKey
|
||||
}
|
||||
@ -475,6 +477,6 @@ extension Checkbox: FormValidationFormFieldProtocol {
|
||||
}
|
||||
|
||||
public func formFieldValue() -> Any? {
|
||||
return NSNumber(value: isSelected)
|
||||
return isSelected ? fieldValue : nil
|
||||
}
|
||||
}
|
||||
|
||||
280
MVMCoreUI/Atoms/Views/GraphView.swift
Normal file
280
MVMCoreUI/Atoms/Views/GraphView.swift
Normal file
@ -0,0 +1,280 @@
|
||||
//
|
||||
// GraphView.swift
|
||||
// MobileFirstFramework
|
||||
//
|
||||
// Created by Ryan on 10/24/19.
|
||||
// Copyright © 2019 Verizon Wireless. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
|
||||
enum GraphSize: String {
|
||||
case small, medium, large
|
||||
}
|
||||
|
||||
enum GraphStyle: String {
|
||||
case unlimited, safetyMode
|
||||
}
|
||||
|
||||
///Graph Object contains properties
|
||||
public struct GraphObject {
|
||||
|
||||
var style: GraphStyle {
|
||||
didSet {
|
||||
updateStyle()
|
||||
}
|
||||
}
|
||||
var size: GraphSize {
|
||||
didSet {
|
||||
updateSize()
|
||||
}
|
||||
}
|
||||
var diameter: CGFloat = 24
|
||||
var lineWidth: CGFloat = 5
|
||||
var clockwise: Bool = true
|
||||
var duration : Double = 1.0
|
||||
var colors = [CGColor]()
|
||||
|
||||
public init(_ json: [AnyHashable : Any]?) {
|
||||
style = .unlimited
|
||||
size = .small
|
||||
guard let json = json else {
|
||||
return
|
||||
}
|
||||
if let styleString = json.optionalStringForKey("style") {
|
||||
style = GraphStyle(rawValue: styleString) ?? .unlimited
|
||||
}
|
||||
if let sizeString = json.optionalStringForKey("size") {
|
||||
size = GraphSize(rawValue: sizeString) ?? .small
|
||||
}
|
||||
updateStyle()
|
||||
updateSize()
|
||||
if let diameter = json.optionalCGFloatForKey("diameter") {
|
||||
self.diameter = diameter
|
||||
}
|
||||
if let lineWidth = json.optionalCGFloatForKey("lineWidth") {
|
||||
self.lineWidth = lineWidth
|
||||
}
|
||||
if let clockwise = json.optionalBoolForKey("clockwise") {
|
||||
self.clockwise = clockwise
|
||||
}
|
||||
if let duration = json["duration"] as? Double {
|
||||
self.duration = duration
|
||||
}
|
||||
if let colorArray = json.optionalArrayForKey("colors") as? [String] {
|
||||
colors = getCGColorsFromArray(colorArray)
|
||||
}
|
||||
}
|
||||
|
||||
func getCGColorsFromArray(_ colorArray: [String]) -> [CGColor] {
|
||||
return colorArray.map { (colorString) -> CGColor in
|
||||
return UIColor.mfGet(forHex: colorString).cgColor
|
||||
}
|
||||
}
|
||||
|
||||
mutating func updateStyle() {
|
||||
switch style {
|
||||
case .unlimited:
|
||||
duration = 1.0
|
||||
clockwise = true
|
||||
//current style, only the end part shows darker look
|
||||
colors = getCGColorsFromArray(["#007AB8","#007AB8","#033554"])
|
||||
break
|
||||
case .safetyMode:
|
||||
duration = 1.5
|
||||
clockwise = true
|
||||
colors = getCGColorsFromArray(["#CC4D0F","#CC4D0F","AB0309"])
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
//those are
|
||||
mutating func updateSize() {
|
||||
switch size {
|
||||
case .small:
|
||||
diameter = MFSizeObject(standardSize: 24)?.getValueBasedOnApplicationWidth() ?? 24
|
||||
lineWidth = MFSizeObject(standardSize: 5)?.getValueBasedOnApplicationWidth() ?? 5
|
||||
break
|
||||
case .medium:
|
||||
diameter = MFSizeObject(standardSize: 100)?.getValueBasedOnApplicationWidth() ?? 100
|
||||
lineWidth = MFSizeObject(standardSize: 8)?.getValueBasedOnApplicationWidth() ?? 8
|
||||
break
|
||||
case .large:
|
||||
diameter = MFSizeObject(standardSize: 180)?.getValueBasedOnApplicationWidth() ?? 180
|
||||
lineWidth = MFSizeObject(standardSize: 12)?.getValueBasedOnApplicationWidth() ?? 12
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@objcMembers open class GraphView: View {
|
||||
|
||||
var heightConstraint: NSLayoutConstraint?
|
||||
var gradientLayer: CALayer?
|
||||
var graphObject: GraphObject?
|
||||
|
||||
|
||||
// MARK: setup
|
||||
open override func setupView() {
|
||||
super.setupView()
|
||||
//avoid adding height constraint multiple times
|
||||
guard heightConstraint == nil else { return }
|
||||
heightConstraint = heightAnchor.constraint(equalToConstant: 0)
|
||||
heightConstraint?.isActive = true
|
||||
widthAnchor.constraint(equalTo: heightAnchor).isActive = true
|
||||
}
|
||||
|
||||
override open func setWithJSON(_ json: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable : Any]?) {
|
||||
super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData)
|
||||
let object = GraphObject(json)
|
||||
graphObject = object
|
||||
createGraphCircle(object)
|
||||
rotationAnimation(object)
|
||||
}
|
||||
|
||||
class func getAngle(_ piValue: Double) -> Double {
|
||||
return piValue / (2.0 * Double.pi) * 360.0
|
||||
}
|
||||
|
||||
class func getPiValue(_ angle: Double) -> Double {
|
||||
return angle / 360.0 * 2.0 * Double.pi
|
||||
}
|
||||
|
||||
// MARK: circle
|
||||
open func createGraphCircle(_ graphObject: GraphObject) {
|
||||
if let sublayers = layer.sublayers {
|
||||
for sublayer in sublayers {
|
||||
sublayer.removeAllAnimations()
|
||||
sublayer.removeFromSuperlayer()
|
||||
}
|
||||
}
|
||||
heightConstraint?.constant = graphObject.diameter
|
||||
|
||||
//create circle path
|
||||
let radius = graphObject.diameter / 2.0
|
||||
|
||||
//begin point will be at the bottom, clockwise direction
|
||||
let path = UIBezierPath(arcCenter: CGPoint(x: radius
|
||||
, y: radius), radius: radius - graphObject.lineWidth/2.0, startAngle: CGFloat(GraphView.getPiValue(90.0)), endAngle: CGFloat(GraphView.getPiValue(90.0 + 360.0)), clockwise: true)
|
||||
path.lineWidth = graphObject.lineWidth
|
||||
|
||||
let circleLayer = CAShapeLayer()
|
||||
circleLayer.path = path.cgPath
|
||||
circleLayer.lineCap = .round
|
||||
circleLayer.lineWidth = graphObject.lineWidth
|
||||
circleLayer.fillColor = UIColor.clear.cgColor
|
||||
circleLayer.strokeColor = UIColor.black.cgColor
|
||||
|
||||
//create gradient layer
|
||||
let gradientLayer = createGradientLayer(graphObject)
|
||||
gradientLayer.mask = circleLayer
|
||||
layer.addSublayer(gradientLayer)
|
||||
self.gradientLayer = gradientLayer
|
||||
}
|
||||
|
||||
/*
|
||||
create three gradient layer for circle layout.
|
||||
_____________
|
||||
| → | top layer for smooth gradient
|
||||
-------------
|
||||
| | |
|
||||
| ↑ | ↓ |
|
||||
| | |
|
||||
-------------
|
||||
*/
|
||||
func createGradientLayer(_ graphObject: GraphObject) -> CALayer {
|
||||
let containLayer = CALayer()
|
||||
containLayer.frame = CGRect(x: 0, y: 0, width: graphObject.diameter, height: graphObject.diameter)
|
||||
let radius = graphObject.diameter / 2.0
|
||||
|
||||
//create graident layers
|
||||
guard graphObject.colors.count > 1 else {
|
||||
containLayer.backgroundColor = graphObject.colors.first
|
||||
return containLayer
|
||||
}
|
||||
var topGradientHeight : CGFloat = 0.0
|
||||
var leftColors = graphObject.colors.prefix(through: graphObject.colors.count/2)
|
||||
let rightColors = graphObject.colors.suffix(from: graphObject.colors.count/2)
|
||||
|
||||
// make the top layer higher than line width for smooth look
|
||||
topGradientHeight = min(max(graphObject.lineWidth, 1.0/(1.0+CGFloat(graphObject.colors.count))*graphObject.diameter), graphObject.diameter)
|
||||
let topLayer = CAGradientLayer()
|
||||
topLayer.frame = CGRect(x: 0.0, y: 0.0, width: graphObject.diameter, height: topGradientHeight)
|
||||
//make the graident edge more smoothy
|
||||
topLayer.startPoint = CGPoint(x: 0.25, y: 0.0)
|
||||
topLayer.endPoint = CGPoint(x: 0.75, y: 0.0)
|
||||
//if number of colors is even, need to display gradient layer, otherwise make top layer as solid color layer
|
||||
if graphObject.colors.count % 2 == 0 {
|
||||
leftColors.removeLast()
|
||||
topLayer.colors = [leftColors.last!, rightColors.first!]
|
||||
} else {
|
||||
topLayer.backgroundColor = leftColors.last
|
||||
}
|
||||
containLayer.addSublayer(topLayer)
|
||||
|
||||
let leftLayer = CAGradientLayer()
|
||||
leftLayer.frame = CGRect(x: 0, y: topGradientHeight, width: radius, height: graphObject.diameter - topGradientHeight)
|
||||
leftLayer.startPoint = CGPoint(x: 0, y: 1)
|
||||
leftLayer.endPoint = CGPoint(x: 0, y: 0)
|
||||
|
||||
//count of graidentLayer.colors must be bigger than 1, otherwise set backgroundColor
|
||||
if leftColors.count > 1 {
|
||||
leftLayer.colors = Array(leftColors)
|
||||
} else {
|
||||
leftLayer.backgroundColor = leftColors.first
|
||||
}
|
||||
containLayer.addSublayer(leftLayer)
|
||||
|
||||
let rightLayer = CAGradientLayer()
|
||||
rightLayer.frame = CGRect(x: radius, y: topGradientHeight, width: radius, height: graphObject.diameter - topGradientHeight)
|
||||
rightLayer.startPoint = CGPoint(x: 0, y: 0)
|
||||
rightLayer.endPoint = CGPoint(x: 0, y: 1)
|
||||
if rightColors.count > 1 {
|
||||
rightLayer.colors = Array(rightColors)
|
||||
} else {
|
||||
rightLayer.backgroundColor = rightColors.first
|
||||
}
|
||||
containLayer.addSublayer(rightLayer)
|
||||
|
||||
return containLayer
|
||||
}
|
||||
|
||||
//MARK: Animation
|
||||
func rotationAnimation(_ object: GraphObject) {
|
||||
MVMCoreDispatchUtility.performBlock(onMainThread:{
|
||||
let rotation = CABasicAnimation(keyPath: "transform.rotation")
|
||||
let animationHandler = GraphViewAnimationHandler.shared
|
||||
let startAngle = animationHandler.getAnimationStartAngle(object.duration, CACurrentMediaTime())
|
||||
if startAngle == 0.0 {
|
||||
animationHandler.storeAnimation(object.duration, CACurrentMediaTime())
|
||||
}
|
||||
var fromValue = GraphView.getPiValue(0.0 + startAngle), toValue = GraphView.getPiValue(360.0 + startAngle)
|
||||
if !object.clockwise {
|
||||
fromValue = GraphView.getPiValue(360.0 - startAngle)
|
||||
toValue = GraphView.getPiValue(0.0 - startAngle)
|
||||
}
|
||||
rotation.fromValue = fromValue
|
||||
rotation.toValue = toValue
|
||||
rotation.duration = object.duration
|
||||
rotation.timingFunction = CAMediaTimingFunction(name: .linear)
|
||||
rotation.fillMode = .both
|
||||
rotation.isRemovedOnCompletion = false
|
||||
|
||||
//avoid infinity animation take high CPU momery usage when layer is not displayed
|
||||
rotation.delegate = self
|
||||
rotation.repeatCount = 1
|
||||
self.gradientLayer?.add(rotation, forKey: "rotation")
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
extension GraphView: CAAnimationDelegate {
|
||||
public func animationDidStop(_ anim: CAAnimation, finished flag: Bool) {
|
||||
if let object = graphObject {
|
||||
rotationAnimation(object)
|
||||
}
|
||||
}
|
||||
}
|
||||
32
MVMCoreUI/Atoms/Views/GraphViewAnimationHandler.swift
Normal file
32
MVMCoreUI/Atoms/Views/GraphViewAnimationHandler.swift
Normal file
@ -0,0 +1,32 @@
|
||||
//
|
||||
// GraphViewAnimationHandler.swift
|
||||
// MobileFirstFramework
|
||||
//
|
||||
// Created by Ryan on 10/29/19.
|
||||
// Copyright © 2019 Verizon Wireless. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
@objcMembers open class GraphViewAnimationHandler: NSObject {
|
||||
|
||||
/// duration : CACurrentMediaTime()
|
||||
private var animations = [Double: Double]()
|
||||
|
||||
static let shared = GraphViewAnimationHandler()
|
||||
|
||||
open func storeAnimation(_ duration: Double, _ currentTime: CFTimeInterval) {
|
||||
guard animations[duration] == nil else {
|
||||
return
|
||||
}
|
||||
animations[duration] = currentTime
|
||||
}
|
||||
|
||||
open func getAnimationStartAngle(_ duration: Double, _ currentTime: CFTimeInterval) -> Double {
|
||||
if let time = animations[duration] {
|
||||
return (currentTime - time) / duration * 360 + 90
|
||||
}
|
||||
return 0.0
|
||||
}
|
||||
|
||||
}
|
||||
@ -423,6 +423,10 @@ const CGFloat SwitchShakeIntensity = 2;
|
||||
return UIAccessibilityTraitButton;
|
||||
}
|
||||
|
||||
- (NSString * _Nullable)formFieldGroupName {
|
||||
return [self.json string:@"groupName"];
|
||||
}
|
||||
|
||||
- (NSString *)accessibilityHint {
|
||||
return [MVMCoreUIUtility hardcodedStringWithKey:@"AccToggleHint"];
|
||||
}
|
||||
|
||||
@ -12,8 +12,6 @@
|
||||
@interface MFProgrammaticTableViewController : MFScrollingViewController <UITableViewDelegate, UITableViewDataSource>
|
||||
|
||||
@property (nullable, weak, nonatomic) UITableView *tableView;
|
||||
@property (nullable, nonatomic, strong) NSLayoutConstraint *topConstraint;
|
||||
@property (nullable, nonatomic, strong) NSLayoutConstraint *bottomConstraint;
|
||||
|
||||
// Registers classes and nibs. Can subclass for different nibs. Can call super and then add new ones after as well.
|
||||
- (void)registerWithTable;
|
||||
|
||||
@ -13,6 +13,9 @@
|
||||
@property (nullable, weak, nonatomic) IBOutlet UIScrollView *scrollView;
|
||||
@property (nullable, weak, nonatomic) IBOutlet UIView *contentView;
|
||||
|
||||
@property (nullable, nonatomic, strong) NSLayoutConstraint *topConstraint;
|
||||
@property (nullable, nonatomic, strong) NSLayoutConstraint *bottomConstraint;
|
||||
|
||||
// Recognizes single tap/touches to screen for dismissing keyboard
|
||||
@property (nonnull, strong, nonatomic) UITapGestureRecognizer *dismissKeyboardTapGesture;
|
||||
|
||||
|
||||
@ -10,7 +10,5 @@
|
||||
|
||||
@interface ProgrammaticScrollViewController : MFScrollingViewController
|
||||
|
||||
@property (nullable, nonatomic, strong) NSLayoutConstraint *topConstraint;
|
||||
@property (nullable, nonatomic, strong) NSLayoutConstraint *bottomConstraint;
|
||||
|
||||
@end
|
||||
|
||||
@ -427,13 +427,13 @@
|
||||
if ([self.bottomView isKindOfClass:[TwoButtonView class]]) {
|
||||
TwoButtonView *buttonView = (TwoButtonView *)self.bottomView;
|
||||
if (right && !left) {
|
||||
[buttonView hidePrimaryRightButton];
|
||||
[buttonView hideRightButton];
|
||||
} else if (!right && left) {
|
||||
[buttonView hidePrimaryLeftButton];
|
||||
[buttonView hideLeftButton];
|
||||
} else if (right && left) {
|
||||
[buttonView hideBothPrimaryButtons];
|
||||
[buttonView hideBothButtons];
|
||||
} else if (!right && !left) {
|
||||
[buttonView showBothPrimaryButtons];
|
||||
[buttonView showBothButtons];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -98,7 +98,7 @@ import UIKit
|
||||
}
|
||||
|
||||
func setupWithTwoButtons() {
|
||||
guard self.viewForButtons == nil else {
|
||||
guard viewForButtons == nil else {
|
||||
return
|
||||
}
|
||||
let viewForButtons = MVMCoreUICommonViewsUtility.commonView()
|
||||
@ -114,7 +114,7 @@ import UIKit
|
||||
}
|
||||
|
||||
open func setupWithPrimaryButton() {
|
||||
guard self.primaryButton == nil else {
|
||||
guard primaryButton == nil && secondaryButton == nil else {
|
||||
return
|
||||
}
|
||||
createPrimaryButton()
|
||||
@ -125,21 +125,37 @@ import UIKit
|
||||
}
|
||||
}
|
||||
|
||||
// Sets up the number of buttons based on the maps. Doesn't set the buttons with the maps because legacy code handles differently from modern code...
|
||||
func setupUI(withPrimaryButtonMap primaryButtonMap: [AnyHashable: Any]?, secondaryButtonMap: [AnyHashable: Any]?, legacy: Bool) {
|
||||
open func setupWithSecondaryButton() {
|
||||
guard secondaryButton == nil && primaryButton == nil else {
|
||||
return
|
||||
}
|
||||
createSecondaryButton()
|
||||
if let secondaryButton = secondaryButton {
|
||||
addSubview(secondaryButton)
|
||||
pinView(toSuperView: secondaryButton)
|
||||
alignCenterHorizontal()
|
||||
}
|
||||
}
|
||||
|
||||
func setupUI(withPrimaryButtonMap primaryButtonMap: [AnyHashable: Any]?, secondaryButtonMap: [AnyHashable: Any]?) {
|
||||
if primaryButtonMap != nil, secondaryButtonMap != nil {
|
||||
heightConstraint?.isActive = false
|
||||
if primaryButton == nil || secondaryButton == nil {
|
||||
removeButtons()
|
||||
setupWithTwoButtons()
|
||||
}
|
||||
} else if primaryButtonMap != nil || (secondaryButtonMap != nil && legacy) {
|
||||
// Only legacy sets up the primary button with a secondary map
|
||||
} else if primaryButtonMap != nil {
|
||||
heightConstraint?.isActive = false
|
||||
if primaryButton == nil || secondaryButton != nil {
|
||||
removeButtons()
|
||||
setupWithPrimaryButton()
|
||||
}
|
||||
} else if secondaryButtonMap != nil {
|
||||
heightConstraint?.isActive = false
|
||||
if secondaryButton == nil || primaryButton != nil {
|
||||
removeButtons()
|
||||
setupWithSecondaryButton()
|
||||
}
|
||||
} else {
|
||||
removeButtons()
|
||||
if heightConstraint == nil {
|
||||
@ -150,7 +166,7 @@ import UIKit
|
||||
}
|
||||
|
||||
open func set(primaryButtonJSON: [AnyHashable: Any]?, secondaryButtonJSON: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) {
|
||||
setupUI(withPrimaryButtonMap: primaryButtonJSON, secondaryButtonMap: secondaryButtonJSON, legacy: false)
|
||||
setupUI(withPrimaryButtonMap: primaryButtonJSON, secondaryButtonMap: secondaryButtonJSON)
|
||||
setDefaultCustom()
|
||||
primaryButton?.setWithJSON(primaryButtonJSON, delegateObject: delegateObject, additionalData: additionalData)
|
||||
secondaryButton?.setWithJSON(secondaryButtonJSON, delegateObject: delegateObject, additionalData: additionalData)
|
||||
@ -178,7 +194,7 @@ import UIKit
|
||||
}
|
||||
|
||||
open func setup(primaryButtonMap: [AnyHashable: Any]?, secondaryButtonMap: [AnyHashable: Any]?, delegateObject: DelegateObject?, additionalData: [AnyHashable: Any]?) {
|
||||
setupUI(withPrimaryButtonMap: primaryButtonMap, secondaryButtonMap: secondaryButtonMap, legacy: true)
|
||||
setupUI(withPrimaryButtonMap: primaryButtonMap, secondaryButtonMap: secondaryButtonMap)
|
||||
if primaryButtonMap != nil, secondaryButtonMap != nil {
|
||||
primaryButton?.setWithActionMap(primaryButtonMap, delegateObject: delegateObject, additionalData: additionalData)
|
||||
secondaryButton?.setWithActionMap(secondaryButtonMap, delegateObject: delegateObject, additionalData: additionalData)
|
||||
@ -186,8 +202,8 @@ import UIKit
|
||||
primaryButton?.setWithActionMap(primaryButtonMap, delegateObject: delegateObject, additionalData: additionalData)
|
||||
primaryButton?.bordered = false
|
||||
} else if secondaryButtonMap != nil {
|
||||
primaryButton?.setWithActionMap(secondaryButtonMap, delegateObject: delegateObject, additionalData: additionalData)
|
||||
primaryButton?.bordered = true
|
||||
secondaryButton?.setWithActionMap(secondaryButtonMap, delegateObject: delegateObject, additionalData: additionalData)
|
||||
secondaryButton?.bordered = true
|
||||
}
|
||||
}
|
||||
|
||||
@ -197,7 +213,7 @@ import UIKit
|
||||
setup(primaryButtonMap: primaryButtonMap, secondaryButtonMap: secondaryButtonMap, delegateObject: delegateObject, additionalData: additionalData)
|
||||
}
|
||||
|
||||
public func hidePrimaryLeftButton() {
|
||||
public func hideLeftButton() {
|
||||
guard let secondaryButton = secondaryButton, !secondaryButton.isHidden else {
|
||||
return
|
||||
}
|
||||
@ -209,7 +225,7 @@ import UIKit
|
||||
}
|
||||
}
|
||||
|
||||
public func hidePrimaryRightButton() {
|
||||
public func hideRightButton() {
|
||||
guard let primaryButton = primaryButton, !primaryButton.isHidden else {
|
||||
return
|
||||
}
|
||||
@ -221,7 +237,7 @@ import UIKit
|
||||
}
|
||||
}
|
||||
|
||||
public func showBothPrimaryButtons() {
|
||||
public func showBothButtons() {
|
||||
primaryButton?.isHidden = false
|
||||
secondaryButton?.isHidden = false
|
||||
if let primaryButton = primaryButton, let secondaryButton = secondaryButton {
|
||||
@ -231,7 +247,7 @@ import UIKit
|
||||
}
|
||||
}
|
||||
|
||||
public func hideBothPrimaryButtons() {
|
||||
public func hideBothButtons() {
|
||||
primaryButton?.isHidden = true
|
||||
secondaryButton?.isHidden = true
|
||||
}
|
||||
@ -241,7 +257,7 @@ import UIKit
|
||||
extension TwoButtonView {
|
||||
@available(*, deprecated)
|
||||
open func setup(primaryButtonMap: [AnyHashable: Any]?, secondaryButtonMap: [AnyHashable: Any]?, actionDelegate: NSObjectProtocol?, additionalData: [AnyHashable: Any]?, buttonDelegate: Any?) {
|
||||
setupUI(withPrimaryButtonMap: primaryButtonMap, secondaryButtonMap: secondaryButtonMap, legacy: true)
|
||||
setupUI(withPrimaryButtonMap: primaryButtonMap, secondaryButtonMap: secondaryButtonMap)
|
||||
if primaryButtonMap != nil, secondaryButtonMap != nil {
|
||||
primaryButton?.setWithActionMap(primaryButtonMap, actionDelegate: actionDelegate as? MVMCoreActionDelegateProtocol & NSObjectProtocol, additionalData: additionalData, buttonDelegate: buttonDelegate as? ButtonDelegateProtocol)
|
||||
secondaryButton?.setWithActionMap(secondaryButtonMap, actionDelegate: actionDelegate as? MVMCoreActionDelegateProtocol & NSObjectProtocol, additionalData: additionalData, buttonDelegate: buttonDelegate as? ButtonDelegateProtocol)
|
||||
@ -249,8 +265,8 @@ extension TwoButtonView {
|
||||
primaryButton?.setWithActionMap(primaryButtonMap, actionDelegate: actionDelegate as? MVMCoreActionDelegateProtocol & NSObjectProtocol, additionalData: additionalData, buttonDelegate: buttonDelegate as? ButtonDelegateProtocol)
|
||||
primaryButton?.bordered = false
|
||||
} else if secondaryButtonMap != nil {
|
||||
primaryButton?.setWithActionMap(secondaryButtonMap, actionDelegate: actionDelegate as? MVMCoreActionDelegateProtocol & NSObjectProtocol, additionalData: additionalData, buttonDelegate: buttonDelegate as? ButtonDelegateProtocol)
|
||||
primaryButton?.bordered = true
|
||||
secondaryButton?.setWithActionMap(secondaryButtonMap, actionDelegate: actionDelegate as? MVMCoreActionDelegateProtocol & NSObjectProtocol, additionalData: additionalData, buttonDelegate: buttonDelegate as? ButtonDelegateProtocol)
|
||||
secondaryButton?.bordered = true
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -40,9 +40,10 @@
|
||||
@"textField" : MFTextField.class,
|
||||
@"digitTextField" : MFDigitTextField.class,
|
||||
@"checkbox" : Checkbox.class,
|
||||
@"checkboxWithLabelView" : CheckboxWithLabelView.class,
|
||||
@"checkboxWithLabel" : CheckboxWithLabelView.class,
|
||||
@"cornerLabels" : CornerLabels.class,
|
||||
@"progressbar": ProgressBar.class,
|
||||
@"circleProgress": GraphView.class,
|
||||
@"multiProgressBar": MultiProgress.class,
|
||||
@"checkbox": MVMCoreUICheckBox.class,
|
||||
@"radioButton": RadioButton.class,
|
||||
|
||||
@ -9,7 +9,7 @@
|
||||
import UIKit
|
||||
|
||||
open class MoleculeListTemplate: ThreeLayerTableViewController {
|
||||
var moleculesInfo: [(identifier: String, class: AnyClass, molecule: [AnyHashable: Any])]?
|
||||
public var moleculesInfo: [(identifier: String, class: AnyClass, molecule: [AnyHashable: Any])]?
|
||||
var observer: NSKeyValueObservation?
|
||||
|
||||
open override var loadObject: MVMCoreLoadObject? {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user