Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A lot of features #19

Open
wants to merge 23 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 40 additions & 29 deletions Source/Categories/ESTabBarController+Autolayout.m
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,14 @@ @implementation ESTabBarController (Autolayout)


- (void)setupButtonsConstraints {

// In case dumb user doesn't know math
if(self.widthPercentages!=nil && self.widthPercentages.count
!= self.tabIcons.count && [[self.widthPercentages valueForKeyPath:@"@sum.self"] floatValue] != 1.0) {
self.widthPercentages = nil;
}
for (NSInteger i = 0; i < self.tabIcons.count; i++) {
[self.buttons[i] setTranslatesAutoresizingMaskIntoConstraints:NO];

[self.view addConstraints:[self leftLayoutConstraintsForButtonAtIndex:i]];
[self.view addConstraints:[self verticalLayoutConstraintsForButtonAtIndex:i]];
[self.view addConstraint:[self widthLayoutConstraintForButtonAtIndex:i]];
Expand All @@ -43,7 +48,6 @@ - (void)setupButtonsConstraints {

- (void)setupSelectionIndicatorConstraints {
self.selectionIndicatorLeadingConstraint = [self leadingLayoutConstraintForIndicator];

[self.buttonsContainer addConstraint:self.selectionIndicatorLeadingConstraint];
[self.buttonsContainer addConstraints:[self widthLayoutConstraintsForIndicator]];
[self.buttonsContainer addConstraints:[self heightLayoutConstraintsForIndicator]];
Expand All @@ -53,13 +57,11 @@ - (void)setupSelectionIndicatorConstraints {

- (void)setupConstraintsForChildController:(UIViewController *)controller {
NSDictionary *views = @{@"view": controller.view};

NSArray *horizontalConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"|-0-[view]-0-|"
options:0
metrics:nil
views:views];
[self.controllersContainer addConstraints:horizontalConstraints];

NSArray *verticalConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-0-[view]-0-|"
options:0
metrics:nil
Expand All @@ -74,7 +76,6 @@ - (void)setupConstraintsForChildController:(UIViewController *)controller {
- (NSArray *)leftLayoutConstraintsForButtonAtIndex:(NSInteger)index {
UIButton *button = self.buttons[index];
NSArray *leftConstraints;

if (index == 0) {
// First button. Stick it to its left margin.
leftConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"|-(0)-[button]"
Expand All @@ -84,21 +85,18 @@ - (NSArray *)leftLayoutConstraintsForButtonAtIndex:(NSInteger)index {
} else {
NSDictionary *views = @{@"previousButton": self.buttons[index - 1],
@"button": button};

// Stick the button to the previous one.
leftConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"[previousButton]-(0)-[button]"
options:0
metrics:nil
views:views];
}

return leftConstraints;
}


- (NSArray *)verticalLayoutConstraintsForButtonAtIndex:(NSInteger)index {
UIButton *button = self.buttons[index];

// The button is sticked to its top and bottom margins.
return [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-(0)-[button]"
options:0
Expand All @@ -109,20 +107,23 @@ - (NSArray *)verticalLayoutConstraintsForButtonAtIndex:(NSInteger)index {

- (NSLayoutConstraint *)widthLayoutConstraintForButtonAtIndex:(NSInteger)index {
UIButton *button = self.buttons[index];

CGFloat width = 1.0/self.buttons.count;
if (self.widthPercentages) {
width = [[self.widthPercentages objectAtIndex:index] floatValue];
}

return [NSLayoutConstraint constraintWithItem:button
attribute:NSLayoutAttributeWidth
relatedBy:NSLayoutRelationEqual
toItem:self.buttonsContainer
attribute:NSLayoutAttributeWidth
multiplier:1.0 / self.buttons.count
multiplier:width
constant:0.0];
}


- (NSLayoutConstraint *)heightLayoutConstraintForButtonAtIndex:(NSInteger)index {
UIButton *button = self.buttons[index];

return [NSLayoutConstraint constraintWithItem:button
attribute:NSLayoutAttributeHeight
relatedBy:NSLayoutRelationEqual
Expand All @@ -134,34 +135,45 @@ - (NSLayoutConstraint *)heightLayoutConstraintForButtonAtIndex:(NSInteger)index


- (NSLayoutConstraint *)leadingLayoutConstraintForIndicator {
NSArray *constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"|-(0)-[selectionIndicator]"
options:0
metrics:nil
views:@{@"selectionIndicator": self.selectionIndicator}];

return [constraints firstObject];
if(self.indicatorSizeRelativeToIcon){
return [NSLayoutConstraint constraintWithItem:self.selectionIndicator attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:self.buttons[0] attribute:NSLayoutAttributeCenterX multiplier:1.0 constant:0.0];
} else {
NSArray *constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"|-(0)-[selectionIndicator]"
options:0
metrics:nil
views:@{@"selectionIndicator": self.selectionIndicator}];
return [constraints firstObject];
}

}


- (NSArray *)widthLayoutConstraintsForIndicator {
NSDictionary *views = @{@"button": self.buttons[0],
@"selectionIndicator": self.selectionIndicator};

return [NSLayoutConstraint constraintsWithVisualFormat:@"[selectionIndicator(==button)]"
options:0
metrics:nil
views:views];
if(self.indicatorSizeRelativeToIcon){
return @[[NSLayoutConstraint constraintWithItem:self.selectionIndicator
attribute:NSLayoutAttributeWidth
relatedBy:NSLayoutRelationEqual
toItem:[self.buttons[0] valueForKey:@"imageView"]
attribute:NSLayoutAttributeWidth
multiplier:1.0
constant:0.0]];
} else {
NSDictionary *views = @{@"button": self.buttons[0],
@"selectionIndicator": self.selectionIndicator};
return [NSLayoutConstraint constraintsWithVisualFormat:@"[selectionIndicator(==button)]"
options:0
metrics:nil
views:views];

}
}


- (NSArray *)heightLayoutConstraintsForIndicator {
NSArray *heightConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"V:[selectionIndicator(==3)]"
return [NSLayoutConstraint constraintsWithVisualFormat:@"V:[selectionIndicator(==3)]"
options:0
metrics:nil
views:@{@"selectionIndicator": self.selectionIndicator}];
self.selectionIndicatorHeightConstraint = [heightConstraints firstObject];

return heightConstraints;
}


Expand All @@ -172,5 +184,4 @@ - (NSArray *)bottomLayoutConstraintsForIndicator {
views:@{@"selectionIndicator": self.selectionIndicator}];
}


@end
3 changes: 2 additions & 1 deletion Source/Categories/UIButton+ESTabBar.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

- (void)customizeForTabBarWithImage:(UIImage *)image
selectedColor:(UIColor *)selectedColor
highlighted:(BOOL)highlighted;
highlighted:(BOOL)highlighted
backgroundColor:(UIColor *)backgroundColor;

@end
23 changes: 12 additions & 11 deletions Source/Categories/UIButton+ESTabBar.m
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,11 @@ @implementation UIButton (ESTabBar)

- (void)customizeForTabBarWithImage:(UIImage *)image
selectedColor:(UIColor *)selectedColor
highlighted:(BOOL)highlighted {
highlighted:(BOOL)highlighted
backgroundColor:(UIColor *)backgroundColor {
if (highlighted) {
[self customizeAsHighlightedButtonForTabBarWithImage:image
selectedColor:selectedColor];
backgroundColor:backgroundColor];
} else {
[self customizeAsNormalButtonForTabBarWithImage:image
selectedColor:selectedColor];
Expand All @@ -32,34 +33,34 @@ - (void)customizeForTabBarWithImage:(UIImage *)image


- (void)customizeAsHighlightedButtonForTabBarWithImage:(UIImage *)image
selectedColor:(UIColor *)selectedColor {
backgroundColor:(UIColor *)backgroundColor {

// We want the image to be always white in highlighted state.
self.tintColor = [UIColor whiteColor];
[self setImage:[image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]
[self setImage:[image imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]
forState:UIControlStateNormal];

// And its background color should always be the selected color.
self.backgroundColor = selectedColor;
self.backgroundColor = backgroundColor;
}


- (void)customizeAsNormalButtonForTabBarWithImage:(UIImage *)image
selectedColor:(UIColor *)selectedColor {

// The tint color is the one used for selected state.
self.tintColor = selectedColor;

// When the button is not selected, we show the image always with its
// original color.
[self setImage:[image imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]
forState:UIControlStateNormal];

// When the button is selected, we apply the tint color using the
// always template mode.
[self setImage:[image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]
forState:UIControlStateSelected];

// We don't want a background color to use the one in the tab bar.
self.backgroundColor = [UIColor clearColor];
}
Expand Down
23 changes: 23 additions & 0 deletions Source/Controllers/ESTabBarController.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,25 @@
//

#import <UIKit/UIKit.h>
#import "ESTabBarDelegate.h"

typedef void (^ESTabBarAction)(void);


@interface ESTabBarController : UIViewController

/// Delegate to expose some events from the tab bar
@property (nonatomic, assign) id<ESTabBarDelegate> delegate;

/// Color to use for when a tab bar button is selected.
@property (nonatomic, strong) UIColor *selectedColor;

/// Background color for the view that contains the buttons.
@property (nonatomic, strong) UIColor *buttonsBackgroundColor;

/// The color of the highlighted button background
@property (nonatomic, strong) UIColor *highlightedBackgroundColor;

/// The index (starting from 0) of the view controller being shown.
@property (nonatomic, readonly) NSInteger selectedIndex;

Expand All @@ -38,6 +44,13 @@ typedef void (^ESTabBarAction)(void);
@property (nonatomic, assign) CGFloat selectionIndicatorHeight;


/// Array with all widths of the buttons. Enables to determine the width of each button in the tab bar.
@property (nonatomic,strong) NSMutableArray *widthPercentages;

/// Sets the small indicator size to be rational to the size of the icon.
@property (nonatomic,assign) BOOL indicatorSizeRelativeToIcon;


/**
Initializes the tab bar with an array of UIImage that will be the icons
to show in the tab bar.
Expand All @@ -58,6 +71,11 @@ typedef void (^ESTabBarAction)(void);
- (void)setViewController:(UIViewController *)viewController
atIndex:(NSInteger)index;

/**
Gets the button container view. Useful for onboarding for tab bar and etc.
*/
- (UIView *)getButtonsContianer;

/**
Sets an action to be fired when tapping a button at a specific index. If there
is also a view controller set at that index, the action is fired immediately
Expand Down Expand Up @@ -92,5 +110,10 @@ typedef void (^ESTabBarAction)(void);
*/
- (void)setSelectedIndex:(NSInteger)selectedIndex animated:(BOOL)animated;

/**
Changes icon image at specific index.
*/
- (void)setIconImageAtIndex:(NSInteger)selectedIndex icon:(UIImage *)icon;


@end
Loading