mirror of
https://github.com/zhigang1992/MessageBarManager.git
synced 2026-01-12 22:48:46 +08:00
fixed class structure
This commit is contained in:
@@ -10,17 +10,12 @@
|
||||
typedef enum {
|
||||
MessageBarMessageTypeError,
|
||||
MessageBarMessageTypeSuccess,
|
||||
MessageBarMessageTypeInfo,
|
||||
MessageBarMessageTypeLogo
|
||||
MessageBarMessageTypeInfo
|
||||
} MessageBarMessageType;
|
||||
|
||||
@interface MessageBarManager : NSObject
|
||||
|
||||
+ (MessageBarManager *)sharedInstance;
|
||||
+ (CGFloat)durationForMessageType:(MessageBarMessageType)messageType;
|
||||
|
||||
- (void)showGenericServerError;
|
||||
- (void)showSaveErrorWithResourceName:(NSString*)resource;
|
||||
|
||||
- (void)showMessageWithTitle:(NSString*)title description:(NSString*)description type:(MessageBarMessageType)type;
|
||||
- (void)showMessageWithTitle:(NSString*)title description:(NSString*)description type:(MessageBarMessageType)type callback:(void (^)())callback;
|
||||
@@ -28,8 +23,15 @@ typedef enum {
|
||||
- (void)showMessageWithTitle:(NSString*)title description:(NSString*)description type:(MessageBarMessageType)type forDuration:(CGFloat)duration;
|
||||
- (void)showMessageWithTitle:(NSString*)title description:(NSString*)description type:(MessageBarMessageType)type forDuration:(CGFloat)duration callback:(void (^)())callback;
|
||||
|
||||
- (void)showAppUpgradeAvailableWithCallback:(void (^)())buttonCallback;
|
||||
- (void)showMessageWithTitle:(NSString*)title description:(NSString*)description type:(MessageBarMessageType)type withButtonCallback:(void (^)())buttonCallback;
|
||||
- (void)showMessageWithTitle:(NSString*)title description:(NSString*)description type:(MessageBarMessageType)type withButtonCallback:(void (^)())buttonCallback callback:(void (^)())callback;
|
||||
@end
|
||||
|
||||
@interface MessageBarStyleSheet : NSObject
|
||||
|
||||
// Colors (override for customization)
|
||||
+ (UIColor*)backgroundColorForMessageType:(MessageBarMessageType)type;
|
||||
+ (UIColor*)strokeColorForMessageType:(MessageBarMessageType)type;
|
||||
|
||||
// Icon images (override for customization)
|
||||
+ (UIImage*)iconImageForMessageType:(MessageBarMessageType)type;
|
||||
|
||||
@end
|
||||
@@ -5,50 +5,37 @@
|
||||
// Copyright (c) 2013 Terry Worona. All rights reserved.
|
||||
//
|
||||
|
||||
#import "GAMessageBarManager.h"
|
||||
#import "MessageBarManager.h"
|
||||
|
||||
// Constants
|
||||
#import "GAConstants.h"
|
||||
|
||||
// quartz
|
||||
// Quartz
|
||||
#import <QuartzCore/QuartzCore.h>
|
||||
|
||||
// Delegate
|
||||
#import "AppDelegate.h"
|
||||
|
||||
// Drawing
|
||||
#import "GADrawUtils.h"
|
||||
// Constants
|
||||
#import "UIConstants.h"
|
||||
|
||||
#define kGAMessageBarAlpha 0.96
|
||||
#define kGAMessageBarPadding 10
|
||||
#define kGAMessageBarButtonWidth 60
|
||||
#define kGAMessageBarButtonHeight 30
|
||||
#define kGAMessageBarMaxDescriptionHeight 250
|
||||
#define kGAMessageBarIconSize 36
|
||||
#define kGAMessageBarRegularDisplayDelay 3.0
|
||||
#define kGAMessageBarErrorDisplayDelay 5.0
|
||||
#define kGAMessageBarTextOffset 2.0
|
||||
#define kMessageBarAlpha 0.96
|
||||
#define kMessageBarPadding 10
|
||||
#define kMessageBarMaxDescriptionHeight 250
|
||||
#define kMessageBarIconSize 36
|
||||
#define kMessageBarDisplayDelay 3.0
|
||||
#define kMessageBarTextOffset 2.0
|
||||
#define kMessageBarAnimationDuration 0.25
|
||||
|
||||
typedef enum {
|
||||
GAMessageViewTypeVirgin = 1,
|
||||
GAMessageViewTypeHit
|
||||
} GAMessageViewType;
|
||||
@class MessageView;
|
||||
|
||||
@class GAMessageView;
|
||||
|
||||
@interface GAMessageView : UIView
|
||||
@interface MessageView : UIView
|
||||
|
||||
@property (nonatomic, strong) NSString *titleString;
|
||||
@property (nonatomic, strong) NSString *descriptionString;
|
||||
@property (nonatomic, assign) GAMessageBarMessageType messageType;
|
||||
@property (nonatomic, assign) MessageBarMessageType messageType;
|
||||
@property (nonatomic, strong) UIImageView *shadowView;
|
||||
|
||||
@property (nonatomic, assign) BOOL hasCallback;
|
||||
@property (nonatomic, strong) NSArray *callbacks;
|
||||
|
||||
@property (nonatomic, assign) BOOL hasButtonCallback;
|
||||
@property (nonatomic, strong) NSArray *buttonCallbacks;
|
||||
|
||||
@property (nonatomic, assign, getter = isHit) BOOL hit;
|
||||
|
||||
@property (nonatomic, assign, readonly) CGFloat height;
|
||||
@@ -56,27 +43,24 @@ typedef enum {
|
||||
|
||||
@property (nonatomic, assign) CGFloat duration;
|
||||
|
||||
@property (nonatomic, strong) UIButton *button;
|
||||
|
||||
- (id)initWithTitle:(NSString*)title description:(NSString*)description type:(GAMessageBarMessageType)type;
|
||||
- (id)initWithTitle:(NSString*)title description:(NSString*)description type:(GAMessageBarMessageType)type buttonText:(NSString*)buttonText;
|
||||
|
||||
- (void)buttonPressed:(id)sender;
|
||||
- (id)initWithTitle:(NSString*)title description:(NSString*)description type:(MessageBarMessageType)type;
|
||||
|
||||
@end
|
||||
|
||||
@interface GAMessageBarManager ()
|
||||
@interface MessageBarManager ()
|
||||
|
||||
@property (nonatomic, strong) NSMutableArray *messageBarQueue;
|
||||
@property (nonatomic, assign, getter = isMessageVisible) BOOL messageVisible;
|
||||
@property (nonatomic, assign) CGFloat messageBarOffset;
|
||||
|
||||
+ (CGFloat)durationForMessageType:(MessageBarMessageType)messageType;
|
||||
|
||||
- (void)showNextMessage;
|
||||
- (void)itemSelected:(UITapGestureRecognizer*)recognizer;
|
||||
|
||||
@end
|
||||
|
||||
@implementation GAMessageBarManager
|
||||
@implementation MessageBarManager
|
||||
|
||||
@synthesize messageBarQueue = _messageBarQueue;
|
||||
@synthesize messageVisible = _messageVisible;
|
||||
@@ -84,35 +68,19 @@ typedef enum {
|
||||
|
||||
#pragma mark - Singleton
|
||||
|
||||
+ (GAMessageBarManager *)sharedInstance
|
||||
+ (MessageBarManager *)sharedInstance
|
||||
{
|
||||
static dispatch_once_t pred;
|
||||
static GAMessageBarManager *instance = nil;
|
||||
static MessageBarManager *instance = nil;
|
||||
dispatch_once(&pred, ^{ instance = [[self alloc] init]; });
|
||||
return instance;
|
||||
}
|
||||
|
||||
#pragma mark - Static
|
||||
|
||||
+ (CGFloat)durationForMessageType:(GAMessageBarMessageType)messageType
|
||||
+ (CGFloat)durationForMessageType:(MessageBarMessageType)messageType
|
||||
{
|
||||
switch (messageType) {
|
||||
case GAMessageBarMessageTypeError:
|
||||
return kGAMessageBarErrorDisplayDelay;
|
||||
break;
|
||||
case GAMessageBarMessageTypeSuccess:
|
||||
return kGAMessageBarRegularDisplayDelay;
|
||||
break;
|
||||
case GAMessageBarMessageTypeInfo:
|
||||
return kGAMessageBarRegularDisplayDelay;
|
||||
break;
|
||||
case GAMessageBarMessageTypeLogo:
|
||||
return kGAMessageBarRegularDisplayDelay;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return kGAMessageBarRegularDisplayDelay;
|
||||
return kMessageBarDisplayDelay;
|
||||
}
|
||||
|
||||
#pragma mark - Alloc/Init
|
||||
@@ -129,34 +97,24 @@ typedef enum {
|
||||
|
||||
#pragma mark - Public
|
||||
|
||||
- (void)showGenericServerError
|
||||
- (void)showMessageWithTitle:(NSString*)title description:(NSString*)description type:(MessageBarMessageType)type
|
||||
{
|
||||
[self showMessageWithTitle:kGAStringMessageUnexpectedErrorTitle description:kGAStringMessageUnexpectedErrorMessage type:GAMessageBarMessageTypeError];
|
||||
[self showMessageWithTitle:title description:description type:type forDuration:[MessageBarManager durationForMessageType:type] callback:nil];
|
||||
}
|
||||
|
||||
- (void)showSaveErrorWithResourceName:(NSString*)resource
|
||||
- (void)showMessageWithTitle:(NSString*)title description:(NSString*)description type:(MessageBarMessageType)type callback:(void (^)())callback
|
||||
{
|
||||
[self showMessageWithTitle:kGAStringMessageResourceSaveErrorTitle description:[NSString stringWithFormat:kGAStringMessageResourceSaveErrorMessage, [resource lowercaseString]] type:GAMessageBarMessageTypeError];
|
||||
[self showMessageWithTitle:title description:description type:type forDuration:[MessageBarManager durationForMessageType:type] callback:callback];
|
||||
}
|
||||
|
||||
- (void)showMessageWithTitle:(NSString*)title description:(NSString*)description type:(GAMessageBarMessageType)type
|
||||
{
|
||||
[self showMessageWithTitle:title description:description type:type forDuration:[GAMessageBarManager durationForMessageType:type] callback:nil];
|
||||
}
|
||||
|
||||
- (void)showMessageWithTitle:(NSString*)title description:(NSString*)description type:(GAMessageBarMessageType)type callback:(void (^)())callback
|
||||
{
|
||||
[self showMessageWithTitle:title description:description type:type forDuration:[GAMessageBarManager durationForMessageType:type] callback:callback];
|
||||
}
|
||||
|
||||
- (void)showMessageWithTitle:(NSString*)title description:(NSString*)description type:(GAMessageBarMessageType)type forDuration:(CGFloat)duration
|
||||
- (void)showMessageWithTitle:(NSString*)title description:(NSString*)description type:(MessageBarMessageType)type forDuration:(CGFloat)duration
|
||||
{
|
||||
[self showMessageWithTitle:title description:description type:type forDuration:duration callback:nil];
|
||||
}
|
||||
|
||||
- (void)showMessageWithTitle:(NSString*)title description:(NSString*)description type:(GAMessageBarMessageType)type forDuration:(CGFloat)duration callback:(void (^)())callback
|
||||
- (void)showMessageWithTitle:(NSString*)title description:(NSString*)description type:(MessageBarMessageType)type forDuration:(CGFloat)duration callback:(void (^)())callback
|
||||
{
|
||||
GAMessageView *messageView = [[GAMessageView alloc] initWithTitle:title description:description type:type];
|
||||
MessageView *messageView = [[MessageView alloc] initWithTitle:title description:description type:type];
|
||||
|
||||
messageView.callbacks = callback ? [NSArray arrayWithObject:callback] : [NSArray array];
|
||||
messageView.hasCallback = callback ? YES : NO;
|
||||
@@ -173,52 +131,6 @@ typedef enum {
|
||||
}
|
||||
}
|
||||
|
||||
- (void)showAppUpgradeAvailableWithCallback:(void (^)())buttonCallback
|
||||
{
|
||||
GAMessageView *messageView = [[GAMessageView alloc] initWithTitle:kGAStringMessageUpdateMessageTitle description:kGAStringMessageUpdateMessage type:GAMessageBarMessageTypeLogo buttonText:kGAStringLabelView];
|
||||
|
||||
messageView.hasButtonCallback = buttonCallback ? YES : NO;
|
||||
messageView.buttonCallbacks = buttonCallback ? [NSArray arrayWithObject:buttonCallback] : [NSArray array];
|
||||
|
||||
messageView.duration = [GAMessageBarManager durationForMessageType:GAMessageBarMessageTypeLogo];
|
||||
messageView.hidden = YES;
|
||||
|
||||
AppDelegate *delegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
|
||||
[delegate.window insertSubview:messageView atIndex:1];
|
||||
[_messageBarQueue addObject:messageView];
|
||||
|
||||
if (!_messageVisible){
|
||||
[self showNextMessage];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)showMessageWithTitle:(NSString*)title description:(NSString*)description type:(GAMessageBarMessageType)type withButtonCallback:(void (^)())buttonCallback
|
||||
{
|
||||
[self showMessageWithTitle:title description:description type:type withButtonCallback:buttonCallback callback:nil];
|
||||
}
|
||||
|
||||
- (void)showMessageWithTitle:(NSString*)title description:(NSString*)description type:(GAMessageBarMessageType)type withButtonCallback:(void (^)())buttonCallback callback:(void (^)())callback
|
||||
{
|
||||
GAMessageView *messageView = [[GAMessageView alloc] initWithTitle:title description:description type:type buttonText:kGAStringLabelView];
|
||||
|
||||
messageView.hasButtonCallback = buttonCallback ? YES : NO;
|
||||
messageView.buttonCallbacks = buttonCallback ? [NSArray arrayWithObject:buttonCallback] : [NSArray array];
|
||||
|
||||
messageView.callbacks = callback ? [NSArray arrayWithObject:callback] : [NSArray array];
|
||||
messageView.hasCallback = callback ? YES : NO;
|
||||
|
||||
messageView.duration = [GAMessageBarManager durationForMessageType:type];
|
||||
messageView.hidden = YES;
|
||||
|
||||
AppDelegate *delegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
|
||||
[delegate.window insertSubview:messageView atIndex:1];
|
||||
[_messageBarQueue addObject:messageView];
|
||||
|
||||
if (!_messageVisible){
|
||||
[self showNextMessage];
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - Private
|
||||
|
||||
- (void)showNextMessage
|
||||
@@ -226,7 +138,7 @@ typedef enum {
|
||||
if ([_messageBarQueue count] > 0){
|
||||
_messageVisible = YES;
|
||||
|
||||
GAMessageView *messageView = [_messageBarQueue objectAtIndex:0];
|
||||
MessageView *messageView = [_messageBarQueue objectAtIndex:0];
|
||||
messageView.frame = CGRectMake(0, -[messageView height], [messageView width], [messageView height]);
|
||||
messageView.hidden = NO;
|
||||
[messageView setNeedsDisplay];
|
||||
@@ -236,7 +148,8 @@ typedef enum {
|
||||
|
||||
if (messageView){
|
||||
[_messageBarQueue removeObject:messageView];
|
||||
[UIView animateWithDuration:kGANumericDefaultAnimationDuration animations:^{
|
||||
|
||||
[UIView animateWithDuration:kMessageBarAnimationDuration animations:^{
|
||||
[messageView setFrame:CGRectMake(messageView.frame.origin.x, _messageBarOffset + messageView.frame.origin.y + [messageView height], [messageView width], [messageView height])]; // slide down
|
||||
}];
|
||||
|
||||
@@ -249,19 +162,20 @@ typedef enum {
|
||||
|
||||
- (void)itemSelected:(id)sender
|
||||
{
|
||||
GAMessageView *messageView = nil;
|
||||
MessageView *messageView = nil;
|
||||
BOOL itemHit = NO;
|
||||
if ([sender isKindOfClass:[UIGestureRecognizer class]]){
|
||||
messageView = (GAMessageView*)((UIGestureRecognizer*)sender).view;
|
||||
messageView = (MessageView*)((UIGestureRecognizer*)sender).view;
|
||||
itemHit = YES;
|
||||
}
|
||||
else if ([sender isKindOfClass:[GAMessageView class]]){
|
||||
messageView = (GAMessageView*)sender;
|
||||
else if ([sender isKindOfClass:[MessageView class]]){
|
||||
messageView = (MessageView*)sender;
|
||||
}
|
||||
|
||||
if (messageView && ![messageView isHit]){
|
||||
messageView.hit = YES;
|
||||
[UIView animateWithDuration:kGANumericDefaultAnimationDuration animations:^{
|
||||
|
||||
[UIView animateWithDuration:kMessageBarAnimationDuration animations:^{
|
||||
[messageView setFrame:CGRectMake(messageView.frame.origin.x, messageView.frame.origin.y - [messageView height] - _messageBarOffset, [messageView width], [messageView height])]; // slide back up
|
||||
} completion:^(BOOL finished) {
|
||||
_messageVisible = NO;
|
||||
@@ -291,9 +205,7 @@ static UIColor *titleColor = nil;
|
||||
static UIFont *descriptionFont = nil;
|
||||
static UIColor *descriptionColor = nil;
|
||||
|
||||
static UIColor *shadowColor = nil;
|
||||
|
||||
@implementation GAMessageView
|
||||
@implementation MessageView
|
||||
|
||||
@synthesize titleString = _titleString;
|
||||
@synthesize descriptionString = _descriptionString;
|
||||
@@ -303,25 +215,16 @@ static UIColor *shadowColor = nil;
|
||||
@synthesize hasCallback = _hasCallback;
|
||||
@synthesize callbacks = _callbacks;
|
||||
|
||||
@synthesize hasButtonCallback = _hasButtonCallback;
|
||||
@synthesize buttonCallbacks = _buttonCallbacks;
|
||||
|
||||
@synthesize hit = _hit;
|
||||
|
||||
@synthesize width = _width;
|
||||
@synthesize height = _height;
|
||||
|
||||
@synthesize duration = _duration;
|
||||
@synthesize button = _button;
|
||||
|
||||
#pragma mark - Alloc/Init
|
||||
|
||||
- (id)initWithTitle:(NSString*)title description:(NSString*)description type:(GAMessageBarMessageType)type
|
||||
{
|
||||
return [self initWithTitle:title description:description type:type buttonText:nil];
|
||||
}
|
||||
|
||||
- (id)initWithTitle:(NSString*)title description:(NSString*)description type:(GAMessageBarMessageType)type buttonText:(NSString*)buttonText
|
||||
- (id)initWithTitle:(NSString*)title description:(NSString*)description type:(MessageBarMessageType)type
|
||||
{
|
||||
self = [super initWithFrame:CGRectZero];
|
||||
if (self){
|
||||
@@ -330,81 +233,25 @@ static UIColor *shadowColor = nil;
|
||||
self.clipsToBounds = NO;
|
||||
self.userInteractionEnabled = YES;
|
||||
|
||||
_shadowView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:kGAImageBarShadowTop]];
|
||||
[self addSubview:_shadowView];
|
||||
|
||||
_titleString = title;
|
||||
_descriptionString = description;
|
||||
_messageType = type;
|
||||
|
||||
titleFont = kGAFontMessageBarTitle;
|
||||
titleColor = [UIColor colorWithWhite:0.95 alpha:1.0];
|
||||
titleFont = [UIFont boldSystemFontOfSize:16.0];
|
||||
titleColor = [UIColor colorWithWhite:1.0 alpha:1.0];
|
||||
|
||||
descriptionFont = kGAFontMessageBarMessage;
|
||||
descriptionColor = [UIColor colorWithWhite:0.9 alpha:1.0];
|
||||
|
||||
shadowColor = [UIColor colorWithWhite:0.2 alpha:0.25];
|
||||
descriptionFont = [UIFont systemFontOfSize:14.0];
|
||||
descriptionColor = [UIColor colorWithWhite:1.0 alpha:1.0];
|
||||
|
||||
_height = 0.0;
|
||||
_width = 0.0;
|
||||
|
||||
_hasCallback = NO;
|
||||
_hit = NO;
|
||||
|
||||
if (buttonText){
|
||||
_button = [UIButton buttonWithType:UIButtonTypeCustom];
|
||||
[_button addTarget:self action:@selector(buttonPressed:) forControlEvents:UIControlEventTouchUpInside];
|
||||
|
||||
_button.titleLabel.font = [UIFont fontWithName:kGAFontSommetRoundedBlack size:14.0];
|
||||
_button.titleLabel.adjustsFontSizeToFitWidth = YES;
|
||||
_button.titleLabel.shadowOffset = CGSizeMake(0, -1);
|
||||
_button.titleLabel.textAlignment = UITextAlignmentCenter;
|
||||
[_button setTitleShadowColor:kGAColorDarkGray forState:UIControlStateNormal];
|
||||
[_button setTitleShadowColor:kGAColorDarkGray forState:UIControlStateDisabled];
|
||||
[_button setTitleShadowColor:kGAColorDarkGray forState:UIControlStateSelected];
|
||||
[_button setTitleShadowColor:[UIColor blackColor] forState:UIControlStateHighlighted];
|
||||
[_button setTitleShadowColor:[UIColor blackColor] forState:UIControlStateHighlighted | UIControlStateSelected];
|
||||
|
||||
[_button setTitle:buttonText forState:UIControlStateNormal];
|
||||
[_button setTitle:buttonText forState:UIControlStateDisabled];
|
||||
[_button setTitle:buttonText forState:UIControlStateSelected];
|
||||
[_button setTitle:buttonText forState:UIControlStateHighlighted];
|
||||
[_button setTitle:buttonText forState:UIControlStateHighlighted | UIControlStateSelected];
|
||||
|
||||
UIImage *buttonBackgroundImage = [UIImage imageNamed:kGAImageButtonNotification];
|
||||
buttonBackgroundImage = [buttonBackgroundImage stretchableImageWithLeftCapWidth:ceil(buttonBackgroundImage.size.width/2) topCapHeight:ceil(buttonBackgroundImage.size.height/2)];
|
||||
|
||||
UIImage *buttonBackgroundDepressedImage = [UIImage imageNamed:kGAImageButtonNotificationDepressed];
|
||||
buttonBackgroundDepressedImage = [buttonBackgroundDepressedImage stretchableImageWithLeftCapWidth:ceil(buttonBackgroundDepressedImage.size.width/2) topCapHeight:ceil(buttonBackgroundDepressedImage.size.height/2)];
|
||||
|
||||
[_button setBackgroundImage:buttonBackgroundImage forState:UIControlStateNormal];
|
||||
[_button setBackgroundImage:buttonBackgroundImage forState:UIControlStateDisabled];
|
||||
[_button setBackgroundImage:buttonBackgroundDepressedImage forState:UIControlStateSelected];
|
||||
[_button setBackgroundImage:buttonBackgroundDepressedImage forState:UIControlStateHighlighted];
|
||||
[_button setBackgroundImage:buttonBackgroundDepressedImage forState:UIControlStateHighlighted | UIControlStateSelected];
|
||||
|
||||
[_button setNeedsDisplay];
|
||||
|
||||
[self addSubview:_button];
|
||||
}
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
#pragma mark - Button Presses
|
||||
|
||||
- (void)buttonPressed:(id)sender
|
||||
{
|
||||
if ([_buttonCallbacks count] > 0){
|
||||
id obj = [_buttonCallbacks objectAtIndex:0];
|
||||
if (![obj isEqual:[NSNull null]]) {
|
||||
((void (^)())obj)();
|
||||
|
||||
[[GAMessageBarManager sharedInstance] performSelector:@selector(itemSelected:) withObject:self afterDelay:0];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - Drawing
|
||||
|
||||
- (void)drawRect:(CGRect)rect
|
||||
@@ -413,35 +260,11 @@ static UIColor *shadowColor = nil;
|
||||
|
||||
CGContextRef context = UIGraphicsGetCurrentContext();
|
||||
|
||||
// bg gradient
|
||||
CGRect gradientRect = CGRectMake(rect.origin.x, rect.origin.y, rect.size.width, rect.size.height);
|
||||
|
||||
// background fill
|
||||
CGContextSaveGState(context);
|
||||
{
|
||||
switch (_messageType) {
|
||||
case GAMessageBarMessageTypeError:
|
||||
drawVerticalLinearGradient(context, gradientRect,
|
||||
[UIColor colorWithRed:0.858 green:0.329 blue:0.309 alpha:kGAMessageBarAlpha].CGColor, // light red
|
||||
[UIColor colorWithRed:0.756 green:0.019 blue:0.0 alpha:kGAMessageBarAlpha].CGColor); // dark red
|
||||
break;
|
||||
case GAMessageBarMessageTypeSuccess:
|
||||
drawVerticalLinearGradient(context, gradientRect,
|
||||
[UIColor colorWithRed:0.149 green:0.749 blue:0.149 alpha:kGAMessageBarAlpha].CGColor, // light green
|
||||
[UIColor colorWithRed:0.0 green:0.549 blue:0.0 alpha:kGAMessageBarAlpha].CGColor); // dark green
|
||||
break;
|
||||
case GAMessageBarMessageTypeInfo:
|
||||
drawVerticalLinearGradient(context, gradientRect,
|
||||
[UIColor colorWithRed:0.0 green:0.776 blue:0.831 alpha:kGAMessageBarAlpha].CGColor, // light teal
|
||||
[UIColor colorWithRed:0.0 green:0.560 blue:0.6 alpha:kGAMessageBarAlpha].CGColor); // dark teal
|
||||
break;
|
||||
case GAMessageBarMessageTypeLogo:
|
||||
drawVerticalLinearGradient(context, gradientRect,
|
||||
[UIColor colorWithRed:0.0 green:0.776 blue:0.831 alpha:kGAMessageBarAlpha].CGColor, // light teal
|
||||
[UIColor colorWithRed:0.0 green:0.560 blue:0.6 alpha:kGAMessageBarAlpha].CGColor); // dark teal
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
[[MessageBarStyleSheet backgroundColorForMessageType:_messageType] set];
|
||||
CGContextFillRect(context, rect);
|
||||
}
|
||||
CGContextRestoreGState(context);
|
||||
|
||||
@@ -450,74 +273,40 @@ static UIColor *shadowColor = nil;
|
||||
{
|
||||
CGContextBeginPath(context);
|
||||
CGContextMoveToPoint(context, 0, rect.size.height);
|
||||
switch (_messageType) {
|
||||
case GAMessageBarMessageTypeError:
|
||||
CGContextSetRGBStrokeColor(context, 0.984f, 0.0f, 0.0f, 1.0f); // red
|
||||
break;
|
||||
case GAMessageBarMessageTypeSuccess:
|
||||
CGContextSetRGBStrokeColor(context, 0.074f, 0.749f, 0.074f, 1.0f); // green
|
||||
break;
|
||||
case GAMessageBarMessageTypeInfo:
|
||||
CGContextSetRGBStrokeColor(context, 0.007f, 0.686f, 0.737f, 1.0f); // teal
|
||||
break;
|
||||
case GAMessageBarMessageTypeLogo:
|
||||
CGContextSetRGBStrokeColor(context, 0.007f, 0.686f, 0.737f, 1.0f); // teal
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
CGContextSetStrokeColorWithColor(context, [MessageBarStyleSheet strokeColorForMessageType:_messageType].CGColor);
|
||||
CGContextSetLineWidth(context, 1.0);
|
||||
CGContextAddLineToPoint(context, rect.size.width, rect.size.height);
|
||||
CGContextStrokePath(context);
|
||||
}
|
||||
CGContextRestoreGState(context);
|
||||
|
||||
CGFloat xOffset = kGAMessageBarPadding;
|
||||
CGFloat yOffset = kGAMessageBarPadding;
|
||||
CGFloat xOffset = kMessageBarPadding;
|
||||
CGFloat yOffset = kMessageBarPadding;
|
||||
|
||||
// icon
|
||||
CGContextSaveGState(context);
|
||||
{
|
||||
switch (_messageType) {
|
||||
case GAMessageBarMessageTypeError:
|
||||
[[UIImage imageNamed:kGAImageIconNotificationWarning] drawInRect:CGRectMake(xOffset, yOffset, kGAMessageBarIconSize, kGAMessageBarIconSize)];
|
||||
break;
|
||||
case GAMessageBarMessageTypeSuccess:
|
||||
[[UIImage imageNamed:kGAImageIconNotificationCheckmark] drawInRect:CGRectMake(xOffset, yOffset, kGAMessageBarIconSize, kGAMessageBarIconSize)];
|
||||
break;
|
||||
case GAMessageBarMessageTypeInfo:
|
||||
[[UIImage imageNamed:kGAImageIconNotificationInfo] drawInRect:CGRectMake(xOffset, yOffset, kGAMessageBarIconSize, kGAMessageBarIconSize)];
|
||||
break;
|
||||
case GAMessageBarMessageTypeLogo:
|
||||
[[UIImage imageNamed:kGAImageIconNotificationLogo] drawInRect:CGRectMake(xOffset, yOffset, kGAMessageBarIconSize, kGAMessageBarIconSize)];
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
[[MessageBarStyleSheet iconImageForMessageType:_messageType] drawInRect:CGRectMake(xOffset, yOffset, kMessageBarIconSize, kMessageBarIconSize)];
|
||||
}
|
||||
CGContextRestoreGState(context);
|
||||
|
||||
yOffset -= kGAMessageBarTextOffset;
|
||||
xOffset += kGAMessageBarIconSize + kGAMessageBarPadding;
|
||||
yOffset -= kMessageBarTextOffset;
|
||||
xOffset += kMessageBarIconSize + kMessageBarPadding;
|
||||
|
||||
CGFloat maxWith = _button ? (rect.size.width - (kGAMessageBarPadding * 3) - ceil(kGAMessageBarPadding * 0.5) - kGAMessageBarIconSize) - kGAMessageBarButtonWidth : (rect.size.width - (kGAMessageBarPadding * 3) - kGAMessageBarIconSize);
|
||||
CGFloat maxWith = (rect.size.width - (kMessageBarPadding * 3) - kMessageBarIconSize);
|
||||
|
||||
CGSize titleLabelSize = [_titleString sizeWithFont:titleFont forWidth:maxWith lineBreakMode:UILineBreakModeTailTruncation];
|
||||
CGSize titleLabelSize = [_titleString sizeWithFont:titleFont forWidth:maxWith lineBreakMode:NSLineBreakByTruncatingTail];
|
||||
if (_titleString && !_descriptionString){
|
||||
yOffset = ceil(rect.size.height * 0.5) - ceil(titleLabelSize.height * 0.5) - kGAMessageBarTextOffset;
|
||||
yOffset = ceil(rect.size.height * 0.5) - ceil(titleLabelSize.height * 0.5) - kMessageBarTextOffset;
|
||||
}
|
||||
[shadowColor set];
|
||||
[_titleString drawInRect:CGRectMake(xOffset, yOffset-1, titleLabelSize.width, titleLabelSize.height) withFont:titleFont lineBreakMode:UILineBreakModeTailTruncation alignment:UITextAlignmentLeft];
|
||||
[titleColor set];
|
||||
[_titleString drawInRect:CGRectMake(xOffset, yOffset, titleLabelSize.width, titleLabelSize.height) withFont:titleFont lineBreakMode:UILineBreakModeTailTruncation alignment:UITextAlignmentLeft];
|
||||
[_titleString drawInRect:CGRectMake(xOffset, yOffset, titleLabelSize.width, titleLabelSize.height) withFont:titleFont lineBreakMode:NSLineBreakByTruncatingTail alignment:NSTextAlignmentLeft];
|
||||
|
||||
yOffset += titleLabelSize.height;
|
||||
|
||||
CGSize descriptionLabelSize = [_descriptionString sizeWithFont:descriptionFont constrainedToSize:CGSizeMake(maxWith, kGAMessageBarMaxDescriptionHeight) lineBreakMode:UILineBreakModeTailTruncation];
|
||||
[shadowColor set];
|
||||
[_descriptionString drawInRect:CGRectMake(xOffset, yOffset-1, descriptionLabelSize.width, descriptionLabelSize.height) withFont:descriptionFont lineBreakMode:UILineBreakModeTailTruncation alignment:UITextAlignmentLeft];
|
||||
CGSize descriptionLabelSize = [_descriptionString sizeWithFont:descriptionFont constrainedToSize:CGSizeMake(maxWith, kMessageBarMaxDescriptionHeight) lineBreakMode:NSLineBreakByTruncatingTail];
|
||||
[descriptionColor set];
|
||||
[_descriptionString drawInRect:CGRectMake(xOffset, yOffset, descriptionLabelSize.width, descriptionLabelSize.height) withFont:descriptionFont lineBreakMode:UILineBreakModeTailTruncation alignment:UITextAlignmentLeft];
|
||||
[_descriptionString drawInRect:CGRectMake(xOffset, yOffset, descriptionLabelSize.width, descriptionLabelSize.height) withFont:descriptionFont lineBreakMode:NSLineBreakByTruncatingTail alignment:NSTextAlignmentLeft];
|
||||
}
|
||||
|
||||
#pragma mark - Layout
|
||||
@@ -526,7 +315,6 @@ static UIColor *shadowColor = nil;
|
||||
{
|
||||
[super layoutSubviews];
|
||||
_shadowView.frame = CGRectMake(0, [self height], [self width], _shadowView.image.size.height);
|
||||
_button.frame = CGRectMake(self.frame.size.width - kGAMessageBarButtonWidth - kGAMessageBarPadding, ceil(self.frame.size.height * 0.5) - ceil(kGAMessageBarButtonHeight * 0.5), kGAMessageBarButtonWidth, kGAMessageBarButtonHeight);
|
||||
}
|
||||
|
||||
#pragma mark - Getters
|
||||
@@ -534,10 +322,10 @@ static UIColor *shadowColor = nil;
|
||||
- (CGFloat)height
|
||||
{
|
||||
if (_height == 0){
|
||||
CGFloat maxWith = _button ? ([self width] - (kGAMessageBarPadding * 3) - ceil(kGAMessageBarPadding * 0.5) - kGAMessageBarIconSize) - kGAMessageBarButtonWidth : ([self width] - (kGAMessageBarPadding * 3) - kGAMessageBarIconSize);
|
||||
CGSize titleLabelSize = [_titleString sizeWithFont:titleFont forWidth:maxWith lineBreakMode:UILineBreakModeTailTruncation];
|
||||
CGSize descriptionLabelSize = [_descriptionString sizeWithFont:descriptionFont constrainedToSize:CGSizeMake(maxWith, 10000) lineBreakMode:UILineBreakModeTailTruncation];
|
||||
_height = MAX((kGAMessageBarPadding*2) + titleLabelSize.height + descriptionLabelSize.height, (kGAMessageBarPadding*2) + kGAMessageBarIconSize);
|
||||
CGFloat maxWith = ([self width] - (kMessageBarPadding * 3) - kMessageBarIconSize);
|
||||
CGSize titleLabelSize = [_titleString sizeWithFont:titleFont forWidth:maxWith lineBreakMode:NSLineBreakByTruncatingTail];
|
||||
CGSize descriptionLabelSize = [_descriptionString sizeWithFont:descriptionFont constrainedToSize:CGSizeMake(maxWith, 10000) lineBreakMode:NSLineBreakByTruncatingTail];
|
||||
_height = MAX((kMessageBarPadding*2) + titleLabelSize.height + descriptionLabelSize.height, (kMessageBarPadding*2) + kMessageBarIconSize);
|
||||
}
|
||||
return _height;
|
||||
}
|
||||
@@ -550,4 +338,67 @@ static UIColor *shadowColor = nil;
|
||||
return _width;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation MessageBarStyleSheet
|
||||
|
||||
#pragma mark - Colors
|
||||
|
||||
+ (UIColor*)backgroundColorForMessageType:(MessageBarMessageType)type
|
||||
{
|
||||
UIColor *backgroundColor = nil;
|
||||
switch (type) {
|
||||
case MessageBarMessageTypeError:
|
||||
backgroundColor = [UIColor colorWithRed:1.0 green:0.611 blue:0.0 alpha:kMessageBarAlpha]; // orange
|
||||
break;
|
||||
case MessageBarMessageTypeSuccess:
|
||||
backgroundColor = [UIColor colorWithRed:0.0f green:0.831f blue:0.176f alpha:kMessageBarAlpha]; // green
|
||||
break;
|
||||
case MessageBarMessageTypeInfo:
|
||||
backgroundColor = [UIColor colorWithRed:0.0 green:0.482 blue:1.0 alpha:kMessageBarAlpha]; // blue
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return backgroundColor;
|
||||
}
|
||||
|
||||
+ (UIColor*)strokeColorForMessageType:(MessageBarMessageType)type
|
||||
{
|
||||
UIColor *strokeColor = nil;
|
||||
switch (type) {
|
||||
case MessageBarMessageTypeError:
|
||||
strokeColor = [UIColor colorWithRed:0.949f green:0.580f blue:0.0f alpha:1.0f]; // orange
|
||||
break;
|
||||
case MessageBarMessageTypeSuccess:
|
||||
strokeColor = [UIColor colorWithRed:0.0f green:0.772f blue:0.164f alpha:1.0f]; // orange
|
||||
break;
|
||||
case MessageBarMessageTypeInfo:
|
||||
strokeColor = [UIColor colorWithRed:0.0f green:0.415f blue:0.803f alpha:1.0f]; // orange
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return strokeColor;
|
||||
}
|
||||
|
||||
+ (UIImage*)iconImageForMessageType:(MessageBarMessageType)type
|
||||
{
|
||||
UIImage *iconImage = nil;
|
||||
switch (type) {
|
||||
case MessageBarMessageTypeError:
|
||||
iconImage = [UIImage imageNamed:kImageIconError];
|
||||
break;
|
||||
case MessageBarMessageTypeSuccess:
|
||||
iconImage = [UIImage imageNamed:kImageIconSucces];
|
||||
break;
|
||||
case MessageBarMessageTypeInfo:
|
||||
iconImage = [UIImage imageNamed:kImageIconInfo];
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return iconImage;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -17,7 +17,6 @@
|
||||
5649826A1741BF7A00077B8C /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 564982691741BF7A00077B8C /* main.m */; };
|
||||
569FCDF81741C09300F2B74C /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 569FCDF41741C09300F2B74C /* AppDelegate.m */; };
|
||||
569FCDF91741C09300F2B74C /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 569FCDF71741C09300F2B74C /* ViewController.m */; };
|
||||
569FCDFD1741C34600F2B74C /* MessageBarManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 569FCDFC1741C34600F2B74C /* MessageBarManager.m */; };
|
||||
56DE553117458A7B0026B7D2 /* icon-error.png in Resources */ = {isa = PBXBuildFile; fileRef = 56DE552B17458A7B0026B7D2 /* icon-error.png */; };
|
||||
56DE553217458A7B0026B7D2 /* icon-error@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 56DE552C17458A7B0026B7D2 /* icon-error@2x.png */; };
|
||||
56DE553317458A7B0026B7D2 /* icon-info.png in Resources */ = {isa = PBXBuildFile; fileRef = 56DE552D17458A7B0026B7D2 /* icon-info.png */; };
|
||||
@@ -42,8 +41,8 @@
|
||||
569FCDF41741C09300F2B74C /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
|
||||
569FCDF61741C09300F2B74C /* ViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = "<group>"; };
|
||||
569FCDF71741C09300F2B74C /* ViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = "<group>"; };
|
||||
569FCDFB1741C34600F2B74C /* MessageBarManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MessageBarManager.h; sourceTree = "<group>"; };
|
||||
569FCDFC1741C34600F2B74C /* MessageBarManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MessageBarManager.m; sourceTree = "<group>"; };
|
||||
56CD5A25175A777B00E9B94E /* MessageBarManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = MessageBarManager.h; path = ../../../Classes/MessageBarManager.h; sourceTree = "<group>"; };
|
||||
56CD5A26175A777B00E9B94E /* MessageBarManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = MessageBarManager.m; path = ../../../Classes/MessageBarManager.m; sourceTree = "<group>"; };
|
||||
56DE552B17458A7B0026B7D2 /* icon-error.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon-error.png"; sourceTree = "<group>"; };
|
||||
56DE552C17458A7B0026B7D2 /* icon-error@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon-error@2x.png"; sourceTree = "<group>"; };
|
||||
56DE552D17458A7B0026B7D2 /* icon-info.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon-info.png"; sourceTree = "<group>"; };
|
||||
@@ -150,8 +149,8 @@
|
||||
569FCDFA1741C33700F2B74C /* Managers */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
569FCDFB1741C34600F2B74C /* MessageBarManager.h */,
|
||||
569FCDFC1741C34600F2B74C /* MessageBarManager.m */,
|
||||
56CD5A25175A777B00E9B94E /* MessageBarManager.h */,
|
||||
56CD5A26175A777B00E9B94E /* MessageBarManager.m */,
|
||||
);
|
||||
name = Managers;
|
||||
sourceTree = "<group>";
|
||||
@@ -261,7 +260,6 @@
|
||||
5649826A1741BF7A00077B8C /* main.m in Sources */,
|
||||
569FCDF81741C09300F2B74C /* AppDelegate.m in Sources */,
|
||||
569FCDF91741C09300F2B74C /* ViewController.m in Sources */,
|
||||
569FCDFD1741C34600F2B74C /* MessageBarManager.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
||||
Binary file not shown.
@@ -1,37 +0,0 @@
|
||||
//
|
||||
// MessageBarManager.h
|
||||
//
|
||||
// Created by Terry Worona on 5/13/13.
|
||||
// Copyright (c) 2013 Terry Worona. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
typedef enum {
|
||||
MessageBarMessageTypeError,
|
||||
MessageBarMessageTypeSuccess,
|
||||
MessageBarMessageTypeInfo
|
||||
} MessageBarMessageType;
|
||||
|
||||
@interface MessageBarManager : NSObject
|
||||
|
||||
+ (MessageBarManager *)sharedInstance;
|
||||
|
||||
- (void)showMessageWithTitle:(NSString*)title description:(NSString*)description type:(MessageBarMessageType)type;
|
||||
- (void)showMessageWithTitle:(NSString*)title description:(NSString*)description type:(MessageBarMessageType)type callback:(void (^)())callback;
|
||||
|
||||
- (void)showMessageWithTitle:(NSString*)title description:(NSString*)description type:(MessageBarMessageType)type forDuration:(CGFloat)duration;
|
||||
- (void)showMessageWithTitle:(NSString*)title description:(NSString*)description type:(MessageBarMessageType)type forDuration:(CGFloat)duration callback:(void (^)())callback;
|
||||
|
||||
@end
|
||||
|
||||
@interface MessageBarStyleSheet : NSObject
|
||||
|
||||
// Colors (override for customization)
|
||||
+ (UIColor*)backgroundColorForMessageType:(MessageBarMessageType)type;
|
||||
+ (UIColor*)strokeColorForMessageType:(MessageBarMessageType)type;
|
||||
|
||||
// Icon images (override for customization)
|
||||
+ (UIImage*)iconImageForMessageType:(MessageBarMessageType)type;
|
||||
|
||||
@end
|
||||
@@ -1,404 +0,0 @@
|
||||
//
|
||||
// MessageBarManager.m
|
||||
//
|
||||
// Created by Terry Worona on 5/13/13.
|
||||
// Copyright (c) 2013 Terry Worona. All rights reserved.
|
||||
//
|
||||
|
||||
#import "MessageBarManager.h"
|
||||
|
||||
// Quartz
|
||||
#import <QuartzCore/QuartzCore.h>
|
||||
|
||||
// Delegate
|
||||
#import "AppDelegate.h"
|
||||
|
||||
// Constants
|
||||
#import "UIConstants.h"
|
||||
|
||||
#define kMessageBarAlpha 0.96
|
||||
#define kMessageBarPadding 10
|
||||
#define kMessageBarMaxDescriptionHeight 250
|
||||
#define kMessageBarIconSize 36
|
||||
#define kMessageBarDisplayDelay 3.0
|
||||
#define kMessageBarTextOffset 2.0
|
||||
#define kMessageBarAnimationDuration 0.25
|
||||
|
||||
@class MessageView;
|
||||
|
||||
@interface MessageView : UIView
|
||||
|
||||
@property (nonatomic, strong) NSString *titleString;
|
||||
@property (nonatomic, strong) NSString *descriptionString;
|
||||
@property (nonatomic, assign) MessageBarMessageType messageType;
|
||||
@property (nonatomic, strong) UIImageView *shadowView;
|
||||
|
||||
@property (nonatomic, assign) BOOL hasCallback;
|
||||
@property (nonatomic, strong) NSArray *callbacks;
|
||||
|
||||
@property (nonatomic, assign, getter = isHit) BOOL hit;
|
||||
|
||||
@property (nonatomic, assign, readonly) CGFloat height;
|
||||
@property (nonatomic, assign, readonly) CGFloat width;
|
||||
|
||||
@property (nonatomic, assign) CGFloat duration;
|
||||
|
||||
- (id)initWithTitle:(NSString*)title description:(NSString*)description type:(MessageBarMessageType)type;
|
||||
|
||||
@end
|
||||
|
||||
@interface MessageBarManager ()
|
||||
|
||||
@property (nonatomic, strong) NSMutableArray *messageBarQueue;
|
||||
@property (nonatomic, assign, getter = isMessageVisible) BOOL messageVisible;
|
||||
@property (nonatomic, assign) CGFloat messageBarOffset;
|
||||
|
||||
+ (CGFloat)durationForMessageType:(MessageBarMessageType)messageType;
|
||||
|
||||
- (void)showNextMessage;
|
||||
- (void)itemSelected:(UITapGestureRecognizer*)recognizer;
|
||||
|
||||
@end
|
||||
|
||||
@implementation MessageBarManager
|
||||
|
||||
@synthesize messageBarQueue = _messageBarQueue;
|
||||
@synthesize messageVisible = _messageVisible;
|
||||
@synthesize messageBarOffset = _messageBarOffset;
|
||||
|
||||
#pragma mark - Singleton
|
||||
|
||||
+ (MessageBarManager *)sharedInstance
|
||||
{
|
||||
static dispatch_once_t pred;
|
||||
static MessageBarManager *instance = nil;
|
||||
dispatch_once(&pred, ^{ instance = [[self alloc] init]; });
|
||||
return instance;
|
||||
}
|
||||
|
||||
#pragma mark - Static
|
||||
|
||||
+ (CGFloat)durationForMessageType:(MessageBarMessageType)messageType
|
||||
{
|
||||
return kMessageBarDisplayDelay;
|
||||
}
|
||||
|
||||
#pragma mark - Alloc/Init
|
||||
|
||||
-(id)init
|
||||
{
|
||||
if(self = [super init]) {
|
||||
_messageBarQueue = [[NSMutableArray alloc] init];
|
||||
_messageVisible = NO;
|
||||
_messageBarOffset = [[UIApplication sharedApplication] statusBarFrame].size.height;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
#pragma mark - Public
|
||||
|
||||
- (void)showMessageWithTitle:(NSString*)title description:(NSString*)description type:(MessageBarMessageType)type
|
||||
{
|
||||
[self showMessageWithTitle:title description:description type:type forDuration:[MessageBarManager durationForMessageType:type] callback:nil];
|
||||
}
|
||||
|
||||
- (void)showMessageWithTitle:(NSString*)title description:(NSString*)description type:(MessageBarMessageType)type callback:(void (^)())callback
|
||||
{
|
||||
[self showMessageWithTitle:title description:description type:type forDuration:[MessageBarManager durationForMessageType:type] callback:callback];
|
||||
}
|
||||
|
||||
- (void)showMessageWithTitle:(NSString*)title description:(NSString*)description type:(MessageBarMessageType)type forDuration:(CGFloat)duration
|
||||
{
|
||||
[self showMessageWithTitle:title description:description type:type forDuration:duration callback:nil];
|
||||
}
|
||||
|
||||
- (void)showMessageWithTitle:(NSString*)title description:(NSString*)description type:(MessageBarMessageType)type forDuration:(CGFloat)duration callback:(void (^)())callback
|
||||
{
|
||||
MessageView *messageView = [[MessageView alloc] initWithTitle:title description:description type:type];
|
||||
|
||||
messageView.callbacks = callback ? [NSArray arrayWithObject:callback] : [NSArray array];
|
||||
messageView.hasCallback = callback ? YES : NO;
|
||||
|
||||
messageView.duration = duration;
|
||||
messageView.hidden = YES;
|
||||
|
||||
AppDelegate *delegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
|
||||
[delegate.window insertSubview:messageView atIndex:1];
|
||||
[_messageBarQueue addObject:messageView];
|
||||
|
||||
if (!_messageVisible){
|
||||
[self showNextMessage];
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - Private
|
||||
|
||||
- (void)showNextMessage
|
||||
{
|
||||
if ([_messageBarQueue count] > 0){
|
||||
_messageVisible = YES;
|
||||
|
||||
MessageView *messageView = [_messageBarQueue objectAtIndex:0];
|
||||
messageView.frame = CGRectMake(0, -[messageView height], [messageView width], [messageView height]);
|
||||
messageView.hidden = NO;
|
||||
[messageView setNeedsDisplay];
|
||||
|
||||
UITapGestureRecognizer *gest = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(itemSelected:)];
|
||||
[messageView addGestureRecognizer:gest];
|
||||
|
||||
if (messageView){
|
||||
[_messageBarQueue removeObject:messageView];
|
||||
|
||||
[UIView animateWithDuration:kMessageBarAnimationDuration animations:^{
|
||||
[messageView setFrame:CGRectMake(messageView.frame.origin.x, _messageBarOffset + messageView.frame.origin.y + [messageView height], [messageView width], [messageView height])]; // slide down
|
||||
}];
|
||||
|
||||
[self performSelector:@selector(itemSelected:) withObject:messageView afterDelay:messageView.duration];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - Gestures
|
||||
|
||||
- (void)itemSelected:(id)sender
|
||||
{
|
||||
MessageView *messageView = nil;
|
||||
BOOL itemHit = NO;
|
||||
if ([sender isKindOfClass:[UIGestureRecognizer class]]){
|
||||
messageView = (MessageView*)((UIGestureRecognizer*)sender).view;
|
||||
itemHit = YES;
|
||||
}
|
||||
else if ([sender isKindOfClass:[MessageView class]]){
|
||||
messageView = (MessageView*)sender;
|
||||
}
|
||||
|
||||
if (messageView && ![messageView isHit]){
|
||||
messageView.hit = YES;
|
||||
|
||||
[UIView animateWithDuration:kMessageBarAnimationDuration animations:^{
|
||||
[messageView setFrame:CGRectMake(messageView.frame.origin.x, messageView.frame.origin.y - [messageView height] - _messageBarOffset, [messageView width], [messageView height])]; // slide back up
|
||||
} completion:^(BOOL finished) {
|
||||
_messageVisible = NO;
|
||||
[messageView removeFromSuperview];
|
||||
|
||||
if (itemHit){
|
||||
if ([messageView.callbacks count] > 0){
|
||||
id obj = [messageView.callbacks objectAtIndex:0];
|
||||
if (![obj isEqual:[NSNull null]]) {
|
||||
((void (^)())obj)();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if([_messageBarQueue count] > 0) {
|
||||
[self showNextMessage];
|
||||
}
|
||||
}];
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
static UIFont *titleFont = nil;
|
||||
static UIColor *titleColor = nil;
|
||||
|
||||
static UIFont *descriptionFont = nil;
|
||||
static UIColor *descriptionColor = nil;
|
||||
|
||||
@implementation MessageView
|
||||
|
||||
@synthesize titleString = _titleString;
|
||||
@synthesize descriptionString = _descriptionString;
|
||||
@synthesize messageType = _messageType;
|
||||
@synthesize shadowView = _shadowView;
|
||||
|
||||
@synthesize hasCallback = _hasCallback;
|
||||
@synthesize callbacks = _callbacks;
|
||||
|
||||
@synthesize hit = _hit;
|
||||
|
||||
@synthesize width = _width;
|
||||
@synthesize height = _height;
|
||||
|
||||
@synthesize duration = _duration;
|
||||
|
||||
#pragma mark - Alloc/Init
|
||||
|
||||
- (id)initWithTitle:(NSString*)title description:(NSString*)description type:(MessageBarMessageType)type
|
||||
{
|
||||
self = [super initWithFrame:CGRectZero];
|
||||
if (self){
|
||||
|
||||
self.backgroundColor = [UIColor clearColor];
|
||||
self.clipsToBounds = NO;
|
||||
self.userInteractionEnabled = YES;
|
||||
|
||||
_titleString = title;
|
||||
_descriptionString = description;
|
||||
_messageType = type;
|
||||
|
||||
titleFont = [UIFont boldSystemFontOfSize:16.0];
|
||||
titleColor = [UIColor colorWithWhite:1.0 alpha:1.0];
|
||||
|
||||
descriptionFont = [UIFont systemFontOfSize:14.0];
|
||||
descriptionColor = [UIColor colorWithWhite:1.0 alpha:1.0];
|
||||
|
||||
_height = 0.0;
|
||||
_width = 0.0;
|
||||
|
||||
_hasCallback = NO;
|
||||
_hit = NO;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
#pragma mark - Drawing
|
||||
|
||||
- (void)drawRect:(CGRect)rect
|
||||
{
|
||||
[super drawRect:rect];
|
||||
|
||||
CGContextRef context = UIGraphicsGetCurrentContext();
|
||||
|
||||
// background fill
|
||||
CGContextSaveGState(context);
|
||||
{
|
||||
[[MessageBarStyleSheet backgroundColorForMessageType:_messageType] set];
|
||||
CGContextFillRect(context, rect);
|
||||
}
|
||||
CGContextRestoreGState(context);
|
||||
|
||||
// bottom stroke
|
||||
CGContextSaveGState(context);
|
||||
{
|
||||
CGContextBeginPath(context);
|
||||
CGContextMoveToPoint(context, 0, rect.size.height);
|
||||
CGContextSetStrokeColorWithColor(context, [MessageBarStyleSheet strokeColorForMessageType:_messageType].CGColor);
|
||||
CGContextSetLineWidth(context, 1.0);
|
||||
CGContextAddLineToPoint(context, rect.size.width, rect.size.height);
|
||||
CGContextStrokePath(context);
|
||||
}
|
||||
CGContextRestoreGState(context);
|
||||
|
||||
CGFloat xOffset = kMessageBarPadding;
|
||||
CGFloat yOffset = kMessageBarPadding;
|
||||
|
||||
// icon
|
||||
CGContextSaveGState(context);
|
||||
{
|
||||
[[MessageBarStyleSheet iconImageForMessageType:_messageType] drawInRect:CGRectMake(xOffset, yOffset, kMessageBarIconSize, kMessageBarIconSize)];
|
||||
}
|
||||
CGContextRestoreGState(context);
|
||||
|
||||
yOffset -= kMessageBarTextOffset;
|
||||
xOffset += kMessageBarIconSize + kMessageBarPadding;
|
||||
|
||||
CGFloat maxWith = (rect.size.width - (kMessageBarPadding * 3) - kMessageBarIconSize);
|
||||
|
||||
CGSize titleLabelSize = [_titleString sizeWithFont:titleFont forWidth:maxWith lineBreakMode:NSLineBreakByTruncatingTail];
|
||||
if (_titleString && !_descriptionString){
|
||||
yOffset = ceil(rect.size.height * 0.5) - ceil(titleLabelSize.height * 0.5) - kMessageBarTextOffset;
|
||||
}
|
||||
[titleColor set];
|
||||
[_titleString drawInRect:CGRectMake(xOffset, yOffset, titleLabelSize.width, titleLabelSize.height) withFont:titleFont lineBreakMode:NSLineBreakByTruncatingTail alignment:NSTextAlignmentLeft];
|
||||
|
||||
yOffset += titleLabelSize.height;
|
||||
|
||||
CGSize descriptionLabelSize = [_descriptionString sizeWithFont:descriptionFont constrainedToSize:CGSizeMake(maxWith, kMessageBarMaxDescriptionHeight) lineBreakMode:NSLineBreakByTruncatingTail];
|
||||
[descriptionColor set];
|
||||
[_descriptionString drawInRect:CGRectMake(xOffset, yOffset, descriptionLabelSize.width, descriptionLabelSize.height) withFont:descriptionFont lineBreakMode:NSLineBreakByTruncatingTail alignment:NSTextAlignmentLeft];
|
||||
}
|
||||
|
||||
#pragma mark - Layout
|
||||
|
||||
- (void)layoutSubviews
|
||||
{
|
||||
[super layoutSubviews];
|
||||
_shadowView.frame = CGRectMake(0, [self height], [self width], _shadowView.image.size.height);
|
||||
}
|
||||
|
||||
#pragma mark - Getters
|
||||
|
||||
- (CGFloat)height
|
||||
{
|
||||
if (_height == 0){
|
||||
CGFloat maxWith = ([self width] - (kMessageBarPadding * 3) - kMessageBarIconSize);
|
||||
CGSize titleLabelSize = [_titleString sizeWithFont:titleFont forWidth:maxWith lineBreakMode:NSLineBreakByTruncatingTail];
|
||||
CGSize descriptionLabelSize = [_descriptionString sizeWithFont:descriptionFont constrainedToSize:CGSizeMake(maxWith, 10000) lineBreakMode:NSLineBreakByTruncatingTail];
|
||||
_height = MAX((kMessageBarPadding*2) + titleLabelSize.height + descriptionLabelSize.height, (kMessageBarPadding*2) + kMessageBarIconSize);
|
||||
}
|
||||
return _height;
|
||||
}
|
||||
|
||||
- (CGFloat)width
|
||||
{
|
||||
if (_width == 0){
|
||||
_width = [UIScreen mainScreen].bounds.size.width;
|
||||
}
|
||||
return _width;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation MessageBarStyleSheet
|
||||
|
||||
#pragma mark - Colors
|
||||
|
||||
+ (UIColor*)backgroundColorForMessageType:(MessageBarMessageType)type
|
||||
{
|
||||
UIColor *backgroundColor = nil;
|
||||
switch (type) {
|
||||
case MessageBarMessageTypeError:
|
||||
backgroundColor = [UIColor colorWithRed:1.0 green:0.611 blue:0.0 alpha:kMessageBarAlpha]; // orange
|
||||
break;
|
||||
case MessageBarMessageTypeSuccess:
|
||||
backgroundColor = [UIColor colorWithRed:0.0f green:0.831f blue:0.176f alpha:kMessageBarAlpha]; // green
|
||||
break;
|
||||
case MessageBarMessageTypeInfo:
|
||||
backgroundColor = [UIColor colorWithRed:0.0 green:0.482 blue:1.0 alpha:kMessageBarAlpha]; // blue
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return backgroundColor;
|
||||
}
|
||||
|
||||
+ (UIColor*)strokeColorForMessageType:(MessageBarMessageType)type
|
||||
{
|
||||
UIColor *strokeColor = nil;
|
||||
switch (type) {
|
||||
case MessageBarMessageTypeError:
|
||||
strokeColor = [UIColor colorWithRed:0.949f green:0.580f blue:0.0f alpha:1.0f]; // orange
|
||||
break;
|
||||
case MessageBarMessageTypeSuccess:
|
||||
strokeColor = [UIColor colorWithRed:0.0f green:0.772f blue:0.164f alpha:1.0f]; // orange
|
||||
break;
|
||||
case MessageBarMessageTypeInfo:
|
||||
strokeColor = [UIColor colorWithRed:0.0f green:0.415f blue:0.803f alpha:1.0f]; // orange
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return strokeColor;
|
||||
}
|
||||
|
||||
+ (UIImage*)iconImageForMessageType:(MessageBarMessageType)type
|
||||
{
|
||||
UIImage *iconImage = nil;
|
||||
switch (type) {
|
||||
case MessageBarMessageTypeError:
|
||||
iconImage = [UIImage imageNamed:kImageIconError];
|
||||
break;
|
||||
case MessageBarMessageTypeSuccess:
|
||||
iconImage = [UIImage imageNamed:kImageIconSucces];
|
||||
break;
|
||||
case MessageBarMessageTypeInfo:
|
||||
iconImage = [UIImage imageNamed:kImageIconInfo];
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return iconImage;
|
||||
}
|
||||
|
||||
@end
|
||||
Reference in New Issue
Block a user