Merge branch 'feature/template_layout_guide' into 'develop'

Feature/template layout guide

See merge request BPHV_MIPS/mvm_core_ui!27
This commit is contained in:
Suresh, Kamlesh 2019-04-10 16:35:43 -04:00
commit 02efde760d
10 changed files with 92 additions and 29 deletions

View File

@ -138,7 +138,6 @@
#pragma mark - MVMCoreUIMoleculeViewProtocol
- (void)setAsMolecule {
self.updateViewHorizontalDefaults = YES;
}
@end

View File

@ -29,13 +29,15 @@
// Returns the standard space around ui objects.
+ (UIEdgeInsets)standardSpaceAroundUIObjectForSize:(CGFloat)size;
// Consolidates generateFormViewWithUIArray and spaceArroundUIObject into one class object so other view controllers can take advantage of these functions.
// Consolidates generateFormViewWithUIArray and spaceArroundUIObject into one class object so other view controllers can take advantage of these functions. By default does not pin to margins.
+ (void)populateView:(nonnull UIView *)view withUIArray:(nonnull NSArray <UIView *>*)formUIArray withSpacingBlock:(nonnull UIEdgeInsets (^) (id _Nullable object))spacingBlock;
+ (void)populateView:(nonnull UIView *)view withUIArray:(nonnull NSArray <UIView *>*)formUIArray useMargins:(BOOL)useMargins withSpacingBlock:(nonnull UIEdgeInsets (^) (id _Nullable object))spacingBlock;
+ (void)populateViewHorizontally:(nonnull UIView *)view withUIArray:(nonnull NSArray <UIView *>*)formUIArray withSpacingBlock:(nonnull UIEdgeInsets (^) (id _Nullable object))spacingBlock;
+ (void)populateView:(nonnull UIView *)view withUIArrayForConstrainingViews:(nonnull NSArray <UIView *>*)formUIArray withSpacingBlock:(nonnull UIEdgeInsets (^) (id _Nullable object))spacingBlock;
// Does the actual laying out. The formuiarray views should already be added to the view.
// Does the actual laying out. The formuiarray views should already be added to the view. By default does not pin to margins
+ (void)autoLayoutView:(nonnull UIView *)view withUIArray:(nonnull NSArray <UIView *>*)formUIArray withSpacingBlock:(nonnull UIEdgeInsets (^) (id _Nullable object))spacingBlock;
+ (void)autoLayoutView:(nonnull UIView *)view withUIArray:(nonnull NSArray <UIView *>*)formUIArray useMargins:(BOOL)useMargins withSpacingBlock:(nonnull UIEdgeInsets (^) (id _Nullable object))spacingBlock;
+ (void)autoLayoutViewHorizontally:(nonnull UIView *)view withUIArray:(nonnull NSArray <UIView *>*)formUIArray withSpacingBlock:(nonnull UIEdgeInsets (^) (id _Nullable object))spacingBlock;
+ (void)autoLayoutViewWithConstrainingViewsWithUIArray:(nonnull NSArray <UIView *>*)formUIArray withSpacingBlock:(nonnull UIEdgeInsets (^) (id _Nullable object))spacingBlock;

View File

@ -10,6 +10,7 @@
#import "MFStyler.h"
#import "ViewConstrainingView.h"
#import "MVMCoreUIUtility.h"
#import "NSLayoutConstraint+MFConvenience.h"
@interface MVMCoreUIStackableViewController ()
@end
@ -69,11 +70,15 @@
}
+ (void)populateView:(nonnull UIView *)view withUIArray:(nonnull NSArray <UIView *>*)formUIArray withSpacingBlock:(nonnull UIEdgeInsets (^) (id _Nullable object))spacingBlock {
[self populateView:view withUIArray:formUIArray useMargins:NO withSpacingBlock:spacingBlock];
}
+ (void)populateView:(nonnull UIView *)view withUIArray:(nonnull NSArray <UIView *>*)formUIArray useMargins:(BOOL)useMargins withSpacingBlock:(nonnull UIEdgeInsets (^) (id _Nullable object))spacingBlock {
if ([formUIArray count] > 0) {
for (UIView *subview in formUIArray) {
[view addSubview:subview];
}
[MVMCoreUIStackableViewController autoLayoutView:view withUIArray:formUIArray withSpacingBlock:spacingBlock];
[MVMCoreUIStackableViewController autoLayoutView:view withUIArray:formUIArray useMargins:useMargins withSpacingBlock:spacingBlock];
}
}
@ -96,34 +101,46 @@
}
}
+ (void)autoLayoutView:(nonnull UIView *)view withUIArray:(nonnull NSArray <UIView *>*)formUIArray withSpacingBlock:(nonnull UIEdgeInsets (^) (id _Nullable object))spacingBlock {
+ (void)autoLayoutView:(nonnull UIView *)view withUIArray:(nonnull NSArray <UIView *>*)formUIArray useMargins:(BOOL)useMargins withSpacingBlock:(nonnull UIEdgeInsets (^) (id _Nullable object))spacingBlock {
if ([formUIArray count] > 0) {
// Adds the first object to the view and pins it to the top of the content view.
id previousUIObject = [formUIArray objectAtIndex:0];
UIEdgeInsets spaceAroundObjectPrevious = spacingBlock(previousUIObject);
UIView *previousUIObject = [formUIArray objectAtIndex:0];
[previousUIObject setTranslatesAutoresizingMaskIntoConstraints:NO];
[NSLayoutConstraint activateConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-top@999-[previousUIObject]" options:NSLayoutFormatDirectionLeadingToTrailing metrics:@{@"top":@(spaceAroundObjectPrevious.top)} views:NSDictionaryOfVariableBindings(previousUIObject)]];
[NSLayoutConstraint activateConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-left@999-[previousUIObject]-right-|" options:NSLayoutFormatDirectionLeadingToTrailing metrics:@{@"left":@(spaceAroundObjectPrevious.left),@"right":@(spaceAroundObjectPrevious.right)} views:NSDictionaryOfVariableBindings(previousUIObject)]];
UIEdgeInsets spaceAroundObjectPrevious = spacingBlock(previousUIObject);
NSLayoutConstraint *constraint = [NSLayoutConstraint pinViewTopToSuperview:previousUIObject useMargins:useMargins constant:spaceAroundObjectPrevious.top];
constraint.priority = 999;
constraint.active = YES;
constraint = [NSLayoutConstraint pinViewLeftToSuperview:previousUIObject useMargins:useMargins constant:spaceAroundObjectPrevious.left];
constraint.priority = 999;
constraint.active = YES;
[NSLayoutConstraint pinViewRightToSuperview:previousUIObject useMargins:useMargins constant:spaceAroundObjectPrevious.right].active = YES;
// Sets the horizontal spacing and adds vertical spacing between all ui objects.
for (NSUInteger i = 1; i < [formUIArray count]; i++) {
id uiObject = [formUIArray objectAtIndex:i];
UIView *uiObject = [formUIArray objectAtIndex:i];
UIEdgeInsets spaceAroundObjectCurrent = spacingBlock(uiObject);
[uiObject setTranslatesAutoresizingMaskIntoConstraints:NO];
[NSLayoutConstraint activateConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[previousUIObject]-space-[uiObject]" options:NSLayoutFormatDirectionLeadingToTrailing metrics:@{@"space":@(spaceAroundObjectPrevious.bottom + spaceAroundObjectCurrent.top)} views:NSDictionaryOfVariableBindings(previousUIObject,uiObject)]];
[NSLayoutConstraint activateConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-left@999-[uiObject]-right-|" options:NSLayoutFormatDirectionLeadingToTrailing metrics:@{@"left":@(spaceAroundObjectCurrent.left),@"right":@(spaceAroundObjectCurrent.right)} views:NSDictionaryOfVariableBindings(uiObject)]];
constraint = [NSLayoutConstraint pinViewLeftToSuperview:uiObject useMargins:useMargins constant:spaceAroundObjectCurrent.left];
constraint.priority = 999;
constraint.active = YES;
[NSLayoutConstraint pinViewRightToSuperview:uiObject useMargins:useMargins constant:spaceAroundObjectCurrent.right].active = YES;
previousUIObject = uiObject;
spaceAroundObjectPrevious = spaceAroundObjectCurrent;
}
// Pins the last object to the bottom of the content view.
[NSLayoutConstraint activateConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[previousUIObject]-bottom-|" options:NSLayoutFormatDirectionLeadingToTrailing metrics:@{@"bottom":@(spaceAroundObjectPrevious.bottom)} views:NSDictionaryOfVariableBindings(previousUIObject)]];
[NSLayoutConstraint pinViewBottomToSuperview:previousUIObject useMargins:useMargins constant:spaceAroundObjectPrevious.bottom].active = YES;
}
}
+ (void)autoLayoutView:(nonnull UIView *)view withUIArray:(nonnull NSArray <UIView *>*)formUIArray withSpacingBlock:(nonnull UIEdgeInsets (^) (id _Nullable object))spacingBlock {
[self autoLayoutView:view withUIArray:formUIArray useMargins:NO withSpacingBlock:spacingBlock];
}
+ (void)autoLayoutViewHorizontally:(nonnull UIView *)view withUIArray:(nonnull NSArray <UIView *>*)formUIArray withSpacingBlock:(nonnull UIEdgeInsets (^) (id _Nullable object))spacingBlock {
if ([formUIArray count] > 0) {

View File

@ -16,6 +16,7 @@ open class ThreeLayerViewController: ProgrammaticScrollViewController {
var topView: UIView?
var middleView: UIView?
var bottomView: UIView?
var useMargins: Bool = true
// The bottom view can be put outside of the scrolling area.
var bottomViewOutsideOfScroll = false
@ -26,6 +27,7 @@ open class ThreeLayerViewController: ProgrammaticScrollViewController {
open override func updateViews() {
super.updateViews()
let width = view.bounds.width
MFStyler.setDefaultMarginsFor(contentView, size: width)
if let topView = topView as? MVMCoreViewProtocol {
topView.updateView(width)
}
@ -116,9 +118,9 @@ extension ThreeLayerViewController {
return nil
}
contentView.addSubview(topView)
topView.leftAnchor.constraint(equalTo: contentView.leftAnchor).isActive = true
contentView.rightAnchor.constraint(equalTo: topView.rightAnchor).isActive = true
topView.topAnchor.constraint(equalTo: contentView.topAnchor).isActive = true
NSLayoutConstraint.pinViewTop(toSuperview: topView, useMargins: useMargins, constant: 0).isActive = true
NSLayoutConstraint.pinViewLeft(toSuperview: topView, useMargins: useMargins, constant: 0).isActive = true
NSLayoutConstraint.pinViewRight(toSuperview: topView, useMargins: useMargins, constant: 0).isActive = true
return topView
}
@ -133,8 +135,8 @@ extension ThreeLayerViewController {
return nil
}
contentView.addSubview(middleView)
middleView.leftAnchor.constraint(equalTo: contentView.leftAnchor).isActive = true
contentView.rightAnchor.constraint(equalTo: middleView.rightAnchor).isActive = true
NSLayoutConstraint.pinViewLeft(toSuperview: middleView, useMargins: useMargins, constant: 0).isActive = true
NSLayoutConstraint.pinViewRight(toSuperview: middleView, useMargins: useMargins, constant: 0).isActive = true
middleView.setContentHuggingPriority(UILayoutPriority.required, for: NSLayoutConstraint.Axis.vertical)
return middleView
}
@ -220,17 +222,17 @@ extension ThreeLayerViewController {
return
}
contentView.addSubview(view);
contentView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
contentView.rightAnchor.constraint(equalTo: view.rightAnchor).isActive = true
view.leftAnchor.constraint(equalTo: contentView.leftAnchor).isActive = true
NSLayoutConstraint.pinViewLeft(toSuperview: view, useMargins: useMargins, constant: 0).isActive = true
NSLayoutConstraint.pinViewRight(toSuperview: view, useMargins: useMargins, constant: 0).isActive = true
NSLayoutConstraint.pinViewBottom(toSuperview: view, useMargins: useMargins, constant: 0).isActive = true
}
func addViewOutsideOfScrollViewBottom(_ view: UIView) {
self.view?.addSubview(view)
if let scrollView = scrollView, let parentView = self.view {
view.topAnchor.constraint(equalTo: scrollView.bottomAnchor).isActive = true
view.leftAnchor.constraint(equalTo: parentView.leftAnchor).isActive = true
parentView.rightAnchor.constraint(equalTo: view.rightAnchor).isActive = true
NSLayoutConstraint.pinViewLeft(toSuperview: view, useMargins: useMargins, constant: 0).isActive = true
NSLayoutConstraint.pinViewRight(toSuperview: view, useMargins: useMargins, constant: 0).isActive = true
if #available(iOS 11.0, *) {
parentView.safeAreaLayoutGuide.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
if let safeAreaView = MVMCoreUICommonViewsUtility.getAndSetupSafeAreaView(on: parentView) {
@ -238,7 +240,7 @@ extension ThreeLayerViewController {
self.safeAreaView = safeAreaView
}
} else {
parentView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
NSLayoutConstraint.pinViewBottom(toSuperview: view, useMargins: useMargins, constant: 0).isActive = true
}
}
}

View File

@ -55,6 +55,13 @@ extern NSString * _Nonnull const ConstraintWidth;
+(nullable NSDictionary *)constraintAlignView :(nonnull UIView *)firstView toSecondView :(nonnull UIView *)secondView alignX :(BOOL)alignX alignY :(BOOL)alignY;
#pragma mark - With Margins
+ (nonnull NSLayoutConstraint *)pinViewTopToSuperview:(nonnull UIView *)view useMargins:(BOOL)useMargins constant:(CGFloat)constant;
+ (nonnull NSLayoutConstraint *)pinViewLeftToSuperview:(nonnull UIView *)view useMargins:(BOOL)useMargins constant:(CGFloat)constant;
+ (nonnull NSLayoutConstraint *)pinViewRightToSuperview:(nonnull UIView *)view useMargins:(BOOL)useMargins constant:(CGFloat)constant;
+ (nonnull NSLayoutConstraint *)pinViewBottomToSuperview:(nonnull UIView *)view useMargins:(BOOL)useMargins constant:(CGFloat)constant;
#pragma mark - Scaling constraints
// These functions will pin a view to its super view with space that is a ratio of the anchor (by default the super view's width if nothing is passed in). (So if the space is 24 and the super's width is 320 in the design, then the ratio should be 24/320 and this will be multiplied by the super's current width, so that the constraint always linearly scales).

View File

@ -150,6 +150,24 @@ NSString *const ConstraintWidth = @"width";
return constraintsDictionary;
}
#pragma mark - With Margins
+ (NSLayoutConstraint *)pinViewTopToSuperview:(UIView *)view useMargins:(BOOL)useMargins constant:(CGFloat)constant {
return [view.topAnchor constraintEqualToAnchor:(useMargins ? view.superview.layoutMarginsGuide.topAnchor : view.superview.topAnchor) constant:constant];
}
+ (NSLayoutConstraint *)pinViewLeftToSuperview:(UIView *)view useMargins:(BOOL)useMargins constant:(CGFloat)constant {
return [view.leftAnchor constraintEqualToAnchor:(useMargins ? view.superview.layoutMarginsGuide.leftAnchor : view.superview.leftAnchor) constant:constant];
}
+ (NSLayoutConstraint *)pinViewRightToSuperview:(UIView *)view useMargins:(BOOL)useMargins constant:(CGFloat)constant {
return [(useMargins ? view.superview.layoutMarginsGuide.rightAnchor : view.superview.rightAnchor) constraintEqualToAnchor:view.rightAnchor constant:constant];
}
+ (NSLayoutConstraint *)pinViewBottomToSuperview:(UIView *)view useMargins:(BOOL)useMargins constant:(CGFloat)constant {
return [(useMargins ? view.superview.layoutMarginsGuide.bottomAnchor : view.superview.bottomAnchor) constraintEqualToAnchor:view.bottomAnchor constant:constant];
}
#pragma mark - Scaling constraints
+ (nullable NSDictionary *)scalingConstraintPinSubview:(nullable UIView *)subview pinTop:(BOOL)pinTop topConstant:(CGFloat)topConstant pinBottom:(BOOL)pinBottom bottomConstant:(CGFloat)bottomConstant pinLeft:(BOOL)pinLeft leftConstant:(CGFloat)leftConstant pinRight:(BOOL)pinRight rightConstant:(CGFloat)rightConstant baseConstant:(CGFloat)baseConstant {

View File

@ -11,7 +11,8 @@ import UIKit
public class MoleculeStackView: MFView {
var spacingBlock: ((Any) -> UIEdgeInsets)?
var moleculesArray: [UIView]?
var useMargins: Bool = false
public override init(frame: CGRect) {
super.init(frame: frame)
}
@ -67,9 +68,9 @@ public class MoleculeStackView: MFView {
}
if let spacingBlock = spacingBlock {
MVMCoreUIStackableViewController.populateView(self, withUIArray: moleculesArray, withSpacingBlock: spacingBlock)
MVMCoreUIStackableViewController.populateView(self, withUIArray: moleculesArray, useMargins: useMargins, withSpacingBlock: spacingBlock)
} else {
MVMCoreUIStackableViewController.populateView(self, withUIArray: moleculesArray) { (object) -> UIEdgeInsets in
MVMCoreUIStackableViewController.populateView(self, withUIArray: moleculesArray, useMargins: useMargins) { (object) -> UIEdgeInsets in
if object as AnyObject? === moleculesArray.first {
return UIEdgeInsets.zero
} else {

View File

@ -25,6 +25,11 @@ import UIKit
super.init(frame: frame)
}
public func setDefaultCustom() {
primaryButton?.setAsStandardCustom()
secondaryButton?.setAsSecondaryCustom()
}
// MARK: - MVMCoreViewProtocol
open override func updateView(_ size: CGFloat) {
super.updateView(size)
@ -139,8 +144,7 @@ import UIKit
open func set(primaryButtonJSON: [AnyHashable: Any]?, secondaryButtonJSON: [AnyHashable: Any]?, actionDelegate: NSObjectProtocol?, additionalData: [AnyHashable: Any]?, buttonDelegate: Any?) {
setupUI(withPrimaryButtonMap: primaryButtonJSON, secondaryButtonMap: secondaryButtonJSON, legacy: false)
primaryButton?.setAsStandardCustom()
secondaryButton?.setAsSecondaryCustom()
setDefaultCustom()
primaryButton?.setWithJSON(primaryButtonJSON, delegate: actionDelegate as? NSObject, additionalData: additionalData)
secondaryButton?.setWithJSON(secondaryButtonJSON, delegate: actionDelegate as? NSObject, additionalData: additionalData)
}

View File

@ -90,6 +90,7 @@ B3 -> Legal
+ (CGFloat)defaultVerticalPaddingForApplicationWidth;
+ (CGFloat)defaultHorizontalPaddingForSize:(CGFloat)size;
+ (CGFloat)defaultVerticalPaddingForSize:(CGFloat)size;
+ (void)setDefaultMarginsForView:(nullable UIView *)view size:(CGFloat)size;
//-------------------------------------------------
// Returns the fonts for these styles. Scales them as needed by default

View File

@ -12,6 +12,7 @@
#import "UIColor+MFConvenience.h"
#import "NSLayoutConstraint+MFConvenience.h"
#import "MVMCoreUISplitViewController.h"
@import MVMCore.MVMCoreDispatchUtility;
CGFloat const PaddingDefault = 24;
CGFloat const PaddingDefaultHorizontalSpacing = 32;
@ -88,6 +89,17 @@ CGFloat const LabelWithInternalButtonLineSpace = 2;
return [[MFSizeObject sizeObjectWithScalingStandardSize:PaddingDefaultVerticalSpacing] getValueBasedOnSize:size];
}
+ (void)setDefaultMarginsForView:(nullable UIView *)view size:(CGFloat)size {
[MVMCoreDispatchUtility performBlockOnMainThread:^{
CGFloat padding = [MFStyler defaultHorizontalPaddingForSize:size];
if (@available(iOS 11.0, *)) {
view.directionalLayoutMargins = NSDirectionalEdgeInsetsMake(0, padding, 0, padding);
} else {
view.layoutMargins = UIEdgeInsetsMake(0, padding, 0, padding);
}
}];
}
#pragma mark - 2.0 fonts
+ (nullable UIFont *)fontH1:(BOOL)genericScaling {