diff --git a/README.md b/README.md index d35bb02..ecb89d6 100644 --- a/README.md +++ b/README.md @@ -18,4 +18,48 @@ import Toast from 'react-native-simple-toast'; Toast.show('This is a toast.'); Toast.show('This is a long toast.',Toast.LONG); -``` \ No newline at end of file +``` +## Options + +Toast was been able to make customizable through these properties + +```javascript +{ + width:300, + height:50, + backgroundColor: "#C2F8FF", + color: "#ffffff", + borderWidth: 3, + borderColor: "#C2F8FF", + borderRadius: 3 +} + +``` +if you want to make a customizable toast,you add an object like above to `show` and `showGravity` + +#### Example usage: + +```javascript +import Toast from 'react-native-simple-toast'; +const style={ + width:300, + height:50, + backgroundColor: "#C2F8FF", + color: "#ffffff", + borderWidth: 3, + borderColor: "#C2F8FF", + borderRadius: 3 + }; +Toast.show('This is a long toast.',Toast.LONG,style); + + +Toast.showWithGravity(message, Toast.SHORT,Toast.TOP,style) +``` +These are properties that can make customizable +`width`, +`height`, +`backgroundColor`, +`color`, +`borderColor`, +`borderWidth` +You can make customizable all of them or some of them or you can use default toast style. \ No newline at end of file diff --git a/index.js b/index.js index ec70f07..5619c92 100644 --- a/index.js +++ b/index.js @@ -3,29 +3,31 @@ import {NativeModules,ToastAndroid,Platform} from 'react-native'; var RCTToastAndroid = Platform.OS === 'android' ? ToastAndroid : NativeModules.LRDRCTSimpleToast; var SimpleToast = { - // Toast duration constants - SHORT: RCTToastAndroid.SHORT, - LONG: RCTToastAndroid.LONG, + // Toast duration constants + SHORT: RCTToastAndroid.SHORT, + LONG: RCTToastAndroid.LONG, - // Toast gravity constants - TOP: RCTToastAndroid.TOP, - BOTTOM: RCTToastAndroid.BOTTOM, - CENTER: RCTToastAndroid.CENTER, + // Toast gravity constants + TOP: RCTToastAndroid.TOP, + BOTTOM: RCTToastAndroid.BOTTOM, + CENTER: RCTToastAndroid.CENTER, - show: function ( - message, - duration - ) { - RCTToastAndroid.show(message, duration === undefined ? this.SHORT : duration); - }, + show: function ( + message, + duration, + customStyle + ) { + RCTToastAndroid.show(message, duration === undefined ? this.SHORT : duration,customStyle); + }, - showWithGravity: function ( - message, - duration, - gravity, - ) { - RCTToastAndroid.showWithGravity(message, duration === undefined ? this.SHORT : duration, gravity); - }, + showWithGravity: function ( + message, + duration, + gravity, + customStyle + ) { + RCTToastAndroid.showWithGravity(message, duration === undefined ? this.SHORT : duration, customStyle, gravity); + }, }; export default SimpleToast; diff --git a/ios/LRDRCTSimpleToast/LRDRCTSimpleToast.m b/ios/LRDRCTSimpleToast/LRDRCTSimpleToast.m index f78bcc5..69d33bc 100644 --- a/ios/LRDRCTSimpleToast/LRDRCTSimpleToast.m +++ b/ios/LRDRCTSimpleToast/LRDRCTSimpleToast.m @@ -65,17 +65,45 @@ - (NSDictionary *)constantsToExport { }; } -RCT_EXPORT_METHOD(show:(NSString *)msg duration:(double)duration { - [self _show:msg duration:duration gravity:LRDRCTSimpleToastGravityBottom]; +RCT_EXPORT_METHOD(show:(NSString *)msg duration:(double)duration customStyle:(NSDictionary *)customStyle { + [self _show:msg duration:duration customStyle:customStyle gravity:LRDRCTSimpleToastGravityBottom]; }); -RCT_EXPORT_METHOD(showWithGravity:(NSString *)msg duration:(double)duration gravity:(nonnull NSNumber *)gravity{ - [self _show:msg duration:duration gravity:gravity.intValue]; +RCT_EXPORT_METHOD(showWithGravity:(NSString *)msg duration:(double)duration customStyle:(NSDictionary *)customStyle gravity:(nonnull NSNumber *)gravity{ + [self _show:msg duration:duration customStyle:customStyle gravity:gravity.intValue]; }); -- (void)_show:(NSString *)msg duration:(NSTimeInterval)duration gravity:(NSInteger)gravity { +- (UIViewController *)visibleViewController:(UIViewController *)rootViewController +{ + if (rootViewController.presentedViewController == nil) + { + return rootViewController; + } + if ([rootViewController.presentedViewController isKindOfClass:[UINavigationController class]]) + { + UINavigationController *navigationController = (UINavigationController *)rootViewController.presentedViewController; + UIViewController *lastViewController = [[navigationController viewControllers] lastObject]; + + return [self visibleViewController:lastViewController]; + } + if ([rootViewController.presentedViewController isKindOfClass:[UITabBarController class]]) + { + UITabBarController *tabBarController = (UITabBarController *)rootViewController.presentedViewController; + UIViewController *selectedViewController = tabBarController.selectedViewController; + + return [self visibleViewController:selectedViewController]; + } + + UIViewController *presentedViewController = (UIViewController *)rootViewController.presentedViewController; + + return [self visibleViewController:presentedViewController]; +} + +- (void)_show:(NSString *)msg duration:(NSTimeInterval)duration customStyle:(NSDictionary *)customStyle gravity:(NSInteger)gravity { dispatch_async(dispatch_get_main_queue(), ^{ - UIView *root = [[[[[UIApplication sharedApplication] delegate] window] rootViewController] view]; + //UIView *root = [[[[[UIApplication sharedApplication] delegate] window] rootViewController] view]; + UIViewController *ctrl = [self visibleViewController:[UIApplication sharedApplication].keyWindow.rootViewController]; + UIView *root = [ctrl view]; CGRect bound = root.bounds; bound.size.height -= _keyOffset; if (bound.size.height > LRDRCTSimpleToastBottomOffset*2) { @@ -97,6 +125,7 @@ - (void)_show:(NSString *)msg duration:(NSTimeInterval)duration gravity:(NSInteg [view makeToast:msg duration:duration position:position + customStyle:customStyle title:nil image:nil style:nil diff --git a/ios/LRDRCTSimpleToast/UIView+Toast.h b/ios/LRDRCTSimpleToast/UIView+Toast.h index f518b13..91bbae6 100755 --- a/ios/LRDRCTSimpleToast/UIView+Toast.h +++ b/ios/LRDRCTSimpleToast/UIView+Toast.h @@ -59,32 +59,36 @@ extern const NSString * CSToastPositionBottom; @param duration The toast duration @param position The toast's center point. Can be one of the predefined CSToastPosition constants or a `CGPoint` wrapped in an `NSValue` object. + @param customStyle The toast customizable style */ - (void)makeToast:(NSString *)message duration:(NSTimeInterval)duration - position:(id)position; + position:(id)position + customStyle:(NSDictionary *)customStyle; /** Creates and presents a new toast view with a message. Duration, position, and style can be set explicitly. - + @param message The message to be displayed @param duration The toast duration @param position The toast's center point. Can be one of the predefined CSToastPosition constants or a `CGPoint` wrapped in an `NSValue` object. @param style The style. The shared style will be used when nil + @param customStyle The style.The toast customizable style when not nil */ - (void)makeToast:(NSString *)message duration:(NSTimeInterval)duration position:(id)position + customStyle:(NSDictionary *)customStyle style:(CSToastStyle *)style; /** Creates and presents a new toast view with a message, title, and image. Duration, position, and style can be set explicitly. The completion block executes when the - toast view completes. `didTap` will be `YES` if the toast view was dismissed from + toast view completes. `didTap` will be `YES` if the toast view was dismissed from a tap. - + @param message The message to be displayed @param duration The toast duration @param position The toast's center point. Can be one of the predefined CSToastPosition @@ -92,12 +96,14 @@ extern const NSString * CSToastPositionBottom; @param title The title @param image The image @param style The style. The shared style will be used when nil + @param customStyle The style.The toast customizable style when not nil @param completion The completion block, executed after the toast view disappears. didTap will be `YES` if the toast view was dismissed from a tap. */ - (void)makeToast:(NSString *)message duration:(NSTimeInterval)duration position:(id)position + customStyle:(NSDictionary *)customStyle title:(NSString *)title image:(UIImage *)image style:(CSToastStyle *)style @@ -108,30 +114,32 @@ extern const NSString * CSToastPositionBottom; The look and feel is configured via the style. Unlike the `makeToast:` methods, this method does not present the toast view automatically. One of the showToast: methods must be used to present the resulting view. - + @warning if message, title, and image are all nil, this method will return nil. - + @param message The message to be displayed @param title The title @param image The image @param style The style. The shared style will be used when nil + @param customStyle The style.The toast customizable style when not nil @return The newly created toast view */ - (UIView *)toastViewForMessage:(NSString *)message + customStyle:(NSDictionary *)customStyle title:(NSString *)title image:(UIImage *)image style:(CSToastStyle *)style; /** Creates and displays a new toast activity indicator view at a specified position. - + @warning Only one toast activity indicator view can be presented per superview. Subsequent calls to `makeToastActivity:` will be ignored until hideToastActivity is called. - + @warning `makeToastActivity:` works independently of the showToast: methods. Toast activity views can be presented and dismissed while toast views are being displayed. `makeToastActivity:` has no effect on the queueing behavior of the showToast: methods. - + @param position The toast's center point. Can be one of the predefined CSToastPosition constants or a `CGPoint` wrapped in an `NSValue` object. */ @@ -144,26 +152,28 @@ extern const NSString * CSToastPositionBottom; /** Displays any view as toast using the default duration and position. - + @param toast The view to be displayed as toast */ - (void)showToast:(UIView *)toast; /** - Displays any view as toast at a provided position and duration. The completion block - executes when the toast view completes. `didTap` will be `YES` if the toast view was + Displays any view as toast at a provided position and duration. The completion block + executes when the toast view completes. `didTap` will be `YES` if the toast view was dismissed from a tap. - + @param toast The view to be displayed as toast @param duration The notification duration @param position The toast's center point. Can be one of the predefined CSToastPosition constants or a `CGPoint` wrapped in an `NSValue` object. @param completion The completion block, executed after the toast view disappears. didTap will be `YES` if the toast view was dismissed from a tap. + @param customStyle The toast customizable style. */ - (void)showToast:(UIView *)toast duration:(NSTimeInterval)duration position:(id)position + customStyle:(NSDictionary *)customStyle completion:(void(^)(BOOL didTap))completion; @end diff --git a/ios/LRDRCTSimpleToast/UIView+Toast.m b/ios/LRDRCTSimpleToast/UIView+Toast.m index 89bfcda..82b8fc3 100755 --- a/ios/LRDRCTSimpleToast/UIView+Toast.m +++ b/ios/LRDRCTSimpleToast/UIView+Toast.m @@ -45,9 +45,9 @@ @interface UIView (ToastPrivate) /** - These private methods are being prefixed with "cs_" to reduce the likelihood of non-obvious + These private methods are being prefixed with "cs_" to reduce the likelihood of non-obvious naming conflicts with other UIView methods. - + @discussion Should the public API also use the cs_ prefix? Technically it should, but it results in code that is less legible. The current public method names seem unlikely to cause conflicts so I think we should favor the cleaner API for now. @@ -67,67 +67,67 @@ @implementation UIView (Toast) #pragma mark - Make Toast Methods - (void)makeToast:(NSString *)message { - [self makeToast:message duration:[CSToastManager defaultDuration] position:[CSToastManager defaultPosition] style:nil]; + [self makeToast:message duration:[CSToastManager defaultDuration] position:[CSToastManager defaultPosition] customStyle:nil style:nil]; } -- (void)makeToast:(NSString *)message duration:(NSTimeInterval)duration position:(id)position { - [self makeToast:message duration:duration position:position style:nil]; +- (void)makeToast:(NSString *)message duration:(NSTimeInterval)duration position:(id)position customStyle:(NSDictionary *)customStyle { + [self makeToast:message duration:duration position:position customStyle:customStyle style:nil]; } -- (void)makeToast:(NSString *)message duration:(NSTimeInterval)duration position:(id)position style:(CSToastStyle *)style { - UIView *toast = [self toastViewForMessage:message title:nil image:nil style:style]; - [self showToast:toast duration:duration position:position completion:nil]; +- (void)makeToast:(NSString *)message duration:(NSTimeInterval)duration position:(id)position customStyle:(NSDictionary *)customStyle style:(CSToastStyle *)style { + UIView *toast = [self toastViewForMessage:message customStyle:customStyle title:nil image:nil style:style]; + [self showToast:toast duration:duration position:position customStyle:customStyle completion:nil]; } -- (void)makeToast:(NSString *)message duration:(NSTimeInterval)duration position:(id)position title:(NSString *)title image:(UIImage *)image style:(CSToastStyle *)style completion:(void(^)(BOOL didTap))completion { - UIView *toast = [self toastViewForMessage:message title:title image:image style:style]; - [self showToast:toast duration:duration position:position completion:completion]; +- (void)makeToast:(NSString *)message duration:(NSTimeInterval)duration position:(id)position customStyle:(NSDictionary *)customStyle title:(NSString *)title image:(UIImage *)image style:(CSToastStyle *)style completion:(void(^)(BOOL didTap))completion { + UIView *toast = [self toastViewForMessage:message customStyle:customStyle title:title image:image style:style]; + [self showToast:toast duration:duration position:position customStyle:customStyle completion:completion]; } #pragma mark - Show Toast Methods - (void)showToast:(UIView *)toast { - [self showToast:toast duration:[CSToastManager defaultDuration] position:[CSToastManager defaultPosition] completion:nil]; + [self showToast:toast duration:[CSToastManager defaultDuration] position:[CSToastManager defaultPosition] customStyle:nil completion:nil]; } -- (void)showToast:(UIView *)toast duration:(NSTimeInterval)duration position:(id)position completion:(void(^)(BOOL didTap))completion { +- (void)showToast:(UIView *)toast duration:(NSTimeInterval)duration position:(id)position customStyle:(NSDictionary *)customStyle completion:(void(^)(BOOL didTap))completion { // sanity if (toast == nil) return; - + // store the completion block on the toast view objc_setAssociatedObject(toast, &CSToastCompletionKey, completion, OBJC_ASSOCIATION_RETAIN_NONATOMIC); - + if ([CSToastManager isQueueEnabled] && objc_getAssociatedObject(self, &CSToastActiveToastViewKey) != nil) { // we're about to queue this toast view so we need to store the duration and position as well objc_setAssociatedObject(toast, &CSToastDurationKey, @(duration), OBJC_ASSOCIATION_RETAIN_NONATOMIC); objc_setAssociatedObject(toast, &CSToastPositionKey, position, OBJC_ASSOCIATION_RETAIN_NONATOMIC); - + // enqueue [self.cs_toastQueue addObject:toast]; } else { // present - [self cs_showToast:toast duration:duration position:position]; + [self cs_showToast:toast duration:duration position:position customStyle:customStyle]; } } #pragma mark - Private Show/Hide Methods -- (void)cs_showToast:(UIView *)toast duration:(NSTimeInterval)duration position:(id)position { +- (void)cs_showToast:(UIView *)toast duration:(NSTimeInterval)duration position:(id)position customStyle:(NSDictionary *)customStyle { toast.center = [self cs_centerPointForPosition:position withToast:toast]; toast.alpha = 0.0; - + if ([CSToastManager isTapToDismissEnabled]) { UITapGestureRecognizer *recognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(cs_handleToastTapped:)]; [toast addGestureRecognizer:recognizer]; toast.userInteractionEnabled = YES; toast.exclusiveTouch = YES; } - + // set the active toast objc_setAssociatedObject(self, &CSToastActiveToastViewKey, toast, OBJC_ASSOCIATION_RETAIN_NONATOMIC); - + [self addSubview:toast]; - + [UIView animateWithDuration:[[CSToastManager sharedStyle] fadeDuration] delay:0.0 options:(UIViewAnimationOptionCurveEaseOut | UIViewAnimationOptionAllowUserInteraction) @@ -143,7 +143,7 @@ - (void)cs_showToast:(UIView *)toast duration:(NSTimeInterval)duration position: - (void)cs_hideToast:(UIView *)toast { [self cs_hideToast:toast fromTap:NO]; } - + - (void)cs_hideToast:(UIView *)toast fromTap:(BOOL)fromTap { [UIView animateWithDuration:[[CSToastManager sharedStyle] fadeDuration] delay:0.0 @@ -152,21 +152,21 @@ - (void)cs_hideToast:(UIView *)toast fromTap:(BOOL)fromTap { toast.alpha = 0.0; } completion:^(BOOL finished) { [toast removeFromSuperview]; - + // clear the active toast objc_setAssociatedObject(self, &CSToastActiveToastViewKey, nil, OBJC_ASSOCIATION_RETAIN_NONATOMIC); - + // execute the completion block, if necessary void (^completion)(BOOL didTap) = objc_getAssociatedObject(toast, &CSToastCompletionKey); if (completion) { completion(fromTap); } - + if ([self.cs_toastQueue count] > 0) { // dequeue UIView *nextToast = [[self cs_toastQueue] firstObject]; [[self cs_toastQueue] removeObjectAtIndex:0]; - + // present the next toast NSTimeInterval duration = [objc_getAssociatedObject(nextToast, &CSToastDurationKey) doubleValue]; id position = objc_getAssociatedObject(nextToast, &CSToastPositionKey); @@ -174,51 +174,69 @@ - (void)cs_hideToast:(UIView *)toast fromTap:(BOOL)fromTap { } }]; } +/* + This method created because of hex color convert to UIColor type. + */ +- (UIColor *)stringColorConvertoUIColor:(NSString *)color { + unsigned int c; + if ([color characterAtIndex:0] == '#') { + [[NSScanner scannerWithString:[color substringFromIndex:1]] scanHexInt:&c]; + } else { + [[NSScanner scannerWithString:color] scanHexInt:&c]; + } + return [UIColor colorWithRed:((c & 0xff0000) >> 16)/255.0 green:((c & 0xff00) >> 8)/255.0 blue:(c & 0xff)/255.0 alpha:1.0]; +} #pragma mark - View Construction -- (UIView *)toastViewForMessage:(NSString *)message title:(NSString *)title image:(UIImage *)image style:(CSToastStyle *)style { +- (UIView *)toastViewForMessage:(NSString *)message customStyle:(NSDictionary *)customStyle title:(NSString *)title image:(UIImage *)image style:(CSToastStyle *)style { // sanity - if(message == nil && title == nil && image == nil) return nil; - + if(message == nil && title == nil && image == nil && customStyle == nil) return nil; + // default to the shared style if (style == nil) { style = [CSToastManager sharedStyle]; } - + // dynamically build a toast view with any combination of message, title, & image UILabel *messageLabel = nil; UILabel *titleLabel = nil; UIImageView *imageView = nil; - + UIColor *textColor; + struct CGColor *borderColor=nil; + struct CGColor *backgroundColor=nil; + float borderWidth=1.0; + float borderRadius=1.0; + float width=0.0; + float height=0.0; UIView *wrapperView = [[UIView alloc] init]; wrapperView.autoresizingMask = (UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin); wrapperView.layer.cornerRadius = style.cornerRadius; - + if (style.displayShadow) { wrapperView.layer.shadowColor = style.shadowColor.CGColor; wrapperView.layer.shadowOpacity = style.shadowOpacity; wrapperView.layer.shadowRadius = style.shadowRadius; wrapperView.layer.shadowOffset = style.shadowOffset; } - - wrapperView.backgroundColor = style.backgroundColor; - + + wrapperView.backgroundColor = [UIColor clearColor]; + if(image != nil) { imageView = [[UIImageView alloc] initWithImage:image]; imageView.contentMode = UIViewContentModeScaleAspectFit; imageView.frame = CGRectMake(style.horizontalPadding, style.verticalPadding, style.imageSize.width, style.imageSize.height); } - + CGRect imageRect = CGRectZero; - + if(imageView != nil) { imageRect.origin.x = style.horizontalPadding; imageRect.origin.y = style.verticalPadding; imageRect.size.width = imageView.bounds.size.width; imageRect.size.height = imageView.bounds.size.height; } - + if (title != nil) { titleLabel = [[UILabel alloc] init]; titleLabel.numberOfLines = style.titleNumberOfLines; @@ -229,7 +247,7 @@ - (UIView *)toastViewForMessage:(NSString *)message title:(NSString *)title imag 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 * style.maxWidthPercentage) - imageRect.size.width, self.bounds.size.height * style.maxHeightPercentage); CGSize expectedSizeTitle = [titleLabel sizeThatFits:maxSizeTitle]; @@ -237,66 +255,124 @@ - (UIView *)toastViewForMessage:(NSString *)message title:(NSString *)title imag expectedSizeTitle = CGSizeMake(MIN(maxSizeTitle.width, expectedSizeTitle.width), MIN(maxSizeTitle.height, expectedSizeTitle.height)); titleLabel.frame = CGRectMake(0.0, 0.0, expectedSizeTitle.width, expectedSizeTitle.height); } - + if(customStyle && customStyle[@"color"]){ + textColor=[self stringColorConvertoUIColor:customStyle[@"color"]]; + } + if(customStyle && !customStyle[@"color"]){ + textColor=style.messageColor; + } + if(customStyle && customStyle[@"borderColor"]){ + borderColor=[self stringColorConvertoUIColor:customStyle[@"borderColor"]].CGColor; + } + if(customStyle && !customStyle[@"borderColor"]){ + borderColor=[UIColor clearColor].CGColor; + } + if(customStyle && customStyle[@"borderWidth"]){ + borderWidth=(float)[customStyle[@"borderWidth"] floatValue]; + } + if(customStyle && !customStyle[@"borderWidth"]){ + borderWidth=0; + } + if(customStyle && customStyle[@"borderRadius"]){ + borderRadius=(float)[customStyle[@"borderRadius"] floatValue]; + } + if(customStyle && !customStyle[@"borderRadius"]){ + borderRadius=0; + } + if(customStyle && customStyle[@"backgroundColor"]){ + backgroundColor=[self stringColorConvertoUIColor:customStyle[@"backgroundColor"]].CGColor; + } + if(customStyle && !customStyle[@"backgroundColor"]){ + backgroundColor=style.backgroundColor.CGColor; + } + if(customStyle && customStyle[@"width"]){ + width=[customStyle[@"width"] floatValue]; + } + + if(!customStyle){ + textColor=style.messageColor; + borderColor=[UIColor clearColor].CGColor; + borderWidth=0; + borderRadius=0; + backgroundColor=style.backgroundColor.CGColor; + } if (message != nil) { - messageLabel = [[UILabel alloc] init]; + messageLabel=[[UILabel alloc] init]; messageLabel.numberOfLines = style.messageNumberOfLines; messageLabel.font = style.messageFont; - messageLabel.textAlignment = style.messageAlignment; + messageLabel.textAlignment =style.messageAlignment; messageLabel.lineBreakMode = NSLineBreakByTruncatingTail; - messageLabel.textColor = style.messageColor; + messageLabel.textColor =textColor; + messageLabel.layer.borderColor = borderColor; + messageLabel.layer.borderWidth=borderWidth; + messageLabel.layer.cornerRadius=borderRadius; + messageLabel.layer.backgroundColor = backgroundColor; messageLabel.backgroundColor = [UIColor clearColor]; messageLabel.alpha = 1.0; messageLabel.text = message; - + CGSize maxSizeMessage = CGSizeMake((self.bounds.size.width * style.maxWidthPercentage) - imageRect.size.width, self.bounds.size.height * style.maxHeightPercentage); CGSize expectedSizeMessage = [messageLabel sizeThatFits:maxSizeMessage]; // UILabel can return a size larger than the max size when the number of lines is 1 expectedSizeMessage = CGSizeMake(MIN(maxSizeMessage.width, expectedSizeMessage.width), MIN(maxSizeMessage.height, expectedSizeMessage.height)); messageLabel.frame = CGRectMake(0.0, 0.0, expectedSizeMessage.width, expectedSizeMessage.height); } - + CGRect titleRect = CGRectZero; - + + if(customStyle && !customStyle[@"width"]){ + width=messageLabel.bounds.size.width; + } + if(customStyle && customStyle[@"height"]){ + height=[customStyle[@"height"] floatValue]; + } + if(customStyle && !customStyle[@"height"]){ + height=messageLabel.bounds.size.height; + } + if(!customStyle){ + width=messageLabel.bounds.size.width; + height=messageLabel.bounds.size.height; + } + if(titleLabel != nil) { titleRect.origin.x = imageRect.origin.x + imageRect.size.width + style.horizontalPadding; titleRect.origin.y = style.verticalPadding; titleRect.size.width = titleLabel.bounds.size.width; titleRect.size.height = titleLabel.bounds.size.height; } - + CGRect messageRect = CGRectZero; - + if(messageLabel != nil) { messageRect.origin.x = imageRect.origin.x + imageRect.size.width + style.horizontalPadding; messageRect.origin.y = titleRect.origin.y + titleRect.size.height + style.verticalPadding; - messageRect.size.width = messageLabel.bounds.size.width; - messageRect.size.height = messageLabel.bounds.size.height; + messageRect.size.width = width; + messageRect.size.height = height; } - + CGFloat longerWidth = MAX(titleRect.size.width, messageRect.size.width); CGFloat longerX = MAX(titleRect.origin.x, messageRect.origin.x); - + // Wrapper width uses the longerWidth or the image width, whatever is larger. Same logic applies to the wrapper height. CGFloat wrapperWidth = MAX((imageRect.size.width + (style.horizontalPadding * 2.0)), (longerX + longerWidth + style.horizontalPadding)); CGFloat wrapperHeight = MAX((messageRect.origin.y + messageRect.size.height + style.verticalPadding), (imageRect.size.height + (style.verticalPadding * 2.0))); - + wrapperView.frame = CGRectMake(0.0, 0.0, wrapperWidth, wrapperHeight); - + if(titleLabel != nil) { titleLabel.frame = titleRect; [wrapperView addSubview:titleLabel]; } - + if(messageLabel != nil) { messageLabel.frame = messageRect; [wrapperView addSubview:messageLabel]; } - + if(imageView != nil) { [wrapperView addSubview:imageView]; } - + return wrapperView; } @@ -321,7 +397,7 @@ - (void)cs_handleToastTapped:(UITapGestureRecognizer *)recognizer { UIView *toast = recognizer.view; NSTimer *timer = (NSTimer *)objc_getAssociatedObject(toast, &CSToastTimerKey); [timer invalidate]; - + [self cs_hideToast:toast fromTap:YES]; } @@ -331,33 +407,33 @@ - (void)makeToastActivity:(id)position { // sanity UIView *existingActivityView = (UIView *)objc_getAssociatedObject(self, &CSToastActivityViewKey); if (existingActivityView != nil) return; - + CSToastStyle *style = [CSToastManager sharedStyle]; - + UIView *activityView = [[UIView alloc] initWithFrame:CGRectMake(0.0, 0.0, style.activitySize.width, style.activitySize.height)]; activityView.center = [self cs_centerPointForPosition:position withToast:activityView]; activityView.backgroundColor = style.backgroundColor; activityView.alpha = 0.0; activityView.autoresizingMask = (UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin); activityView.layer.cornerRadius = style.cornerRadius; - + if (style.displayShadow) { activityView.layer.shadowColor = style.shadowColor.CGColor; activityView.layer.shadowOpacity = style.shadowOpacity; activityView.layer.shadowRadius = style.shadowRadius; activityView.layer.shadowOffset = style.shadowOffset; } - + 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:style.fadeDuration delay:0.0 options:UIViewAnimationOptionCurveEaseOut @@ -385,7 +461,7 @@ - (void)hideToastActivity { - (CGPoint)cs_centerPointForPosition:(id)point withToast:(UIView *)toast { CSToastStyle *style = [CSToastManager sharedStyle]; - + if([point isKindOfClass:[NSString class]]) { if([point caseInsensitiveCompare:CSToastPositionTop] == NSOrderedSame) { return CGPointMake(self.bounds.size.width/2, (toast.frame.size.height / 2) + style.verticalPadding); @@ -395,7 +471,7 @@ - (CGPoint)cs_centerPointForPosition:(id)point withToast:(UIView *)toast { } else if ([point isKindOfClass:[NSValue class]]) { return [point CGPointValue]; } - + // default to bottom return CGPointMake(self.bounds.size.width/2, (self.bounds.size.height - (toast.frame.size.height / 2)) - style.verticalPadding); } @@ -419,8 +495,8 @@ - (instancetype)initWithDefaultStyle { self.cornerRadius = 10.0; self.titleFont = [UIFont boldSystemFontOfSize:16.0]; self.messageFont = [UIFont systemFontOfSize:16.0]; - self.titleAlignment = NSTextAlignmentLeft; - self.messageAlignment = NSTextAlignmentLeft; + self.titleAlignment = NSTextAlignmentCenter; + self.messageAlignment = NSTextAlignmentCenter; self.titleNumberOfLines = 0; self.messageNumberOfLines = 0; self.displayShadow = NO;