diff --git a/MVMCoreUI/Atoms/Views/MFView.m b/MVMCoreUI/Atoms/Views/MFView.m index 28bcdd81..9eeb673a 100644 --- a/MVMCoreUI/Atoms/Views/MFView.m +++ b/MVMCoreUI/Atoms/Views/MFView.m @@ -39,7 +39,7 @@ } - (void)setupView { - self.preservesSuperviewLayoutMargins = YES; + self.preservesSuperviewLayoutMargins = NO; } - (void)updateView:(CGFloat)size { diff --git a/MVMCoreUI/Atoms/Views/ViewConstrainingView.h b/MVMCoreUI/Atoms/Views/ViewConstrainingView.h index acf451a8..55280666 100644 --- a/MVMCoreUI/Atoms/Views/ViewConstrainingView.h +++ b/MVMCoreUI/Atoms/Views/ViewConstrainingView.h @@ -30,8 +30,9 @@ @property (nullable, strong, nonatomic) IBOutlet NSLayoutConstraint *topPinLow; @property (nullable, strong, nonatomic) IBOutlet NSLayoutConstraint *bottomPinLow; -/// In updateView, will set horizontal padding to default if set to YES. +/// In updateView, will set horizontal padding to default if set to NO. @property (nonatomic) BOOL updateViewHorizontalDefaults; +@property (nonatomic) BOOL updateViewVerticalDefaults; /// A molecule if we constrain one. @property (weak, nullable, nonatomic) UIView *molecule; diff --git a/MVMCoreUI/Atoms/Views/ViewConstrainingView.m b/MVMCoreUI/Atoms/Views/ViewConstrainingView.m index c6152bcc..73e545c5 100644 --- a/MVMCoreUI/Atoms/Views/ViewConstrainingView.m +++ b/MVMCoreUI/Atoms/Views/ViewConstrainingView.m @@ -14,6 +14,8 @@ #import "MFStyler.h" #import "MVMCoreUIConstants.h" #import "MVMCoreUIMoleculeMappingObject.h" +#import "MVMCoreUIUtility.h" +#import "MVMCoreUIViewConstrainingProtocol.h" @interface ViewConstrainingView () @property (weak, nullable, nonatomic) UIView *constrainedView; @@ -27,8 +29,8 @@ [self addConstrainedView:molecule alignment:alignment]; [self setAsMolecule]; } - [self setMoleculeAccessibility]; self.molecule = molecule; + [self setMoleculeAccessibility]; } return self; } @@ -280,21 +282,14 @@ } - (void)shouldSetHorizontalMargins:(BOOL)shouldSet { - self.updateViewHorizontalDefaults = shouldSet; + if (![self.json optionalNumberForKey:@"useHorizontalMargins"]) { + self.updateViewHorizontalDefaults = shouldSet; + } } - (void)shouldSetVerticalMargins:(BOOL)shouldSet { - BOOL useStandardSpacing = shouldSet; - if (shouldSet && [self.molecule respondsToSelector:@selector(useStandardConstraints)]) { - useStandardSpacing = [((UIView *)self.molecule) useStandardConstraints]; - } - - if (useStandardSpacing) { - [self setTopPinConstant:PaddingDefaultVerticalSpacing]; - [self setBottomPinConstant:PaddingDefaultVerticalSpacing]; - } else { - [self setTopPinConstant:0]; - [self setBottomPinConstant:0]; + if (![self.json optionalNumberForKey:@"useVerticalMargins"]) { + self.updateViewVerticalDefaults = shouldSet; } } @@ -304,11 +299,7 @@ [super setupView]; self.translatesAutoresizingMaskIntoConstraints = NO; self.backgroundColor = [UIColor clearColor]; - if (@available(iOS 11.0, *)) { - self.directionalLayoutMargins = NSDirectionalEdgeInsetsZero; - } else { - self.layoutMargins = UIEdgeInsetsZero; - } + [MVMCoreUIUtility setMarginsForView:self leading:0 top:0 trailing:0 bottom:0]; } - (void)updateView:(CGFloat)size { @@ -316,14 +307,12 @@ if ([self.constrainedView respondsToSelector:@selector(updateView:)]) { [((id)self.constrainedView) updateView:size]; } - if (self.updateViewHorizontalDefaults) { - [MVMCoreDispatchUtility performBlockOnMainThread:^{ - CGFloat padding = [MFStyler defaultHorizontalPaddingForSize:size]; - [self setLeftPinConstant:padding]; - [self setRightPinConstant:padding]; - [MFStyler setDefaultMarginsForView:self size:size]; - }]; - } + [MFStyler setDefaultMarginsForView:self size:size horizontal:self.updateViewHorizontalDefaults vertical:self.updateViewVerticalDefaults]; + UIEdgeInsets margins = [MVMCoreUIUtility getMarginsForView:self]; + [self setLeftPinConstant:margins.left]; + [self setRightPinConstant:margins.right]; + [self setTopPinConstant:margins.top]; + [self setBottomPinConstant:margins.bottom]; } #pragma mark - MVMCoreUIMoleculeViewProtocol @@ -340,13 +329,18 @@ } - (void)reset { + self.updateViewHorizontalDefaults = NO; + self.updateViewVerticalDefaults = NO; + if ([self.molecule respondsToSelector:@selector(alignment)]) { + [self alignHorizontal:[(UIView *)self.molecule alignment]]; + } + [self alignVertical:UIStackViewAlignmentFill]; if ([self.molecule respondsToSelector:@selector(reset)]) { [self.molecule performSelector:@selector(reset)]; } } - (void)setAsMolecule { - self.updateViewHorizontalDefaults = YES; } - (void)setWithJSON:(NSDictionary *)json delegateObject:(MVMCoreUIDelegateObject *)delegateObject additionalData:(NSDictionary *)additionalData { @@ -361,13 +355,32 @@ [self insertSubview:molecule atIndex:0]; [self pinViewToSuperView:molecule]; } + self.molecule = molecule; } [self setMoleculeAccessibility]; } - if (self.molecule) { - if ([self.molecule respondsToSelector:@selector(copyBackgroundColor)] && [self.molecule performSelector:@selector(copyBackgroundColor)]) { - self.backgroundColor = self.molecule.backgroundColor; - } + + NSNumber *useHorizontalMargins = [json optionalNumberForKey:@"useHorizontalMargins"]; + if (useHorizontalMargins) { + self.updateViewHorizontalDefaults = [useHorizontalMargins boolValue]; + } + NSNumber *useVerticalMargins = [json optionalNumberForKey:@"useVerticalMargins"]; + if (useVerticalMargins) { + self.updateViewVerticalDefaults = [useVerticalMargins boolValue]; + } + + // Set the alignment for the stack in the containing view. The json driven value is for the axis direction alignment. + NSString *alignment = [json string:@"horizontalAlignment"]; + if (alignment) { + [self alignHorizontal:[ViewConstrainingView getAlignmentForString:alignment defaultAlignment:UIStackViewAlignmentFill]]; + } + alignment = [json string:@"verticalAlignment"]; + if (alignment) { + [self alignVertical:[ViewConstrainingView getAlignmentForString:alignment defaultAlignment:UIStackViewAlignmentFill]]; + } + + if ([self.molecule respondsToSelector:@selector(copyBackgroundColor)] && [self.molecule performSelector:@selector(copyBackgroundColor)]) { + self.backgroundColor = self.molecule.backgroundColor; } } diff --git a/MVMCoreUI/Molecules/MoleculeCollectionViewCell.swift b/MVMCoreUI/Molecules/MoleculeCollectionViewCell.swift index 5f18d454..6afec1bc 100644 --- a/MVMCoreUI/Molecules/MoleculeCollectionViewCell.swift +++ b/MVMCoreUI/Molecules/MoleculeCollectionViewCell.swift @@ -10,7 +10,12 @@ import UIKit open class MoleculeCollectionViewCell: UICollectionViewCell, MVMCoreUIMoleculeViewProtocol, MoleculeListCellProtocol { open var molecule: (UIView & MVMCoreUIMoleculeViewProtocol)? + open var json: [AnyHashable: Any]? + // In updateView, will set padding to default. + open var updateViewHorizontalDefaults = true + open var updateViewVerticalDefaults = true + open var allowsPeaking = false var peakingLeftArrow = UIImageView(image: MVMCoreUIUtility.imageNamed("peakingRightArrow")?.withRenderingMode(.alwaysTemplate)) var peakingRightArrow = UIImageView(image: MVMCoreUIUtility.imageNamed("peakingRightArrow")?.withRenderingMode(.alwaysTemplate)) @@ -58,6 +63,14 @@ open class MoleculeCollectionViewCell: UICollectionViewCell, MVMCoreUIMoleculeVi } public func setWithJSON(_ json: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable : Any]?) { + self.json = json + + if let useHorizontalMargins = json?.optionalBoolForKey("useHorizontalMargins") { + updateViewHorizontalDefaults = useHorizontalMargins + } + if let useVerticalMargins = json?.optionalBoolForKey("useVerticalMargins") { + updateViewVerticalDefaults = useVerticalMargins + } // Handles peaking. allowsPeaking = json?.optionalBoolForKey("peakingUI") ?? true @@ -67,27 +80,38 @@ open class MoleculeCollectionViewCell: UICollectionViewCell, MVMCoreUIMoleculeVi peakingRightArrow.tintColor = color } + if let backgroundColorString = json?.optionalStringForKey(KeyBackgroundColor) { + backgroundColor = UIColor.mfGet(forHex: backgroundColorString) + } + guard let moleculeJSON = json?.optionalDictionaryForKey(KeyMolecule) else { return } if molecule == nil { if let moleculeView = MVMCoreUIMoleculeMappingObject.shared()?.createMolecule(forJSON: moleculeJSON, delegateObject: delegateObject, constrainIfNeeded: true) { contentView.insertSubview(moleculeView, at: 0) - NSLayoutConstraint.activate(Array(NSLayoutConstraint.pinView(toSuperview: moleculeView, useMargins: false).values)) + NSLayoutConstraint.activate(Array(NSLayoutConstraint.pinView(toSuperview: moleculeView, useMargins: true).values)) molecule = moleculeView } } else { molecule?.setWithJSON(moleculeJSON, delegateObject: delegateObject, additionalData: additionalData) } + // This molecule will handle spacing by default. if let castView = molecule as? MVMCoreUIViewConstrainingProtocol { - let standardConstraints = castView.useStandardConstraints?() ?? true - castView.shouldSetHorizontalMargins?(standardConstraints) - castView.shouldSetVerticalMargins?(standardConstraints) + castView.shouldSetHorizontalMargins?(false) + castView.shouldSetVerticalMargins?(false) } - backgroundColor = molecule?.backgroundColor + accessibilityElements = molecule?.subviews } + public func reset() { + molecule?.reset?() + updateViewVerticalDefaults = true + updateViewHorizontalDefaults = true + backgroundColor = .white + } + public static func name(forReuse molecule: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?) -> String? { guard let molecule = molecule?.optionalDictionaryForKey(KeyMolecule) else { return nil @@ -97,6 +121,7 @@ open class MoleculeCollectionViewCell: UICollectionViewCell, MVMCoreUIMoleculeVi public func updateView(_ size: CGFloat) { molecule?.updateView(size) + MFStyler.setDefaultMarginsFor(contentView, size: size, horizontal: updateViewHorizontalDefaults, vertical: updateViewVerticalDefaults) } public func setPeaking(_ peaking: Bool, animated: Bool) { diff --git a/MVMCoreUI/Molecules/MoleculeStackView.swift b/MVMCoreUI/Molecules/MoleculeStackView.swift index 74178f5f..ad395eec 100644 --- a/MVMCoreUI/Molecules/MoleculeStackView.swift +++ b/MVMCoreUI/Molecules/MoleculeStackView.swift @@ -41,13 +41,12 @@ public class MoleculeStackView: ViewConstrainingView { var items: [StackItem] = [] var useStackSpacingBeforeFirstItem = false - private var moleculesShouldSetHorizontalMargins = true + private var moleculesShouldSetHorizontalMargins = false private var moleculesShouldSetVerticalMargins = false /// For setting the direction of the stack var axis: NSLayoutConstraint.Axis = .vertical { didSet { - moleculesShouldSetHorizontalMargins = (moleculesShouldSetHorizontalMargins && axis == .vertical) if axis != oldValue { restack() } @@ -109,6 +108,8 @@ public class MoleculeStackView: ViewConstrainingView { guard contentView.superview == nil else { return } + MVMCoreUIUtility.setMarginsFor(contentView, leading: 0, top: 0, trailing: 0, bottom: 0) + updateViewHorizontalDefaults = true translatesAutoresizingMaskIntoConstraints = false backgroundColor = .clear addSubview(contentView) @@ -125,12 +126,10 @@ public class MoleculeStackView: ViewConstrainingView { } // MARK: - MVMCoreUIMoleculeViewProtocol - public override func setAsMolecule() { - updateViewHorizontalDefaults = false - } - public override func reset() { + super.reset() backgroundColor = .clear + updateViewHorizontalDefaults = true for item in items { if let view = item.view as? MVMCoreUIMoleculeViewProtocol { view.reset?() @@ -138,23 +137,6 @@ public class MoleculeStackView: ViewConstrainingView { } } - public override func shouldSetHorizontalMargins(_ shouldSet: Bool) { - super.shouldSetHorizontalMargins(shouldSet) - updateViewHorizontalDefaults = false - moleculesShouldSetHorizontalMargins = (shouldSet && axis == .vertical) - for item in items { - (item.view as? MVMCoreUIViewConstrainingProtocol)?.shouldSetHorizontalMargins?(moleculesShouldSetHorizontalMargins) - } - } - - public override func shouldSetVerticalMargins(_ shouldSet: Bool) { - super.shouldSetVerticalMargins(shouldSet) - moleculesShouldSetVerticalMargins = false - for item in items { - (item.view as? MVMCoreUIViewConstrainingProtocol)?.shouldSetVerticalMargins?(moleculesShouldSetVerticalMargins) - } - } - open override func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) { let previousJSON = self.json super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData) @@ -175,10 +157,6 @@ public class MoleculeStackView: ViewConstrainingView { setAxisWithJSON(json) spacing = json?.optionalCGFloatForKey("spacing") ?? 16 - // Set the alignment for the stack in the containing view. The json driven value is for the axis direction alignment. - alignHorizontal(ViewConstrainingView.getAlignmentFor(json?.optionalStringForKey("horizontalAlignment"), defaultAlignment: .fill)) - alignVertical(ViewConstrainingView.getAlignmentFor(json?.optionalStringForKey("verticalAlignment"), defaultAlignment: .fill)) - // Adds the molecules and sets the json. for (index, map) in molecules.enumerated() { if let moleculeJSON = map.optionalDictionaryForKey(KeyMolecule) { diff --git a/MVMCoreUI/Molecules/MoleculeTableViewCell.swift b/MVMCoreUI/Molecules/MoleculeTableViewCell.swift index fc681c12..eff1e5c5 100644 --- a/MVMCoreUI/Molecules/MoleculeTableViewCell.swift +++ b/MVMCoreUI/Molecules/MoleculeTableViewCell.swift @@ -13,6 +13,10 @@ import UIKit open var molecule: (UIView & MVMCoreUIMoleculeViewProtocol)? open var json: [AnyHashable: Any]? + // In updateView, will set padding to default. + open var updateViewHorizontalDefaults = true + open var updateViewVerticalDefaults = true + // For the accessory view convenience. public var caretView: CaretView? private var caretViewWidthSizeObject: MFSizeObject? @@ -41,7 +45,7 @@ import UIKit // MARK: - MFViewProtocol public func updateView(_ size: CGFloat) { - MFStyler.setDefaultMarginsFor(self, size: size, horizontal: true, vertical: true) + MFStyler.setDefaultMarginsFor(self, size: size, horizontal: updateViewHorizontalDefaults, vertical: updateViewVerticalDefaults) if #available(iOS 11.0, *) { if accessoryView != nil { // Smaller left margin if accessory view. @@ -83,6 +87,31 @@ import UIKit // MARK: - MVMCoreUIMoleculeViewProtocol public func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) { self.json = json; + + if let useHorizontalMargins = json?.optionalBoolForKey("useHorizontalMargins") { + updateViewHorizontalDefaults = useHorizontalMargins + } + if let useVerticalMargins = json?.optionalBoolForKey("useVerticalMargins") { + updateViewVerticalDefaults = useVerticalMargins + } + + if let backgroundColorString = json?.optionalStringForKey(KeyBackgroundColor) { + backgroundColor = UIColor.mfGet(forHex: backgroundColorString) + } + + // Add the caret if there is an action and it's not declared hidden. + if let _ = json?.optionalDictionaryForKey("actionMap"), json!.boolForKey("hideArrow") { + addCaretViewAccessory() + } else { + accessoryView = nil + } + + // override the separator + if let separator = json?.optionalDictionaryForKey("separator") { + addSeparatorsIfNeeded() + bottomSeparatorView?.setWithJSON(separator, delegateObject: delegateObject, additionalData: additionalData) + } + guard let json = json, let moleculeJSON = json.optionalDictionaryForKey(KeyMolecule) else { return } @@ -101,30 +130,19 @@ import UIKit } else { molecule?.setWithJSON(moleculeJSON, delegateObject: delegateObject, additionalData: additionalData) } + + // This molecule will by default handle margins. if let castView = molecule as? MVMCoreUIViewConstrainingProtocol { - let standardConstraints = castView.useStandardConstraints?() ?? true - castView.shouldSetHorizontalMargins?(!standardConstraints) - castView.shouldSetVerticalMargins?(!standardConstraints) - } - - backgroundColor = molecule?.backgroundColor - - // Add the caret if there is an action and it's not declared hidden. - if let _ = json.optionalDictionaryForKey("actionMap"), !json.boolForKey("hideArrow") { - addCaretViewAccessory() - } else { - accessoryView = nil - } - - // override the separator - if let separator = json.optionalDictionaryForKey("separator") { - addSeparatorsIfNeeded() - bottomSeparatorView?.setWithJSON(separator, delegateObject: delegateObject, additionalData: additionalData) + castView.shouldSetHorizontalMargins?(false) + castView.shouldSetVerticalMargins?(false) } } public func reset() { molecule?.reset?() + updateViewVerticalDefaults = true + updateViewHorizontalDefaults = true + backgroundColor = .white } public static func estimatedHeight(forRow json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat { diff --git a/MVMCoreUI/Molecules/StandardFooterView.swift b/MVMCoreUI/Molecules/StandardFooterView.swift index a135ccc0..8f4ca0b5 100644 --- a/MVMCoreUI/Molecules/StandardFooterView.swift +++ b/MVMCoreUI/Molecules/StandardFooterView.swift @@ -12,14 +12,16 @@ open class StandardFooterView: ViewConstrainingView { open override func setupView() { super.setupView() setupMoleculeFromJSON = true + updateViewVerticalDefaults = true + updateViewHorizontalDefaults = true } open override func setWithJSON(_ json: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable : Any]?) { super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData) + + // This molecule will by default handle margins. (molecule as? MVMCoreUIViewConstrainingProtocol)?.shouldSetHorizontalMargins?(false) (molecule as? MVMCoreUIViewConstrainingProtocol)?.shouldSetVerticalMargins?(false) - shouldSetVerticalMargins(true) - shouldSetHorizontalMargins(true) } public override static func estimatedHeight(forRow json: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat { diff --git a/MVMCoreUI/Molecules/StandardHeaderView.swift b/MVMCoreUI/Molecules/StandardHeaderView.swift index ff5b8538..fbaa5518 100644 --- a/MVMCoreUI/Molecules/StandardHeaderView.swift +++ b/MVMCoreUI/Molecules/StandardHeaderView.swift @@ -15,11 +15,18 @@ public class StandardHeaderView: ViewConstrainingView { open override func updateView(_ size: CGFloat) { super.updateView(size) separatorView?.updateView(size) + if separatorView?.isHidden ?? true { + let margins = MVMCoreUIUtility.getMarginsFor(self) + MVMCoreUIUtility.setMarginsFor(self, leading: margins.left, top: margins.top, trailing: margins.right, bottom: 0) + bottomPin?.constant = 0 + } } public override func setupView() { super.setupView() setupMoleculeFromJSON = true + updateViewVerticalDefaults = true + updateViewHorizontalDefaults = true if separatorView == nil, let separatorView = SeparatorView.separatorAdd(to: self, position: SeparatorPositionBot, withHorizontalPadding: 0) { separatorView.setAsHeavy() addSubview(separatorView) @@ -40,19 +47,14 @@ public class StandardHeaderView: ViewConstrainingView { // MARK: - MVMCoreUIMoleculeViewProtocol open override func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) { super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData) + + // This molecule will by default handle margins. (molecule as? MVMCoreUIViewConstrainingProtocol)?.shouldSetHorizontalMargins?(false) (molecule as? MVMCoreUIViewConstrainingProtocol)?.shouldSetVerticalMargins?(false) - shouldSetVerticalMargins(true) - shouldSetHorizontalMargins(true) if let separatorJSON = json?.optionalDictionaryForKey("separator") { separatorView?.setWithJSON(separatorJSON, delegateObject: delegateObject, additionalData: additionalData) } - if separatorView?.isHidden ?? true { - bottomPin?.constant = 0 - } else { - bottomPin?.constant = PaddingDefaultVerticalSpacing - } } open override func reset() { diff --git a/MVMCoreUI/Styles/MFStyler.m b/MVMCoreUI/Styles/MFStyler.m index dc9288d8..2b0d0a0a 100644 --- a/MVMCoreUI/Styles/MFStyler.m +++ b/MVMCoreUI/Styles/MFStyler.m @@ -98,11 +98,7 @@ CGFloat const LabelWithInternalButtonLineSpace = 2; [MVMCoreDispatchUtility performBlockOnMainThread:^{ CGFloat horizontalPadding = horizontal ? [MFStyler defaultHorizontalPaddingForSize:size] : 0; CGFloat verticalPadding = vertical ? PaddingDefaultVerticalSpacing : 0; - if (@available(iOS 11.0, *)) { - view.directionalLayoutMargins = NSDirectionalEdgeInsetsMake(verticalPadding, horizontalPadding, verticalPadding, horizontalPadding); - } else { - view.layoutMargins = UIEdgeInsetsMake(verticalPadding, horizontalPadding, verticalPadding, horizontalPadding); - } + [MVMCoreUIUtility setMarginsForView:view leading:horizontalPadding top:verticalPadding trailing:horizontalPadding bottom:verticalPadding]; }]; } diff --git a/MVMCoreUI/Utility/MVMCoreUIUtility.h b/MVMCoreUI/Utility/MVMCoreUIUtility.h index 81545583..b6698537 100644 --- a/MVMCoreUI/Utility/MVMCoreUIUtility.h +++ b/MVMCoreUI/Utility/MVMCoreUIUtility.h @@ -28,6 +28,13 @@ NS_ASSUME_NONNULL_BEGIN // Returns an image from this framework's bundle + (nullable UIImage *)imageNamed:(nullable NSString *)imageName; +// Returns the margins for a view. ++ (UIEdgeInsets)getMarginsForView:(nullable UIView *)view; + +#pragma mark - Setters + ++ (void)setMarginsForView:(nullable UIView *)view leading:(CGFloat)leading top:(CGFloat)top trailing:(CGFloat)trailing bottom:(CGFloat)bottom; + #pragma mark - Formatting // Formats the given mdn. diff --git a/MVMCoreUI/Utility/MVMCoreUIUtility.m b/MVMCoreUI/Utility/MVMCoreUIUtility.m index 1afabeab..8201e999 100644 --- a/MVMCoreUI/Utility/MVMCoreUIUtility.m +++ b/MVMCoreUI/Utility/MVMCoreUIUtility.m @@ -57,6 +57,24 @@ return image; } ++ (UIEdgeInsets)getMarginsForView:(nullable UIView *)view { + if (@available(iOS 11.0, *)) { + return UIEdgeInsetsMake(view.directionalLayoutMargins.top, view.directionalLayoutMargins.leading, view.directionalLayoutMargins.bottom, view.directionalLayoutMargins.trailing); + } else { + return view.layoutMargins; + } +} + +#pragma mark - Setters + ++ (void)setMarginsForView:(nullable UIView *)view leading:(CGFloat)leading top:(CGFloat)top trailing:(CGFloat)trailing bottom:(CGFloat)bottom { + if (@available(iOS 11.0, *)) { + view.directionalLayoutMargins = NSDirectionalEdgeInsetsMake(top, leading, bottom, trailing); + } else { + view.layoutMargins = UIEdgeInsetsMake(top, leading, bottom, trailing); + } +} + #pragma mark - Formatting // As per business confirmation format should be xxx.xxx.xxxx same across application