//
// Toast+UIView.h
#import<UIKit/UIKit.h>
@interface UIView (Toast)
// each makeToast method creates a view and displays it as toast
- (void)makeToast:(NSString *)message withValue:(NSString *)value withTextColor:(UIColor *) color;
- (void)makeToast:(NSString *)message duration:(CGFloat)interval position:(id)position withTextColor:(UIColor *) color withValue:(NSString *)value;
- (void)makeToast:(NSString *)message duration:(CGFloat)interval position:(id)position title:(NSString *)title withTextColor:(UIColor *) color withValue:(NSString *)value;
- (void)makeToast:(NSString *)message duration:(CGFloat)interval position:(id)position title:(NSString *)title image:(UIImage *)image withTextColor:(UIColor *) color withValue:(NSString *)value;
- (void)makeToast:(NSString *)message duration:(CGFloat)interval position:(id)position image:(UIImage *)image withTextColor:(UIColor *) color withValue:(NSString *)value;
// displays toast with an activity spinner
- (void)makeToastActivity;
- (void)makeToastActivity:(id)position;
- (void)hideToastActivity;
// the showToast methods display any view as toast
- (void)showToast:(UIView *)toast;
- (void)showToast:(UIView *)toast duration:(CGFloat)interval position:(id)point;
@end
//
// Toast+UIView.m
#import "Toast+UIView.h"
#import <QuartzCore/QuartzCore.h>
#import <objc/runtime.h>
/*
* CONFIGURE THESE VALUES TO ADJUST LOOK & FEEL,
* DISPLAY DURATION, ETC.
*/
// general appearance
staticconst CGFloat CSToastMaxWidth =0.8; // 80% of parent view width
staticconst CGFloat CSToastMaxHeight =0.8; // 80% of parent view height
staticconst CGFloat CSToastHorizontalPadding =10.0;
staticconst CGFloat CSToastVerticalPadding =10.0;
staticconst CGFloat CSToastCornerRadius =10.0;
staticconst CGFloat CSToastOpacity =0.8;
staticconst CGFloat CSToastFontSize =16.0;
staticconst CGFloat CSToastMaxTitleLines =0;
staticconst CGFloat CSToastMaxMessageLines =0;
staticconst CGFloat CSToastFadeDuration =0.2;
// shadow appearance
staticconst CGFloat CSToastShadowOpacity =0.5;
staticconst CGFloat CSToastShadowRadius =6.0;
staticconst CGSize CSToastShadowOffset = {4.0, 4.0 };
staticconst BOOL CSToastDisplayShadow =YES;
// display duration and position
staticconst CGFloat CSToastDefaultDuration =2.0;
staticconst NSString * CSToastDefaultPosition =@"center";
// image view size
staticconst CGFloat CSToastImageViewWidth =80.0;
staticconst CGFloat CSToastImageViewHeight =80.0;
// activity
staticconst CGFloat CSToastActivityWidth =100.0;
staticconst CGFloat CSToastActivityHeight =100.0;
staticconst NSString * CSToastActivityDefaultPosition =@"center";
staticconst NSString * CSToastActivityViewKey =@"CSToastActivityViewKey";
@interface UIView (ToastPrivate)
- (CGPoint)centerPointForPosition:(id)position withToast:(UIView *)toast;
- (UIView *)viewForMessage:(NSString *)message title:(NSString *)title image:(UIImage *)image color:(UIColor *)color;
@end
@implementation UIView (Toast)
#pragma mark - Toast Methods
- (void)makeToast:(NSString *)message withValue:(NSString *)value withTextColor:(UIColor *)color
{
[selfmakeToast:message duration:CSToastDefaultDurationposition:CSToastDefaultPositionwithTextColor:color withValue:value];
}
- (void)makeToast:(NSString *)message duration:(CGFloat)interval position:(id)position withTextColor:(UIColor *) color withValue:(NSString *)value
{
UIView *toast = [selfviewForMessage:message title:nil image:nilcolor:color value:value];
[selfshowToast:toast duration:intervalposition:position];
}
- (void)makeToast:(NSString *)message duration:(CGFloat)interval position:(id)position title:(NSString *)title withTextColor:(UIColor *) color withValue:(NSString *)value
{
UIView *toast = [selfviewForMessage:message title:title image:nilcolor:color value:value];
[selfshowToast:toast duration:intervalposition:position];
}
- (void)makeToast:(NSString *)message duration:(CGFloat)interval position:(id)position image:(UIImage *)image withTextColor:(UIColor *) color withValue:(NSString *)value
{
UIView *toast = [selfviewForMessage:message title:nil image:imagecolor:color value:value];
[selfshowToast:toast duration:intervalposition:position];
}
- (void)makeToast:(NSString *)message duration:(CGFloat)interval position:(id)position title:(NSString *)title image:(UIImage *)image withTextColor:(UIColor *) color withValue:(NSString *)value
{
UIView *toast = [selfviewForMessage:message title:title image:image color:color value:value];
[selfshowToast:toast duration:intervalposition:position];
}
- (void)showToast:(UIView *)toast
{
[selfshowToast:toast duration:CSToastDefaultDurationposition:CSToastDefaultPosition];
}
- (void)showToast:(UIView *)toast duration:(CGFloat)interval position:(id)point {
toast.center = [selfcenterPointForPosition:point withToast:toast];
toast.alpha =0.0;
[[CCDirectorsharedDirector].viewinsertSubview:toastatIndex:INFINITY];
[UIViewanimateWithDuration:CSToastFadeDuration
delay:0.0
options:UIViewAnimationOptionCurveEaseOut
animations:^{
toast.alpha =1.0;
} completion:^(BOOL finished) {
[UIViewanimateWithDuration:CSToastFadeDuration+0.3f
delay:interval
options:UIViewAnimationOptionCurveEaseIn
animations:^{
toast.alpha =0.0;
}completion:^(BOOL finished) {
[toastremoveFromSuperview];
}];
}];
// UIView animateWithDuration:<#(NSTimeInterval)#> animations:<#^(void)animations#>
}
#pragma mark - Toast Activity Methods
- (void)makeToastActivity {
[selfmakeToastActivity:CSToastActivityDefaultPosition];
}
- (void)makeToastActivity:(id)position {
// sanity
UIView *existingActivityView = (UIView *)objc_getAssociatedObject(self, &CSToastActivityViewKey);
if (existingActivityView !=nil) return;
UIView *activityView = [[[UIViewalloc] initWithFrame:CGRectMake(0,0, CSToastActivityWidth,CSToastActivityHeight)]autorelease];
activityView.center = [selfcenterPointForPosition:position withToast:activityView];
activityView.backgroundColor = [[UIColorblackColor] colorWithAlphaComponent:CSToastOpacity];
activityView.alpha =0.0;
activityView.autoresizingMask = (UIViewAutoresizingFlexibleLeftMargin |UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin);
activityView.layer.cornerRadius =CSToastCornerRadius;
if (CSToastDisplayShadow) {
activityView.layer.shadowColor = [UIColorblackColor].CGColor;
activityView.layer.shadowOpacity =CSToastShadowOpacity;
activityView.layer.shadowRadius =CSToastShadowRadius;
activityView.layer.shadowOffset =CSToastShadowOffset;
}
UIActivityIndicatorView *activityIndicatorView = [[[UIActivityIndicatorViewalloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge]autorelease];
activityIndicatorView.center =CGPointMake(activityView.bounds.size.width /2, activityView.bounds.size.height /2);
[activityView addSubview:activityIndicatorView];
[activityIndicatorView startAnimating];
// associate ourselves with the activity view
objc_setAssociatedObject (self, &CSToastActivityViewKey, activityView,OBJC_ASSOCIATION_RETAIN_NONATOMIC);
[selfaddSubview:activityView];
[UIViewanimateWithDuration:CSToastFadeDuration
delay:0.0
options:UIViewAnimationOptionCurveEaseOut
animations:^{
activityView.alpha =1.0;
} completion:nil];
}
- (void)hideToastActivity {
UIView *existingActivityView = (UIView *)objc_getAssociatedObject(self, &CSToastActivityViewKey);
if (existingActivityView !=nil) {
[UIViewanimateWithDuration:CSToastFadeDuration
delay:0.0
options:(UIViewAnimationOptionCurveEaseIn |UIViewAnimationOptionBeginFromCurrentState)
animations:^{
existingActivityView.alpha =0.0;
} completion:^(BOOL finished) {
[existingActivityViewremoveFromSuperview];
objc_setAssociatedObject (self, &CSToastActivityViewKey,nil, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}];
}
}
#pragma mark - Private Methods
- (CGPoint)centerPointForPosition:(id)point withToast:(UIView *)toast {
if([point isKindOfClass:[NSStringclass]]) {
// convert string literals @"top", @"bottom", @"center", or any point wrapped in an NSValue object into a CGPoint
if([point caseInsensitiveCompare:@"top"] ==NSOrderedSame) {
return CGPointMake(self.bounds.size.width/2, (toast.frame.size.height /2) + CSToastVerticalPadding);
} else if([pointcaseInsensitiveCompare:@"bottom"] ==NSOrderedSame) {
return CGPointMake(self.bounds.size.width/2, (self.bounds.size.height - (toast.frame.size.height / 2)) - CSToastVerticalPadding);
} else if([pointcaseInsensitiveCompare:@"center"] ==NSOrderedSame) {
return CGPointMake(self.bounds.size.width /2, self.bounds.size.height / 2);
}
} else if ([pointisKindOfClass:[NSValueclass]]) {
return [pointCGPointValue];
}
NSLog(@"Warning: Invalid position for toast.");
return [selfcenterPointForPosition:CSToastDefaultPositionwithToast:toast];
}
- (UIView *)viewForMessage:(NSString *)message title:(NSString *)title image:(UIImage *)image color:(UIColor *) color value:(NSString *) value{
// sanity
if((message ==nil) && (title == nil) && (image == nil)) return nil;
// dynamically build a toast view with any combination of message, title, & image.
KeyUILabel *messageLabel =nil;
KeyUILabel *titleLabel =nil;
UIImageView *imageView =nil;
// create the parent view
UIView *wrapperView = [[UIViewalloc] init];
wrapperView.autoresizingMask = (UIViewAutoresizingFlexibleLeftMargin |UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin);
wrapperView.layer.cornerRadius =CSToastCornerRadius;
if (CSToastDisplayShadow) {
wrapperView.layer.shadowColor = [UIColorblackColor].CGColor;
wrapperView.layer.shadowOpacity =CSToastShadowOpacity;
wrapperView.layer.shadowRadius =CSToastShadowRadius;
wrapperView.layer.shadowOffset =CSToastShadowOffset;
}
wrapperView.backgroundColor = [[UIColorblackColor] colorWithAlphaComponent:CSToastOpacity];
if(image !=nil) {
imageView = [[UIImageViewalloc] initWithImage:image];
imageView.contentMode =UIViewContentModeScaleAspectFit;
imageView.frame =CGRectMake(CSToastHorizontalPadding,CSToastVerticalPadding, CSToastImageViewWidth,CSToastImageViewHeight);
}
CGFloat imageWidth, imageHeight, imageLeft;
// the imageView frame values will be used to size & position the other views
if(imageView !=nil) {
imageWidth = imageView.bounds.size.width;
imageHeight = imageView.bounds.size.height;
imageLeft =CSToastHorizontalPadding;
} else {
imageWidth = imageHeight = imageLeft =0.0;
}
if (title !=nil) {
titleLabel = [[KeyUILabelalloc] init];
titleLabel.numberOfLines =CSToastMaxTitleLines;
titleLabel.font = [UIFontboldSystemFontOfSize:CSToastFontSize];
titleLabel.textAlignment =NSTextAlignmentLeft;
titleLabel.lineBreakMode =NSLineBreakByWordWrapping;
titleLabel.textColor = color;
titleLabel.backgroundColor = [UIColorclearColor];
titleLabel.alpha =1.0;
titleLabel.text = title;
// size the title label according to the length of the text
CGSize maxSizeTitle =CGSizeMake((self.bounds.size.width *CSToastMaxWidth) - imageWidth, self.bounds.size.height *CSToastMaxHeight);
CGSize expectedSizeTitle = [titlesizeWithFont:titleLabel.fontconstrainedToSize:maxSizeTitle lineBreakMode:titleLabel.lineBreakMode];
titleLabel.frame =CGRectMake(0.0,0.0, expectedSizeTitle.width, expectedSizeTitle.height);
}
if (message !=nil) {
messageLabel = [[[KeyUILabelalloc] init]autorelease];
messageLabel.numberOfLines =CSToastMaxMessageLines;
messageLabel.font = [UIFontsystemFontOfSize:CSToastFontSize];
messageLabel.lineBreakMode =NSLineBreakByWordWrapping;
messageLabel.textColor =color;
messageLabel.backgroundColor = [UIColorclearColor];
messageLabel.alpha =1.0;
messageLabel.text =message;
// size the message label according to the length of the text
CGSize maxSizeMessage =CGSizeMake((self.bounds.size.width *CSToastMaxWidth) - imageWidth, self.bounds.size.height *CSToastMaxHeight);
CGSize expectedSizeMessage = [messagesizeWithFont:messageLabel.fontconstrainedToSize:maxSizeMessage lineBreakMode:messageLabel.lineBreakMode];
messageLabel.frame =CGRectMake(0.0,0.0, expectedSizeMessage.width, expectedSizeMessage.height);
}
// titleLabel frame values
CGFloat titleWidth, titleHeight, titleTop, titleLeft;
if(titleLabel !=nil) {
titleWidth = titleLabel.bounds.size.width;
titleHeight = titleLabel.bounds.size.height;
titleTop =CSToastVerticalPadding;
titleLeft = imageLeft + imageWidth +CSToastHorizontalPadding;
} else {
titleWidth = titleHeight = titleTop = titleLeft =0.0;
}
// messageLabel frame values
CGFloat messageWidth, messageHeight, messageLeft, messageTop;
if(messageLabel !=nil) {
messageWidth = messageLabel.bounds.size.width;
messageHeight = messageLabel.bounds.size.height;
messageLeft = imageLeft + imageWidth +CSToastHorizontalPadding;
messageTop = titleTop + titleHeight +CSToastVerticalPadding;
} else {
messageWidth = messageHeight = messageLeft = messageTop =0.0;
}
CGFloat longerWidth =MAX(titleWidth, messageWidth);
CGFloat longerLeft =MAX(titleLeft, messageLeft);
// wrapper width uses the longerWidth or the image width, whatever is larger. same logic applies to the wrapper height
CGFloat wrapperWidth =MAX((imageWidth + (CSToastHorizontalPadding *2)), (longerLeft + longerWidth + CSToastHorizontalPadding));
CGFloat wrapperHeight =MAX((messageTop + messageHeight + CSToastVerticalPadding), (imageHeight + (CSToastVerticalPadding *2)));
wrapperView.frame =CGRectMake(0.0,0.0, wrapperWidth, wrapperHeight);
if(titleLabel !=nil) {
titleLabel.frame =CGRectMake(titleLeft, titleTop, titleWidth, titleHeight);
[wrapperView addSubview:titleLabel];
}
if(messageLabel !=nil) {
messageLabel.frame =CGRectMake(messageLeft, messageTop, messageWidth, messageHeight);
[wrapperView addSubview:messageLabel];
}
if(imageView !=nil) {
[wrapperView addSubview:imageView];
}
return wrapperView;
}
@end
//
// ToastDisplay.h
// 这个class就是直接在屏幕中央打印游戏信息 (内容提示,错误提示)
@interface ToastDisplay :NSObject
{
NSMutableArray *_displays;
}
+(ToastDisplay *) sharedToastDisplay;
// 0 = 白色; 1 = 红色
+ (void)showToast:(NSString *)message withColorType:(int)colorType;
@end
//
// ToastDisplay.m
#import "ToastDisplay.h"
#import "KeyUILabel.h"
/*
* CONFIGURE THESE VALUES TO ADJUST LOOK & FEEL,
* DISPLAY DURATION, ETC.
*/
// general appearance
staticconst CGFloat CSToastVerticalPadding =60.0;
staticconst CGFloat CSToastHeight =20.0;
staticconst CGFloat CSToastFontSize =13.0;
staticconst CGFloat CSToastMaxTitleLines =0;
staticconst CGFloat CSToastMaxMessageLines =0;
staticconst CGFloat CSToastFadeDuration =0.2;
staticconst CGFloat CSToastMoveDuration =0.1;
staticconst CGFloat CSToastPosition =15.0;
staticconst CGFloat CSToastDelay =0.0;
// display duration and position
staticconst CGFloat CSToastDefaultDuration =10.0;
@implementation ToastDisplay
SYNTHESIZE_SINGLETON_FOR_CLASS(ToastDisplay)
- (id) init
{
self = [superinit];
if (self) {
_displays = [[NSMutableArrayalloc] init];
}
return self;
}
- (void) dealloc
{
[_displaysrelease];
[superdealloc];
}
#pragma mark -
#pragma mark Public method
#pragma mark -
+ (void)showToast:(NSString *)message withColorType:(int)colorType;
{
if (message ==nil) {
return;
}
[[ToastDisplaysharedToastDisplay] show:[[ToastDisplaysharedToastDisplay] makeViewOfMessage:messagewithColorType:colorType]];
}
#pragma mark -
#pragma mark Private method
#pragma mark -
- (KeyUILabel *)makeViewOfMessage:(NSString *)msg withColorType:(int)colorType
{
// 如果还有其他的view正在
[selfreposition];
KeyUILabel * messageLabel = [[KeyUILabelalloc] initWithFrame:CGRectMake(0,0, [CCDirectorsharedDirector].view.bounds.size.width,CSToastHeight * Content_Size)];
messageLabel.autoresizingMask = (UIViewAutoresizingFlexibleLeftMargin |UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin);
[_displaysaddObject:messageLabel];
[messageLabel release];
messageLabel.center =CGPointMake([CCDirectorsharedDirector].view.bounds.size.width/2, ([CCDirector sharedDirector].view.bounds.size.height - ([CCDirector sharedDirector].view.frame.size.height / 2) - CSToastVerticalPadding * Content_Size));
messageLabel.numberOfLines =CSToastMaxMessageLines;
messageLabel.font = [UIFontsystemFontOfSize:CSToastFontSize *Content_Size];
messageLabel.lineBreakMode =NSLineBreakByWordWrapping;
if (colorType ==1)
{
messageLabel.textColor = [UIColorwhiteColor];
}
elseif (colorType == 2)
{
messageLabel.textColor = [UIColorredColor];
}
messageLabel.textAlignment =NSTextAlignmentCenter;
messageLabel.backgroundColor = [UIColorclearColor];
messageLabel.alpha =1.0;
messageLabel.text = msg;
return messageLabel;
}
- (void)reposition
{
CCLOG(@"display size...%d", [_displayscount]);
for (KeyUILabel * tin _displays) {
// [UIView animateWithDuration:CSToastMoveDuration animations:^{
//
// }];
CCLOG(@"view y...%f", t.frame.origin.y);
[t setFrame:CGRectMake (t.frame.origin.x, (t.frame.origin.y - (CSToastPosition *Content_Size)), t.frame.size.width, t.frame.size.height)];
CCLOG(@"after view y...%f\n----------------", t.frame.origin.y);
}
}
- (void)show:(KeyUILabel *)toast{
toast.alpha =0.0;
[[CCDirectorsharedDirector].viewinsertSubview:toastatIndex:INFINITY];
[UIViewanimateWithDuration:CSToastFadeDuration
delay:0.0
options:UIViewAnimationOptionCurveEaseOut
animations:^{
toast.alpha =1.0;
} completion:^(BOOL finished) {
[UIViewanimateWithDuration:CSToastFadeDuration+0.3f
delay:CSToastDefaultDuration
options:UIViewAnimationOptionCurveEaseIn
animations:^{
toast.alpha =0.0;
}completion:^(BOOL finished) {
[_displaysremoveObject:toast]; //把当前的view在array里面移除;
[toastremoveFromSuperview];
}];
}];
}
@end