diff --git a/README.md b/README.md index d8922d4..689022e 100644 --- a/README.md +++ b/README.md @@ -125,6 +125,12 @@ The border width for item views. Default 2. @property (nonatomic, weak) id delegate; ``` +The label font and color. Default to 14pt white system font. The keys are ```RNFrostedLabelFont``` and ```RNFrostedLabelColor```. +```objc +- (void)setLabelOptions:(NSDictionary*)options; +``` + + An optional delegate to respond to selection of item views. Optional delegate methods, provided by [George Villasboas](https://github.com/ghvillasboas), include: ```objc diff --git a/RNFrostedSidebar.h b/RNFrostedSidebar.h index 566682b..e15d8f4 100644 --- a/RNFrostedSidebar.h +++ b/RNFrostedSidebar.h @@ -11,6 +11,9 @@ #import +FOUNDATION_EXPORT NSString *const RNFrostedLabelFont; +FOUNDATION_EXPORT NSString *const RNFrostedLabelColor; + @class RNFrostedSidebar; @protocol RNFrostedSidebarDelegate @@ -20,6 +23,7 @@ - (void)sidebar:(RNFrostedSidebar *)sidebar willDismissFromScreenAnimated:(BOOL)animatedYesOrNo; - (void)sidebar:(RNFrostedSidebar *)sidebar didDismissFromScreenAnimated:(BOOL)animatedYesOrNo; - (void)sidebar:(RNFrostedSidebar *)sidebar didTapItemAtIndex:(NSUInteger)index; +- (BOOL)sidebar:(RNFrostedSidebar *)sidebar shouldTapItemAtIndex:(NSUInteger)index; - (void)sidebar:(RNFrostedSidebar *)sidebar didEnable:(BOOL)itemEnabled itemAtIndex:(NSUInteger)index; @end @@ -27,6 +31,12 @@ + (instancetype)visibleSidebar; +// Just the actual views +@property (nonatomic, readonly) NSArray *views; + +// Backwards compatibility +@property (nonatomic, strong) NSMutableArray *itemViews; + // The width of the sidebar // Default 150 @property (nonatomic, assign) CGFloat width; @@ -66,6 +76,7 @@ // An optional delegate to respond to interaction events @property (nonatomic, weak) id delegate; +- (instancetype)initWithImages:(NSArray *)images selectedIndices:(NSIndexSet *)selectedIndices borderColors:(NSArray *)colors labelStrings:(NSArray*)labels; - (instancetype)initWithImages:(NSArray *)images selectedIndices:(NSIndexSet *)selectedIndices borderColors:(NSArray *)colors; - (instancetype)initWithImages:(NSArray *)images selectedIndices:(NSIndexSet *)selectedIndices; - (instancetype)initWithImages:(NSArray *)images; @@ -78,4 +89,6 @@ - (void)dismissAnimated:(BOOL)animated; - (void)dismissAnimated:(BOOL)animated completion:(void (^)(BOOL finished))completion; +- (void)setLabelOptions:(NSDictionary*)options; + @end diff --git a/RNFrostedSidebar.m b/RNFrostedSidebar.m index 6f518c2..07b4b23 100644 --- a/RNFrostedSidebar.m +++ b/RNFrostedSidebar.m @@ -11,6 +11,9 @@ #import "RNFrostedSidebar.h" #import +NSString *const RNFrostedLabelFont = @"RNFrostedLabelFont"; +NSString *const RNFrostedLabelColor = @"RNFrostedLabelColor"; + #pragma mark - Categories @implementation UIView (rn_Screenshot) @@ -18,9 +21,12 @@ @implementation UIView (rn_Screenshot) - (UIImage *)rn_screenshot { UIGraphicsBeginImageContext(self.bounds.size); if([self respondsToSelector:@selector(drawViewHierarchyInRect:afterScreenUpdates:)]){ - [self drawViewHierarchyInRect:self.bounds afterScreenUpdates:NO]; - } - else{ + if (![self drawViewHierarchyInRect:self.bounds afterScreenUpdates:NO]) { + // do not throw exceiption... +// [NSException raise:@"" format:@"RNFrostedSidebar: unable to drawViewHierarchyInRect!"]; + } + } else { + // Important: The OS X v10.5 implementation of this method does not support the entire Core Animation composition model. [self.layer renderInContext:UIGraphicsGetCurrentContext()]; } UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); @@ -96,9 +102,9 @@ - (UIImage *)applyBlurWithRadius:(CGFloat)blurRadius tintColor:(UIColor *)tintCo if (radius % 2 != 1) { radius += 1; // force radius to be odd so that the three box-blur methodology works. } - vImageBoxConvolve_ARGB8888(&effectInBuffer, &effectOutBuffer, NULL, 0, 0, radius, radius, 0, kvImageEdgeExtend); - vImageBoxConvolve_ARGB8888(&effectOutBuffer, &effectInBuffer, NULL, 0, 0, radius, radius, 0, kvImageEdgeExtend); - vImageBoxConvolve_ARGB8888(&effectInBuffer, &effectOutBuffer, NULL, 0, 0, radius, radius, 0, kvImageEdgeExtend); + vImageBoxConvolve_ARGB8888(&effectInBuffer, &effectOutBuffer, NULL, 0, 0, (unsigned)radius, (unsigned)radius, 0, kvImageEdgeExtend); + vImageBoxConvolve_ARGB8888(&effectOutBuffer, &effectInBuffer, NULL, 0, 0, (unsigned)radius, (unsigned)radius, 0, kvImageEdgeExtend); + vImageBoxConvolve_ARGB8888(&effectInBuffer, &effectOutBuffer, NULL, 0, 0, (unsigned)radius, (unsigned)radius, 0, kvImageEdgeExtend); } BOOL effectImageBuffersAreSwapped = NO; if (hasSaturationChange) { @@ -175,17 +181,22 @@ @interface RNCalloutItemView : UIView @property (nonatomic, strong) UIImageView *imageView; @property (nonatomic, assign) NSInteger itemIndex; @property (nonatomic, strong) UIColor *originalBackgroundColor; - @end @implementation RNCalloutItemView -- (instancetype)init { - if (self = [super init]) { +- (UIImageView *)imageView { + if (!_imageView) { _imageView = [[UIImageView alloc] init]; - _imageView.backgroundColor = [UIColor clearColor]; + _imageView.backgroundColor = UIColor.clearColor; _imageView.contentMode = UIViewContentModeScaleAspectFit; - [self addSubview:_imageView]; + } + return _imageView; +} + +- (instancetype)init { + if (self = [super init]) { + [self addSubview:self.imageView]; } return self; } @@ -206,16 +217,14 @@ - (void)setOriginalBackgroundColor:(UIColor *)originalBackgroundColor { - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { [super touchesBegan:touches withEvent:event]; - float r, g, b, a; - float darkenFactor = 0.3f; + CGFloat r, g, b, a; + CGFloat darkenFactor = 0.3f; UIColor *darkerColor; if ([self.originalBackgroundColor getRed:&r green:&g blue:&b alpha:&a]) { darkerColor = [UIColor colorWithRed:MAX(r - darkenFactor, 0.0) green:MAX(g - darkenFactor, 0.0) blue:MAX(b - darkenFactor, 0.0) alpha:a]; - } - else if ([self.originalBackgroundColor getWhite:&r alpha:&a]) { + } else if ([self.originalBackgroundColor getWhite:&r alpha:&a]) { darkerColor = [UIColor colorWithWhite:MAX(r - darkenFactor, 0.0) alpha:a]; - } - else { + } else { @throw @"Item color should be RGBA or White/Alpha in order to darken the button color."; } self.backgroundColor = darkerColor; @@ -240,24 +249,48 @@ @interface RNFrostedSidebar () @property (nonatomic, strong) UIScrollView *contentView; @property (nonatomic, strong) UIImageView *blurView; @property (nonatomic, strong) UITapGestureRecognizer *tapGesture; -@property (nonatomic, strong) NSArray *images; -@property (nonatomic, strong) NSArray *borderColors; -@property (nonatomic, strong) NSMutableArray *itemViews; +@property (nonatomic, copy) NSArray *images; +@property (nonatomic, copy) NSArray *labels; +@property (nonatomic, copy) NSArray *borderColors; @property (nonatomic, strong) NSMutableIndexSet *selectedIndices; - +@property (nonatomic, strong, readonly) UIImage *blurImage; @end static RNFrostedSidebar *rn_frostedMenu; @implementation RNFrostedSidebar +@synthesize blurImage = _blurImage; + (instancetype)visibleSidebar { return rn_frostedMenu; } -- (instancetype)initWithImages:(NSArray *)images selectedIndices:(NSIndexSet *)selectedIndices borderColors:(NSArray *)colors { - if (self = [super init]) { - _isSingleSelect = NO; +#pragma mark - Getters + +- (NSArray *)views { + const SEL selector = NSSelectorFromString(@"originalBackgroundColor"); + NSMutableArray *result = [[NSMutableArray alloc] init]; + for (UIView *view in self.view.subviews) { + if ([view.class isSubclassOfClass:UIScrollView.class]) { + for (UIView *individualView in view.subviews) { + if ([individualView respondsToSelector:selector]) { + [result addObject:individualView]; + } + } + } + } + return result.copy; +} + +- (NSMutableIndexSet *)selectedIndices { + if (!_selectedIndices) { + _selectedIndices = [[NSMutableIndexSet alloc] init]; + } + return _selectedIndices; +} + +- (UIScrollView *)contentView { + if (!_contentView) { _contentView = [[UIScrollView alloc] init]; _contentView.alwaysBounceHorizontal = NO; _contentView.alwaysBounceVertical = YES; @@ -265,44 +298,98 @@ - (instancetype)initWithImages:(NSArray *)images selectedIndices:(NSIndexSet *)s _contentView.clipsToBounds = NO; _contentView.showsHorizontalScrollIndicator = NO; _contentView.showsVerticalScrollIndicator = NO; - - _width = 150; - _animationDuration = 0.25f; - _itemSize = CGSizeMake(_width/2, _width/2); - _itemViews = [NSMutableArray array]; + } + return _contentView; +} + +- (NSMutableArray *)itemViews { + if (!_itemViews) { + _itemViews = [[NSMutableArray alloc] init]; + } + return _itemViews; +} + +- (NSArray *)labels { + if (!_labels) { + _labels = @[]; + } + return _labels; +} + +- (UIColor *)tintColor { + if (!_tintColor) { _tintColor = [UIColor colorWithWhite:0.2 alpha:0.73]; - _borderWidth = 2; + } + return _tintColor; +} + +- (UIColor *)itemBackgroundColor { + if (!_itemBackgroundColor) { _itemBackgroundColor = [UIColor colorWithRed:1 green:1 blue:1 alpha:0.25]; + } + return _itemBackgroundColor; +} + +#pragma mark - Constructors + +- (instancetype)initWithImages:(NSArray *)images selectedIndices:(NSIndexSet *)selectedIndices borderColors:(NSArray *)colors labelStrings:(NSArray*)labels +{ + if (self = [super init]) { + self.isSingleSelect = NO; - if (colors) { - NSAssert([colors count] == [images count], @"Border color count must match images count. If you want a blank border, use [UIColor clearColor]."); - } + self.width = 150; + self.animationDuration = 0.25f; + self.itemSize = CGSizeMake(_width/2, _width/2); + + self.borderWidth = 2; + + NSAssert(labels.count == images.count, @"Label count must match images count. If you don't want a labeled button, use @\"\" If you want a blank border, use UIColor.clearColor."); + + self.selectedIndices = selectedIndices.mutableCopy; + self.borderColors = colors; + self.images = images; - _selectedIndices = [selectedIndices mutableCopy] ?: [NSMutableIndexSet indexSet]; - _borderColors = colors; - _images = images; + NSMutableArray *labelsArray = [[NSMutableArray alloc] init]; - [_images enumerateObjectsUsingBlock:^(UIImage *image, NSUInteger idx, BOOL *stop) { + [self.images enumerateObjectsUsingBlock:^(UIImage *image, NSUInteger idx, BOOL *stop) { RNCalloutItemView *view = [[RNCalloutItemView alloc] init]; view.itemIndex = idx; view.clipsToBounds = YES; view.imageView.image = image; - [_contentView addSubview:view]; - - [_itemViews addObject:view]; + + [self.contentView addSubview:view]; + + [self.itemViews addObject:view]; + + if (labels) { + UILabel* label = [[UILabel alloc] init]; + label.textColor = UIColor.whiteColor; + label.font = [UIFont systemFontOfSize:14]; + label.text = labels[idx]; + label.backgroundColor = UIColor.clearColor; + label.textAlignment = NSTextAlignmentCenter; + label.numberOfLines = 0; + [labelsArray addObject:label]; + [self.contentView addSubview:label]; + } - if (_borderColors && _selectedIndices && [_selectedIndices containsIndex:idx]) { - UIColor *color = _borderColors[idx]; - view.layer.borderColor = color.CGColor; - } - else { - view.layer.borderColor = [UIColor clearColor].CGColor; - } + UIColor *borderColor = (self.borderColors && [self.selectedIndices containsIndex:idx]) + ? self.borderColors[idx] + : UIColor.clearColor; + view.layer.borderColor = borderColor.CGColor; }]; + + self.labels = labelsArray; + + rn_frostedMenu = self; } return self; } +- (instancetype)initWithImages:(NSArray *)images selectedIndices:(NSIndexSet *)selectedIndices borderColors:(NSArray *)colors { + return [self initWithImages:images selectedIndices:selectedIndices borderColors:colors labelStrings:nil]; +} + - (instancetype)initWithImages:(NSArray *)images selectedIndices:(NSIndexSet *)selectedIndices { return [self initWithImages:images selectedIndices:selectedIndices borderColors:nil]; } @@ -316,9 +403,19 @@ - (instancetype)init { return nil; } +#pragma mark - Setters + +- (void)setLabelOptions:(NSDictionary*)options +{ + [self.labels enumerateObjectsUsingBlock:^(UILabel* label, NSUInteger idx, BOOL *stop) { + [label setFont:options[RNFrostedLabelFont]]; + [label setTextColor:options[RNFrostedLabelColor]]; + }]; +} + - (void)loadView { [super loadView]; - self.view.backgroundColor = [UIColor clearColor]; + self.view.backgroundColor = UIColor.clearColor; [self.view addSubview:self.contentView]; self.tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTap:)]; [self.view addGestureRecognizer:self.tapGesture]; @@ -332,20 +429,39 @@ - (NSUInteger)supportedInterfaceOrientations { return UIInterfaceOrientationMaskAll; } -- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration { - [super willAnimateRotationToInterfaceOrientation:toInterfaceOrientation duration:duration]; - - if ([self isViewLoaded] && self.view.window != nil) { +- (void) blurImageNeedsUpdate { + if (self.isViewLoaded && self.view.window) { self.view.alpha = 0; - UIImage *blurImage = [self.parentViewController.view rn_screenshot]; - blurImage = [blurImage applyBlurWithRadius:5 tintColor:self.tintColor saturationDeltaFactor:1.8 maskImage:nil]; - self.blurView.image = blurImage; - self.view.alpha = 1; + self.blurView.alpha = 0; - [self layoutSubviews]; + self.blurView.frame = self.contentView.frame; + _blurImage = nil; + self.blurView.image = self.blurImage; + + [UIView animateWithDuration:1.0 animations:^{ + self.view.alpha = 1; + self.blurView.alpha = 1; + }]; + + // [self layoutSubviews]; + // [self blurImageNeedsUpdate]; } } +- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation +{ + [self blurImageNeedsUpdate]; +} + +- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration +{ + [super willAnimateRotationToInterfaceOrientation:toInterfaceOrientation duration:duration]; + self.view.alpha = 0; + self.blurView.alpha = 0; + + [self layoutSubviews]; +} + #pragma mark - Show - (void)animateSpringWithView:(RNCalloutItemView *)view idx:(NSUInteger)idx initDelay:(CGFloat)initDelay { @@ -378,43 +494,59 @@ - (void)animateFauxBounceWithView:(RNCalloutItemView *)view idx:(NSUInteger)idx }]; } -- (void)showInViewController:(UIViewController *)controller animated:(BOOL)animated { - if (rn_frostedMenu != nil) { - [rn_frostedMenu dismissAnimated:NO completion:nil]; +- (UIImage *) blurImage { + if (!_blurImage) { + UIImage *blurImage = [self.parentViewController.view rn_screenshot]; + _blurImage = [blurImage applyBlurWithRadius:5 tintColor:self.tintColor saturationDeltaFactor:1.8 maskImage:nil]; } + return _blurImage; +} + +- (void)showInViewController:(UIViewController *)controller animated:(BOOL)animated { + [rn_frostedMenu dismissAnimated:NO completion:nil]; if ([self.delegate respondsToSelector:@selector(sidebar:willShowOnScreenAnimated:)]) { [self.delegate sidebar:self willShowOnScreenAnimated:animated]; } - rn_frostedMenu = self; - - UIImage *blurImage = [controller.view rn_screenshot]; - blurImage = [blurImage applyBlurWithRadius:5 tintColor:self.tintColor saturationDeltaFactor:1.8 maskImage:nil]; - [self rn_addToParentViewController:controller callingAppearanceMethods:YES]; self.view.frame = controller.view.bounds; CGFloat parentWidth = self.view.bounds.size.width; CGRect contentFrame = self.view.bounds; - contentFrame.origin.x = _showFromRight ? parentWidth : -_width; - contentFrame.size.width = _width; + contentFrame.origin.x = (self.showFromRight) ? parentWidth + : -self.width; + contentFrame.size.width = self.width; self.contentView.frame = contentFrame; [self layoutItems]; - CGRect blurFrame = CGRectMake(_showFromRight ? self.view.bounds.size.width : 0, 0, 0, self.view.bounds.size.height); + CGRect blurFrame = CGRectMake((_showFromRight) ? self.view.bounds.size.width + : 0, + 0, + 0, + self.view.bounds.size.height); + + [self.blurView removeFromSuperview]; + + // if blurImage is not the right size for the blurFrame, invalid it + if (self.blurImage.size.height != blurFrame.size.height + || self.blurImage.size.width != blurFrame.size.width) { + _blurImage = nil; + } - self.blurView = [[UIImageView alloc] initWithImage:blurImage]; + self.blurView = [[UIImageView alloc] initWithImage:self.blurImage]; self.blurView.frame = blurFrame; - self.blurView.contentMode = _showFromRight ? UIViewContentModeTopRight : UIViewContentModeTopLeft; + self.blurView.contentMode = (self.showFromRight) ? UIViewContentModeTopRight + : UIViewContentModeTopLeft; self.blurView.clipsToBounds = YES; [self.view insertSubview:self.blurView belowSubview:self.contentView]; - contentFrame.origin.x = _showFromRight ? parentWidth - _width : 0; + contentFrame.origin.x = (self.showFromRight) ? parentWidth - self.width + : 0; blurFrame.origin.x = contentFrame.origin.x; - blurFrame.size.width = _width; + blurFrame.size.width = self.width; void (^animations)() = ^{ self.contentView.frame = contentFrame; @@ -432,8 +564,7 @@ - (void)showInViewController:(UIViewController *)controller animated:(BOOL)anima options:kNilOptions animations:animations completion:completion]; - } - else{ + } else { animations(); completion(YES); } @@ -450,16 +581,16 @@ - (void)showInViewController:(UIViewController *)controller animated:(BOOL)anima if (sdkHasSpringAnimation) { [self animateSpringWithView:view idx:idx initDelay:initDelay]; - } - else { + } else { [self animateFauxBounceWithView:view idx:idx initDelay:initDelay]; } }]; } + - (void)showAnimated:(BOOL)animated { UIViewController *controller = [UIApplication sharedApplication].keyWindow.rootViewController; - while (controller.presentedViewController != nil) { + while (controller.presentedViewController) { controller = controller.presentedViewController; } [self showInViewController:controller animated:animated]; @@ -498,10 +629,12 @@ - (void)dismissAnimated:(BOOL)animated completion:(void (^)(BOOL finished))compl if (animated) { CGFloat parentWidth = self.view.bounds.size.width; CGRect contentFrame = self.contentView.frame; - contentFrame.origin.x = self.showFromRight ? parentWidth : -_width; + contentFrame.origin.x = (self.showFromRight) ? parentWidth + : -_width; CGRect blurFrame = self.blurView.frame; - blurFrame.origin.x = self.showFromRight ? parentWidth : 0; + blurFrame.origin.x = (self.showFromRight) ? parentWidth + : 0; blurFrame.size.width = 0; [UIView animateWithDuration:self.animationDuration @@ -528,13 +661,31 @@ - (void)handleTap:(UITapGestureRecognizer *)recognizer { else { NSInteger tapIndex = [self indexOfTap:[recognizer locationInView:self.contentView]]; if (tapIndex != NSNotFound) { - [self didTapItemAtIndex:tapIndex]; + [self tryTapItemAtIndex:tapIndex]; } } } #pragma mark - Private +- (void)tryTapItemAtIndex:(NSUInteger)index { + BOOL needsTap = YES; + + // if isSingleSelect and already selected, dont tap again. + if (self.isSingleSelect) { + needsTap &= ! [self.selectedIndices containsIndex:index]; + } + + // if the delegate says we shouldn't tap, it's authoritative. + if ([self.delegate respondsToSelector:@selector(sidebar:shouldTapItemAtIndex:)]) { + needsTap &= [self.delegate sidebar:self shouldTapItemAtIndex:index]; + } + + if (needsTap) { + [self didTapItemAtIndex:index]; + } +} + - (void)didTapItemAtIndex:(NSUInteger)index { BOOL didEnable = ! [self.selectedIndices containsIndex:index]; @@ -543,7 +694,7 @@ - (void)didTapItemAtIndex:(NSUInteger)index { UIView *view = self.itemViews[index]; if (didEnable) { - if (_isSingleSelect){ + if (_isSingleSelect) { [self.selectedIndices removeAllIndexes]; [self.itemViews enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { UIView *aView = (UIView *)obj; @@ -559,9 +710,8 @@ - (void)didTapItemAtIndex:(NSUInteger)index { [view.layer addAnimation:borderAnimation forKey:nil]; [self.selectedIndices addIndex:index]; - } - else { - if (!_isSingleSelect){ + } else { + if (!_isSingleSelect) { view.layer.borderColor = [UIColor clearColor].CGColor; [self.selectedIndices removeIndex:index]; } @@ -607,8 +757,9 @@ - (void)didTapItemAtIndex:(NSUInteger)index { } - (void)layoutSubviews { - CGFloat x = self.showFromRight ? self.parentViewController.view.bounds.size.width - _width : 0; - self.contentView.frame = CGRectMake(x, 0, _width, self.parentViewController.view.bounds.size.height); + CGFloat x = (self.showFromRight) ? self.parentViewController.view.bounds.size.width - self.width + : 0; + self.contentView.frame = CGRectMake(x, 0, self.width, self.parentViewController.view.bounds.size.height); self.blurView.frame = self.contentView.frame; [self layoutItems]; @@ -616,15 +767,51 @@ - (void)layoutSubviews { - (void)layoutItems { CGFloat leftPadding = (self.width - self.itemSize.width)/2; - CGFloat topPadding = leftPadding; + CGFloat __block topPadding = leftPadding; + + NSMutableArray *labelHeights = [[NSMutableArray alloc] init]; + topPadding = leftPadding; + [self.labels enumerateObjectsUsingBlock:^(UILabel *label, NSUInteger idx, BOOL *stop) { + + // calculate label height + CGSize maximumLabelSize = CGSizeMake(self.width, FLT_MAX); + + NSDictionary *attributes = @{NSFontAttributeName: label.font}; + CGRect rect = [label.text boundingRectWithSize:maximumLabelSize options:NSStringDrawingUsesLineFragmentOrigin attributes:attributes context:nil]; + + CGSize expectedLabelSize = rect.size; + + [labelHeights addObject:[NSNumber numberWithFloat:expectedLabelSize.height]]; + + if (idx > 0) { + topPadding += [[labelHeights objectAtIndex:idx - 1] floatValue]; + topPadding += leftPadding; + } + + topPadding += self.itemSize.height; + + CGRect frame = CGRectMake(0, topPadding, self.width, expectedLabelSize.height); + label.frame = frame; + }]; + + topPadding = leftPadding; [self.itemViews enumerateObjectsUsingBlock:^(RNCalloutItemView *view, NSUInteger idx, BOOL *stop) { - CGRect frame = CGRectMake(leftPadding, topPadding*idx + self.itemSize.height*idx + topPadding, self.itemSize.width, self.itemSize.height); + if (idx > 0) { + topPadding += [[labelHeights objectAtIndex:idx - 1] floatValue]; + topPadding += self.itemSize.height; + topPadding += leftPadding; + } + + CGRect frame = CGRectMake(leftPadding, topPadding, self.itemSize.width, self.itemSize.height); view.frame = frame; view.layer.cornerRadius = frame.size.width/2.f; }]; - NSInteger items = [self.itemViews count]; - self.contentView.contentSize = CGSizeMake(0, items * (self.itemSize.height + leftPadding) + leftPadding); + // add height of last item to topPadding + topPadding += [[labelHeights objectAtIndex:[self.itemViews count] - 1] floatValue]; + topPadding += self.itemSize.height; + + self.contentView.contentSize = CGSizeMake(0, topPadding); } - (NSInteger)indexOfTap:(CGPoint)location { @@ -641,23 +828,31 @@ - (NSInteger)indexOfTap:(CGPoint)location { } - (void)rn_addToParentViewController:(UIViewController *)parentViewController callingAppearanceMethods:(BOOL)callAppearanceMethods { - if (self.parentViewController != nil) { + if (self.parentViewController) { [self rn_removeFromParentViewControllerCallingAppearanceMethods:callAppearanceMethods]; } - if (callAppearanceMethods) [self beginAppearanceTransition:YES animated:NO]; + if (callAppearanceMethods) { + [self beginAppearanceTransition:YES animated:NO]; + } [parentViewController addChildViewController:self]; [parentViewController.view addSubview:self.view]; [self didMoveToParentViewController:self]; - if (callAppearanceMethods) [self endAppearanceTransition]; + if (callAppearanceMethods) { + [self endAppearanceTransition]; + } } - (void)rn_removeFromParentViewControllerCallingAppearanceMethods:(BOOL)callAppearanceMethods { - if (callAppearanceMethods) [self beginAppearanceTransition:NO animated:NO]; + if (callAppearanceMethods) { + [self beginAppearanceTransition:NO animated:NO]; + } [self willMoveToParentViewController:nil]; [self.view removeFromSuperview]; [self removeFromParentViewController]; - if (callAppearanceMethods) [self endAppearanceTransition]; + if (callAppearanceMethods) { + [self endAppearanceTransition]; + } } @end diff --git a/RNFrostedSidebar.xcodeproj/project.pbxproj b/RNFrostedSidebar.xcodeproj/project.pbxproj index 4ce8677..10d12c5 100644 --- a/RNFrostedSidebar.xcodeproj/project.pbxproj +++ b/RNFrostedSidebar.xcodeproj/project.pbxproj @@ -71,6 +71,7 @@ 8646017917BAF99800FCE7F4 /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; }; 8681BB5717BAFB5A007F1B43 /* RNFrostedSidebar.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNFrostedSidebar.h; sourceTree = ""; }; 8681BB5817BAFB5A007F1B43 /* RNFrostedSidebar.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNFrostedSidebar.m; sourceTree = ""; }; + 94EB590819818A8400E17200 /* CFNetwork.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CFNetwork.framework; path = System/Library/Frameworks/CFNetwork.framework; sourceTree = SDKROOT; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -143,6 +144,7 @@ 8646015F17BAF99800FCE7F4 /* Frameworks */ = { isa = PBXGroup; children = ( + 94EB590819818A8400E17200 /* CFNetwork.framework */, 862D1B2517BC2CA000157004 /* Accelerate.framework */, 862D1B2317BC2C9B00157004 /* QuartzCore.framework */, 8646016017BAF99800FCE7F4 /* Foundation.framework */, @@ -287,6 +289,7 @@ GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 7.0; ONLY_ACTIVE_ARCH = YES; + OTHER_LDFLAGS = ""; SDKROOT = iphoneos; TARGETED_DEVICE_FAMILY = "1,2"; }; @@ -318,6 +321,7 @@ GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 7.0; + OTHER_LDFLAGS = ""; SDKROOT = iphoneos; TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = YES; @@ -329,10 +333,14 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(SYSTEM_APPS_DIR)/Reveal.app/Contents/SharedSupport/iOS-Libraries", + ); GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "example/RNFrostedSidebar-Prefix.pch"; INFOPLIST_FILE = "example/RNFrostedSidebar-Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 5.1; + IPHONEOS_DEPLOYMENT_TARGET = 7.1; PRODUCT_NAME = RNFrostedSidebar; WRAPPER_EXTENSION = app; }; @@ -343,10 +351,14 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(SYSTEM_APPS_DIR)/Reveal.app/Contents/SharedSupport/iOS-Libraries", + ); GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "example/RNFrostedSidebar-Prefix.pch"; INFOPLIST_FILE = "example/RNFrostedSidebar-Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 5.1; + IPHONEOS_DEPLOYMENT_TARGET = 7.1; PRODUCT_NAME = RNFrostedSidebar; WRAPPER_EXTENSION = app; }; diff --git a/example/ViewController.m b/example/ViewController.m index 44a07b3..5063ad3 100644 --- a/example/ViewController.m +++ b/example/ViewController.m @@ -49,18 +49,41 @@ - (IBAction)onBurger:(id)sender { [UIColor colorWithRed:126/255.f green:242/255.f blue:195/255.f alpha:1], [UIColor colorWithRed:119/255.f green:152/255.f blue:255/255.f alpha:1], ]; + + NSArray* labels = @[@"short Text", + @"short Text", + @"longer Text...", + @"More longer Text...", + @"Much more longer Text...", + @"realy realy realy realy realy realy long Text...", + @"profile", + @"star", + @"gear", + @"globe", + @"profile", + @"star" + ]; + RNFrostedSidebar *sideMenu = [[RNFrostedSidebar alloc] initWithImages:images selectedIndices:self.optionIndices borderColors:colors labelStrings:labels]; + sideMenu.width = 150; + sideMenu.itemSize = CGSizeMake(80, 80); - RNFrostedSidebar *callout = [[RNFrostedSidebar alloc] initWithImages:images selectedIndices:self.optionIndices borderColors:colors]; +// RNFrostedSidebar *callout = [[RNFrostedSidebar alloc] initWithImages:images selectedIndices:self.optionIndices borderColors:colors]; // RNFrostedSidebar *callout = [[RNFrostedSidebar alloc] initWithImages:images]; - callout.delegate = self; -// callout.showFromRight = YES; - [callout show]; + + [sideMenu setLabelOptions:@{ + RNFrostedLabelFont: [UIFont systemFontOfSize:20], + RNFrostedLabelColor: [UIColor whiteColor] + }]; + + sideMenu.delegate = self; +// sideMenu.showFromRight = YES; + [sideMenu show]; } #pragma mark - RNFrostedSidebarDelegate - (void)sidebar:(RNFrostedSidebar *)sidebar didTapItemAtIndex:(NSUInteger)index { - NSLog(@"Tapped item at index %i",index); + NSLog(@"Tapped item at index %lu",(long)index); if (index == 3) { [sidebar dismissAnimated:YES completion:nil]; }