├── LICENSE.txt ├── README.md ├── iToast.h ├── iToast.m └── iToast.podspec /LICENSE.txt: -------------------------------------------------------------------------------- 1 | MIT LICENSE 2 | 3 | Copyright (c) 2012 Guru Software 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # What is iToast 4 | 5 | This page tells you what toast notifications are and why you may need them in your iPhone/iPad application. 6 | 7 | *** 8 | 9 | If you develop already for Android, then you know what it is so you can skip to the next section. 10 | 11 | For the others of us: a toast is a spécial way to display 'non intrusive' message to the user. Those message are displayed on a configurable place on the screen and they disapear after a configurable time interval. The way they appear is similar to the way the Growl app (on mac do). 12 | 13 | 14 | # Difference between iToast and Toast on Android 15 | 16 | * The iToasts disapear when tapped by the user even if the configured time is not elapsed. 17 | * iToasts can have an image-icon attached to them (info, warning, error). 18 | * There is application wide configuration object that you can use so that all your iToast looks the same. 19 | * We are planning to add a plug-in based system so that we can offer many look'n feel for the toasts instead of the default. 20 | * iToast advertise the chaining of call so that you can create any toast with any configuration in on instruction. 21 | 22 | # Benefits of using Toast 23 | 24 | Some benefits are: 25 | 26 | * The user is not distracted by such alert and just notice them: he don't need to click "Ok". As a rule of thumb we use iToast now everywhere we would have put a UIAlertView with only a single Button. 27 | * You can add it anywhere on the screen depending of the importance of the iToast. We display them with a gravity of *Top* when it is of medium importance, *Center* when it is *Very importan* an Bottom when it is of low importance. 28 | # How to use iToast. 29 | 30 | # Simple Usage 31 | 32 | There is only one way to create an iToast: so you won't need to retain much. In it basic form, you create an iToast this way: 33 | 34 | 35 | [[iToast makeText:NSLocalizedString(@"The activity has been successfully saved.", @"")] show]; 36 | 37 | 38 | 39 | # Chaining calls 40 | Like in jQuery, you can chain call and terminate by using the *show* method, there are many things you can configure. Look bellow. 41 | 42 | 43 | 44 | [[[iToast makeText:NSLocalizedString(@"The activity has been successfully saved.", @"")] 45 | setGravity:iToastGravityBottom] show]; 46 | 47 | 48 | 49 | Note : Above the gravity can be any of `iToastGravityBottom`, `iToastGravityTop`, `iToastGravityCenter`. 50 | 51 | * You can also provide the a physical position on the screen: see the class interface. 52 | * You can provide two offset value that will be added to the actual position of the iToast: you can use this to either move it a few pixel to the left (negative *offsetLeft*), right (positive *offsetLeft*), top or bottom. 53 | 54 | Or 55 | 56 | 57 | [[[[iToast makeText:NSLocalizedString(@"Something to display a very long time", @"")] 58 | setGravity:iToastGravityBottom] setDuration:iToastDurationLong] show]; 59 | 60 | 61 | *Note :* Above the duration can be any integer (the number of millisecond to display it). There is Three preset you can use for duration: 62 | 63 | * iToastDurationLong 64 | * iToastDurationShort 65 | * iToastDurationNormal 66 | 67 | ## The Interface 68 | 69 | 70 | @interface iToast : NSObject { 71 | iToastSettings *_settings; 72 | NSInteger offsetLeft; 73 | NSInteger offsetTop; 74 | 75 | NSTimer *timer; 76 | 77 | UIView *view; 78 | NSString *text; 79 | } 80 | 81 | - (void) show; 82 | 83 | - (iToast *) setDuration:(NSInteger ) duration; 84 | - (iToast *) setGravity:(iToastGravity) gravity 85 | offsetLeft:(NSInteger) left 86 | offsetTop:(NSInteger) top; 87 | - (iToast *) setGravity:(iToastGravity) gravity; 88 | - (iToast *) setPostion:(CGPoint) position; 89 | 90 | + (iToast *) makeText:(NSString *) text; 91 | 92 | -(iToastSettings *) theSettings; 93 | 94 | @end 95 | 96 | 97 | # The Shared Settings 98 | 99 | You don't need to set all the settings each time you want to show an iToast. There is a shared settings repo that each iToast copy it setting when first created. 100 | 101 | To modify the shared setting, you first obtain the shared settings like: 102 | 103 | iToastSettings *theSettings = [iToastSettings getSharedSettings]; 104 | 105 | 106 | Then you change the settings: 107 | 108 | 109 | theSettings.duration = 4000; 110 | 111 | 112 | ## The interface of the SharedSettings 113 | 114 | @interface iToastSettings : NSObject{ 115 | NSInteger duration; 116 | iToastGravity gravity; 117 | CGPoint postition; 118 | iToastType toastType; 119 | 120 | NSDictionary *images; 121 | 122 | BOOL positionIsSet; 123 | } 124 | 125 | 126 | @property(assign) NSInteger duration; 127 | @property(assign) iToastGravity gravity; 128 | @property(assign) CGPoint postition; 129 | @property(readonly) NSDictionary *images; 130 | 131 | 132 | - (void) setImage:(UIImage *)img forType:(iToastType) type; 133 | + (iToastSettings *) getSharedSettings; 134 | 135 | @end 136 | 137 | 138 | 139 | # Not yet implemented 140 | 141 | You are interested by those features? write the code and share with the community. 142 | 143 | * Display of icons based of the type of iToast. 144 | * Plugin based interface to customize the toasts. 145 | 146 | 147 | Showing your appreciation 148 | ========================= 149 | A few people already requested it, so now it's here: a Flattr button. 150 | 151 | [![Flattr this][2]][1] 152 | 153 | [1]: http://flattr.com/thing/852846/toast-notifications-ios 154 | [2]: http://api.flattr.com/button/button-static-50x60.png 155 | -------------------------------------------------------------------------------- /iToast.h: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | iToast.h 4 | 5 | MIT LICENSE 6 | 7 | Copyright (c) 2012 Guru Software 8 | 9 | Permission is hereby granted, free of charge, to any person obtaining a copy 10 | of this software and associated documentation files (the "Software"), to deal 11 | in the Software without restriction, including without limitation the rights 12 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | copies of the Software, and to permit persons to whom the Software is 14 | furnished to do so, subject to the following conditions: 15 | 16 | The above copyright notice and this permission notice shall be included in 17 | all copies or substantial portions of the Software. 18 | 19 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | THE SOFTWARE. 26 | */ 27 | 28 | #import 29 | #import 30 | 31 | typedef enum iToastGravity { 32 | iToastGravityTop = 1000001, 33 | iToastGravityBottom, 34 | iToastGravityCenter 35 | }iToastGravity; 36 | 37 | typedef enum iToastDuration { 38 | iToastDurationLong = 10000, 39 | iToastDurationShort = 1000, 40 | iToastDurationNormal = 3000 41 | }iToastDuration; 42 | 43 | typedef enum iToastType { 44 | iToastTypeInfo = -100000, 45 | iToastTypeNotice, 46 | iToastTypeWarning, 47 | iToastTypeError, 48 | iToastTypeNone // For internal use only (to force no image) 49 | }iToastType; 50 | 51 | typedef enum { 52 | iToastImageLocationTop, 53 | iToastImageLocationLeft 54 | } iToastImageLocation; 55 | 56 | 57 | @class iToastSettings; 58 | 59 | @interface iToast : NSObject { 60 | iToastSettings *_settings; 61 | 62 | NSTimer *timer; 63 | 64 | UIView *view; 65 | NSString *text; 66 | } 67 | 68 | - (void) show; 69 | - (void) show:(iToastType) type; 70 | - (iToast *) setDuration:(NSInteger ) duration; 71 | - (iToast *) setGravity:(iToastGravity) gravity 72 | offsetLeft:(NSInteger) left 73 | offsetTop:(NSInteger) top; 74 | - (iToast *) setGravity:(iToastGravity) gravity; 75 | - (iToast *) setPostion:(CGPoint) position; 76 | - (iToast *) setFontSize:(CGFloat) fontSize; 77 | - (iToast *) setUseShadow:(BOOL) useShadow; 78 | - (iToast *) setCornerRadius:(CGFloat) cornerRadius; 79 | - (iToast *) setBgRed:(CGFloat) bgRed; 80 | - (iToast *) setBgGreen:(CGFloat) bgGreen; 81 | - (iToast *) setBgBlue:(CGFloat) bgBlue; 82 | - (iToast *) setBgAlpha:(CGFloat) bgAlpha; 83 | 84 | + (iToast *) makeText:(NSString *) text; 85 | 86 | -(iToastSettings *) theSettings; 87 | 88 | @end 89 | 90 | 91 | 92 | @interface iToastSettings : NSObject{ 93 | NSInteger duration; 94 | iToastGravity gravity; 95 | CGPoint postition; 96 | iToastType toastType; 97 | CGFloat fontSize; 98 | BOOL useShadow; 99 | CGFloat cornerRadius; 100 | CGFloat bgRed; 101 | CGFloat bgGreen; 102 | CGFloat bgBlue; 103 | CGFloat bgAlpha; 104 | NSInteger offsetLeft; 105 | NSInteger offsetTop; 106 | 107 | NSDictionary *images; 108 | 109 | BOOL positionIsSet; 110 | } 111 | 112 | 113 | @property(assign) NSInteger duration; 114 | @property(assign) iToastGravity gravity; 115 | @property(assign) CGPoint postition; 116 | @property(assign) CGFloat fontSize; 117 | @property(assign) BOOL useShadow; 118 | @property(assign) CGFloat cornerRadius; 119 | @property(assign) CGFloat bgRed; 120 | @property(assign) CGFloat bgGreen; 121 | @property(assign) CGFloat bgBlue; 122 | @property(assign) CGFloat bgAlpha; 123 | @property(assign) NSInteger offsetLeft; 124 | @property(assign) NSInteger offsetTop; 125 | @property(readonly) NSDictionary *images; 126 | @property(assign) iToastImageLocation imageLocation; 127 | 128 | 129 | - (void) setImage:(UIImage *)img forType:(iToastType) type; 130 | - (void) setImage:(UIImage *)img withLocation:(iToastImageLocation)location forType:(iToastType)type; 131 | + (iToastSettings *) getSharedSettings; 132 | 133 | @end -------------------------------------------------------------------------------- /iToast.m: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | iToast.m 4 | 5 | MIT LICENSE 6 | 7 | Copyright (c) 2011 Guru Software 8 | 9 | Permission is hereby granted, free of charge, to any person obtaining a copy 10 | of this software and associated documentation files (the "Software"), to deal 11 | in the Software without restriction, including without limitation the rights 12 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | copies of the Software, and to permit persons to whom the Software is 14 | furnished to do so, subject to the following conditions: 15 | 16 | The above copyright notice and this permission notice shall be included in 17 | all copies or substantial portions of the Software. 18 | 19 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | THE SOFTWARE. 26 | 27 | */ 28 | 29 | 30 | #import "iToast.h" 31 | #import 32 | 33 | #define CURRENT_TOAST_TAG 6984678 34 | 35 | static const CGFloat kComponentPadding = 5; 36 | 37 | static iToastSettings *sharedSettings = nil; 38 | 39 | @interface iToast(private) 40 | 41 | - (iToast *) settings; 42 | - (CGRect)_toastFrameForImageSize:(CGSize)imageSize withLocation:(iToastImageLocation)location andTextSize:(CGSize)textSize; 43 | - (CGRect)_frameForImage:(iToastType)type inToastFrame:(CGRect)toastFrame; 44 | 45 | @end 46 | 47 | 48 | @implementation iToast 49 | 50 | 51 | - (id) initWithText:(NSString *) tex{ 52 | if (self = [super init]) { 53 | text = [tex copy]; 54 | } 55 | 56 | return self; 57 | } 58 | 59 | - (void) show{ 60 | [self show:iToastTypeNone]; 61 | } 62 | 63 | - (void) show:(iToastType) type { 64 | 65 | iToastSettings *theSettings = _settings; 66 | 67 | if (!theSettings) { 68 | theSettings = [iToastSettings getSharedSettings]; 69 | } 70 | 71 | UIImage *image = [theSettings.images valueForKey:[NSString stringWithFormat:@"%i", type]]; 72 | 73 | UIFont *font = [UIFont systemFontOfSize:theSettings.fontSize]; 74 | 75 | NSAttributedString *attributedText =[[NSAttributedString alloc] initWithString:text attributes:@{ NSFontAttributeName: font}]; 76 | CGRect rect = [attributedText boundingRectWithSize:CGSizeMake(280, 60) 77 | options:NSStringDrawingUsesLineFragmentOrigin 78 | context:nil]; 79 | CGSize textSize = rect.size; 80 | 81 | UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, textSize.width + kComponentPadding, textSize.height + kComponentPadding)]; 82 | label.backgroundColor = [UIColor clearColor]; 83 | label.textColor = [UIColor whiteColor]; 84 | label.font = font; 85 | label.text = text; 86 | label.numberOfLines = 0; 87 | if (theSettings.useShadow) { 88 | label.shadowColor = [UIColor darkGrayColor]; 89 | label.shadowOffset = CGSizeMake(1, 1); 90 | } 91 | 92 | UIButton *v = [UIButton buttonWithType:UIButtonTypeCustom]; 93 | if (image) { 94 | v.frame = [self _toastFrameForImageSize:image.size withLocation:[theSettings imageLocation] andTextSize:textSize]; 95 | 96 | switch ([theSettings imageLocation]) { 97 | case iToastImageLocationLeft: 98 | [label setTextAlignment:NSTextAlignmentLeft]; 99 | label.center = CGPointMake(image.size.width + kComponentPadding * 2 100 | + (v.frame.size.width - image.size.width - kComponentPadding * 2) / 2, 101 | v.frame.size.height / 2); 102 | break; 103 | case iToastImageLocationTop: 104 | [label setTextAlignment:NSTextAlignmentCenter]; 105 | label.center = CGPointMake(v.frame.size.width / 2, 106 | (image.size.height + kComponentPadding * 2 107 | + (v.frame.size.height - image.size.height - kComponentPadding * 2) / 2)); 108 | break; 109 | default: 110 | break; 111 | } 112 | 113 | } else { 114 | v.frame = CGRectMake(0, 0, textSize.width + kComponentPadding * 2, textSize.height + kComponentPadding * 2); 115 | label.center = CGPointMake(v.frame.size.width / 2, v.frame.size.height / 2); 116 | } 117 | CGRect lbfrm = label.frame; 118 | lbfrm.origin.x = ceil(lbfrm.origin.x); 119 | lbfrm.origin.y = ceil(lbfrm.origin.y); 120 | label.frame = lbfrm; 121 | [v addSubview:label]; 122 | [label release]; 123 | 124 | if (image) { 125 | UIImageView *imageView = [[UIImageView alloc] initWithImage:image]; 126 | imageView.frame = [self _frameForImage:type inToastFrame:v.frame]; 127 | [v addSubview:imageView]; 128 | [imageView release]; 129 | } 130 | 131 | v.backgroundColor = [UIColor colorWithRed:theSettings.bgRed green:theSettings.bgGreen blue:theSettings.bgBlue alpha:theSettings.bgAlpha]; 132 | v.layer.cornerRadius = theSettings.cornerRadius; 133 | 134 | UIWindow *window = [[[UIApplication sharedApplication] windows] objectAtIndex:0]; 135 | 136 | CGPoint point = CGPointZero; 137 | 138 | // Set correct orientation/location regarding device orientation 139 | UIInterfaceOrientation orientation = (UIInterfaceOrientation)[[UIApplication sharedApplication] statusBarOrientation]; 140 | double version = [[[UIDevice currentDevice] systemVersion] doubleValue]; 141 | switch (orientation) { 142 | case UIDeviceOrientationPortrait: 143 | { 144 | if (theSettings.gravity == iToastGravityTop) { 145 | point = CGPointMake(window.frame.size.width / 2, 45); 146 | } else if (theSettings.gravity == iToastGravityBottom) { 147 | point = CGPointMake(window.frame.size.width / 2, window.frame.size.height - 45); 148 | } else if (theSettings.gravity == iToastGravityCenter) { 149 | point = CGPointMake(window.frame.size.width/2, window.frame.size.height/2); 150 | } else { 151 | point = theSettings.postition; 152 | } 153 | 154 | point = CGPointMake(point.x + theSettings.offsetLeft, point.y + theSettings.offsetTop); 155 | break; 156 | } 157 | case UIDeviceOrientationPortraitUpsideDown: 158 | { 159 | if (version < 8.0) { 160 | v.transform = CGAffineTransformMakeRotation(M_PI); 161 | } 162 | 163 | float width = window.frame.size.width; 164 | float height = window.frame.size.height; 165 | 166 | if (theSettings.gravity == iToastGravityTop) { 167 | point = CGPointMake(width / 2, height - 45); 168 | } else if (theSettings.gravity == iToastGravityBottom) { 169 | point = CGPointMake(width / 2, 45); 170 | } else if (theSettings.gravity == iToastGravityCenter) { 171 | point = CGPointMake(width/2, height/2); 172 | } else { 173 | // TODO : handle this case 174 | point = theSettings.postition; 175 | } 176 | 177 | point = CGPointMake(point.x - theSettings.offsetLeft, point.y - theSettings.offsetTop); 178 | break; 179 | } 180 | case UIDeviceOrientationLandscapeLeft: 181 | { 182 | if (version < 8.0) { 183 | v.transform = CGAffineTransformMakeRotation(M_PI/2); //rotation in radians 184 | } 185 | 186 | if (theSettings.gravity == iToastGravityTop) { 187 | point = CGPointMake(window.frame.size.width - 45, window.frame.size.height / 2); 188 | } else if (theSettings.gravity == iToastGravityBottom) { 189 | point = CGPointMake(45,window.frame.size.height / 2); 190 | } else if (theSettings.gravity == iToastGravityCenter) { 191 | point = CGPointMake(window.frame.size.width/2, window.frame.size.height/2); 192 | } else { 193 | // TODO : handle this case 194 | point = theSettings.postition; 195 | } 196 | 197 | point = CGPointMake(point.x - theSettings.offsetTop, point.y - theSettings.offsetLeft); 198 | break; 199 | } 200 | case UIDeviceOrientationLandscapeRight: 201 | { 202 | if (version < 8.0) { 203 | v.transform = CGAffineTransformMakeRotation(-M_PI/2); 204 | } 205 | 206 | if (theSettings.gravity == iToastGravityTop) { 207 | point = CGPointMake(45, window.frame.size.height / 2); 208 | } else if (theSettings.gravity == iToastGravityBottom) { 209 | point = CGPointMake(window.frame.size.width - 45, window.frame.size.height/2); 210 | } else if (theSettings.gravity == iToastGravityCenter) { 211 | point = CGPointMake(window.frame.size.width/2, window.frame.size.height/2); 212 | } else { 213 | // TODO : handle this case 214 | point = theSettings.postition; 215 | } 216 | 217 | point = CGPointMake(point.x + theSettings.offsetTop, point.y + theSettings.offsetLeft); 218 | break; 219 | } 220 | default: 221 | break; 222 | } 223 | 224 | v.center = point; 225 | v.frame = CGRectIntegral(v.frame); 226 | 227 | NSTimer *timer1 = [NSTimer timerWithTimeInterval:((float)theSettings.duration)/1000 228 | target:self selector:@selector(hideToast:) 229 | userInfo:nil repeats:NO]; 230 | [[NSRunLoop mainRunLoop] addTimer:timer1 forMode:NSDefaultRunLoopMode]; 231 | 232 | v.tag = CURRENT_TOAST_TAG; 233 | 234 | UIView *currentToast = [window viewWithTag:CURRENT_TOAST_TAG]; 235 | if (currentToast != nil) { 236 | [currentToast removeFromSuperview]; 237 | } 238 | 239 | v.alpha = 0; 240 | [window addSubview:v]; 241 | [UIView beginAnimations:nil context:nil]; 242 | v.alpha = 1; 243 | [UIView commitAnimations]; 244 | 245 | view = [v retain]; 246 | 247 | [v addTarget:self action:@selector(hideToast:) forControlEvents:UIControlEventTouchDown]; 248 | } 249 | 250 | - (CGRect)_toastFrameForImageSize:(CGSize)imageSize withLocation:(iToastImageLocation)location andTextSize:(CGSize)textSize { 251 | CGRect theRect = CGRectZero; 252 | switch (location) { 253 | case iToastImageLocationLeft: 254 | theRect = CGRectMake(0, 0, 255 | imageSize.width + textSize.width + kComponentPadding * 3, 256 | MAX(textSize.height, imageSize.height) + kComponentPadding * 2); 257 | break; 258 | case iToastImageLocationTop: 259 | theRect = CGRectMake(0, 0, 260 | MAX(textSize.width, imageSize.width) + kComponentPadding * 2, 261 | imageSize.height + textSize.height + kComponentPadding * 3); 262 | 263 | default: 264 | break; 265 | } 266 | return theRect; 267 | } 268 | 269 | - (CGRect)_frameForImage:(iToastType)type inToastFrame:(CGRect)toastFrame { 270 | iToastSettings *theSettings = _settings; 271 | UIImage *image = [theSettings.images valueForKey:[NSString stringWithFormat:@"%i", type]]; 272 | 273 | if (!image) return CGRectZero; 274 | 275 | CGRect imageFrame = CGRectZero; 276 | 277 | switch ([theSettings imageLocation]) { 278 | case iToastImageLocationLeft: 279 | imageFrame = CGRectMake(kComponentPadding, (toastFrame.size.height - image.size.height) / 2, image.size.width, image.size.height); 280 | break; 281 | case iToastImageLocationTop: 282 | imageFrame = CGRectMake((toastFrame.size.width - image.size.width) / 2, kComponentPadding, image.size.width, image.size.height); 283 | break; 284 | 285 | default: 286 | break; 287 | } 288 | 289 | return imageFrame; 290 | 291 | } 292 | 293 | - (void) hideToast:(NSTimer*)theTimer{ 294 | [UIView beginAnimations:nil context:NULL]; 295 | view.alpha = 0; 296 | [UIView commitAnimations]; 297 | 298 | NSTimer *timer2 = [NSTimer timerWithTimeInterval:500 299 | target:self selector:@selector(hideToast:) 300 | userInfo:nil repeats:NO]; 301 | [[NSRunLoop mainRunLoop] addTimer:timer2 forMode:NSDefaultRunLoopMode]; 302 | } 303 | 304 | - (void) removeToast:(NSTimer*)theTimer{ 305 | [view removeFromSuperview]; 306 | } 307 | 308 | 309 | + (iToast *) makeText:(NSString *) _text{ 310 | iToast *toast = [[[iToast alloc] initWithText:_text] autorelease]; 311 | 312 | return toast; 313 | } 314 | 315 | 316 | - (iToast *) setDuration:(NSInteger ) duration{ 317 | [self theSettings].duration = duration; 318 | return self; 319 | } 320 | 321 | - (iToast *) setGravity:(iToastGravity) gravity 322 | offsetLeft:(NSInteger) left 323 | offsetTop:(NSInteger) top{ 324 | [self theSettings].gravity = gravity; 325 | [self theSettings].offsetLeft = left; 326 | [self theSettings].offsetTop = top; 327 | return self; 328 | } 329 | 330 | - (iToast *) setGravity:(iToastGravity) gravity{ 331 | [self theSettings].gravity = gravity; 332 | return self; 333 | } 334 | 335 | - (iToast *) setPostion:(CGPoint) _position{ 336 | [self theSettings].postition = CGPointMake(_position.x, _position.y); 337 | 338 | return self; 339 | } 340 | 341 | - (iToast *) setFontSize:(CGFloat) fontSize{ 342 | [self theSettings].fontSize = fontSize; 343 | return self; 344 | } 345 | 346 | - (iToast *) setUseShadow:(BOOL) useShadow{ 347 | [self theSettings].useShadow = useShadow; 348 | return self; 349 | } 350 | 351 | - (iToast *) setCornerRadius:(CGFloat) cornerRadius{ 352 | [self theSettings].cornerRadius = cornerRadius; 353 | return self; 354 | } 355 | 356 | - (iToast *) setBgRed:(CGFloat) bgRed{ 357 | [self theSettings].bgRed = bgRed; 358 | return self; 359 | } 360 | 361 | - (iToast *) setBgGreen:(CGFloat) bgGreen{ 362 | [self theSettings].bgGreen = bgGreen; 363 | return self; 364 | } 365 | 366 | - (iToast *) setBgBlue:(CGFloat) bgBlue{ 367 | [self theSettings].bgBlue = bgBlue; 368 | return self; 369 | } 370 | 371 | - (iToast *) setBgAlpha:(CGFloat) bgAlpha{ 372 | [self theSettings].bgAlpha = bgAlpha; 373 | return self; 374 | } 375 | 376 | 377 | -(iToastSettings *) theSettings{ 378 | if (!_settings) { 379 | _settings = [[iToastSettings getSharedSettings] copy]; 380 | } 381 | 382 | return _settings; 383 | } 384 | 385 | @end 386 | 387 | 388 | @implementation iToastSettings 389 | @synthesize offsetLeft; 390 | @synthesize offsetTop; 391 | @synthesize duration; 392 | @synthesize gravity; 393 | @synthesize postition; 394 | @synthesize fontSize; 395 | @synthesize useShadow; 396 | @synthesize cornerRadius; 397 | @synthesize bgRed; 398 | @synthesize bgGreen; 399 | @synthesize bgBlue; 400 | @synthesize bgAlpha; 401 | @synthesize images; 402 | @synthesize imageLocation; 403 | 404 | - (void) setImage:(UIImage *) img withLocation:(iToastImageLocation)location forType:(iToastType) type { 405 | if (type == iToastTypeNone) { 406 | // This should not be used, internal use only (to force no image) 407 | return; 408 | } 409 | 410 | if (!images) { 411 | images = [[NSMutableDictionary alloc] initWithCapacity:4]; 412 | } 413 | 414 | if (img) { 415 | NSString *key = [NSString stringWithFormat:@"%i", type]; 416 | [images setValue:img forKey:key]; 417 | } 418 | 419 | [self setImageLocation:location]; 420 | } 421 | 422 | - (void)setImage:(UIImage *)img forType:(iToastType)type { 423 | [self setImage:img withLocation:iToastImageLocationLeft forType:type]; 424 | } 425 | 426 | 427 | + (iToastSettings *) getSharedSettings{ 428 | if (!sharedSettings) { 429 | sharedSettings = [iToastSettings new]; 430 | sharedSettings.gravity = iToastGravityCenter; 431 | sharedSettings.duration = iToastDurationShort; 432 | sharedSettings.fontSize = 16.0; 433 | sharedSettings.useShadow = YES; 434 | sharedSettings.cornerRadius = 5.0; 435 | sharedSettings.bgRed = 0; 436 | sharedSettings.bgGreen = 0; 437 | sharedSettings.bgBlue = 0; 438 | sharedSettings.bgAlpha = 0.7; 439 | sharedSettings.offsetLeft = 0; 440 | sharedSettings.offsetTop = 0; 441 | } 442 | 443 | return sharedSettings; 444 | 445 | } 446 | 447 | - (id) copyWithZone:(NSZone *)zone{ 448 | iToastSettings *copy = [iToastSettings new]; 449 | copy.gravity = self.gravity; 450 | copy.duration = self.duration; 451 | copy.postition = self.postition; 452 | copy.fontSize = self.fontSize; 453 | copy.useShadow = self.useShadow; 454 | copy.cornerRadius = self.cornerRadius; 455 | copy.bgRed = self.bgRed; 456 | copy.bgGreen = self.bgGreen; 457 | copy.bgBlue = self.bgBlue; 458 | copy.bgAlpha = self.bgAlpha; 459 | copy.offsetLeft = self.offsetLeft; 460 | copy.offsetTop = self.offsetTop; 461 | 462 | NSArray *keys = [self.images allKeys]; 463 | 464 | for (NSString *key in keys){ 465 | [copy setImage:[images valueForKey:key] forType:[key intValue]]; 466 | } 467 | 468 | [copy setImageLocation:imageLocation]; 469 | 470 | return copy; 471 | } 472 | 473 | @end 474 | -------------------------------------------------------------------------------- /iToast.podspec: -------------------------------------------------------------------------------- 1 | 2 | Pod::Spec.new do |s| 3 | s.name = 'iToast' 4 | s.version = "0.0.1" 5 | s.summary = 'An Objective-C iOS way to display non intrusive messages to the user like in Android.' 6 | s.homepage = 'https://github.com/ecstasy2/toast-notifications-ios' 7 | s.license = { :type => 'MIT', :file => 'LICENSE.txt' } 8 | s.author = 'DIALLO Mamadou Bobo' 9 | s.source = { :git => 'https://github.com/ecstasy2/toast-notifications-ios.git' ,:commit => '68ea9a1'} 10 | s.source_files = '*.{h,m}' 11 | s.framework = 'QuartzCore' 12 | s.requires_arc = true 13 | end 14 | --------------------------------------------------------------------------------