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

New Features #18

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
2 changes: 1 addition & 1 deletion ISHHoverBar.podspec
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

Pod::Spec.new do |s|
s.name = 'ISHHoverBar'
s.version = '1.0.1'
s.version = '1.0.2'
s.summary = 'A vertical or horizontal toolbar that is designed to hover (float) over your content as seen in the iOS 10 Maps app'
s.description = <<-DESC
A floating UIToolBar replacement supporting vertical and horizontal orientation. It is designed to hover over your content and plays nicely with auto layout.
Expand Down
19 changes: 19 additions & 0 deletions ISHHoverBar.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
DC1CDCE81D344FA600EBF9E5 /* MapKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DC1CDCE71D344FA600EBF9E5 /* MapKit.framework */; };
DC5D282E1D3515C0005084AC /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = DC5D282A1D3515C0005084AC /* LaunchScreen.storyboard */; };
DC5D282F1D3515C0005084AC /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = DC5D282C1D3515C0005084AC /* Main.storyboard */; };
FA90B96A20B74ACE006993F3 /* ISHHoverBarItemType.h in Headers */ = {isa = PBXBuildFile; fileRef = FA90B96920B74ACE006993F3 /* ISHHoverBarItemType.h */; settings = {ATTRIBUTES = (Public, ); }; };
FA90B96B20B74E0D006993F3 /* HoverBarItem.m in Sources */ = {isa = PBXBuildFile; fileRef = FA94120420B729B900E7C045 /* HoverBarItem.m */; };
/* End PBXBuildFile section */

/* Begin PBXContainerItemProxy section */
Expand Down Expand Up @@ -80,6 +82,9 @@
DC5D282B1D3515C0005084AC /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
DC5D282D1D3515C0005084AC /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
DC5D28311D351652005084AC /* ISHHoverBar+Tests.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ISHHoverBar+Tests.h"; sourceTree = "<group>"; };
FA90B96920B74ACE006993F3 /* ISHHoverBarItemType.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ISHHoverBarItemType.h; sourceTree = "<group>"; };
FA94120420B729B900E7C045 /* HoverBarItem.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = HoverBarItem.m; sourceTree = "<group>"; };
FA94120620B729C200E7C045 /* HoverBarItem.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = HoverBarItem.h; sourceTree = "<group>"; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
Expand Down Expand Up @@ -143,6 +148,7 @@
children = (
1BEE266B1D364BB100301E9E /* ISHHoverBar.h */,
DC1CDCE41D343FA400EBF9E5 /* ISHHoverBar.m */,
FA90B96920B74ACE006993F3 /* ISHHoverBarItemType.h */,
1BEE266D1D364BB100301E9E /* Info.plist */,
);
path = ISHHoverBar;
Expand Down Expand Up @@ -183,6 +189,8 @@
DC5D28301D3515CF005084AC /* Classes */ = {
isa = PBXGroup;
children = (
FA94120620B729C200E7C045 /* HoverBarItem.h */,
FA94120420B729B900E7C045 /* HoverBarItem.m */,
DC1CDCC11D343F5C00EBF9E5 /* AppDelegate.h */,
DC1CDCC21D343F5C00EBF9E5 /* AppDelegate.m */,
DC1CDCC41D343F5C00EBF9E5 /* ViewController.h */,
Expand All @@ -199,6 +207,7 @@
buildActionMask = 2147483647;
files = (
1BEE266C1D364BB100301E9E /* ISHHoverBar.h in Headers */,
FA90B96A20B74ACE006993F3 /* ISHHoverBarItemType.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down Expand Up @@ -272,6 +281,7 @@
TargetAttributes = {
1BEE26681D364BB100301E9E = {
CreatedOnToolsVersion = 7.3.1;
LastSwiftMigration = 0930;
};
DC1CDCBA1D343F5C00EBF9E5 = {
CreatedOnToolsVersion = 7.3.1;
Expand Down Expand Up @@ -347,6 +357,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
FA90B96B20B74E0D006993F3 /* HoverBarItem.m in Sources */,
DC1CDCC61D343F5C00EBF9E5 /* ViewController.m in Sources */,
DC1CDCC31D343F5C00EBF9E5 /* AppDelegate.m in Sources */,
DC1CDCC01D343F5C00EBF9E5 /* main.m in Sources */,
Expand Down Expand Up @@ -404,7 +415,9 @@
1BEE26731D364BB200301E9E /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO;
APPLICATION_EXTENSION_API_ONLY = YES;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_IDENTITY = "";
DEFINES_MODULE = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
Expand All @@ -416,6 +429,8 @@
PRODUCT_BUNDLE_IDENTIFIER = de.iosphere.ISHHoverBar;
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 3.0;
TARGETED_DEVICE_FAMILY = "1,2";
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
Expand All @@ -425,7 +440,9 @@
1BEE26741D364BB200301E9E /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO;
APPLICATION_EXTENSION_API_ONLY = YES;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_IDENTITY = "";
DEFINES_MODULE = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
Expand All @@ -437,6 +454,8 @@
PRODUCT_BUNDLE_IDENTIFIER = de.iosphere.ISHHoverBar;
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
SWIFT_COMPILATION_MODE = singlefile;
SWIFT_VERSION = 3.0;
TARGETED_DEVICE_FAMILY = "1,2";
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
Expand Down
3 changes: 3 additions & 0 deletions ISHHoverBar/ISHHoverBar.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
//

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

typedef NS_ENUM (NSInteger, ISHHoverBarOrientation) {
/// In vertical orientation the ISHHoverBar places bar buttons from top to bottom.
Expand Down Expand Up @@ -46,4 +47,6 @@ IB_DESIGNABLE
/// The bar's shadow color. Default is black.
@property (nonatomic, nullable) IBInspectable UIColor *shadowColor;

-(void)reload;

@end
81 changes: 55 additions & 26 deletions ISHHoverBar/ISHHoverBar.m
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
//

#import "ISHHoverBar.h"
#import "ISHHoverBarItemType.h"

const CGFloat ISHHoverBarDefaultItemDimension = 44.0;

Expand Down Expand Up @@ -167,6 +168,7 @@ - (void)drawRect:(CGRect)rect {

@interface ISHHoverBar ()
@property (nonatomic, nonnull) UIVisualEffectView *backgroundView;
@property (nonatomic, nonnull) UIView *backgroundContainerView;
@property (nonatomic, nonnull) ISHHoverSeparatorView *separatorView;
@property (nonatomic, nonnull) ISHHoverShadowLayer *shadowLayer;
@property (nonatomic, nullable) NSArray<UIControl *> *controls;
Expand Down Expand Up @@ -196,15 +198,19 @@ - (void)commonInit {
[self setShadowLayer:shadowLayer];
[self.layer addSublayer:shadowLayer];

UIView* backgroundContainerView = [[UIView alloc] init];
self.backgroundContainerView = backgroundContainerView;
[self addSubview:backgroundContainerView];

// add visual effects view as background
UIVisualEffectView *bgView = [[UIVisualEffectView alloc] initWithEffect:[UIBlurEffect effectWithStyle:UIBlurEffectStyleExtraLight]];
[self setBackgroundView:bgView];
[self addSubview:bgView];
[self.backgroundContainerView addSubview:bgView];

// add separator drawing view on top
ISHHoverSeparatorView *sepView = [ISHHoverSeparatorView new];
[self setSeparatorView:sepView];
[self addSubview:sepView];
[self.backgroundContainerView addSubview:sepView];

// set default values
[self setBorderColor:[UIColor lightGrayColor]];
Expand Down Expand Up @@ -240,7 +246,16 @@ - (void)setItems:(nullable NSArray<UIBarButtonItem *> *)items {
#pragma mark - Layout

- (CGSize)intrinsicContentSize {
CGFloat itemLength = ISHHoverBarDefaultItemDimension * (CGFloat)self.items.count;

CGFloat itemLength = 0.0;
for (UIBarButtonItem* item in self.items) {
NSLog(@"%d", [item conformsToProtocol:@protocol(ISHHoverBarItemType)]);
if ([item conformsToProtocol:@protocol(ISHHoverBarItemType)]) {
itemLength += ((UIBarButtonItem<ISHHoverBarItemType> *)item).length;
} else {
itemLength += ISHHoverBarDefaultItemDimension;
}
}

switch (self.orientation) {
case ISHHoverBarOrientationVertical:
Expand All @@ -258,25 +273,39 @@ - (void)layoutSubviews {
[self.backgroundView setFrame:self.bounds];
[self.separatorView setFrame:self.bounds];
[self.shadowLayer setFrame:self.bounds];
(self.backgroundContainerView).frame = self.bounds;

switch (self.orientation) {
case ISHHoverBarOrientationVertical:
yStep = ISHHoverBarDefaultItemDimension;
break;

case ISHHoverBarOrientationHorizontal:
xStep = ISHHoverBarDefaultItemDimension;
break;
}

CGRect frame = CGRectMake(0, 0, ISHHoverBarDefaultItemDimension, ISHHoverBarDefaultItemDimension);

int i = 0;
for (UIControl *control in self.controls) {
[control setFrame:frame];
frame = CGRectOffset(frame, xStep, yStep);
CGFloat length = ISHHoverBarDefaultItemDimension;
if ([self.items[i] conformsToProtocol:@protocol(ISHHoverBarItemType)]) {
length = ((UIBarButtonItem<ISHHoverBarItemType> *) self.items[i]).length;
}
CGRect frame;

switch (self.orientation) {
case ISHHoverBarOrientationVertical:
frame = CGRectMake(0, 0, ISHHoverBarDefaultItemDimension, length);
control.frame = CGRectOffset(frame, xStep, yStep);
yStep += length;
break;

case ISHHoverBarOrientationHorizontal:
frame = CGRectMake(0, 0, length, ISHHoverBarDefaultItemDimension);
control.frame = CGRectOffset(frame, xStep, yStep);
xStep += length;
break;
}
i++;
}
}

-(void)reload {
[self.separatorView setNeedsDisplay];
[self invalidateIntrinsicContentSize];
[self setNeedsLayout];
}

#pragma mark - Control management

- (void)reloadControls {
Expand All @@ -290,7 +319,7 @@ - (void)reloadControls {
continue;
}

[self addSubview:control];
[self.backgroundContainerView addSubview:control];
[controls addObject:control];
[self.itemsControlsMap setObject:item forKey:control];
}
Expand Down Expand Up @@ -368,32 +397,32 @@ - (void)setControls:(nullable NSArray<UIControl *> *)controls {
#pragma mark - Background view

- (void)setCornerRadius:(CGFloat)cornerRadius {
[self.backgroundView setClipsToBounds:(cornerRadius != 0)];
[self.backgroundView.layer setCornerRadius:cornerRadius];
self.backgroundContainerView.clipsToBounds = (cornerRadius != 0);
self.backgroundContainerView.layer.cornerRadius = cornerRadius;
[self.shadowLayer setCornerRadius:cornerRadius];
}

- (CGFloat)cornerRadius {
return self.backgroundView.layer.cornerRadius;
return self.backgroundContainerView.layer.cornerRadius;
}

- (void)setBorderWidth:(CGFloat)borderWidth {
[self.backgroundView.layer setBorderWidth:borderWidth];
self.backgroundContainerView.layer.borderWidth = borderWidth;
[self.separatorView setSeparatorWidth:borderWidth];
}

- (CGFloat)borderWidth {
return self.backgroundView.layer.borderWidth;
return self.backgroundContainerView.layer.borderWidth;
}

- (void)setBorderColor:(nullable UIColor *)borderColor {
[self.backgroundView.layer setBorderColor:[borderColor CGColor]];
self.backgroundContainerView.layer.borderColor = borderColor.CGColor;
[self.separatorView setSeparatorColor:borderColor];
}

- (nullable UIColor *)borderColor {
if (self.backgroundView.layer.borderColor) {
return [UIColor colorWithCGColor:self.backgroundView.layer.borderColor];
if (self.backgroundContainerView.layer.borderColor) {
return [UIColor colorWithCGColor:self.backgroundContainerView.layer.borderColor];
}

return nil;
Expand Down
15 changes: 15 additions & 0 deletions ISHHoverBar/ISHHoverBarItemType.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
//
// ISHHoverBarItemType.h
// ISHHoverBar
//
// Created by Alex Steiner on 24.05.18.
// Copyright © 2018 iosphere GmbH. All rights reserved.
//

#import <Foundation/Foundation.h>

@protocol ISHHoverBarItemType

@property (nonatomic) CGFloat length;

@end
6 changes: 3 additions & 3 deletions ISHHoverBarTests/ISHHoverBarTests.m
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ - (void)testInitializers {

for (ISHHoverBar *bar in bars) {
// after initialization we expect to have one subview (background)
XCTAssertEqual(bar.subviews.count, 2);
XCTAssertEqual(bar.subviews[0].subviews.count, 2);

// Test defaults
XCTAssertEqual(bar.borderWidth, 1.0/[[UIScreen mainScreen] scale]);
Expand Down Expand Up @@ -96,12 +96,12 @@ - (void)testReloadingControls {
// we expect to have one per item plus background and separator
NSUInteger expectedViewCount = self.hoverBar.items.count + 2;

XCTAssertEqual(self.hoverBar.subviews.count, expectedViewCount);
XCTAssertEqual(self.hoverBar.subviews[0].subviews.count, expectedViewCount);

// run setup a second time to set the items again
[self setupDefaultItems];

XCTAssertEqual(self.hoverBar.subviews.count, expectedViewCount);
XCTAssertEqual(self.hoverBar.subviews[0].subviews.count, expectedViewCount);
}

- (void)testControlsLayout {
Expand Down
10 changes: 9 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,15 @@ The following aspects of `ISHHoverBar` can be changed via code or *Interface Bui
* `borderWidth`
* `borderColor`
* Background visual effect: `effect`


### Item background color

The color can easily be changed by changing the `backgroundColor` property of the `UIBarButtonItem`.

### Item size
If you want to change the item size to a fixed length you can pass an object that conforms to `ISHHoverBarItemType`. This onyl has the additional attribute `CGFloat length`.
After chaning the length call `[self.hoverbar reload]` to apply the changes.

## General info

`ISHHoverBar` is written in **Objective-C** to allow easy integration into any iOS project
Expand Down
19 changes: 19 additions & 0 deletions SampleApp/HoverBarItem.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//
// HoverBarItem.h
// ISHHoverBar
//
// Created by Alex Steiner on 24.05.18.
// Copyright © 2018 iosphere GmbH. All rights reserved.
//

#import <UIKit/UIKit.h>
@import ISHHoverBar;

@interface HoverBarItem : UIBarButtonItem <ISHHoverBarItemType>

@property (nonatomic) CGFloat length;

- (instancetype)initWithImage:(UIImage *)image style:(UIBarButtonItemStyle)style target:(id)target action:(SEL)action length:(CGFloat)length;
- (instancetype)initWithCustomView:(UIView *)customView length:(CGFloat)length;

@end
30 changes: 30 additions & 0 deletions SampleApp/HoverBarItem.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
//
// HoverBarItem.m
// ISHHoverBar
//
// Created by Alex Steiner on 24.05.18.
// Copyright © 2018 iosphere GmbH. All rights reserved.
//

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

@interface HoverBarItem ()
@end

@implementation HoverBarItem

- (instancetype)initWithImage:(UIImage *)image style:(UIBarButtonItemStyle)style target:(id)target action:(SEL)action length:(CGFloat)length {
self = [super initWithImage:image style:style target:target action:action];
self.length = length;
return self;
}


- (instancetype)initWithCustomView:(UIView *)customView length:(CGFloat)length {
self = [super initWithCustomView:customView];
self.length = length;
return self;
}

@end