forked from github/Toast-PhoneGap-Plugin
452 lines
20 KiB
Objective-C
452 lines
20 KiB
Objective-C
#import "Toast+UIView.h"
|
|
#import <QuartzCore/QuartzCore.h>
|
|
#import <objc/runtime.h>
|
|
|
|
/*
|
|
* CONFIGURE THESE VALUES TO ADJUST LOOK & FEEL,
|
|
* DISPLAY DURATION, ETC.
|
|
*/
|
|
|
|
// general appearance
|
|
static const CGFloat CSToastMaxWidth = 0.8; // 80% of parent view width
|
|
static const CGFloat CSToastMaxHeight = 0.8; // 80% of parent view height
|
|
static const CGFloat CSToastHorizontalPadding = 16.0;
|
|
static const CGFloat CSToastVerticalPadding = 12.0;
|
|
static const CGFloat CSToastTopBottomOffset = 20.0;
|
|
static const CGFloat CSToastCornerRadius = 20.0;
|
|
static const CGFloat CSToastOpacity = 0.8;
|
|
static const CGFloat CSToastFontSize = 13.0;
|
|
static const CGFloat CSToastMaxTitleLines = 0;
|
|
static const CGFloat CSToastMaxMessageLines = 0;
|
|
static const NSTimeInterval CSToastFadeDuration = 0.3;
|
|
|
|
// shadow appearance
|
|
static const CGFloat CSToastShadowOpacity = 0.8;
|
|
static const CGFloat CSToastShadowRadius = 6.0;
|
|
static const CGSize CSToastShadowOffset = { 4.0, 4.0 };
|
|
static const BOOL CSToastDisplayShadow = YES;
|
|
|
|
// display duration and position
|
|
static const NSString * CSToastDefaultPosition = @"bottom";
|
|
static const NSTimeInterval CSToastDefaultDuration = 3.0;
|
|
|
|
// image view size
|
|
static const CGFloat CSToastImageViewWidth = 80.0;
|
|
static const CGFloat CSToastImageViewHeight = 80.0;
|
|
|
|
// activity
|
|
static const CGFloat CSToastActivityWidth = 100.0;
|
|
static const CGFloat CSToastActivityHeight = 100.0;
|
|
static const NSString * CSToastActivityDefaultPosition = @"center";
|
|
|
|
// interaction
|
|
static const BOOL CSToastHidesOnTap = YES; // excludes activity views
|
|
|
|
// associative reference keys
|
|
static const NSString * CSToastTimerKey = @"CSToastTimerKey";
|
|
static const NSString * CSToastActivityViewKey = @"CSToastActivityViewKey";
|
|
|
|
static UIView *prevToast = NULL;
|
|
|
|
// doesn't matter these are static
|
|
static id commandDelegate;
|
|
static id callbackId;
|
|
static id msg;
|
|
static id data;
|
|
static id styling;
|
|
|
|
@interface UIView (ToastPrivate)
|
|
|
|
- (void)hideToast:(UIView *)toast;
|
|
- (void)toastTimerDidFinish:(NSTimer *)timer;
|
|
- (void)handleToastTapped:(UITapGestureRecognizer *)recognizer;
|
|
- (CGPoint)centerPointForPosition:(id)position withToast:(UIView *)toast withAddedPixelsY:(int) addPixelsY;
|
|
- (UIView *)viewForMessage:(NSString *)message title:(NSString *)title image:(UIImage *)image;
|
|
- (CGSize)sizeForString:(NSString *)string font:(UIFont *)font constrainedToSize:(CGSize)constrainedSize lineBreakMode:(NSLineBreakMode)lineBreakMode;
|
|
@end
|
|
|
|
|
|
@implementation UIView (Toast)
|
|
|
|
|
|
#pragma mark - Toast Methods
|
|
|
|
- (void)makeToast:(NSString *)message {
|
|
[self makeToast:message duration:CSToastDefaultDuration position:CSToastDefaultPosition];
|
|
}
|
|
|
|
- (void)makeToast:(NSString *)message duration:(NSTimeInterval)duration position:(id)position {
|
|
UIView *toast = [self viewForMessage:message title:nil image:nil];
|
|
[self showToast:toast duration:duration position:position];
|
|
}
|
|
|
|
- (void)makeToast:(NSString *)message
|
|
duration:(NSTimeInterval)duration
|
|
position:(id)position addPixelsY:(int)addPixelsY
|
|
data:(NSDictionary*)_data
|
|
styling:(NSDictionary*)_styling
|
|
commandDelegate:(id <CDVCommandDelegate>)_commandDelegate
|
|
callbackId:(NSString *)_callbackId {
|
|
|
|
commandDelegate = _commandDelegate;
|
|
callbackId = _callbackId;
|
|
msg = message;
|
|
data = _data;
|
|
styling = _styling;
|
|
|
|
UIView *toast = [self viewForMessage:message title:nil image:nil];
|
|
[self showToast:toast duration:duration position:position addedPixelsY:addPixelsY];
|
|
}
|
|
|
|
- (void)makeToast:(NSString *)message duration:(NSTimeInterval)duration position:(id)position title:(NSString *)title {
|
|
UIView *toast = [self viewForMessage:message title:title image:nil];
|
|
[self showToast:toast duration:duration position:position];
|
|
}
|
|
|
|
- (void)makeToast:(NSString *)message duration:(NSTimeInterval)duration position:(id)position image:(UIImage *)image {
|
|
UIView *toast = [self viewForMessage:message title:nil image:image];
|
|
[self showToast:toast duration:duration position:position];
|
|
}
|
|
|
|
- (void)makeToast:(NSString *)message duration:(NSTimeInterval)duration position:(id)position title:(NSString *)title image:(UIImage *)image {
|
|
UIView *toast = [self viewForMessage:message title:title image:image];
|
|
[self showToast:toast duration:duration position:position];
|
|
}
|
|
|
|
- (void)showToast:(UIView *)toast {
|
|
[self showToast:toast duration:CSToastDefaultDuration position:CSToastDefaultPosition];
|
|
}
|
|
|
|
- (void)showToast:(UIView *)toast duration:(NSTimeInterval)duration position:(id)point {
|
|
[self showToast:toast duration:CSToastDefaultDuration position:CSToastDefaultPosition addedPixelsY:0];
|
|
}
|
|
|
|
- (void)showToast:(UIView *)toast duration:(NSTimeInterval)duration position:(id)point addedPixelsY:(int) addPixelsY {
|
|
[self hideToast];
|
|
prevToast = toast;
|
|
toast.center = [self centerPointForPosition:point withToast:toast withAddedPixelsY:addPixelsY];
|
|
toast.alpha = 0.0;
|
|
|
|
// note that we changed this to be always true
|
|
if (CSToastHidesOnTap) {
|
|
UITapGestureRecognizer *recognizer = [[UITapGestureRecognizer alloc] initWithTarget:toast action:@selector(handleToastTapped:)];
|
|
[toast addGestureRecognizer:recognizer];
|
|
toast.userInteractionEnabled = YES;
|
|
toast.exclusiveTouch = YES;
|
|
}
|
|
|
|
// make sure that if InAppBrowser is active, we're still showing Toasts on top of it
|
|
UIViewController *vc = [self getTopMostViewController];
|
|
UIView *v = [vc view];
|
|
[v addSubview:toast];
|
|
|
|
NSNumber * opacity = styling[@"opacity"];
|
|
CGFloat theOpacity = opacity == nil ? CSToastOpacity : [opacity floatValue];
|
|
|
|
[UIView animateWithDuration:CSToastFadeDuration
|
|
delay:0.0
|
|
options:(UIViewAnimationOptionCurveEaseOut | UIViewAnimationOptionAllowUserInteraction)
|
|
animations:^{
|
|
toast.alpha = theOpacity;
|
|
} completion:^(BOOL finished) {
|
|
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:duration target:self selector:@selector(toastTimerDidFinish:) userInfo:toast repeats:NO];
|
|
// associate the timer with the toast view
|
|
objc_setAssociatedObject (toast, &CSToastTimerKey, timer, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
|
|
}];
|
|
|
|
}
|
|
|
|
- (UIViewController*) getTopMostViewController {
|
|
UIViewController *presentingViewController = [[[UIApplication sharedApplication] delegate] window].rootViewController;
|
|
while (presentingViewController.presentedViewController != nil) {
|
|
presentingViewController = presentingViewController.presentedViewController;
|
|
}
|
|
return presentingViewController;
|
|
}
|
|
|
|
- (void)hideToast {
|
|
if (prevToast){
|
|
[self hideToast:prevToast];
|
|
}
|
|
}
|
|
|
|
- (void)hideToast:(UIView *)toast {
|
|
[UIView animateWithDuration:CSToastFadeDuration
|
|
delay:0.0
|
|
options:(UIViewAnimationOptionCurveEaseIn | UIViewAnimationOptionBeginFromCurrentState)
|
|
animations:^{
|
|
toast.alpha = 0.0;
|
|
} completion:^(BOOL finished) {
|
|
[toast removeFromSuperview];
|
|
}];
|
|
}
|
|
|
|
#pragma mark - Events
|
|
|
|
- (void)toastTimerDidFinish:(NSTimer *)timer {
|
|
[self hideToast:(UIView *)timer.userInfo];
|
|
}
|
|
|
|
- (void)handleToastTapped:(UITapGestureRecognizer *)recognizer {
|
|
NSTimer *timer = (NSTimer *)objc_getAssociatedObject(self, &CSToastTimerKey);
|
|
[timer invalidate];
|
|
|
|
[self hideToast:recognizer.view];
|
|
|
|
// also send an event back to JS
|
|
NSMutableDictionary *dict = [[NSMutableDictionary alloc] initWithObjectsAndKeys:msg, @"message", @"touch", @"event", nil];
|
|
if (data != nil) {
|
|
[dict setObject:data forKey:@"data"];
|
|
}
|
|
|
|
CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:dict];
|
|
[commandDelegate sendPluginResult:pluginResult callbackId:callbackId];
|
|
}
|
|
|
|
#pragma mark - Toast Activity Methods
|
|
|
|
- (void)makeToastActivity {
|
|
[self makeToastActivity:CSToastActivityDefaultPosition];
|
|
}
|
|
|
|
- (void)makeToastActivity:(id)position {
|
|
// sanity
|
|
UIView *existingActivityView = (UIView *)objc_getAssociatedObject(self, &CSToastActivityViewKey);
|
|
if (existingActivityView != nil) return;
|
|
|
|
UIView *activityView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, CSToastActivityWidth, CSToastActivityHeight)];
|
|
activityView.center = [self centerPointForPosition:position withToast:activityView withAddedPixelsY:0];
|
|
activityView.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:CSToastOpacity];
|
|
activityView.alpha = 0.0;
|
|
activityView.autoresizingMask = (UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin);
|
|
activityView.layer.cornerRadius = CSToastCornerRadius;
|
|
|
|
if (CSToastDisplayShadow) {
|
|
activityView.layer.shadowColor = [UIColor blackColor].CGColor;
|
|
activityView.layer.shadowOpacity = CSToastShadowOpacity;
|
|
activityView.layer.shadowRadius = CSToastShadowRadius;
|
|
activityView.layer.shadowOffset = CSToastShadowOffset;
|
|
}
|
|
|
|
UIActivityIndicatorView *activityIndicatorView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
|
|
activityIndicatorView.center = CGPointMake(activityView.bounds.size.width / 2, activityView.bounds.size.height / 2);
|
|
[activityView addSubview:activityIndicatorView];
|
|
[activityIndicatorView startAnimating];
|
|
|
|
// associate the activity view with self
|
|
objc_setAssociatedObject (self, &CSToastActivityViewKey, activityView, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
|
|
|
|
[self addSubview:activityView];
|
|
|
|
[UIView animateWithDuration: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) {
|
|
[UIView animateWithDuration:CSToastFadeDuration
|
|
delay:0.0
|
|
options:(UIViewAnimationOptionCurveEaseIn | UIViewAnimationOptionBeginFromCurrentState)
|
|
animations:^{
|
|
existingActivityView.alpha = 0.0;
|
|
} completion:^(BOOL finished) {
|
|
[existingActivityView removeFromSuperview];
|
|
objc_setAssociatedObject (self, &CSToastActivityViewKey, nil, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
|
|
}];
|
|
}
|
|
}
|
|
|
|
#pragma mark - Helpers
|
|
|
|
- (CGPoint)centerPointForPosition:(id)point withToast:(UIView *)toast withAddedPixelsY:(int) addPixelsY {
|
|
if([point isKindOfClass:[NSString class]]) {
|
|
// 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) + addPixelsY + CSToastVerticalPadding + CSToastTopBottomOffset);
|
|
} else if([point caseInsensitiveCompare:@"bottom"] == NSOrderedSame) {
|
|
return CGPointMake(self.bounds.size.width/2, (self.bounds.size.height - (toast.frame.size.height / 2)) - CSToastVerticalPadding - CSToastTopBottomOffset + addPixelsY);
|
|
} else if([point caseInsensitiveCompare:@"center"] == NSOrderedSame) {
|
|
return CGPointMake(self.bounds.size.width / 2, (self.bounds.size.height / 2) + addPixelsY);
|
|
}
|
|
} else if ([point isKindOfClass:[NSValue class]]) {
|
|
return [point CGPointValue];
|
|
}
|
|
|
|
NSLog(@"Warning: Invalid position for toast.");
|
|
return [self centerPointForPosition:CSToastDefaultPosition withToast:toast withAddedPixelsY:addPixelsY];
|
|
}
|
|
|
|
- (CGSize)sizeForString:(NSString *)string font:(UIFont *)font constrainedToSize:(CGSize)constrainedSize lineBreakMode:(NSLineBreakMode)lineBreakMode {
|
|
if ([string respondsToSelector:@selector(boundingRectWithSize:options:attributes:context:)]) {
|
|
NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
|
|
paragraphStyle.lineBreakMode = lineBreakMode;
|
|
NSDictionary *attributes = @{NSFontAttributeName:font, NSParagraphStyleAttributeName:paragraphStyle};
|
|
CGRect boundingRect = [string boundingRectWithSize:constrainedSize options:NSStringDrawingUsesLineFragmentOrigin attributes:attributes context:nil];
|
|
return CGSizeMake(ceilf(boundingRect.size.width), ceilf(boundingRect.size.height));
|
|
}
|
|
|
|
#pragma clang diagnostic push
|
|
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
|
return [string sizeWithFont:font constrainedToSize:constrainedSize lineBreakMode:lineBreakMode];
|
|
#pragma clang diagnostic pop
|
|
}
|
|
|
|
- (UIView *)viewForMessage:(NSString *)message title:(NSString *)title image:(UIImage *)image {
|
|
// sanity
|
|
if((message == nil) && (title == nil) && (image == nil)) return nil;
|
|
|
|
// dynamically build a toast view with any combination of message, title, & image.
|
|
UILabel *messageLabel = nil;
|
|
UILabel *titleLabel = nil;
|
|
UIImageView *imageView = nil;
|
|
|
|
// create the parent view
|
|
UIView *wrapperView = [[UIView alloc] init];
|
|
wrapperView.autoresizingMask = (UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin);
|
|
|
|
NSNumber * cornerRadius = styling[@"cornerRadius"];
|
|
wrapperView.layer.cornerRadius = cornerRadius == nil ? CSToastCornerRadius : [cornerRadius floatValue];
|
|
|
|
if (CSToastDisplayShadow) {
|
|
wrapperView.layer.shadowColor = [UIColor blackColor].CGColor;
|
|
wrapperView.layer.shadowOpacity = CSToastShadowOpacity;
|
|
wrapperView.layer.shadowRadius = CSToastShadowRadius;
|
|
wrapperView.layer.shadowOffset = CSToastShadowOffset;
|
|
}
|
|
|
|
NSString * backgroundColor = styling[@"backgroundColor"];
|
|
UIColor *theColor = backgroundColor == nil ? [UIColor blackColor] : [self colorFromHexString:backgroundColor];
|
|
|
|
NSNumber * horizontalPadding = styling[@"horizontalPadding"];
|
|
CGFloat theHorizontalPadding = horizontalPadding == nil ? CSToastHorizontalPadding : [horizontalPadding floatValue];
|
|
|
|
NSNumber * verticalPadding = styling[@"verticalPadding"];
|
|
CGFloat theVerticalPadding = verticalPadding == nil ? CSToastVerticalPadding : [verticalPadding floatValue];
|
|
|
|
NSNumber * textSize = styling[@"textSize"];
|
|
CGFloat theTextSize = textSize == nil ? CSToastFontSize : [textSize floatValue];
|
|
|
|
wrapperView.backgroundColor = theColor;
|
|
|
|
if(image != nil) {
|
|
imageView = [[UIImageView alloc] initWithImage:image];
|
|
imageView.contentMode = UIViewContentModeScaleAspectFit;
|
|
imageView.frame = CGRectMake(theHorizontalPadding, theVerticalPadding, 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 = theHorizontalPadding;
|
|
} else {
|
|
imageWidth = imageHeight = imageLeft = 0.0;
|
|
}
|
|
|
|
if (title != nil) {
|
|
NSString * titleLabelTextColor = styling[@"textColor"];
|
|
UIColor *theTitleLabelTextColor = titleLabelTextColor == nil ? [UIColor whiteColor] : [self colorFromHexString:titleLabelTextColor];
|
|
|
|
titleLabel = [[UILabel alloc] init];
|
|
titleLabel.numberOfLines = CSToastMaxTitleLines;
|
|
titleLabel.font = [UIFont boldSystemFontOfSize:theTextSize];
|
|
titleLabel.textAlignment = NSTextAlignmentLeft;
|
|
titleLabel.lineBreakMode = NSLineBreakByWordWrapping;
|
|
titleLabel.textColor = theTitleLabelTextColor;
|
|
titleLabel.backgroundColor = [UIColor clearColor];
|
|
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 = [self sizeForString:title font:titleLabel.font constrainedToSize:maxSizeTitle lineBreakMode:titleLabel.lineBreakMode];
|
|
titleLabel.frame = CGRectMake(0.0, 0.0, expectedSizeTitle.width, expectedSizeTitle.height);
|
|
}
|
|
|
|
if (message != nil) {
|
|
NSString * messageLabelTextColor = styling[@"textColor"];
|
|
UIColor *theMessageLabelTextColor = messageLabelTextColor == nil ? [UIColor whiteColor] : [self colorFromHexString:messageLabelTextColor];
|
|
|
|
messageLabel = [[UILabel alloc] init];
|
|
messageLabel.numberOfLines = CSToastMaxMessageLines;
|
|
messageLabel.font = [UIFont systemFontOfSize:theTextSize];
|
|
messageLabel.lineBreakMode = NSLineBreakByWordWrapping;
|
|
messageLabel.textColor = theMessageLabelTextColor;
|
|
messageLabel.backgroundColor = [UIColor clearColor];
|
|
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 = [self sizeForString:message font:messageLabel.font constrainedToSize: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 = theVerticalPadding;
|
|
titleLeft = imageLeft + imageWidth + theHorizontalPadding;
|
|
} 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 + theHorizontalPadding;
|
|
messageTop = titleTop + titleHeight + theVerticalPadding;
|
|
} 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 + (theHorizontalPadding * 2)), (longerLeft + longerWidth + theHorizontalPadding));
|
|
CGFloat wrapperHeight = MAX((messageTop + messageHeight + theVerticalPadding), (imageHeight + (theVerticalPadding * 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;
|
|
}
|
|
|
|
// Assumes input like "#00FF00" (#RRGGBB)
|
|
- (UIColor*) colorFromHexString:(NSString*) hexString {
|
|
unsigned rgbValue = 0;
|
|
NSScanner *scanner = [NSScanner scannerWithString:hexString];
|
|
[scanner setScanLocation:1]; // bypass '#' character
|
|
[scanner scanHexInt:&rgbValue];
|
|
return [UIColor colorWithRed:((rgbValue & 0xFF0000) >> 16) / 255.0 green:((rgbValue & 0xFF00) >> 8) / 255.0 blue:(rgbValue & 0xFF) / 255.0 alpha:1.0];
|
|
}
|
|
|
|
@end
|