assets, strings, and imports

This commit is contained in:
Pfeil, Scott Robert 2019-01-15 19:10:34 -05:00
parent 9dae621f2f
commit 49e4f4aa17
26 changed files with 219 additions and 115 deletions

View File

@ -123,6 +123,8 @@
D29DF32121ED0CBA003B2FB9 /* LabelView.m in Sources */ = {isa = PBXBuildFile; fileRef = D29DF31F21ED0CBA003B2FB9 /* LabelView.m */; };
D29DF32421ED0DA2003B2FB9 /* TextButtonView.m in Sources */ = {isa = PBXBuildFile; fileRef = D29DF32221ED0DA2003B2FB9 /* TextButtonView.m */; };
D29DF32521ED0DA2003B2FB9 /* TextButtonView.h in Headers */ = {isa = PBXBuildFile; fileRef = D29DF32321ED0DA2003B2FB9 /* TextButtonView.h */; settings = {ATTRIBUTES = (Public, ); }; };
D29DF32C21EE8736003B2FB9 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = D29DF32821EE8736003B2FB9 /* Localizable.strings */; };
D29DF32E21EE8C3D003B2FB9 /* Media.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = D29DF32D21EE8C3D003B2FB9 /* Media.xcassets */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
@ -244,6 +246,10 @@
D29DF31F21ED0CBA003B2FB9 /* LabelView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LabelView.m; sourceTree = "<group>"; };
D29DF32221ED0DA2003B2FB9 /* TextButtonView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TextButtonView.m; sourceTree = "<group>"; };
D29DF32321ED0DA2003B2FB9 /* TextButtonView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TextButtonView.h; sourceTree = "<group>"; };
D29DF32921EE8736003B2FB9 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = "<group>"; };
D29DF32A21EE8736003B2FB9 /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/Localizable.strings; sourceTree = "<group>"; };
D29DF32B21EE8736003B2FB9 /* es-MX */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "es-MX"; path = "es-MX.lproj/Localizable.strings"; sourceTree = "<group>"; };
D29DF32D21EE8C3D003B2FB9 /* Media.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Media.xcassets; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@ -280,7 +286,6 @@
isa = PBXGroup;
children = (
D29DF31421ECECA7003B2FB9 /* SupportingFiles */,
D29DF26621E6A9E4003B2FB9 /* ThirdParty */,
D29DF27021E79B2C003B2FB9 /* OtherHandlers */,
D29DF14E21E693BB003B2FB9 /* Session */,
D29DF13A21E68682003B2FB9 /* Utility */,
@ -559,7 +564,10 @@
D29DF31421ECECA7003B2FB9 /* SupportingFiles */ = {
isa = PBXGroup;
children = (
D29DF32721EE8736003B2FB9 /* Strings */,
D29DF26621E6A9E4003B2FB9 /* ThirdParty */,
D29DF31521ECECC0003B2FB9 /* Fonts */,
D29DF32D21EE8C3D003B2FB9 /* Media.xcassets */,
);
path = SupportingFiles;
sourceTree = "<group>";
@ -575,6 +583,14 @@
path = Fonts;
sourceTree = "<group>";
};
D29DF32721EE8736003B2FB9 /* Strings */ = {
isa = PBXGroup;
children = (
D29DF32821EE8736003B2FB9 /* Localizable.strings */,
);
path = Strings;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXHeadersBuildPhase section */
@ -684,6 +700,8 @@
hasScannedForEncodings = 0;
knownRegions = (
en,
es,
"es-MX",
);
mainGroup = D29DF0C221E404D4003B2FB9;
productRefGroup = D29DF0CD21E404D4003B2FB9 /* Products */;
@ -705,7 +723,9 @@
D29DF31C21ECECC0003B2FB9 /* NHaasGroteskDSStd-75Bd.otf in Resources */,
D29DF24F21E6A177003B2FB9 /* MFTextField.xib in Resources */,
D29DF31D21ECECC0003B2FB9 /* NHaasGroteskDSStd-55Rg.otf in Resources */,
D29DF32C21EE8736003B2FB9 /* Localizable.strings in Resources */,
D29DF31A21ECECC0003B2FB9 /* NHaasGroteskDSStd-45Lt.otf in Resources */,
D29DF32E21EE8C3D003B2FB9 /* Media.xcassets in Resources */,
D29DF31B21ECECC0003B2FB9 /* OCRAExtended.ttf in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
@ -772,6 +792,19 @@
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXVariantGroup section */
D29DF32821EE8736003B2FB9 /* Localizable.strings */ = {
isa = PBXVariantGroup;
children = (
D29DF32921EE8736003B2FB9 /* en */,
D29DF32A21EE8736003B2FB9 /* es */,
D29DF32B21EE8736003B2FB9 /* es-MX */,
);
name = Localizable.strings;
sourceTree = "<group>";
};
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
D29DF0D221E404D4003B2FB9 /* Debug */ = {
isa = XCBuildConfiguration;

View File

@ -12,6 +12,10 @@
#import <MVMCore/MVMCoreLoadDelegateProtocol.h>
#import <MVMCore/MVMCorePresentationDelegateProtocol.h>
#import <MVMCore/MVMCoreActionDelegateProtocol.h>
@import MVMCore.NSDictionary_MFConvenience;
@import MVMCore.MVMCoreLoadObject;
@import MVMCore.MVMCoreJSONConstants;
#import <MVMCoreUI/MFTextField.h>
#import <MVMCoreUI/ButtonDelegateProtocol.h>
@ -170,9 +174,6 @@
// Called when the user presses a menu option. Determines if we should load the option the default way or not.
- (BOOL)mainTableView:(nonnull MainMenuViewController *)mainTableView shouldSelectOptionAtIndexPath:(nonnull NSIndexPath *)indexPath;
// applies an image to the navigation title
-(void)createTitleWithImageName:(nullable NSString *)imageName;
#pragma mark - UITextField Functions
// Resigns the first responder.
@ -283,8 +284,5 @@
// subclass to set up intro animations
- (void)setupIntroAnimations;
// can be overriden to return the close button action map
- (nullable NSDictionary *)closeButtonActionMap;
@end

View File

@ -110,42 +110,12 @@
}
}
- (BOOL)checkforHeaderImage {
return [self.loadObject.pageJSON stringForKey:@"headerLogo"].length;
}
-(void)createTitleWithImageName:(nullable NSString *)imageName {
UIView *titleView = [[UIView alloc] init];
titleView.bounds = CGRectMake(CGRectGetMaxX(titleView.bounds), CGRectGetMaxY(titleView.bounds), 1, 1);
UIImageView *imageView = [[UIImageView alloc] initWithImage:[MVMCoreUIUtility imageNamed:imageName]];
imageView.translatesAutoresizingMaskIntoConstraints = NO;
imageView.contentMode = UIViewContentModeScaleAspectFit;
[titleView addSubview:imageView];
[NSLayoutConstraint constraintPinSubviewToSuperview:imageView];
[NSLayoutConstraint constraintPinView:imageView heightConstraint:YES heightConstant:12 widthConstraint:YES widthConstant:127];
//
[NSLayoutConstraint constraintPinView:titleView heightConstraint:YES heightConstant:1 widthConstraint:YES widthConstant:1];
[NSLayoutConstraint constraintPinSubview:imageView pinCenterX:YES pinCenterY:YES];
titleView.isAccessibilityElement = YES;
titleView.accessibilityLabel = [self screenHeading];
titleView.accessibilityTraits = UIAccessibilityTraitHeader;
self.navigationItem.titleView = titleView;
}
- (void)newDataBuildScreen {
if ([self checkforHeaderImage]) {
// user header image
[self createTitleWithImageName:[self.loadObject.pageJSON stringForKey:@"headerLogo"]];
} else {
// Sets the screen to use the screen heading.
NSString *screenHeading = [self screenHeading];
if (screenHeading) {
[self setScreenHeadingMessage:screenHeading];
}
// Sets the screen to use the screen heading.
NSString *screenHeading = [self screenHeading];
if (screenHeading) {
[self setScreenHeadingMessage:screenHeading];
}
}
@ -320,7 +290,7 @@
// Update separator.
UIView *separatorView = (UIView *)[MVMCoreUISession sharedGlobal].splitViewController.navigationBarSeparator;
separatorView.hidden = (self.class == [MVMCoreUITabBarPageControlViewController class]
separatorView.hidden = ([self.class isKindOfClass:[MVMCoreUITabBarPageControlViewController class]]
|| self.tabBarPageControl
|| self.loadObject.requestParameters.tabWasPressed);
}

View File

@ -33,12 +33,19 @@ typedef NS_ENUM(NSInteger, MFNumberOfDrawers) {
@property (nullable, strong, nonatomic) UIBarButtonItem *leftPanelButton;
@property (nullable, strong, nonatomic) UIBarButtonItem *rightPanelButton;
@property (nullable, strong, nonatomic) UIBarButtonItem *backButton;
@property (nullable, weak, nonatomic, readonly) UINavigationController *navigationController;
// Reference to the top alert view
@property (nullable, weak, nonatomic) MVMCoreUITopAlertView *topAlertView;
@property (nullable, strong, nonatomic) SeparatorView *navigationBarSeparator;
// References to the current navigation item settings.
@property (nonatomic, readonly) BOOL leftPanelIsAccessible;
@property (nonatomic, readonly) BOOL rightPanelIsAccessible;
@property (nullable, weak, nonatomic, readonly) UIViewController *navigationItemViewController;
// Convenience getter
+ (nullable instancetype)mainSplitViewController;
@ -56,6 +63,10 @@ typedef NS_ENUM(NSInteger, MFNumberOfDrawers) {
- (void)hideRightPanelIfNeededAnimated:(BOOL)animated;
- (void)showRightPanelAnimated:(BOOL)animated;
// Setters for the navigation items
- (void)setLeftNavigationItemForViewController:(UIViewController * _Nonnull)viewController accessible:(BOOL)accessible extended:(BOOL)extended;
- (void)setRightNavigationItemForViewController:(UIViewController * _Nonnull)viewController accessible:(BOOL)accessible extended:(BOOL)extended;
// Force hides both drawers. Does not animate or open always extended drawers on ipad either.
- (void)forceHideBothDrawers;

View File

@ -44,8 +44,6 @@
// A view that covers the detail view when the master is out.
@property (weak, nonatomic) IBOutlet UIView *mainViewCoverView;
@property (strong, nonatomic) UIBarButtonItem *backButton;
@property (weak, nonatomic) IBOutlet UIProgressView *bottomProgressBar;
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *bottomProgressBarHeightConstraint;
@ -63,9 +61,9 @@ typedef NS_OPTIONS(NSInteger, MFExtendedDrawer) {
};
@property (nonatomic) MFExtendedDrawer extendedDrawers;
@property (nonatomic) BOOL leftPanelIsAccessible;
@property (nonatomic) BOOL rightPanelIsAccessible;
@property (weak, nonatomic) UIViewController *viewController;
@property (nonatomic, readwrite) BOOL leftPanelIsAccessible;
@property (nonatomic, readwrite) BOOL rightPanelIsAccessible;
@property (weak, nonatomic, readwrite) UIViewController *navigationItemViewController;
@property (strong, nonatomic) NSNumber *transitionWidth;
// Dismisses any panel
@ -203,7 +201,7 @@ CGFloat const PanelAnimationDuration = 0.2;
if ([viewController.navigationController.viewControllers count] > 1) {
[leftBarButtonItems addObject:self.backButton];
}
if ((accessible || !extended) && self.leftPanelButton) {
if ((accessible && !extended) && self.leftPanelButton) {
[leftBarButtonItems addObject:self.leftPanelButton];
}
NSArray *extraButtons = [self additionalLeftButtons];
@ -219,7 +217,7 @@ CGFloat const PanelAnimationDuration = 0.2;
} else {
self.leftPanelIsAccessible = leftPanelIsAccessible;
}
self.viewController = viewController;
self.navigationItemViewController = viewController;
[MVMCoreDispatchUtility performBlockOnMainThread:^{
BOOL extended = NO;
if (!self.leftPanelIsAccessible) {
@ -368,7 +366,7 @@ CGFloat const PanelAnimationDuration = 0.2;
- (void)setRightNavigationItemForViewController:(UIViewController * _Nonnull)viewController accessible:(BOOL)accessible extended:(BOOL)extended {
NSMutableArray *navigationItems = [[NSMutableArray alloc] init];
if ((accessible || !extended) && self.rightPanelButton) {
if ((accessible && !extended) && self.rightPanelButton) {
[navigationItems addObject:self.rightPanelButton];
}
NSArray *extraButtons = [self additionalRightButtons];
@ -408,7 +406,7 @@ CGFloat const PanelAnimationDuration = 0.2;
} else {
self.rightPanelIsAccessible = rightPanelIsAccessible;
}
self.viewController = viewController;
self.navigationItemViewController = viewController;
[MVMCoreDispatchUtility performBlockOnMainThread:^{
BOOL extended = NO;
@ -855,8 +853,8 @@ CGFloat const PanelAnimationDuration = 0.2;
}
- (void)resetDrawers {
[self setLeftPanelIsAccessible:self.leftPanelIsAccessible forViewController:self.viewController];
[self setRightPanelIsAccessible:self.rightPanelIsAccessible forViewController:self.viewController];
[self setLeftPanelIsAccessible:self.leftPanelIsAccessible forViewController:self.navigationItemViewController];
[self setRightPanelIsAccessible:self.rightPanelIsAccessible forViewController:self.navigationItemViewController];
[self.view setNeedsLayout];
[self.view layoutIfNeeded];
@ -928,16 +926,6 @@ CGFloat const PanelAnimationDuration = 0.2;
}
}
- (NSString *)getPageTypeForDetailViewController {
UIViewController *viewController = [self getCurrentDetailViewController];
if ([viewController conformsToProtocol:@protocol(MVMCoreViewControllerProtocol)] && [viewController respondsToSelector:@selector(pageType)]) {
return ((UIViewController <MVMCoreViewControllerProtocol> *)viewController).pageType;
} else {
return @"NoPageType";
}
}
#pragma mark - navigation bar
- (void)setNavigationIconColor:(nullable UIColor *)color {

View File

@ -0,0 +1,23 @@
{
"images" : [
{
"idiom" : "universal",
"filename" : "back.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "back@2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"filename" : "back@3x.png",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 242 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 414 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 588 B

View File

@ -0,0 +1,23 @@
{
"images" : [
{
"idiom" : "universal",
"filename" : "fallback_en.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "fallback_en@2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"filename" : "fallback_en@3x.png",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

View File

@ -0,0 +1,23 @@
{
"images" : [
{
"idiom" : "universal",
"filename" : "fallback_es.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "fallback_es@2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"filename" : "fallback_es@3x.png",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

View File

@ -0,0 +1,31 @@
/*
Localizable.strings
MVMCore
Created by Pfeil, Scott Robert on 11/28/17.
Copyright © 2017 myverizon. All rights reserved.
*/
//// Accessibility
"AccCloseButton" = "Close";
// Tab
"AccTab" = ", tab";
"AccTabHint" = "Double tap to select.";
// top alert
"toptabbar_tab_selected" = ", tab, Selected";
"AccTopAlertClosed" = "Top alert notification is closed.";
"top_alert_notification" = "Top alert notification";
// Textfield
"textfield_today_string" = "Today";
"textfield_error_message" = "%@.\n The error message.\n %@";
"textfield_picker_item" = " picker item";
"textfield_regular" = " regular";
"textfield_disabled_state" = "disabled";
// MDNTextfield
"textfield_contacts_barbutton" = "My Contacts";
"textfield_phone_format_error_message" = "Invalid phone number format.";
// DigitTextfield
"mfdigittextfield_regular" = " regular";
// Camera
"AccCameraButton" = "Camera Button";
"AccCameraHint" = "Double tap to launch camera for scanning";

View File

@ -0,0 +1,27 @@
/*
Localizable.strings
MVMCore
Created by Pfeil, Scott Robert on 11/28/17.
Copyright © 2017 myverizon. All rights reserved.
*/
"AccCloseButton" = "Cerrar";
"AccTab" = ", pestaña";
"AccTabHint" = "Toca dos veces para seleccionar.";
"toptabbar_tab_selected" = ", pestaña, Seleccionado";
"AccTopAlertClosed" = "La notificación de alerta máxima está desactivada.";
"top_alert_notification" = "Notificación de alerta máxima";
"textfield_today_string" = "Hoy";
"textfield_error_message" = "%@.\n El mensaje de error.\n %@";
"textfield_picker_item" = " artículo de selector";
"textfield_regular" = " regular";
"textfield_disabled_state" = "inactivo";
//MDNTextfield
"textfield_contacts_barbutton" = "Mis contactos";
"textfield_phone_format_error_message" = "Formato de número de teléfono inválido.";
// DigitTextfield
"mfdigittextfield_regular" = " regular";
// Camera
"AccCameraButton" = "Botón de cámara";
"AccCameraHint" = "Toca dos veces para iniciar la cámara para escanear";

View File

@ -0,0 +1,27 @@
/*
Localizable.strings
MVMCore
Created by Pfeil, Scott Robert on 11/28/17.
Copyright © 2017 myverizon. All rights reserved.
*/
"AccCloseButton" = "Cerrar";
"AccTab" = ", pestaña";
"AccTabHint" = "Toca dos veces para seleccionar.";
"toptabbar_tab_selected" = ", pestaña, Seleccionado";
"AccTopAlertClosed" = "La notificación de alerta máxima está desactivada.";
"top_alert_notification" = "Notificación de alerta máxima";
"textfield_today_string" = "Hoy";
"textfield_error_message" = "%@.\n El mensaje de error.\n %@";
"textfield_picker_item" = " artículo de selector";
"textfield_regular" = " regular";
"textfield_disabled_state" = "inactivo";
//MDNTextfield
"textfield_contacts_barbutton" = "Mis contactos";
"textfield_phone_format_error_message" = "Formato de número de teléfono inválido.";
// DigitTextfield
"mfdigittextfield_regular" = " regular";
// Camera
"AccCameraButton" = "Botón de cámara";
"AccCameraHint" = "Toca dos veces para iniciar la cámara para escanear";

View File

@ -67,12 +67,6 @@
#pragma mark - Buttons
// Returns a close button. Can pass in the button to use, if not it will create it. Can also specify if we should constrain the height and width to the default.
+ (nonnull UIButton *)closeButton:(nullable UIButton *)button constrainHeightAndWidth:(BOOL)constrainHeightAndWidth;
// Returns a close button. Can pass in the button to use, if not it will create it. Can also specify if we should constrain the height and width to the default OR with a diameter(applies only when constrainHeightAndWidth is NO). If diameter is 0, the case with constrainHeightAndWidth == YES will be applied
+ (nonnull UIButton *)circleCloseButtonWhiteBackground:(nullable UIButton *)button constrainHeightAndWidth:(BOOL)constrainHeightAndWidth orDiameter:(CGFloat) diameter;
//add the close button (x) to the top left of the view, return the button
//@param view: the view to add the close button, it will add to the top right cornor as defult, pass in nil if you only want the reference to the button but not adding it to any view
//if verticalCentered is true, the button will pin to the vertical center of the view instead of top right

View File

@ -254,52 +254,8 @@ static const CGFloat VertialShadowOffset = 6;
#pragma mark - Buttons
+ (nonnull UIButton *)closeButton:(nullable UIButton *)button constrainHeightAndWidth:(BOOL)constrainHeightAndWidth {
UIButton *theButton = button;
if (!button) {
theButton = [UIButton buttonWithType:UIButtonTypeCustom];
}
theButton.tintColor = [UIColor mfRedColor];
[theButton setImage:[[MVMCoreUIUtility imageNamed:@"close_30px"] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate] forState:UIControlStateNormal];
theButton.translatesAutoresizingMaskIntoConstraints = NO;
[theButton setImageEdgeInsets:UIEdgeInsetsMake(5, 10, 5, 0)];
// Adds the height and width constraint
if (constrainHeightAndWidth) {
[NSLayoutConstraint activateConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:[theButton(==40)]" options:0 metrics:nil views:NSDictionaryOfVariableBindings(theButton)]];
[NSLayoutConstraint activateConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[theButton(==40)]" options:0 metrics:nil views:NSDictionaryOfVariableBindings(theButton)]];
}
return theButton;
}
+ (nonnull UIButton *)circleCloseButtonWhiteBackground:(nullable UIButton *)button constrainHeightAndWidth:(BOOL)constrainHeightAndWidth orDiameter:(CGFloat) diameter {
UIButton *theButton = button;
if (!button) {
theButton = [UIButton buttonWithType:UIButtonTypeCustom];
}
theButton.tintColor = [UIColor mfGrayColor];
theButton.backgroundColor = [UIColor whiteColor];
[theButton setImage:[MVMCoreUIUtility imageNamed:@"close"] forState:UIControlStateNormal];
theButton.translatesAutoresizingMaskIntoConstraints = NO;
// Adds the height and width constraint
if (constrainHeightAndWidth || diameter == 0) {
theButton.layer.cornerRadius = 20;
[NSLayoutConstraint activateConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:[theButton(==40)]" options:0 metrics:nil views:NSDictionaryOfVariableBindings(theButton)]];
[NSLayoutConstraint activateConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[theButton(==40)]" options:0 metrics:nil views:NSDictionaryOfVariableBindings(theButton)]];
}
else {
theButton.layer.cornerRadius = diameter/2;
[NSLayoutConstraint activateConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:[theButton(==diameter)]" options:0 metrics:@{@"diameter": @(diameter)} views:NSDictionaryOfVariableBindings(theButton)]];
[NSLayoutConstraint activateConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[theButton(==diameter)]" options:0 metrics:@{@"diameter": @(diameter)} views:NSDictionaryOfVariableBindings(theButton)]];
}
return theButton;
}
+ (nonnull MFCustomButton *)addCloseButtonToView:(UIView *)view action:(ButtonTapBlock)actionBlock verticalCentered:(BOOL)verticalCentered {
MFCustomButton *button = [[MFCustomButton alloc]initWithFrame:CGRectZero];
MFCustomButton *button = [[MFCustomButton alloc] initWithFrame:CGRectZero];
button.translatesAutoresizingMaskIntoConstraints = NO;
[button setTitle:@"✕" forState:UIControlStateNormal];
button.titleLabel.font = [MFStyler fontForHeadlineAlternative];