diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..8eecd5c --- /dev/null +++ b/.gitignore @@ -0,0 +1,28 @@ +# Xcode +# +# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore + +## Build generated +build/ +DerivedData + +## Various settings +*.pbxuser +!default.pbxuser +*.mode1v3 +!default.mode1v3 +*.mode2v3 +!default.mode2v3 +*.perspectivev3 +!default.perspectivev3 +xcuserdata + +## Other +*.xccheckout +*.moved-aside +*.xcuserstate +*.xcscmblueprint + +## Obj-C/Swift specific +*.hmap +*.ipa diff --git a/Example/DemoViewController.h b/Example/DemoViewController.h new file mode 100644 index 0000000..c4377f6 --- /dev/null +++ b/Example/DemoViewController.h @@ -0,0 +1,13 @@ +// +// DemoViewController.h +// RMessage +// +// Created by Adonis Peralta on 12/7/15. +// Copyright © 2015 Rendezvous Inc. All rights reserved. +// + +#import + +@interface DemoViewController : UIViewController + +@end diff --git a/Example/DemoViewController.m b/Example/DemoViewController.m new file mode 100644 index 0000000..feb6109 --- /dev/null +++ b/Example/DemoViewController.m @@ -0,0 +1,222 @@ +// +// DemoViewController.m +// RMessage +// +// Created by Adonis Peralta on 12/7/15. +// Copyright © 2015 Rendezvous Inc. All rights reserved. +// + +#import "DemoViewController.h" +#import "RMessage.h" +#import "RMessageView.h" + +@interface DemoViewController () + +@end + +@implementation DemoViewController + +- (void)viewDidLoad +{ + [super viewDidLoad]; + [RMessage setDefaultViewController:self]; + [RMessage setDelegate:self]; + [self.navigationController.navigationBar setTranslucent:YES]; + self.extendedLayoutIncludesOpaqueBars = YES; +} + +- (IBAction)didTapError:(id)sender +{ + [RMessage showNotificationWithTitle:NSLocalizedString(@"Something failed", nil) + subtitle:NSLocalizedString(@"The internet connection seems to be down. Please check it!", nil) + type:RMessageTypeError + customTypeString:nil]; +} + +- (IBAction)didTapWarning:(id)sender +{ + [RMessage showNotificationWithTitle:NSLocalizedString(@"Some random warning", nil) + subtitle:NSLocalizedString(@"Look out! Something is happening there!", nil) + type:RMessageTypeWarning + customTypeString:nil]; +} + +- (IBAction)didTapMessage:(id)sender +{ + [RMessage showNotificationWithTitle:NSLocalizedString(@"Tell the user something", nil) + subtitle:NSLocalizedString(@"This is some neutral notification!", nil) + type:RMessageTypeNormal + customTypeString:nil]; +} + +- (IBAction)didTapSuccess:(id)sender +{ + [RMessage showNotificationWithTitle:NSLocalizedString(@"Success", nil) + subtitle:NSLocalizedString(@"Some task was successfully completed!", nil) + type:RMessageTypeSuccess + customTypeString:nil]; +} + +- (IBAction)didTapButton:(id)sender +{ + [RMessage showNotificationInViewController:self + title:NSLocalizedString(@"New version available", nil) + subtitle:NSLocalizedString(@"Please update our app. We would be very thankful", nil) + iconImage:nil + type:RMessageTypeNormal + customTypeString:nil + duration:RMessageDurationAutomatic + callback:nil + buttonTitle:NSLocalizedString(@"Update", nil) + buttonCallback:^{ + [RMessage showNotificationWithTitle:NSLocalizedString(@"Thanks for updating", nil) + type:RMessageTypeSuccess + customTypeString:nil]; + } + atPosition:RMessagePositionTop + canBeDismissedByUser:YES]; +} + +- (IBAction)didTapToggleNavigationBar:(id)sender +{ + [self.navigationController setNavigationBarHidden:!self.navigationController.navigationBarHidden animated:YES]; +} + +- (IBAction)didTapToggleNavigationBarAlpha:(id)sender +{ + CGFloat alpha = self.navigationController.navigationBar.alpha; + self.navigationController.navigationBar.alpha = (alpha == 1.f) ? 0.5 : 1; +} + +- (IBAction)didTapToggleWantsFullscreen:(id)sender +{ + self.extendedLayoutIncludesOpaqueBars = !self.extendedLayoutIncludesOpaqueBars; + [self.navigationController.navigationBar setTranslucent:!self.navigationController.navigationBar.isTranslucent]; +} + +- (IBAction)didTapCustomImage:(id)sender +{ + [RMessage showNotificationInViewController:self + title:NSLocalizedString(@"Custom image", nil) + subtitle:NSLocalizedString(@"This uses an image you can define", nil) + iconImage:[UIImage imageNamed:@"NotificationButtonBackground.png"] + type:RMessageTypeNormal + customTypeString:nil + duration:RMessageDurationAutomatic + callback:nil + buttonTitle:nil + buttonCallback:nil + atPosition:RMessagePositionTop + canBeDismissedByUser:YES]; +} + +- (IBAction)didTapDismissCurrentMessage:(id)sender +{ + [RMessage dismissActiveNotification]; +} + +- (IBAction)didTapEndless:(id)sender +{ + [RMessage showNotificationInViewController:self + title:NSLocalizedString(@"Endless", nil) + subtitle:NSLocalizedString(@"This message can not be dismissed and will not be hidden automatically. Tap the 'Dismiss' button to dismiss the currently shown message", nil) + iconImage:nil + type:RMessageTypeSuccess + customTypeString:nil + duration:RMessageDurationEndless + callback:nil + buttonTitle:nil + buttonCallback:nil + atPosition:RMessagePositionTop + canBeDismissedByUser:NO]; +} + +- (IBAction)didTapLong:(id)sender +{ + [RMessage showNotificationInViewController:self + title:NSLocalizedString(@"Long", nil) + subtitle:NSLocalizedString(@"This message is displayed 10 seconds instead of the calculated value", nil) + iconImage:nil + type:RMessageTypeWarning + customTypeString:nil + duration:10.0 + callback:nil + buttonTitle:nil + buttonCallback:nil + atPosition:RMessagePositionTop + canBeDismissedByUser:YES]; +} + +- (IBAction)didTapBottom:(id)sender +{ + [RMessage showNotificationInViewController:self + title:NSLocalizedString(@"Hu!", nil) + subtitle:NSLocalizedString(@"I'm down here :)", nil) + iconImage:nil + type:RMessageTypeSuccess + customTypeString:nil + duration:RMessageDurationAutomatic + callback:nil + buttonTitle:nil + buttonCallback:nil + atPosition:RMessagePositionBottom + canBeDismissedByUser:YES]; +} + +- (IBAction)didTapText:(id)sender +{ + [RMessage showNotificationWithTitle:NSLocalizedString(@"With 'Text' I meant a long text, so here it is", nil) + subtitle:NSLocalizedString(@"Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus.At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus", nil) + type:RMessageTypeWarning + customTypeString:nil]; +} + +- (IBAction)didTapCustomDesign:(id)sender +{ + // this is an example on how to apply a custom design + [RMessage addCustomDesignFromFileWithName:@"AlternativeDesign"]; + [RMessage showNotificationWithTitle:NSLocalizedString(@"Updated to custom design file", nil) + subtitle:NSLocalizedString(@"From now on, all the titles of success messages are larger", nil) + type:RMessageTypeCustom + customTypeString:@"alternate-error"]; +} + + +- (IBAction)didTapNavBarOverlay:(id)sender +{ + if (self.navigationController.navigationBarHidden){ + [self.navigationController setNavigationBarHidden:NO]; + } + + [RMessage showNotificationInViewController:self.navigationController + title:NSLocalizedString(@"Whoa!", nil) + subtitle:NSLocalizedString(@"Over the Navigation Bar!", nil) + iconImage:nil + type:RMessageTypeSuccess + customTypeString:nil + duration:RMessageDurationAutomatic + callback:nil + buttonTitle:nil + buttonCallback:nil + atPosition:RMessagePositionNavBarOverlay + canBeDismissedByUser:YES]; +} + + + +//- (CGFloat)messageLocationOfMessageView:(RMessageView *)messageView +//{ +// return 44.0; // any calculation here +//} + +//- (void)customizeMessageView:(RMessageView *)messageView +//{ +// messageView.alpha = 0.5; +//} + +- (IBAction)didTapNavbarHidden:(id)sender +{ + self.navigationController.navigationBarHidden = !self.navigationController.navigationBarHidden; +} + +@end diff --git a/Example/Podfile b/Example/Podfile new file mode 100644 index 0000000..0638f8a --- /dev/null +++ b/Example/Podfile @@ -0,0 +1,4 @@ +source 'https://github.com/CocoaPods/Specs.git' +pod 'HexColors', :git => 'https://github.com/mRs-/HexColors.git' +pod 'PPTopMostController', :git => 'https://github.com/donileo/PPTopMostController.git' +pod 'RMessage', :path => '../' diff --git a/Example/Podfile.lock b/Example/Podfile.lock new file mode 100644 index 0000000..4d79dbc --- /dev/null +++ b/Example/Podfile.lock @@ -0,0 +1,34 @@ +PODS: + - HexColors (3.0.0) + - PPTopMostController (0.0.1) + - RMessage (1.0.1): + - HexColors (~> 3.0.0) + - PPTopMostController + +DEPENDENCIES: + - HexColors (from `https://github.com/mRs-/HexColors.git`) + - PPTopMostController (from `https://github.com/donileo/PPTopMostController.git`) + - RMessage (from `../`) + +EXTERNAL SOURCES: + HexColors: + :git: https://github.com/mRs-/HexColors.git + PPTopMostController: + :git: https://github.com/donileo/PPTopMostController.git + RMessage: + :path: "../" + +CHECKOUT OPTIONS: + HexColors: + :commit: aa42656d5fb8ca7942927a4d73696900d7306914 + :git: https://github.com/mRs-/HexColors.git + PPTopMostController: + :commit: 9e725746cff79a6286554d76dcce279909c327ab + :git: https://github.com/donileo/PPTopMostController.git + +SPEC CHECKSUMS: + HexColors: 8b83e3fe90c0d466dae7b98c9d22da95799f99cb + PPTopMostController: ca6c8fd33abd2895d57d86bfe27ae7425b44eea8 + RMessage: 824c881c073427bd3334716630ac4b53dbb2b6a8 + +COCOAPODS: 0.39.0 diff --git a/Example/Pods/Headers/Private/HexColors/HexColors.h b/Example/Pods/Headers/Private/HexColors/HexColors.h new file mode 120000 index 0000000..c1fa62f --- /dev/null +++ b/Example/Pods/Headers/Private/HexColors/HexColors.h @@ -0,0 +1 @@ +../../../HexColors/Classes/HexColors.h \ No newline at end of file diff --git a/Example/Pods/Headers/Private/PPTopMostController/PPTopMostControllerProtocol.h b/Example/Pods/Headers/Private/PPTopMostController/PPTopMostControllerProtocol.h new file mode 120000 index 0000000..4fe03e4 --- /dev/null +++ b/Example/Pods/Headers/Private/PPTopMostController/PPTopMostControllerProtocol.h @@ -0,0 +1 @@ +../../../PPTopMostController/PPTopMostController-Files/PPTopMostControllerProtocol.h \ No newline at end of file diff --git a/Example/Pods/Headers/Private/PPTopMostController/UINavigationController+PPTopMostController.h b/Example/Pods/Headers/Private/PPTopMostController/UINavigationController+PPTopMostController.h new file mode 120000 index 0000000..7e62a8a --- /dev/null +++ b/Example/Pods/Headers/Private/PPTopMostController/UINavigationController+PPTopMostController.h @@ -0,0 +1 @@ +../../../PPTopMostController/PPTopMostController-Files/UINavigationController+PPTopMostController.h \ No newline at end of file diff --git a/Example/Pods/Headers/Private/PPTopMostController/UITabBarController+PPTopMostController.h b/Example/Pods/Headers/Private/PPTopMostController/UITabBarController+PPTopMostController.h new file mode 120000 index 0000000..3a947bf --- /dev/null +++ b/Example/Pods/Headers/Private/PPTopMostController/UITabBarController+PPTopMostController.h @@ -0,0 +1 @@ +../../../PPTopMostController/PPTopMostController-Files/UITabBarController+PPTopMostController.h \ No newline at end of file diff --git a/Example/Pods/Headers/Private/PPTopMostController/UIViewController+PPTopMostController.h b/Example/Pods/Headers/Private/PPTopMostController/UIViewController+PPTopMostController.h new file mode 120000 index 0000000..b74404e --- /dev/null +++ b/Example/Pods/Headers/Private/PPTopMostController/UIViewController+PPTopMostController.h @@ -0,0 +1 @@ +../../../PPTopMostController/PPTopMostController-Files/UIViewController+PPTopMostController.h \ No newline at end of file diff --git a/Example/Pods/Headers/Private/RMessage/RMessage.h b/Example/Pods/Headers/Private/RMessage/RMessage.h new file mode 120000 index 0000000..6155fee --- /dev/null +++ b/Example/Pods/Headers/Private/RMessage/RMessage.h @@ -0,0 +1 @@ +../../../../../RMessage/RMessage.h \ No newline at end of file diff --git a/Example/Pods/Headers/Private/RMessage/RMessageView.h b/Example/Pods/Headers/Private/RMessage/RMessageView.h new file mode 120000 index 0000000..b9747f2 --- /dev/null +++ b/Example/Pods/Headers/Private/RMessage/RMessageView.h @@ -0,0 +1 @@ +../../../../../RMessage/RMessageView.h \ No newline at end of file diff --git a/Example/Pods/Headers/Public/HexColors/HexColors.h b/Example/Pods/Headers/Public/HexColors/HexColors.h new file mode 120000 index 0000000..c1fa62f --- /dev/null +++ b/Example/Pods/Headers/Public/HexColors/HexColors.h @@ -0,0 +1 @@ +../../../HexColors/Classes/HexColors.h \ No newline at end of file diff --git a/Example/Pods/Headers/Public/PPTopMostController/PPTopMostControllerProtocol.h b/Example/Pods/Headers/Public/PPTopMostController/PPTopMostControllerProtocol.h new file mode 120000 index 0000000..4fe03e4 --- /dev/null +++ b/Example/Pods/Headers/Public/PPTopMostController/PPTopMostControllerProtocol.h @@ -0,0 +1 @@ +../../../PPTopMostController/PPTopMostController-Files/PPTopMostControllerProtocol.h \ No newline at end of file diff --git a/Example/Pods/Headers/Public/PPTopMostController/UINavigationController+PPTopMostController.h b/Example/Pods/Headers/Public/PPTopMostController/UINavigationController+PPTopMostController.h new file mode 120000 index 0000000..7e62a8a --- /dev/null +++ b/Example/Pods/Headers/Public/PPTopMostController/UINavigationController+PPTopMostController.h @@ -0,0 +1 @@ +../../../PPTopMostController/PPTopMostController-Files/UINavigationController+PPTopMostController.h \ No newline at end of file diff --git a/Example/Pods/Headers/Public/PPTopMostController/UITabBarController+PPTopMostController.h b/Example/Pods/Headers/Public/PPTopMostController/UITabBarController+PPTopMostController.h new file mode 120000 index 0000000..3a947bf --- /dev/null +++ b/Example/Pods/Headers/Public/PPTopMostController/UITabBarController+PPTopMostController.h @@ -0,0 +1 @@ +../../../PPTopMostController/PPTopMostController-Files/UITabBarController+PPTopMostController.h \ No newline at end of file diff --git a/Example/Pods/Headers/Public/PPTopMostController/UIViewController+PPTopMostController.h b/Example/Pods/Headers/Public/PPTopMostController/UIViewController+PPTopMostController.h new file mode 120000 index 0000000..b74404e --- /dev/null +++ b/Example/Pods/Headers/Public/PPTopMostController/UIViewController+PPTopMostController.h @@ -0,0 +1 @@ +../../../PPTopMostController/PPTopMostController-Files/UIViewController+PPTopMostController.h \ No newline at end of file diff --git a/Example/Pods/Headers/Public/RMessage/RMessage.h b/Example/Pods/Headers/Public/RMessage/RMessage.h new file mode 120000 index 0000000..6155fee --- /dev/null +++ b/Example/Pods/Headers/Public/RMessage/RMessage.h @@ -0,0 +1 @@ +../../../../../RMessage/RMessage.h \ No newline at end of file diff --git a/Example/Pods/Headers/Public/RMessage/RMessageView.h b/Example/Pods/Headers/Public/RMessage/RMessageView.h new file mode 120000 index 0000000..b9747f2 --- /dev/null +++ b/Example/Pods/Headers/Public/RMessage/RMessageView.h @@ -0,0 +1 @@ +../../../../../RMessage/RMessageView.h \ No newline at end of file diff --git a/Example/Pods/HexColors/Classes/HexColors.h b/Example/Pods/HexColors/Classes/HexColors.h new file mode 100755 index 0000000..fc7fddd --- /dev/null +++ b/Example/Pods/HexColors/Classes/HexColors.h @@ -0,0 +1,33 @@ +// +// HexColor.h +// +// Created by Marius Landwehr on 02.12.12. +// The MIT License (MIT) +// Copyright (c) 2013 Marius Landwehr marius.landwehr@gmail.com +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +#import "TargetConditionals.h" + +#if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR + #import + #define HXColor UIColor +#else + #import + #define HXColor NSColor +#endif + +@interface HXColor (HexColorAddition) + ++ (HXColor *)hx_colorWithHexString:(NSString *)hexString; ++ (HXColor *)hx_colorWithHexString:(NSString *)hexString alpha:(CGFloat)alpha; + ++ (HXColor *)hx_colorWith8BitRed:(NSInteger)red green:(NSInteger)green blue:(NSInteger)blue; ++ (HXColor *)hx_colorWith8BitRed:(NSInteger)red green:(NSInteger)green blue:(NSInteger)blue alpha:(CGFloat)alpha; + +@end diff --git a/Example/Pods/HexColors/Classes/HexColors.m b/Example/Pods/HexColors/Classes/HexColors.m new file mode 100755 index 0000000..9e8521a --- /dev/null +++ b/Example/Pods/HexColors/Classes/HexColors.m @@ -0,0 +1,119 @@ +// +// HexColor.m +// +// Created by Marius Landwehr on 02.12.12. +// The MIT License (MIT) +// Copyright (c) 2013 Marius Landwehr marius.landwehr@gmail.com +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +#import "HexColors.h" + +@implementation HXColor (HexColorAddition) + ++ (HXColor *)hx_colorWithHexString:(NSString *)hexString +{ + // Check for hash and add the missing hash + if('#' != [hexString characterAtIndex:0]) + { + hexString = [NSString stringWithFormat:@"#%@", hexString]; + } + + CGFloat alpha = 1.0; + if (5 == hexString.length || 9 == hexString.length) { + NSString * alphaHex = [hexString substringWithRange:NSMakeRange(1, 9 == hexString.length ? 2 : 1)]; + if (1 == alphaHex.length) alphaHex = [NSString stringWithFormat:@"%@%@", alphaHex, alphaHex]; + hexString = [NSString stringWithFormat:@"#%@", [hexString substringFromIndex:9 == hexString.length ? 3 : 2]]; + unsigned alpha_u = [[self class] hx_hexValueToUnsigned:alphaHex]; + alpha = ((CGFloat) alpha_u) / 255.0; + } + + return [[self class] hx_colorWithHexString:hexString alpha:alpha]; +} + ++ (HXColor *)hx_colorWithHexString:(NSString *)hexString alpha:(CGFloat)alpha +{ + if (hexString.length == 0) { + return nil; + } + + // Check for hash and add the missing hash + if('#' != [hexString characterAtIndex:0]) + { + hexString = [NSString stringWithFormat:@"#%@", hexString]; + } + + // check for string length + if (7 != hexString.length && 4 != hexString.length) { + NSString *defaultHex = [NSString stringWithFormat:@"0xff"]; + unsigned defaultInt = [[self class] hx_hexValueToUnsigned:defaultHex]; + + HXColor *color = [HXColor hx_colorWith8BitRed:defaultInt green:defaultInt blue:defaultInt alpha:1.0]; + return color; + } + + // check for 3 character HexStrings + hexString = [[self class] hx_hexStringTransformFromThreeCharacters:hexString]; + + NSString *redHex = [NSString stringWithFormat:@"0x%@", [hexString substringWithRange:NSMakeRange(1, 2)]]; + unsigned redInt = [[self class] hx_hexValueToUnsigned:redHex]; + + NSString *greenHex = [NSString stringWithFormat:@"0x%@", [hexString substringWithRange:NSMakeRange(3, 2)]]; + unsigned greenInt = [[self class] hx_hexValueToUnsigned:greenHex]; + + NSString *blueHex = [NSString stringWithFormat:@"0x%@", [hexString substringWithRange:NSMakeRange(5, 2)]]; + unsigned blueInt = [[self class] hx_hexValueToUnsigned:blueHex]; + + HXColor *color = [HXColor hx_colorWith8BitRed:redInt green:greenInt blue:blueInt alpha:alpha]; + + return color; +} + ++ (HXColor *)hx_colorWith8BitRed:(NSInteger)red green:(NSInteger)green blue:(NSInteger)blue +{ + return [[self class] hx_colorWith8BitRed:red green:green blue:blue alpha:1.0]; +} + ++ (HXColor *)hx_colorWith8BitRed:(NSInteger)red green:(NSInteger)green blue:(NSInteger)blue alpha:(CGFloat)alpha +{ + HXColor *color = nil; +#if (TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE) + color = [HXColor colorWithRed:(float)red/255 green:(float)green/255 blue:(float)blue/255 alpha:alpha]; +#else + color = [HXColor colorWithCalibratedRed:(float)red/255 green:(float)green/255 blue:(float)blue/255 alpha:alpha]; +#endif + + return color; +} + ++ (NSString *)hx_hexStringTransformFromThreeCharacters:(NSString *)hexString +{ + if(hexString.length == 4) + { + hexString = [NSString stringWithFormat:@"#%1$c%1$c%2$c%2$c%3$c%3$c", + [hexString characterAtIndex:1], + [hexString characterAtIndex:2], + [hexString characterAtIndex:3]]; + + } + + return hexString; +} + ++ (unsigned)hx_hexValueToUnsigned:(NSString *)hexValue +{ + unsigned value = 0; + + NSScanner *hexValueScanner = [NSScanner scannerWithString:hexValue]; + [hexValueScanner scanHexInt:&value]; + + return value; +} + + +@end diff --git a/Example/Pods/HexColors/LICENCE b/Example/Pods/HexColors/LICENCE new file mode 100644 index 0000000..b57c882 --- /dev/null +++ b/Example/Pods/HexColors/LICENCE @@ -0,0 +1,8 @@ +The MIT License (MIT) +Copyright (c) 2012 Marius Landwehr marius.landwehr@gmail.com + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/Example/Pods/HexColors/README.md b/Example/Pods/HexColors/README.md new file mode 100644 index 0000000..fc84ce4 --- /dev/null +++ b/Example/Pods/HexColors/README.md @@ -0,0 +1,76 @@ +HexColors +========================= +![Badge w/ Version](https://cocoapod-badges.herokuapp.com/v/HexColors/badge.png) + +![Badge w/ Version](https://cocoapod-badges.herokuapp.com/p/HexColors/badge.png) + +HexColors is drop in category for HexColor Support for NSColor and UIColor. Support for HexColors with prefixed # and without. + +#RELEASE 3.0.0 +Popular request was to pre-fix the function calls because of better support of different libraries and dependencies. All functions are now prefixed with hx_ + +#Example iOS +##objective-c## +``` objective-c +// with hash +UIColor *colorWithHex = [UIColor hx_colorWithHexString:@"#ff8942"]; + +// without hash +UIColor *secondColorWithHex = [UIColor hx_colorWithHexString:@"ff8942"]; + +// short handling +UIColor *shortColorWithHex = [UIColor hx_colorWithHexString:@"fff"]; +``` +##swift## +``` swift +// with hash +let colorWithHex = UIColor.hx_colorWithHexString("#ff8942") + +// without hash +let secondColorWithHex = UIColor.hx_colorWithHexString("ff8942") + +// short handling +let shortColorWithHex = UIColor.hx_colorWithHexString("fff") +``` + +#Example Mac OS X +``` objective-c +// with hash +NSColor *colorWithHex = [NSColor hx_colorWithHexString:@"#ff8942"]; + +// wihtout hash +NSColor *secondColorWithHex = [NSColor hx_colorWithHexString:@"ff8942"]; + +// short handling +NSColor *shortColorWithHex = [NSColor hx_colorWithHexString:@"fff"]; +``` +##swift## +``` swift +// with hash +let colorWithHex = NSColor.hx_colorWithHexString("#ff8942") + +// without hash +let secondColorWithHex = NSColor.hx_colorWithHexString("ff8942") + +// short handling +let shortColorWithHex = NSColor.hx_colorWithHexString("fff") +``` + +#Installation +* `#import "HexColors.h"` where you want to use easy as pie HexColors +* `pod install HexColors` +* or just drag the source files in your project + +##Requirements +HexColors requires [iOS 5.0](http://developer.apple.com/library/ios/#releasenotes/General/WhatsNewIniPhoneOS/Articles/iPhoneOS4.html) and above, and Mac OS X 10.6 + +##Credits +HexColors was created by [Marius Landwehr](https://github.com/mRs-) because of the pain recalculating Hex values to RGB. + +HexColors was ported to Mac OS X by [holgersindbaek](https://github.com/holgersindbaek). + +##Creator +[Marius Landwehr](https://github.com/mRs-) [@mariusLAN](https://twitter.com/mariusLAN) + +##License +HexColors is available under the MIT license. See the LICENSE file for more info. diff --git a/Example/Pods/Local Podspecs/HexColors.podspec.json b/Example/Pods/Local Podspecs/HexColors.podspec.json new file mode 100644 index 0000000..14e6fbd --- /dev/null +++ b/Example/Pods/Local Podspecs/HexColors.podspec.json @@ -0,0 +1,22 @@ +{ + "name": "HexColors", + "version": "3.0.0", + "license": "MIT", + "summary": "Easy HEX- and RGB-Color Handling for UIColor and NSColor as a drop in category. Former MLUIColorAdditions.", + "homepage": "https://github.com/mRs-/HexColors", + "description": "HexColors is easy drop in category for HexColor integration in iOS and Mac OS X. Its build as a category for easy to use and can be used for UIColor and NSColor class.", + "authors": { + "Marius Landwehr": "marius.landwehr@gmail.com", + "holgersindbaek": "holgersindbaek@gmail.com" + }, + "source": { + "git": "https://github.com/mRs-/HexColors.git", + "tag": "3.0.0" + }, + "platforms": { + "ios": "5.0", + "osx": "10.6", + "watchos": "2.0" + }, + "source_files": "Classes/HexColors.{h,m}" +} diff --git a/Example/Pods/Local Podspecs/PPTopMostController.podspec.json b/Example/Pods/Local Podspecs/PPTopMostController.podspec.json new file mode 100644 index 0000000..c95bff1 --- /dev/null +++ b/Example/Pods/Local Podspecs/PPTopMostController.podspec.json @@ -0,0 +1,23 @@ +{ + "name": "PPTopMostController", + "version": "0.0.1", + "summary": "This protocol aims to simplify the code behind 'which controller/view is on screen'.", + "description": "To get the top most controller displayed, just do UIViewController *c = [UIViewController topMostController];\nAnd you are done.", + "homepage": "https://github.com/ipodishima/PPTopMostController", + "license": { + "type": "MIT", + "file": "LICENCE" + }, + "authors": { + "Marian Paul": "marian@ipup.pro" + }, + "source": { + "git": "https://github.com/ipodishima/PPTopMostController.git", + "tag": "0.0.1" + }, + "platforms": { + "ios": "5.0" + }, + "source_files": "PPTopMostController-Files", + "exclude_files": "PPTopMostController" +} diff --git a/Example/Pods/Local Podspecs/RMessage.podspec.json b/Example/Pods/Local Podspecs/RMessage.podspec.json new file mode 100644 index 0000000..f356f9e --- /dev/null +++ b/Example/Pods/Local Podspecs/RMessage.podspec.json @@ -0,0 +1,34 @@ +{ + "name": "RMessage", + "version": "1.0.1", + "summary": "Easy to use and customizable messages/notifications for iOS à la Tweetbot.", + "description": "This framework provides an easy to use class to show little notification views on the top of the screen. (à la Tweetbot).\nThe notification moves from the top of the screen underneath the navigation bar and stays there for a few seconds, depending on the length of the displayed text. To dismiss a notification before the time runs out, the user can swipe it to the top or just tap it.\nThere are 4 different types already set up for you: Success, Error, Warning, Message.", + "homepage": "https://github.com/donileo/RMessage", + "license": "MIT", + "authors": { + "Adonis Peralta": "donileo@gmail.com" + }, + "source": { + "git": "https://github.com/donileo/RMessage.git", + "tag": "1.0.1" + }, + "social_media_url": "https://twitter.com/donileo", + "platforms": { + "ios": "7.0" + }, + "requires_arc": true, + "source_files": "RMessage/**/*.{h,m}", + "resources": [ + "RMessage/Resources/**/*.xib", + "RMessage/Assets/**/*.{png,jpg,json}" + ], + "public_header_files": "RMessage/*.h", + "dependencies": { + "HexColors": [ + "~> 3.0.0" + ], + "PPTopMostController": [ + + ] + } +} diff --git a/Example/Pods/Manifest.lock b/Example/Pods/Manifest.lock new file mode 100644 index 0000000..4d79dbc --- /dev/null +++ b/Example/Pods/Manifest.lock @@ -0,0 +1,34 @@ +PODS: + - HexColors (3.0.0) + - PPTopMostController (0.0.1) + - RMessage (1.0.1): + - HexColors (~> 3.0.0) + - PPTopMostController + +DEPENDENCIES: + - HexColors (from `https://github.com/mRs-/HexColors.git`) + - PPTopMostController (from `https://github.com/donileo/PPTopMostController.git`) + - RMessage (from `../`) + +EXTERNAL SOURCES: + HexColors: + :git: https://github.com/mRs-/HexColors.git + PPTopMostController: + :git: https://github.com/donileo/PPTopMostController.git + RMessage: + :path: "../" + +CHECKOUT OPTIONS: + HexColors: + :commit: aa42656d5fb8ca7942927a4d73696900d7306914 + :git: https://github.com/mRs-/HexColors.git + PPTopMostController: + :commit: 9e725746cff79a6286554d76dcce279909c327ab + :git: https://github.com/donileo/PPTopMostController.git + +SPEC CHECKSUMS: + HexColors: 8b83e3fe90c0d466dae7b98c9d22da95799f99cb + PPTopMostController: ca6c8fd33abd2895d57d86bfe27ae7425b44eea8 + RMessage: 824c881c073427bd3334716630ac4b53dbb2b6a8 + +COCOAPODS: 0.39.0 diff --git a/Example/Pods/PPTopMostController/LICENCE b/Example/Pods/PPTopMostController/LICENCE new file mode 100644 index 0000000..484975a --- /dev/null +++ b/Example/Pods/PPTopMostController/LICENCE @@ -0,0 +1,5 @@ +Copyright © 2013, Marian Paul +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. +The Software is provided "as is", without warranty of any kind, express or implied, including but not limited to the warranties of merchantability, fitness for a particular purpose and noninfringement. In no event shall the authors or copyright holders be liable for any claim, damages or other liability, whether in an action of contract, tort or otherwise, arising from, out of or in connection with the Software or the use or other dealings in the Software. +Except as contained in this notice, the name(s) of (the) Author shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from (the )Author. diff --git a/Example/Pods/PPTopMostController/PPTopMostController-Files/PPTopMostControllerProtocol.h b/Example/Pods/PPTopMostController/PPTopMostController-Files/PPTopMostControllerProtocol.h new file mode 100644 index 0000000..df43295 --- /dev/null +++ b/Example/Pods/PPTopMostController/PPTopMostController-Files/PPTopMostControllerProtocol.h @@ -0,0 +1,13 @@ +// +// PPTopMostControllerProtocol.h +// PPTopMostController +// +// Created by Marian Paul on 24/05/13. +// Copyright (c) 2013 iPuP. All rights reserved. +// + +#import + +@protocol PPTopMostControllerProtocol +- (UIViewController *)visibleViewController; +@end diff --git a/Example/Pods/PPTopMostController/PPTopMostController-Files/UINavigationController+PPTopMostController.h b/Example/Pods/PPTopMostController/PPTopMostController-Files/UINavigationController+PPTopMostController.h new file mode 100644 index 0000000..f20fe3b --- /dev/null +++ b/Example/Pods/PPTopMostController/PPTopMostController-Files/UINavigationController+PPTopMostController.h @@ -0,0 +1,14 @@ +// +// UINavigationController+PPTopMostController.h +// PPTopMostController +// +// Created by Marian Paul on 24/05/13. +// Copyright (c) 2013 iPuP. All rights reserved. +// + +#import +#import "PPTopMostControllerProtocol.h" + +@interface UINavigationController (PPTopMostController) + +@end diff --git a/Example/Pods/PPTopMostController/PPTopMostController-Files/UINavigationController+PPTopMostController.m b/Example/Pods/PPTopMostController/PPTopMostController-Files/UINavigationController+PPTopMostController.m new file mode 100644 index 0000000..19ca563 --- /dev/null +++ b/Example/Pods/PPTopMostController/PPTopMostController-Files/UINavigationController+PPTopMostController.m @@ -0,0 +1,17 @@ +// +// UINavigationController+PPTopMostController.m +// PPTopMostController +// +// Created by Marian Paul on 24/05/13. +// Copyright (c) 2013 iPuP. All rights reserved. +// + +#import "UINavigationController+PPTopMostController.h" + +@implementation UINavigationController (PPTopMostController) + +- (UIViewController *)visibleViewController { + return self.topViewController; +} + +@end diff --git a/Example/Pods/PPTopMostController/PPTopMostController-Files/UITabBarController+PPTopMostController.h b/Example/Pods/PPTopMostController/PPTopMostController-Files/UITabBarController+PPTopMostController.h new file mode 100644 index 0000000..6dedef6 --- /dev/null +++ b/Example/Pods/PPTopMostController/PPTopMostController-Files/UITabBarController+PPTopMostController.h @@ -0,0 +1,14 @@ +// +// UITabBarController+PPTopMostController.h +// PPTopMostController +// +// Created by Marian Paul on 24/05/13. +// Copyright (c) 2013 iPuP. All rights reserved. +// + +#import +#import "PPTopMostControllerProtocol.h" + +@interface UITabBarController (PPTopMostController) + +@end diff --git a/Example/Pods/PPTopMostController/PPTopMostController-Files/UITabBarController+PPTopMostController.m b/Example/Pods/PPTopMostController/PPTopMostController-Files/UITabBarController+PPTopMostController.m new file mode 100644 index 0000000..ccf9b17 --- /dev/null +++ b/Example/Pods/PPTopMostController/PPTopMostController-Files/UITabBarController+PPTopMostController.m @@ -0,0 +1,17 @@ +// +// UITabBarController+PPTopMostController.m +// PPTopMostController +// +// Created by Marian Paul on 24/05/13. +// Copyright (c) 2013 iPuP. All rights reserved. +// + +#import "UITabBarController+PPTopMostController.h" + +@implementation UITabBarController (PPTopMostController) + +- (UIViewController *)visibleViewController { + return self.selectedViewController; +} + +@end diff --git a/Example/Pods/PPTopMostController/PPTopMostController-Files/UIViewController+PPTopMostController.h b/Example/Pods/PPTopMostController/PPTopMostController-Files/UIViewController+PPTopMostController.h new file mode 100644 index 0000000..24fbcc2 --- /dev/null +++ b/Example/Pods/PPTopMostController/PPTopMostController-Files/UIViewController+PPTopMostController.h @@ -0,0 +1,18 @@ +// +// UIViewController+PPTopMostController.h +// PPTopMostController +// +// Created by Marian Paul on 24/05/13. +// Copyright (c) 2013 iPuP. All rights reserved. +// + +#import +#import "PPTopMostControllerProtocol.h" + +@interface UIViewController (PPTopMostController) +/** + This is your entry point. + Will return the top most controller, looping through each controllers adopting the PPTopMostControllerProtocol + */ ++ (UIViewController *)topMostController; +@end diff --git a/Example/Pods/PPTopMostController/PPTopMostController-Files/UIViewController+PPTopMostController.m b/Example/Pods/PPTopMostController/PPTopMostController-Files/UIViewController+PPTopMostController.m new file mode 100644 index 0000000..4a6062a --- /dev/null +++ b/Example/Pods/PPTopMostController/PPTopMostController-Files/UIViewController+PPTopMostController.m @@ -0,0 +1,47 @@ +// +// UIViewController+PPTopMostController.m +// PPTopMostController +// +// Created by Marian Paul on 24/05/13. +// Copyright (c) 2013 iPuP. All rights reserved. +// + +#import "UIViewController+PPTopMostController.h" +#import "UINavigationController+PPTopMostController.h" +#import "UITabBarController+PPTopMostController.h" + +@implementation UIViewController (PPTopMostController) + ++ (UIViewController *)getModalViewControllerOfControllerIfExists:(UIViewController *)controller { + UIViewController *toReturn = nil; + // modalViewController is deprecated since iOS 6, so use presentedViewController instead + if ([controller respondsToSelector:@selector(presentedViewController)]) toReturn = [controller performSelector:@selector(presentedViewController)]; + else toReturn = [controller performSelector:@selector(modalViewController)]; + + // If no modal view controller found, return the controller itself + if (!toReturn) toReturn = controller; + return toReturn; +} + ++ (UIViewController *)topMostController { + // Start with the window rootViewController + UIViewController *topController = ((UIWindow *)[[UIApplication sharedApplication].windows objectAtIndex:0]).rootViewController; + + // Is there any modal view on top? + topController = [self getModalViewControllerOfControllerIfExists:topController]; + + // Keep reference to the old controller while looping + UIViewController *oldTopController = nil; + + // Loop them all + while ([topController conformsToProtocol:@protocol(PPTopMostControllerProtocol)] && oldTopController != topController) { + oldTopController = topController; + topController = [(UIViewController < PPTopMostControllerProtocol > *) topController visibleViewController]; + // Again, check for any modal controller + topController = [self getModalViewControllerOfControllerIfExists:topController]; + } + + return topController; +} + +@end diff --git a/Example/Pods/PPTopMostController/README.md b/Example/Pods/PPTopMostController/README.md new file mode 100644 index 0000000..4b1f653 --- /dev/null +++ b/Example/Pods/PPTopMostController/README.md @@ -0,0 +1,216 @@ +PPTopMostControllerProtocol +======================= + +This project aims to simplify the code behind "*which controller/view is on screen*". + +Sometimes, you may want to dispatch an event to the current displayed controller. For example: + +- A notification view like the download of the resource is complete, +- A view which tells you the status of the app, online or offline, +- etc + +For those usages with a notification view, you probably want to display the view without any efforts to the displayed controller. And more important, the view should stay displayed even if you push a new view from navigation controller. + +Just to be clear, this protocol only gives you the tools to get the current displayed controller. It's up to you to do something useful with this tool. +There is an example on the sample code provided with a [NotificationView](https://github.com/ipodishima/PPTopMostController/blob/master/PPTopMostController/PPTopMostController/NotificationView.m). Please also take a look at RZNotificationView (coming soon) + +Please also note that PPTopMostController does support modal controllers. + +# Try it with MacBuildServer + + + + +#Installation + +The easiest way to install PPTopMostController is via the [CocoaPods](http://cocoapods.org/) package manager, since it's really flexible and provides easy installation. + +## Via CocoaPods (coming soon) + +If you don't have cocoapods yet (shame on you), install it: + +``` bash +$ [sudo] gem install cocoapods +$ pod setup +``` + +Go to the directory of your Xcode project, and Create and/or Edit your Podfile and add PPTopMostController: + +``` bash +$ cd /path/to/MyProject +$ touch Podfile +# Edit the podfile using your favorite editor +$ edit Podfile +platform :ios +pod 'PPTopMostController', '~> the version you want' +``` + +Run the install: + +``` bash +$ pod install +``` + +Finally, open your project in Xcode from the .xcworkspace file (not the usual project file! This is really important) + +``` bash +$ open MyProject.xcworkspace +``` + +Import *UIViewController+PPTopMostController.h* file to your PCH file or your AppDelegate file. + +You are ready to go. + +## Old fashionned way + +1. Add PPTopMostController as a submodule to your project + +``` bash +$ cd /path/to/MyApplication +# If this is a new project, initialize git... +$ git init +$ git submodule add git@github.com:ipodishima/PPTopMostController.git vendor/PPTopMostController +$ git submodule update --init --recursive +``` + +2. In your XCode Project, take all the files from PPTopMostController-Files folder and drag them into your project. +3. Import *UIViewController+PPTopMostController.h* file to your PCH file or your AppDelegate file. + +You are ready to go. + +# ARC Support + +PPTopMostController does not care about ARC and non-ARC. Do whatever you want! + +# Compatibility + +From iOS 4 to iOS 6. + +# Usage + +## Get the current displayed controller + +To get the top most controller displayed, just do + + UIViewController *c = [UIViewController topMostController]; + +And you are done. + +## Add support for custom container + +There is an example with [PPRevealSideViewController](https://github.com/ipup/PPRevealSideViewController) on the sample. + +1. Create a category on your container : *YourContainer+PPTopMostController.h* (don't forget to import the header somewhere) +2. Import the PPTopMostController protocol : `#import "PPTopMostControllerProtocol.h"` +3. Adopt the protocol +```` + @interface YourContainer (PPTopMostController) +```` +4. Conforms to it + + - (UIViewController *)visibleViewController { + return /*The controller you want to set it's top one. Remember that PPTopMostController go through controller hierarchy and find controllers conforming to PPTopMostControllerProtocol*/; + } + +That's it! + +# Why PPTopMostController? +Let's take the case where you have for example a manager which downloads data + a view which triggers notification when an error occured. + +## Using a delegate + +(This would be quite the same idea with completion block) +You would declare a protocol + + @protocol DLManagerDelegate + - (void) dlManager:(DLManager*)manager didFailWithError:(NSError*)error; + @end + +And create a property for the delegate + + @property (nonatomic, weak) id delegate; + +In each controller, you would adopt the protocol + + @interface AController : UIViewController + +And implement the method + + - (void) dlManager:(DLManager*)manager didFailWithError:(NSError*)error + { + [NotificationView showFromController:self ...]; + } + +Tell the delegate when failing + + - (void) weFail:(NSError*)error + { + [self.delegate dlManager:self didFailWithError:error]; + } + +Plus managed the thing that if you change the controller displayed, reassign correctly the delegate + + [[DLManager shared] setDelegate:self]; + +**Boring** + +## Using notifications + +You would declare the notification + + extern NSString *const DLManagerDidFailNotification; + ++ + + NSString *const DLManagerDidFailNotification = @"DLManagerDidFailNotification"; + +Post it when failing + + - (void) weFail:(NSError*)error + { + NSDictionary *userInfo = @{@"error": error}; + [[NSNotificationCenter defaultCenter] postNotificationName:DLManagerDidFailNotification object:nil userInfo:userInfo]; + } + +And in each controller, you add observer + + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(dispatchNotificationFail:) + name:DLManagerDidFailNotification + object:nil]; + +Don't forget to remove the observer + +And implement the method + + - (void) dispatchNotificationFail:(NSNotification*)notif + { + [NotificationView showFromController:self ...]; + } + +**Boring** + +## Using PPTopMostController + +Just implement the method `weFail:` from DLManager + + - (void) weFail:(NSError*)error + { + [NotificationView showFromController:[UIViewController topMostController] ...]; + } + +**Not boring** + +License +------- + +This Code is released under the MIT License by [Marian Paul for iPuP SARL](http://www.ipup.pro) + +Please tell me when you use this protocol in your project! And if you have great controls build with PPTopMostController, let me a note, I will include the link on this readme + +Regards, +Marian Paul aka ipodishima + +http://www.ipup.pro diff --git a/Example/Pods/Pods.xcodeproj/project.pbxproj b/Example/Pods/Pods.xcodeproj/project.pbxproj new file mode 100644 index 0000000..4877753 --- /dev/null +++ b/Example/Pods/Pods.xcodeproj/project.pbxproj @@ -0,0 +1,849 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 067F9DACC53D2F2B2D616F8917E25467 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3E4E89230EF59BC255123B67864ACF77 /* Foundation.framework */; }; + 1077503710160776AF36AF031B9ED7F3 /* UITabBarController+PPTopMostController.m in Sources */ = {isa = PBXBuildFile; fileRef = E7B56304CE2DA8850A548481AB2B9395 /* UITabBarController+PPTopMostController.m */; settings = {COMPILER_FLAGS = "-DOS_OBJECT_USE_OBJC=0"; }; }; + 16F3CA7AB9375167F5452842C213BEC1 /* RMessage.h in Headers */ = {isa = PBXBuildFile; fileRef = 0BF9E1B5B0B3AA74BF0B0A3369A14A3E /* RMessage.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 20C273F0880A2105628D056158875920 /* HexColors.m in Sources */ = {isa = PBXBuildFile; fileRef = C9BAB675D080D11807A83F8FD66BA317 /* HexColors.m */; settings = {COMPILER_FLAGS = "-DOS_OBJECT_USE_OBJC=0"; }; }; + 23C8904F392BDFCBF9A4F18B642FA665 /* Pods-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 272643F56613CA0D336AE3DBF19DC404 /* Pods-dummy.m */; }; + 29DAC922DD5ABE7E79C45C8F052A2425 /* UIViewController+PPTopMostController.m in Sources */ = {isa = PBXBuildFile; fileRef = 5F8231D271F29202100DB59055D2C4A7 /* UIViewController+PPTopMostController.m */; settings = {COMPILER_FLAGS = "-DOS_OBJECT_USE_OBJC=0"; }; }; + 3642DD78055E38F7FB67BE17CFDD7A05 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3E4E89230EF59BC255123B67864ACF77 /* Foundation.framework */; }; + 3702DC2695772A30CE6A012DE48C93F9 /* PPTopMostController-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = C0CFB939D5B8C9910708B314FCA3AB15 /* PPTopMostController-dummy.m */; }; + 3C02E1799B3CEF2975D812A3A988FA4E /* UINavigationController+PPTopMostController.m in Sources */ = {isa = PBXBuildFile; fileRef = 328BB210EED741D0951654C4EA48BDAD /* UINavigationController+PPTopMostController.m */; settings = {COMPILER_FLAGS = "-DOS_OBJECT_USE_OBJC=0"; }; }; + 527B65410811856F9B0D17CA02B9FB66 /* UIViewController+PPTopMostController.h in Headers */ = {isa = PBXBuildFile; fileRef = 6FE18BF16B99DA5B588DF7FEDE455422 /* UIViewController+PPTopMostController.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 5E2581740536B8A44AF50DBA7E3B07E5 /* RMessageView.h in Headers */ = {isa = PBXBuildFile; fileRef = 54D93A189FABC413AED0AE7DAE215206 /* RMessageView.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 7ABCD8EC48C2F7D62004D143D66C678D /* RMessage-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 430FA11FFF0BEE864CF1C6A8E6BBFDDB /* RMessage-dummy.m */; }; + 85B98247C863155692CCDAE11423E411 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3E4E89230EF59BC255123B67864ACF77 /* Foundation.framework */; }; + 8E96BAEFA26D00FFD1E1B006FDCB9C13 /* RMessage.m in Sources */ = {isa = PBXBuildFile; fileRef = 2D73840065923F8038A892201689702A /* RMessage.m */; }; + 9EA8B82625D30CCA49775FD84E8E3BF4 /* HexColors-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 360DD393B54068DF0DC094E980B10B08 /* HexColors-dummy.m */; }; + 9F44B438EA8F0425A9A1A680BC4FDE32 /* UITabBarController+PPTopMostController.h in Headers */ = {isa = PBXBuildFile; fileRef = 3F67BD84B208B68CE8510151ED5462EC /* UITabBarController+PPTopMostController.h */; settings = {ATTRIBUTES = (Public, ); }; }; + B39009ACA5609B50E7E0172AB9FE27E5 /* UINavigationController+PPTopMostController.h in Headers */ = {isa = PBXBuildFile; fileRef = 8B834D2305652A7C1E7901DC677BAE06 /* UINavigationController+PPTopMostController.h */; settings = {ATTRIBUTES = (Public, ); }; }; + BD39580F9EFC908BC6AAB2548C311846 /* RMessageView.m in Sources */ = {isa = PBXBuildFile; fileRef = 5FD8F456E674D220D2221D71BA6655FD /* RMessageView.m */; }; + C036E17644646304E03BF60C127A21FC /* HexColors.h in Headers */ = {isa = PBXBuildFile; fileRef = 316870125844702EBA1FBE955FE47E92 /* HexColors.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D75BBF3A6C6D3745AE85273CEC34CFCA /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3E4E89230EF59BC255123B67864ACF77 /* Foundation.framework */; }; + D7C615A1C2435EB5EF38B66447359DB4 /* PPTopMostControllerProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = 4343F23FBF438B643B8CF50EEF5841B3 /* PPTopMostControllerProtocol.h */; settings = {ATTRIBUTES = (Public, ); }; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 0ED52E0AC5ED49BCB6C9FEAE5F7E622F /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = D41D8CD98F00B204E9800998ECF8427E /* Project object */; + proxyType = 1; + remoteGlobalIDString = 0B41D180E700F78F2A32720E1BBE07D4; + remoteInfo = PPTopMostController; + }; + B786F79444CFFCA32102CC4EF8391341 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = D41D8CD98F00B204E9800998ECF8427E /* Project object */; + proxyType = 1; + remoteGlobalIDString = C70D6D047BA3EAC9F94695B5CB2AADF4; + remoteInfo = RMessage; + }; + D5448C4E8321E0EC09409DFF9DB768F3 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = D41D8CD98F00B204E9800998ECF8427E /* Project object */; + proxyType = 1; + remoteGlobalIDString = E9EF397B95762DDB254C71DDCB4B1381; + remoteInfo = HexColors; + }; + EE6FB2DF110DD09FA6C40DB92F3B4C9C /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = D41D8CD98F00B204E9800998ECF8427E /* Project object */; + proxyType = 1; + remoteGlobalIDString = 0B41D180E700F78F2A32720E1BBE07D4; + remoteInfo = PPTopMostController; + }; + F719E7EA3B441D528503D441E34B17B0 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = D41D8CD98F00B204E9800998ECF8427E /* Project object */; + proxyType = 1; + remoteGlobalIDString = E9EF397B95762DDB254C71DDCB4B1381; + remoteInfo = HexColors; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + 09E35BFD539CDB3825221F71E0B7DD85 /* NotificationBackgroundSuccess.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; path = NotificationBackgroundSuccess.png; sourceTree = ""; }; + 0B9F93FB2054B84208D96EF3C93F57F1 /* libPods.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libPods.a; sourceTree = BUILT_PRODUCTS_DIR; }; + 0BF9E1B5B0B3AA74BF0B0A3369A14A3E /* RMessage.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RMessage.h; sourceTree = ""; }; + 10834806BD7B412BC24F347361FA2C8E /* Pods-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-acknowledgements.plist"; sourceTree = ""; }; + 12B02F3709E2B9CD1BA6F27ED67F4602 /* NotificationBackgroundWarningIcon@2x.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; path = "NotificationBackgroundWarningIcon@2x.png"; sourceTree = ""; }; + 15018C95B6E0DBAD01B2B988940433E1 /* NotificationBackgroundError.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; path = NotificationBackgroundError.png; sourceTree = ""; }; + 1686AB8A2BFCB742CE7C049ED1650607 /* RMessage-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "RMessage-prefix.pch"; sourceTree = ""; }; + 179E81B3B20AD8434A3BB528029889B7 /* PPTopMostController-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "PPTopMostController-prefix.pch"; sourceTree = ""; }; + 244269FA4FABEFBE123CD786CB007189 /* HexColors-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "HexColors-prefix.pch"; sourceTree = ""; }; + 26A1A16F407081A9077669811C9FE78A /* NotificationBackgroundWarning.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; path = NotificationBackgroundWarning.png; sourceTree = ""; }; + 272643F56613CA0D336AE3DBF19DC404 /* Pods-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-dummy.m"; sourceTree = ""; }; + 2D73840065923F8038A892201689702A /* RMessage.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RMessage.m; sourceTree = ""; }; + 316870125844702EBA1FBE955FE47E92 /* HexColors.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = HexColors.h; path = Classes/HexColors.h; sourceTree = ""; }; + 328BB210EED741D0951654C4EA48BDAD /* UINavigationController+PPTopMostController.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "UINavigationController+PPTopMostController.m"; path = "PPTopMostController-Files/UINavigationController+PPTopMostController.m"; sourceTree = ""; }; + 360DD393B54068DF0DC094E980B10B08 /* HexColors-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "HexColors-dummy.m"; sourceTree = ""; }; + 37DB56D75062CC75FCB0966E1C6E8A8E /* Pods-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-acknowledgements.markdown"; sourceTree = ""; }; + 3E4E89230EF59BC255123B67864ACF77 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS9.0.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; }; + 3F67BD84B208B68CE8510151ED5462EC /* UITabBarController+PPTopMostController.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "UITabBarController+PPTopMostController.h"; path = "PPTopMostController-Files/UITabBarController+PPTopMostController.h"; sourceTree = ""; }; + 409AD58F7FBA2833D3D06325A38A6348 /* NotificationBackgroundSuccess@2x.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; path = "NotificationBackgroundSuccess@2x.png"; sourceTree = ""; }; + 430FA11FFF0BEE864CF1C6A8E6BBFDDB /* RMessage-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "RMessage-dummy.m"; sourceTree = ""; }; + 4343F23FBF438B643B8CF50EEF5841B3 /* PPTopMostControllerProtocol.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = PPTopMostControllerProtocol.h; path = "PPTopMostController-Files/PPTopMostControllerProtocol.h"; sourceTree = ""; }; + 4E762F23EC34ED4A6FF3312D84E33A40 /* Pods.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = Pods.debug.xcconfig; sourceTree = ""; }; + 4FFA578BD9CB365254B3CE12929A3A5E /* RMessageDefaultDesign.json */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.json; path = RMessageDefaultDesign.json; sourceTree = ""; }; + 54BC84662E53D1F0C081E99F9C16FA6F /* RMessage.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = RMessage.xcconfig; sourceTree = ""; }; + 54D93A189FABC413AED0AE7DAE215206 /* RMessageView.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RMessageView.h; sourceTree = ""; }; + 5F8231D271F29202100DB59055D2C4A7 /* UIViewController+PPTopMostController.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "UIViewController+PPTopMostController.m"; path = "PPTopMostController-Files/UIViewController+PPTopMostController.m"; sourceTree = ""; }; + 5FD8F456E674D220D2221D71BA6655FD /* RMessageView.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RMessageView.m; sourceTree = ""; }; + 603B7D7A97FB39877B9FC4CB9F09ABF5 /* libRMessage.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libRMessage.a; sourceTree = BUILT_PRODUCTS_DIR; }; + 6911BECA35E7518D864239B7E898EEF3 /* Pods-frameworks.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-frameworks.sh"; sourceTree = ""; }; + 6FE18BF16B99DA5B588DF7FEDE455422 /* UIViewController+PPTopMostController.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "UIViewController+PPTopMostController.h"; path = "PPTopMostController-Files/UIViewController+PPTopMostController.h"; sourceTree = ""; }; + 7A6F93B1C0E91F535877FBABBA0EEEE6 /* NotificationButtonBackground.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; path = NotificationButtonBackground.png; sourceTree = ""; }; + 7E1D69932A80D3AB72A769B50E0391E3 /* PPTopMostController.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = PPTopMostController.xcconfig; sourceTree = ""; }; + 8B834D2305652A7C1E7901DC677BAE06 /* UINavigationController+PPTopMostController.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "UINavigationController+PPTopMostController.h"; path = "PPTopMostController-Files/UINavigationController+PPTopMostController.h"; sourceTree = ""; }; + 951853E52F17622C80D1B3EBE27A9267 /* NotificationBackgroundError@2x.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; path = "NotificationBackgroundError@2x.png"; sourceTree = ""; }; + 98431717943EC65E622A673BFE79754A /* NotificationBackgroundMessage@2x.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; path = "NotificationBackgroundMessage@2x.png"; sourceTree = ""; }; + 98C98CDFB3F20F2925F6CD1F141BB14F /* Pods.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = Pods.release.xcconfig; sourceTree = ""; }; + 9A8BE4231801B9D5432534836ACCF85E /* NotificationBackgroundSuccessIcon.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; path = NotificationBackgroundSuccessIcon.png; sourceTree = ""; }; + A1A36D34413696BE466E2CA0AFF194DA /* Pods-resources.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-resources.sh"; sourceTree = ""; }; + B3D45C1BE24BDC76D60F8D12623E1106 /* libHexColors.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libHexColors.a; sourceTree = BUILT_PRODUCTS_DIR; }; + B7034106E1B0D65F9359BA35BB7FB9EE /* libPPTopMostController.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libPPTopMostController.a; sourceTree = BUILT_PRODUCTS_DIR; }; + BA6428E9F66FD5A23C0A2E06ED26CD2F /* Podfile */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = Podfile; path = ../Podfile; sourceTree = SOURCE_ROOT; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; + C0CFB939D5B8C9910708B314FCA3AB15 /* PPTopMostController-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "PPTopMostController-dummy.m"; sourceTree = ""; }; + C611DE38A047C878B4C6131C68F8A485 /* NotificationBackgroundWarning@2x.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; path = "NotificationBackgroundWarning@2x.png"; sourceTree = ""; }; + C9BAB675D080D11807A83F8FD66BA317 /* HexColors.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = HexColors.m; path = Classes/HexColors.m; sourceTree = ""; }; + CD49EA750E73821420BD4D3B5783C573 /* NotificationBackgroundErrorIcon.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; path = NotificationBackgroundErrorIcon.png; sourceTree = ""; }; + D84E2D4054C2A4EC07F8E98121F0ECF7 /* NotificationBackgroundErrorIcon@2x.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; path = "NotificationBackgroundErrorIcon@2x.png"; sourceTree = ""; }; + DF428199C7900A68E522809505182AE8 /* RMessageView.xib */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = file.xib; path = RMessageView.xib; sourceTree = ""; }; + E0B75E5BD7E9DDDBBB5D8C00709D4C41 /* HexColors.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = HexColors.xcconfig; sourceTree = ""; }; + E178891019F9EBC840C5687FB5D760B8 /* AlternativeDesign.json */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.json; path = AlternativeDesign.json; sourceTree = ""; }; + E7B56304CE2DA8850A548481AB2B9395 /* UITabBarController+PPTopMostController.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "UITabBarController+PPTopMostController.m"; path = "PPTopMostController-Files/UITabBarController+PPTopMostController.m"; sourceTree = ""; }; + E90E1344A7C361D7747623BC9D1E9EAB /* NotificationButtonBackground@2x.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; path = "NotificationButtonBackground@2x.png"; sourceTree = ""; }; + EB30BBEC761F07F7B38BCB5E7CADEA1D /* NotificationBackgroundMessage.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; path = NotificationBackgroundMessage.png; sourceTree = ""; }; + F3099F0486CC0E5E24F68E3084393771 /* NotificationBackgroundWarningIcon.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; path = NotificationBackgroundWarningIcon.png; sourceTree = ""; }; + FBA35DC7046F26703A3BA16FDBF0E408 /* NotificationBackgroundSuccessIcon@2x.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; path = "NotificationBackgroundSuccessIcon@2x.png"; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 1CA9E4B06AF82B7C67DC302218579D08 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 3642DD78055E38F7FB67BE17CFDD7A05 /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + A75FF1684F0D5B60C247056DD947A8C6 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 85B98247C863155692CCDAE11423E411 /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + AEF78BE1E27D21F656081E3C94B14996 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + D75BBF3A6C6D3745AE85273CEC34CFCA /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + DE6E52D7ADE0C76F0E1FE5BDFF47591D /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 067F9DACC53D2F2B2D616F8917E25467 /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 037C0CA694176A3C0915F62C9D20B3E6 /* Targets Support Files */ = { + isa = PBXGroup; + children = ( + B3D1D13E0C6553800746CB8FD61CF946 /* Pods */, + ); + name = "Targets Support Files"; + sourceTree = ""; + }; + 09A04ED5ADC2B6D0D311915898379336 /* RMessage */ = { + isa = PBXGroup; + children = ( + 56CFAB44E0BA7F9D9ECEF855A281C6B0 /* Resources */, + 3E438FDEECC180AC7ECFEFEA67BD84DB /* RMessage */, + FCB7317C5276B45960563882592F48BA /* Support Files */, + ); + name = RMessage; + path = ../..; + sourceTree = ""; + }; + 3E438FDEECC180AC7ECFEFEA67BD84DB /* RMessage */ = { + isa = PBXGroup; + children = ( + 0BF9E1B5B0B3AA74BF0B0A3369A14A3E /* RMessage.h */, + 2D73840065923F8038A892201689702A /* RMessage.m */, + 54D93A189FABC413AED0AE7DAE215206 /* RMessageView.h */, + 5FD8F456E674D220D2221D71BA6655FD /* RMessageView.m */, + ); + path = RMessage; + sourceTree = ""; + }; + 41345AB4A04CCED087A3D5231A8712A3 /* PPTopMostController */ = { + isa = PBXGroup; + children = ( + 4343F23FBF438B643B8CF50EEF5841B3 /* PPTopMostControllerProtocol.h */, + 8B834D2305652A7C1E7901DC677BAE06 /* UINavigationController+PPTopMostController.h */, + 328BB210EED741D0951654C4EA48BDAD /* UINavigationController+PPTopMostController.m */, + 3F67BD84B208B68CE8510151ED5462EC /* UITabBarController+PPTopMostController.h */, + E7B56304CE2DA8850A548481AB2B9395 /* UITabBarController+PPTopMostController.m */, + 6FE18BF16B99DA5B588DF7FEDE455422 /* UIViewController+PPTopMostController.h */, + 5F8231D271F29202100DB59055D2C4A7 /* UIViewController+PPTopMostController.m */, + FC007F005C2617666B0E68BA7281FD18 /* Support Files */, + ); + path = PPTopMostController; + sourceTree = ""; + }; + 56CFAB44E0BA7F9D9ECEF855A281C6B0 /* Resources */ = { + isa = PBXGroup; + children = ( + AFE32F938B27A257FD3E2D02E4733809 /* RMessage */, + ); + name = Resources; + sourceTree = ""; + }; + 5F9DDD8E96B8CF836DFC3C84A5C609EB /* Support Files */ = { + isa = PBXGroup; + children = ( + E0B75E5BD7E9DDDBBB5D8C00709D4C41 /* HexColors.xcconfig */, + 360DD393B54068DF0DC094E980B10B08 /* HexColors-dummy.m */, + 244269FA4FABEFBE123CD786CB007189 /* HexColors-prefix.pch */, + ); + name = "Support Files"; + path = "../Target Support Files/HexColors"; + sourceTree = ""; + }; + 7DB346D0F39D3F0E887471402A8071AB = { + isa = PBXGroup; + children = ( + BA6428E9F66FD5A23C0A2E06ED26CD2F /* Podfile */, + B9BC57F5D0B6D3B9938C2019FBC259DF /* Development Pods */, + BC3CA7F9E30CC8F7E2DD044DD34432FC /* Frameworks */, + 84D278C2C4D8EC4CE0FEA99DC0F3E9F4 /* Pods */, + D2E4BA12488B9DFC3C4BF3FBC8B39321 /* Products */, + 037C0CA694176A3C0915F62C9D20B3E6 /* Targets Support Files */, + ); + sourceTree = ""; + }; + 84D278C2C4D8EC4CE0FEA99DC0F3E9F4 /* Pods */ = { + isa = PBXGroup; + children = ( + E55B395346EEFAAB4CB40F65E4945D94 /* HexColors */, + 41345AB4A04CCED087A3D5231A8712A3 /* PPTopMostController */, + ); + name = Pods; + sourceTree = ""; + }; + AFE32F938B27A257FD3E2D02E4733809 /* RMessage */ = { + isa = PBXGroup; + children = ( + EB074D808F72A90D9EA215119B3DE579 /* Assets */, + E324728B9C62A3AE725002E3DD113501 /* Resources */, + ); + path = RMessage; + sourceTree = ""; + }; + B3D1D13E0C6553800746CB8FD61CF946 /* Pods */ = { + isa = PBXGroup; + children = ( + 37DB56D75062CC75FCB0966E1C6E8A8E /* Pods-acknowledgements.markdown */, + 10834806BD7B412BC24F347361FA2C8E /* Pods-acknowledgements.plist */, + 272643F56613CA0D336AE3DBF19DC404 /* Pods-dummy.m */, + 6911BECA35E7518D864239B7E898EEF3 /* Pods-frameworks.sh */, + A1A36D34413696BE466E2CA0AFF194DA /* Pods-resources.sh */, + 4E762F23EC34ED4A6FF3312D84E33A40 /* Pods.debug.xcconfig */, + 98C98CDFB3F20F2925F6CD1F141BB14F /* Pods.release.xcconfig */, + ); + name = Pods; + path = "Target Support Files/Pods"; + sourceTree = ""; + }; + B9BC57F5D0B6D3B9938C2019FBC259DF /* Development Pods */ = { + isa = PBXGroup; + children = ( + 09A04ED5ADC2B6D0D311915898379336 /* RMessage */, + ); + name = "Development Pods"; + sourceTree = ""; + }; + BC3CA7F9E30CC8F7E2DD044DD34432FC /* Frameworks */ = { + isa = PBXGroup; + children = ( + BF6342C8B29F4CEEA088EFF7AB4DE362 /* iOS */, + ); + name = Frameworks; + sourceTree = ""; + }; + BF6342C8B29F4CEEA088EFF7AB4DE362 /* iOS */ = { + isa = PBXGroup; + children = ( + 3E4E89230EF59BC255123B67864ACF77 /* Foundation.framework */, + ); + name = iOS; + sourceTree = ""; + }; + D2E4BA12488B9DFC3C4BF3FBC8B39321 /* Products */ = { + isa = PBXGroup; + children = ( + B3D45C1BE24BDC76D60F8D12623E1106 /* libHexColors.a */, + 0B9F93FB2054B84208D96EF3C93F57F1 /* libPods.a */, + B7034106E1B0D65F9359BA35BB7FB9EE /* libPPTopMostController.a */, + 603B7D7A97FB39877B9FC4CB9F09ABF5 /* libRMessage.a */, + ); + name = Products; + sourceTree = ""; + }; + E324728B9C62A3AE725002E3DD113501 /* Resources */ = { + isa = PBXGroup; + children = ( + DF428199C7900A68E522809505182AE8 /* RMessageView.xib */, + ); + path = Resources; + sourceTree = ""; + }; + E55B395346EEFAAB4CB40F65E4945D94 /* HexColors */ = { + isa = PBXGroup; + children = ( + 316870125844702EBA1FBE955FE47E92 /* HexColors.h */, + C9BAB675D080D11807A83F8FD66BA317 /* HexColors.m */, + 5F9DDD8E96B8CF836DFC3C84A5C609EB /* Support Files */, + ); + path = HexColors; + sourceTree = ""; + }; + EB074D808F72A90D9EA215119B3DE579 /* Assets */ = { + isa = PBXGroup; + children = ( + E178891019F9EBC840C5687FB5D760B8 /* AlternativeDesign.json */, + 15018C95B6E0DBAD01B2B988940433E1 /* NotificationBackgroundError.png */, + 951853E52F17622C80D1B3EBE27A9267 /* NotificationBackgroundError@2x.png */, + CD49EA750E73821420BD4D3B5783C573 /* NotificationBackgroundErrorIcon.png */, + D84E2D4054C2A4EC07F8E98121F0ECF7 /* NotificationBackgroundErrorIcon@2x.png */, + EB30BBEC761F07F7B38BCB5E7CADEA1D /* NotificationBackgroundMessage.png */, + 98431717943EC65E622A673BFE79754A /* NotificationBackgroundMessage@2x.png */, + 09E35BFD539CDB3825221F71E0B7DD85 /* NotificationBackgroundSuccess.png */, + 409AD58F7FBA2833D3D06325A38A6348 /* NotificationBackgroundSuccess@2x.png */, + 9A8BE4231801B9D5432534836ACCF85E /* NotificationBackgroundSuccessIcon.png */, + FBA35DC7046F26703A3BA16FDBF0E408 /* NotificationBackgroundSuccessIcon@2x.png */, + 26A1A16F407081A9077669811C9FE78A /* NotificationBackgroundWarning.png */, + C611DE38A047C878B4C6131C68F8A485 /* NotificationBackgroundWarning@2x.png */, + F3099F0486CC0E5E24F68E3084393771 /* NotificationBackgroundWarningIcon.png */, + 12B02F3709E2B9CD1BA6F27ED67F4602 /* NotificationBackgroundWarningIcon@2x.png */, + 7A6F93B1C0E91F535877FBABBA0EEEE6 /* NotificationButtonBackground.png */, + E90E1344A7C361D7747623BC9D1E9EAB /* NotificationButtonBackground@2x.png */, + 4FFA578BD9CB365254B3CE12929A3A5E /* RMessageDefaultDesign.json */, + ); + path = Assets; + sourceTree = ""; + }; + FC007F005C2617666B0E68BA7281FD18 /* Support Files */ = { + isa = PBXGroup; + children = ( + 7E1D69932A80D3AB72A769B50E0391E3 /* PPTopMostController.xcconfig */, + C0CFB939D5B8C9910708B314FCA3AB15 /* PPTopMostController-dummy.m */, + 179E81B3B20AD8434A3BB528029889B7 /* PPTopMostController-prefix.pch */, + ); + name = "Support Files"; + path = "../Target Support Files/PPTopMostController"; + sourceTree = ""; + }; + FCB7317C5276B45960563882592F48BA /* Support Files */ = { + isa = PBXGroup; + children = ( + 54BC84662E53D1F0C081E99F9C16FA6F /* RMessage.xcconfig */, + 430FA11FFF0BEE864CF1C6A8E6BBFDDB /* RMessage-dummy.m */, + 1686AB8A2BFCB742CE7C049ED1650607 /* RMessage-prefix.pch */, + ); + name = "Support Files"; + path = "Example/Pods/Target Support Files/RMessage"; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + 248CF9A0F772655E57B8CDA811178539 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + D7C615A1C2435EB5EF38B66447359DB4 /* PPTopMostControllerProtocol.h in Headers */, + B39009ACA5609B50E7E0172AB9FE27E5 /* UINavigationController+PPTopMostController.h in Headers */, + 9F44B438EA8F0425A9A1A680BC4FDE32 /* UITabBarController+PPTopMostController.h in Headers */, + 527B65410811856F9B0D17CA02B9FB66 /* UIViewController+PPTopMostController.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 6C6136C2C41E7C5BD0D81456844ACBB7 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + C036E17644646304E03BF60C127A21FC /* HexColors.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + F94677C6F183D2FF235B87C354FE03CC /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 16F3CA7AB9375167F5452842C213BEC1 /* RMessage.h in Headers */, + 5E2581740536B8A44AF50DBA7E3B07E5 /* RMessageView.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + 0B41D180E700F78F2A32720E1BBE07D4 /* PPTopMostController */ = { + isa = PBXNativeTarget; + buildConfigurationList = AC969276CDC1F79C2E13111573B8F257 /* Build configuration list for PBXNativeTarget "PPTopMostController" */; + buildPhases = ( + 82D978017BE74226813D1C99D362EA4C /* Sources */, + A75FF1684F0D5B60C247056DD947A8C6 /* Frameworks */, + 248CF9A0F772655E57B8CDA811178539 /* Headers */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = PPTopMostController; + productName = PPTopMostController; + productReference = B7034106E1B0D65F9359BA35BB7FB9EE /* libPPTopMostController.a */; + productType = "com.apple.product-type.library.static"; + }; + AA806CA5C06DE1A597C51352EA116BB2 /* Pods */ = { + isa = PBXNativeTarget; + buildConfigurationList = 671ED3F21E531B9FBCBED4247D0F7427 /* Build configuration list for PBXNativeTarget "Pods" */; + buildPhases = ( + 2EF2D60924D2315715FD0B35670A5C07 /* Sources */, + DE6E52D7ADE0C76F0E1FE5BDFF47591D /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + 6C721BC556420CAE4A2C8895C60323C2 /* PBXTargetDependency */, + B20C5C4DEF9D432AAF1002196E3089F6 /* PBXTargetDependency */, + 6839F59947D28884BF31562C3CD0AE87 /* PBXTargetDependency */, + ); + name = Pods; + productName = Pods; + productReference = 0B9F93FB2054B84208D96EF3C93F57F1 /* libPods.a */; + productType = "com.apple.product-type.library.static"; + }; + C70D6D047BA3EAC9F94695B5CB2AADF4 /* RMessage */ = { + isa = PBXNativeTarget; + buildConfigurationList = 4E7DD7DD11805F91319385D9728D3029 /* Build configuration list for PBXNativeTarget "RMessage" */; + buildPhases = ( + D30629895002C650C442E84ED0DDAAE7 /* Sources */, + AEF78BE1E27D21F656081E3C94B14996 /* Frameworks */, + F94677C6F183D2FF235B87C354FE03CC /* Headers */, + ); + buildRules = ( + ); + dependencies = ( + 80CC2F722F0C756D3F3151334796374C /* PBXTargetDependency */, + F0140EB70D014B90D0169631BA29EB50 /* PBXTargetDependency */, + ); + name = RMessage; + productName = RMessage; + productReference = 603B7D7A97FB39877B9FC4CB9F09ABF5 /* libRMessage.a */; + productType = "com.apple.product-type.library.static"; + }; + E9EF397B95762DDB254C71DDCB4B1381 /* HexColors */ = { + isa = PBXNativeTarget; + buildConfigurationList = ACABDDD53049FF494333AA35F2BA7BF8 /* Build configuration list for PBXNativeTarget "HexColors" */; + buildPhases = ( + B90C033F980A1DA86821F8653933F53E /* Sources */, + 1CA9E4B06AF82B7C67DC302218579D08 /* Frameworks */, + 6C6136C2C41E7C5BD0D81456844ACBB7 /* Headers */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = HexColors; + productName = HexColors; + productReference = B3D45C1BE24BDC76D60F8D12623E1106 /* libHexColors.a */; + productType = "com.apple.product-type.library.static"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + D41D8CD98F00B204E9800998ECF8427E /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 0700; + LastUpgradeCheck = 0700; + }; + buildConfigurationList = 2D8E8EC45A3A1A1D94AE762CB5028504 /* Build configuration list for PBXProject "Pods" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + ); + mainGroup = 7DB346D0F39D3F0E887471402A8071AB; + productRefGroup = D2E4BA12488B9DFC3C4BF3FBC8B39321 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + E9EF397B95762DDB254C71DDCB4B1381 /* HexColors */, + AA806CA5C06DE1A597C51352EA116BB2 /* Pods */, + 0B41D180E700F78F2A32720E1BBE07D4 /* PPTopMostController */, + C70D6D047BA3EAC9F94695B5CB2AADF4 /* RMessage */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXSourcesBuildPhase section */ + 2EF2D60924D2315715FD0B35670A5C07 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 23C8904F392BDFCBF9A4F18B642FA665 /* Pods-dummy.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 82D978017BE74226813D1C99D362EA4C /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 3702DC2695772A30CE6A012DE48C93F9 /* PPTopMostController-dummy.m in Sources */, + 3C02E1799B3CEF2975D812A3A988FA4E /* UINavigationController+PPTopMostController.m in Sources */, + 1077503710160776AF36AF031B9ED7F3 /* UITabBarController+PPTopMostController.m in Sources */, + 29DAC922DD5ABE7E79C45C8F052A2425 /* UIViewController+PPTopMostController.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + B90C033F980A1DA86821F8653933F53E /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 9EA8B82625D30CCA49775FD84E8E3BF4 /* HexColors-dummy.m in Sources */, + 20C273F0880A2105628D056158875920 /* HexColors.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + D30629895002C650C442E84ED0DDAAE7 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 7ABCD8EC48C2F7D62004D143D66C678D /* RMessage-dummy.m in Sources */, + 8E96BAEFA26D00FFD1E1B006FDCB9C13 /* RMessage.m in Sources */, + BD39580F9EFC908BC6AAB2548C311846 /* RMessageView.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 6839F59947D28884BF31562C3CD0AE87 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = RMessage; + target = C70D6D047BA3EAC9F94695B5CB2AADF4 /* RMessage */; + targetProxy = B786F79444CFFCA32102CC4EF8391341 /* PBXContainerItemProxy */; + }; + 6C721BC556420CAE4A2C8895C60323C2 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = HexColors; + target = E9EF397B95762DDB254C71DDCB4B1381 /* HexColors */; + targetProxy = F719E7EA3B441D528503D441E34B17B0 /* PBXContainerItemProxy */; + }; + 80CC2F722F0C756D3F3151334796374C /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = HexColors; + target = E9EF397B95762DDB254C71DDCB4B1381 /* HexColors */; + targetProxy = D5448C4E8321E0EC09409DFF9DB768F3 /* PBXContainerItemProxy */; + }; + B20C5C4DEF9D432AAF1002196E3089F6 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = PPTopMostController; + target = 0B41D180E700F78F2A32720E1BBE07D4 /* PPTopMostController */; + targetProxy = 0ED52E0AC5ED49BCB6C9FEAE5F7E622F /* PBXContainerItemProxy */; + }; + F0140EB70D014B90D0169631BA29EB50 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = PPTopMostController; + target = 0B41D180E700F78F2A32720E1BBE07D4 /* PPTopMostController */; + targetProxy = EE6FB2DF110DD09FA6C40DB92F3B4C9C /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin XCBuildConfiguration section */ + 2E0CCFDBE72C316F40761AF8445AC523 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 98C98CDFB3F20F2925F6CD1F141BB14F /* Pods.release.xcconfig */; + buildSettings = { + ENABLE_STRICT_OBJC_MSGSEND = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MACH_O_TYPE = staticlib; + MTL_ENABLE_DEBUG_INFO = NO; + OTHER_LDFLAGS = ""; + OTHER_LIBTOOLFLAGS = ""; + PODS_ROOT = "$(SRCROOT)"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + }; + name = Release; + }; + 309CC7E14BD0C20ECE1245BCD8E61993 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 54BC84662E53D1F0C081E99F9C16FA6F /* RMessage.xcconfig */; + buildSettings = { + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_PREFIX_HEADER = "Target Support Files/RMessage/RMessage-prefix.pch"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + OTHER_LDFLAGS = ""; + OTHER_LIBTOOLFLAGS = ""; + PRIVATE_HEADERS_FOLDER_PATH = ""; + PRODUCT_NAME = "$(TARGET_NAME)"; + PUBLIC_HEADERS_FOLDER_PATH = ""; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + }; + name = Release; + }; + 3C390DE79ACA040D2C7F85EF15A49313 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7E1D69932A80D3AB72A769B50E0391E3 /* PPTopMostController.xcconfig */; + buildSettings = { + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_PREFIX_HEADER = "Target Support Files/PPTopMostController/PPTopMostController-prefix.pch"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = YES; + OTHER_LDFLAGS = ""; + OTHER_LIBTOOLFLAGS = ""; + PRIVATE_HEADERS_FOLDER_PATH = ""; + PRODUCT_NAME = "$(TARGET_NAME)"; + PUBLIC_HEADERS_FOLDER_PATH = ""; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + }; + name = Debug; + }; + 714E1DCF85B5271D157A65D2AABF2050 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7E1D69932A80D3AB72A769B50E0391E3 /* PPTopMostController.xcconfig */; + buildSettings = { + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_PREFIX_HEADER = "Target Support Files/PPTopMostController/PPTopMostController-prefix.pch"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + OTHER_LDFLAGS = ""; + OTHER_LIBTOOLFLAGS = ""; + PRIVATE_HEADERS_FOLDER_PATH = ""; + PRODUCT_NAME = "$(TARGET_NAME)"; + PUBLIC_HEADERS_FOLDER_PATH = ""; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + }; + name = Release; + }; + A1696F083E904430A41D549E93B6ABE0 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 54BC84662E53D1F0C081E99F9C16FA6F /* RMessage.xcconfig */; + buildSettings = { + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_PREFIX_HEADER = "Target Support Files/RMessage/RMessage-prefix.pch"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = YES; + OTHER_LDFLAGS = ""; + OTHER_LIBTOOLFLAGS = ""; + PRIVATE_HEADERS_FOLDER_PATH = ""; + PRODUCT_NAME = "$(TARGET_NAME)"; + PUBLIC_HEADERS_FOLDER_PATH = ""; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + }; + name = Debug; + }; + A70CDAD61F90AC503C7D04CC22DA2923 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + ONLY_ACTIVE_ARCH = YES; + STRIP_INSTALLED_PRODUCT = NO; + SYMROOT = "${SRCROOT}/../build"; + }; + name = Debug; + }; + B2A1A3433A671EC474679E92C4F4A970 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = E0B75E5BD7E9DDDBBB5D8C00709D4C41 /* HexColors.xcconfig */; + buildSettings = { + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_PREFIX_HEADER = "Target Support Files/HexColors/HexColors-prefix.pch"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + OTHER_LDFLAGS = ""; + OTHER_LIBTOOLFLAGS = ""; + PRIVATE_HEADERS_FOLDER_PATH = ""; + PRODUCT_NAME = "$(TARGET_NAME)"; + PUBLIC_HEADERS_FOLDER_PATH = ""; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + }; + name = Release; + }; + E744AB36EAEFEF1EDFAB2722F0C047E4 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = E0B75E5BD7E9DDDBBB5D8C00709D4C41 /* HexColors.xcconfig */; + buildSettings = { + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_PREFIX_HEADER = "Target Support Files/HexColors/HexColors-prefix.pch"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = YES; + OTHER_LDFLAGS = ""; + OTHER_LIBTOOLFLAGS = ""; + PRIVATE_HEADERS_FOLDER_PATH = ""; + PRODUCT_NAME = "$(TARGET_NAME)"; + PUBLIC_HEADERS_FOLDER_PATH = ""; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + }; + name = Debug; + }; + EBA9FC6203743164CCAC71AAC608BAAC /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 4E762F23EC34ED4A6FF3312D84E33A40 /* Pods.debug.xcconfig */; + buildSettings = { + ENABLE_STRICT_OBJC_MSGSEND = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MACH_O_TYPE = staticlib; + MTL_ENABLE_DEBUG_INFO = YES; + OTHER_LDFLAGS = ""; + OTHER_LIBTOOLFLAGS = ""; + PODS_ROOT = "$(SRCROOT)"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + }; + name = Debug; + }; + FB45FFD90572718D82AB9092B750F0CA /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = YES; + ENABLE_NS_ASSERTIONS = NO; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_PREPROCESSOR_DEFINITIONS = "RELEASE=1"; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + STRIP_INSTALLED_PRODUCT = NO; + SYMROOT = "${SRCROOT}/../build"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 2D8E8EC45A3A1A1D94AE762CB5028504 /* Build configuration list for PBXProject "Pods" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + A70CDAD61F90AC503C7D04CC22DA2923 /* Debug */, + FB45FFD90572718D82AB9092B750F0CA /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 4E7DD7DD11805F91319385D9728D3029 /* Build configuration list for PBXNativeTarget "RMessage" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + A1696F083E904430A41D549E93B6ABE0 /* Debug */, + 309CC7E14BD0C20ECE1245BCD8E61993 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 671ED3F21E531B9FBCBED4247D0F7427 /* Build configuration list for PBXNativeTarget "Pods" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + EBA9FC6203743164CCAC71AAC608BAAC /* Debug */, + 2E0CCFDBE72C316F40761AF8445AC523 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + AC969276CDC1F79C2E13111573B8F257 /* Build configuration list for PBXNativeTarget "PPTopMostController" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 3C390DE79ACA040D2C7F85EF15A49313 /* Debug */, + 714E1DCF85B5271D157A65D2AABF2050 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + ACABDDD53049FF494333AA35F2BA7BF8 /* Build configuration list for PBXNativeTarget "HexColors" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + E744AB36EAEFEF1EDFAB2722F0C047E4 /* Debug */, + B2A1A3433A671EC474679E92C4F4A970 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = D41D8CD98F00B204E9800998ECF8427E /* Project object */; +} diff --git a/Example/Pods/Pods.xcodeproj/xcshareddata/xcschemes/RMessage.xcscheme b/Example/Pods/Pods.xcodeproj/xcshareddata/xcschemes/RMessage.xcscheme new file mode 100644 index 0000000..00890a8 --- /dev/null +++ b/Example/Pods/Pods.xcodeproj/xcshareddata/xcschemes/RMessage.xcscheme @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Example/Pods/Target Support Files/HexColors/HexColors-dummy.m b/Example/Pods/Target Support Files/HexColors/HexColors-dummy.m new file mode 100644 index 0000000..13d510c --- /dev/null +++ b/Example/Pods/Target Support Files/HexColors/HexColors-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_HexColors : NSObject +@end +@implementation PodsDummy_HexColors +@end diff --git a/Example/Pods/Target Support Files/HexColors/HexColors.xcconfig b/Example/Pods/Target Support Files/HexColors/HexColors.xcconfig new file mode 100644 index 0000000..2bb539b --- /dev/null +++ b/Example/Pods/Target Support Files/HexColors/HexColors.xcconfig @@ -0,0 +1,4 @@ +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Private/HexColors" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/HexColors" "${PODS_ROOT}/Headers/Public/PPTopMostController" "${PODS_ROOT}/Headers/Public/RMessage" +PODS_ROOT = ${SRCROOT} +SKIP_INSTALL = YES \ No newline at end of file diff --git a/Example/Pods/Target Support Files/PPTopMostController/PPTopMostController-dummy.m b/Example/Pods/Target Support Files/PPTopMostController/PPTopMostController-dummy.m new file mode 100644 index 0000000..8f57bac --- /dev/null +++ b/Example/Pods/Target Support Files/PPTopMostController/PPTopMostController-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_PPTopMostController : NSObject +@end +@implementation PodsDummy_PPTopMostController +@end diff --git a/Example/Pods/Target Support Files/PPTopMostController/PPTopMostController.xcconfig b/Example/Pods/Target Support Files/PPTopMostController/PPTopMostController.xcconfig new file mode 100644 index 0000000..f77702f --- /dev/null +++ b/Example/Pods/Target Support Files/PPTopMostController/PPTopMostController.xcconfig @@ -0,0 +1,4 @@ +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Private/PPTopMostController" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/HexColors" "${PODS_ROOT}/Headers/Public/PPTopMostController" "${PODS_ROOT}/Headers/Public/RMessage" +PODS_ROOT = ${SRCROOT} +SKIP_INSTALL = YES \ No newline at end of file diff --git a/Example/Pods/Target Support Files/Pods/Pods-acknowledgements.markdown b/Example/Pods/Target Support Files/Pods/Pods-acknowledgements.markdown new file mode 100644 index 0000000..b2a44da --- /dev/null +++ b/Example/Pods/Target Support Files/Pods/Pods-acknowledgements.markdown @@ -0,0 +1,47 @@ +# Acknowledgements +This application makes use of the following third party libraries: + +## HexColors + +The MIT License (MIT) +Copyright (c) 2012 Marius Landwehr marius.landwehr@gmail.com + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + +## PPTopMostController + +Copyright © 2013, Marian Paul +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. +The Software is provided "as is", without warranty of any kind, express or implied, including but not limited to the warranties of merchantability, fitness for a particular purpose and noninfringement. In no event shall the authors or copyright holders be liable for any claim, damages or other liability, whether in an action of contract, tort or otherwise, arising from, out of or in connection with the Software or the use or other dealings in the Software. +Except as contained in this notice, the name(s) of (the) Author shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from (the )Author. + + +## RMessage + +Copyright (c) 2014 Rendezvous, Inc. Adonis Peralta + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +Generated by CocoaPods - http://cocoapods.org diff --git a/Example/Pods/Target Support Files/Pods/Pods-acknowledgements.plist b/Example/Pods/Target Support Files/Pods/Pods-acknowledgements.plist new file mode 100644 index 0000000..67709f2 --- /dev/null +++ b/Example/Pods/Target Support Files/Pods/Pods-acknowledgements.plist @@ -0,0 +1,85 @@ + + + + + PreferenceSpecifiers + + + FooterText + This application makes use of the following third party libraries: + Title + Acknowledgements + Type + PSGroupSpecifier + + + FooterText + The MIT License (MIT) +Copyright (c) 2012 Marius Landwehr marius.landwehr@gmail.com + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + Title + HexColors + Type + PSGroupSpecifier + + + FooterText + Copyright © 2013, Marian Paul +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. +The Software is provided "as is", without warranty of any kind, express or implied, including but not limited to the warranties of merchantability, fitness for a particular purpose and noninfringement. In no event shall the authors or copyright holders be liable for any claim, damages or other liability, whether in an action of contract, tort or otherwise, arising from, out of or in connection with the Software or the use or other dealings in the Software. +Except as contained in this notice, the name(s) of (the) Author shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from (the )Author. + + Title + PPTopMostController + Type + PSGroupSpecifier + + + FooterText + Copyright (c) 2014 Rendezvous, Inc. Adonis Peralta <donileo@gmail.com> + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + + Title + RMessage + Type + PSGroupSpecifier + + + FooterText + Generated by CocoaPods - http://cocoapods.org + Title + + Type + PSGroupSpecifier + + + StringsTable + Acknowledgements + Title + Acknowledgements + + diff --git a/Example/Pods/Target Support Files/Pods/Pods-dummy.m b/Example/Pods/Target Support Files/Pods/Pods-dummy.m new file mode 100644 index 0000000..ade64bd --- /dev/null +++ b/Example/Pods/Target Support Files/Pods/Pods-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_Pods : NSObject +@end +@implementation PodsDummy_Pods +@end diff --git a/Example/Pods/Target Support Files/Pods/Pods-frameworks.sh b/Example/Pods/Target Support Files/Pods/Pods-frameworks.sh new file mode 100755 index 0000000..6f76344 --- /dev/null +++ b/Example/Pods/Target Support Files/Pods/Pods-frameworks.sh @@ -0,0 +1,84 @@ +#!/bin/sh +set -e + +echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" +mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + +SWIFT_STDLIB_PATH="${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" + +install_framework() +{ + if [ -r "${BUILT_PRODUCTS_DIR}/$1" ]; then + local source="${BUILT_PRODUCTS_DIR}/$1" + elif [ -r "${BUILT_PRODUCTS_DIR}/$(basename "$1")" ]; then + local source="${BUILT_PRODUCTS_DIR}/$(basename "$1")" + elif [ -r "$1" ]; then + local source="$1" + fi + + local destination="${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + + if [ -L "${source}" ]; then + echo "Symlinked..." + source="$(readlink "${source}")" + fi + + # use filter instead of exclude so missing patterns dont' throw errors + echo "rsync -av --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\"" + rsync -av --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}" + + local basename + basename="$(basename -s .framework "$1")" + binary="${destination}/${basename}.framework/${basename}" + if ! [ -r "$binary" ]; then + binary="${destination}/${basename}" + fi + + # Strip invalid architectures so "fat" simulator / device frameworks work on device + if [[ "$(file "$binary")" == *"dynamically linked shared library"* ]]; then + strip_invalid_archs "$binary" + fi + + # Resign the code if required by the build settings to avoid unstable apps + code_sign_if_enabled "${destination}/$(basename "$1")" + + # Embed linked Swift runtime libraries. No longer necessary as of Xcode 7. + if [ "${XCODE_VERSION_MAJOR}" -lt 7 ]; then + local swift_runtime_libs + swift_runtime_libs=$(xcrun otool -LX "$binary" | grep --color=never @rpath/libswift | sed -E s/@rpath\\/\(.+dylib\).*/\\1/g | uniq -u && exit ${PIPESTATUS[0]}) + for lib in $swift_runtime_libs; do + echo "rsync -auv \"${SWIFT_STDLIB_PATH}/${lib}\" \"${destination}\"" + rsync -auv "${SWIFT_STDLIB_PATH}/${lib}" "${destination}" + code_sign_if_enabled "${destination}/${lib}" + done + fi +} + +# Signs a framework with the provided identity +code_sign_if_enabled() { + if [ -n "${EXPANDED_CODE_SIGN_IDENTITY}" -a "${CODE_SIGNING_REQUIRED}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then + # Use the current code_sign_identitiy + echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}" + echo "/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} --preserve-metadata=identifier,entitlements \"$1\"" + /usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} --preserve-metadata=identifier,entitlements "$1" + fi +} + +# Strip invalid architectures +strip_invalid_archs() { + binary="$1" + # Get architectures for current file + archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | rev)" + stripped="" + for arch in $archs; do + if ! [[ "${VALID_ARCHS}" == *"$arch"* ]]; then + # Strip non-valid architectures in-place + lipo -remove "$arch" -output "$binary" "$binary" || exit 1 + stripped="$stripped $arch" + fi + done + if [[ "$stripped" ]]; then + echo "Stripped $binary of architectures:$stripped" + fi +} + diff --git a/Example/Pods/Target Support Files/Pods/Pods-resources.sh b/Example/Pods/Target Support Files/Pods/Pods-resources.sh new file mode 100755 index 0000000..19d8850 --- /dev/null +++ b/Example/Pods/Target Support Files/Pods/Pods-resources.sh @@ -0,0 +1,137 @@ +#!/bin/sh +set -e + +mkdir -p "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" + +RESOURCES_TO_COPY=${PODS_ROOT}/resources-to-copy-${TARGETNAME}.txt +> "$RESOURCES_TO_COPY" + +XCASSET_FILES=() + +realpath() { + DIRECTORY="$(cd "${1%/*}" && pwd)" + FILENAME="${1##*/}" + echo "$DIRECTORY/$FILENAME" +} + +install_resource() +{ + case $1 in + *.storyboard) + echo "ibtool --reference-external-strings-file --errors --warnings --notices --output-format human-readable-text --compile ${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$1\" .storyboard`.storyboardc ${PODS_ROOT}/$1 --sdk ${SDKROOT}" + ibtool --reference-external-strings-file --errors --warnings --notices --output-format human-readable-text --compile "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$1\" .storyboard`.storyboardc" "${PODS_ROOT}/$1" --sdk "${SDKROOT}" + ;; + *.xib) + echo "ibtool --reference-external-strings-file --errors --warnings --notices --output-format human-readable-text --compile ${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$1\" .xib`.nib ${PODS_ROOT}/$1 --sdk ${SDKROOT}" + ibtool --reference-external-strings-file --errors --warnings --notices --output-format human-readable-text --compile "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$1\" .xib`.nib" "${PODS_ROOT}/$1" --sdk "${SDKROOT}" + ;; + *.framework) + echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + echo "rsync -av ${PODS_ROOT}/$1 ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + rsync -av "${PODS_ROOT}/$1" "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + ;; + *.xcdatamodel) + echo "xcrun momc \"${PODS_ROOT}/$1\" \"${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1"`.mom\"" + xcrun momc "${PODS_ROOT}/$1" "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1" .xcdatamodel`.mom" + ;; + *.xcdatamodeld) + echo "xcrun momc \"${PODS_ROOT}/$1\" \"${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1" .xcdatamodeld`.momd\"" + xcrun momc "${PODS_ROOT}/$1" "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1" .xcdatamodeld`.momd" + ;; + *.xcmappingmodel) + echo "xcrun mapc \"${PODS_ROOT}/$1\" \"${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1" .xcmappingmodel`.cdm\"" + xcrun mapc "${PODS_ROOT}/$1" "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1" .xcmappingmodel`.cdm" + ;; + *.xcassets) + ABSOLUTE_XCASSET_FILE=$(realpath "${PODS_ROOT}/$1") + XCASSET_FILES+=("$ABSOLUTE_XCASSET_FILE") + ;; + /*) + echo "$1" + echo "$1" >> "$RESOURCES_TO_COPY" + ;; + *) + echo "${PODS_ROOT}/$1" + echo "${PODS_ROOT}/$1" >> "$RESOURCES_TO_COPY" + ;; + esac +} +if [[ "$CONFIGURATION" == "Debug" ]]; then + install_resource "../../RMessage/Resources/RMessageView.xib" + install_resource "../../RMessage/Assets/AlternativeDesign.json" + install_resource "../../RMessage/Assets/NotificationBackgroundError.png" + install_resource "../../RMessage/Assets/NotificationBackgroundError@2x.png" + install_resource "../../RMessage/Assets/NotificationBackgroundErrorIcon.png" + install_resource "../../RMessage/Assets/NotificationBackgroundErrorIcon@2x.png" + install_resource "../../RMessage/Assets/NotificationBackgroundMessage.png" + install_resource "../../RMessage/Assets/NotificationBackgroundMessage@2x.png" + install_resource "../../RMessage/Assets/NotificationBackgroundSuccess.png" + install_resource "../../RMessage/Assets/NotificationBackgroundSuccess@2x.png" + install_resource "../../RMessage/Assets/NotificationBackgroundSuccessIcon.png" + install_resource "../../RMessage/Assets/NotificationBackgroundSuccessIcon@2x.png" + install_resource "../../RMessage/Assets/NotificationBackgroundWarning.png" + install_resource "../../RMessage/Assets/NotificationBackgroundWarning@2x.png" + install_resource "../../RMessage/Assets/NotificationBackgroundWarningIcon.png" + install_resource "../../RMessage/Assets/NotificationBackgroundWarningIcon@2x.png" + install_resource "../../RMessage/Assets/NotificationButtonBackground.png" + install_resource "../../RMessage/Assets/NotificationButtonBackground@2x.png" + install_resource "../../RMessage/Assets/RMessageDefaultDesign.json" +fi +if [[ "$CONFIGURATION" == "Release" ]]; then + install_resource "../../RMessage/Resources/RMessageView.xib" + install_resource "../../RMessage/Assets/AlternativeDesign.json" + install_resource "../../RMessage/Assets/NotificationBackgroundError.png" + install_resource "../../RMessage/Assets/NotificationBackgroundError@2x.png" + install_resource "../../RMessage/Assets/NotificationBackgroundErrorIcon.png" + install_resource "../../RMessage/Assets/NotificationBackgroundErrorIcon@2x.png" + install_resource "../../RMessage/Assets/NotificationBackgroundMessage.png" + install_resource "../../RMessage/Assets/NotificationBackgroundMessage@2x.png" + install_resource "../../RMessage/Assets/NotificationBackgroundSuccess.png" + install_resource "../../RMessage/Assets/NotificationBackgroundSuccess@2x.png" + install_resource "../../RMessage/Assets/NotificationBackgroundSuccessIcon.png" + install_resource "../../RMessage/Assets/NotificationBackgroundSuccessIcon@2x.png" + install_resource "../../RMessage/Assets/NotificationBackgroundWarning.png" + install_resource "../../RMessage/Assets/NotificationBackgroundWarning@2x.png" + install_resource "../../RMessage/Assets/NotificationBackgroundWarningIcon.png" + install_resource "../../RMessage/Assets/NotificationBackgroundWarningIcon@2x.png" + install_resource "../../RMessage/Assets/NotificationButtonBackground.png" + install_resource "../../RMessage/Assets/NotificationButtonBackground@2x.png" + install_resource "../../RMessage/Assets/RMessageDefaultDesign.json" +fi + +mkdir -p "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" +rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" +if [[ "${ACTION}" == "install" ]] && [[ "${SKIP_INSTALL}" == "NO" ]]; then + mkdir -p "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" + rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" +fi +rm -f "$RESOURCES_TO_COPY" + +if [[ -n "${WRAPPER_EXTENSION}" ]] && [ "`xcrun --find actool`" ] && [ -n "$XCASSET_FILES" ] +then + case "${TARGETED_DEVICE_FAMILY}" in + 1,2) + TARGET_DEVICE_ARGS="--target-device ipad --target-device iphone" + ;; + 1) + TARGET_DEVICE_ARGS="--target-device iphone" + ;; + 2) + TARGET_DEVICE_ARGS="--target-device ipad" + ;; + *) + TARGET_DEVICE_ARGS="--target-device mac" + ;; + esac + + # Find all other xcassets (this unfortunately includes those of path pods and other targets). + OTHER_XCASSETS=$(find "$PWD" -iname "*.xcassets" -type d) + while read line; do + if [[ $line != "`realpath $PODS_ROOT`*" ]]; then + XCASSET_FILES+=("$line") + fi + done <<<"$OTHER_XCASSETS" + + printf "%s\0" "${XCASSET_FILES[@]}" | xargs -0 xcrun actool --output-format human-readable-text --notices --warnings --platform "${PLATFORM_NAME}" --minimum-deployment-target "${IPHONEOS_DEPLOYMENT_TARGET}" ${TARGET_DEVICE_ARGS} --compress-pngs --compile "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" +fi diff --git a/Example/Pods/Target Support Files/Pods/Pods.debug.xcconfig b/Example/Pods/Target Support Files/Pods/Pods.debug.xcconfig new file mode 100644 index 0000000..524eb49 --- /dev/null +++ b/Example/Pods/Target Support Files/Pods/Pods.debug.xcconfig @@ -0,0 +1,5 @@ +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/HexColors" "${PODS_ROOT}/Headers/Public/PPTopMostController" "${PODS_ROOT}/Headers/Public/RMessage" +OTHER_CFLAGS = $(inherited) -isystem "${PODS_ROOT}/Headers/Public" -isystem "${PODS_ROOT}/Headers/Public/HexColors" -isystem "${PODS_ROOT}/Headers/Public/PPTopMostController" -isystem "${PODS_ROOT}/Headers/Public/RMessage" +OTHER_LDFLAGS = $(inherited) -ObjC -l"HexColors" -l"PPTopMostController" -l"RMessage" +PODS_ROOT = ${SRCROOT}/Pods \ No newline at end of file diff --git a/Example/Pods/Target Support Files/Pods/Pods.release.xcconfig b/Example/Pods/Target Support Files/Pods/Pods.release.xcconfig new file mode 100644 index 0000000..524eb49 --- /dev/null +++ b/Example/Pods/Target Support Files/Pods/Pods.release.xcconfig @@ -0,0 +1,5 @@ +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/HexColors" "${PODS_ROOT}/Headers/Public/PPTopMostController" "${PODS_ROOT}/Headers/Public/RMessage" +OTHER_CFLAGS = $(inherited) -isystem "${PODS_ROOT}/Headers/Public" -isystem "${PODS_ROOT}/Headers/Public/HexColors" -isystem "${PODS_ROOT}/Headers/Public/PPTopMostController" -isystem "${PODS_ROOT}/Headers/Public/RMessage" +OTHER_LDFLAGS = $(inherited) -ObjC -l"HexColors" -l"PPTopMostController" -l"RMessage" +PODS_ROOT = ${SRCROOT}/Pods \ No newline at end of file diff --git a/Example/Pods/Target Support Files/RMessage/RMessage-dummy.m b/Example/Pods/Target Support Files/RMessage/RMessage-dummy.m new file mode 100644 index 0000000..e5bac9b --- /dev/null +++ b/Example/Pods/Target Support Files/RMessage/RMessage-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_RMessage : NSObject +@end +@implementation PodsDummy_RMessage +@end diff --git a/Example/Pods/Target Support Files/RMessage/RMessage.xcconfig b/Example/Pods/Target Support Files/RMessage/RMessage.xcconfig new file mode 100644 index 0000000..9e67bc6 --- /dev/null +++ b/Example/Pods/Target Support Files/RMessage/RMessage.xcconfig @@ -0,0 +1,4 @@ +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Private/RMessage" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/HexColors" "${PODS_ROOT}/Headers/Public/PPTopMostController" "${PODS_ROOT}/Headers/Public/RMessage" +PODS_ROOT = ${SRCROOT} +SKIP_INSTALL = YES \ No newline at end of file diff --git a/Example/RMessage.xcodeproj/project.pbxproj b/Example/RMessage.xcodeproj/project.pbxproj new file mode 100644 index 0000000..f1373ab --- /dev/null +++ b/Example/RMessage.xcodeproj/project.pbxproj @@ -0,0 +1,376 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 13D35098CB928A2DF0BA1C1A /* libPods.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 369A336D2AF5EA764AE7E770 /* libPods.a */; }; + 7AD2C5BB1C16735F007C3580 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AD2C5BA1C16735F007C3580 /* main.m */; }; + 7AD2C5BE1C16735F007C3580 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AD2C5BD1C16735F007C3580 /* AppDelegate.m */; }; + 7AD2C5C41C16735F007C3580 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 7AD2C5C21C16735F007C3580 /* Main.storyboard */; }; + 7AD2C5C61C16735F007C3580 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 7AD2C5C51C16735F007C3580 /* Assets.xcassets */; }; + 7AD2C5D51C1673DF007C3580 /* DemoViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AD2C5D41C1673DF007C3580 /* DemoViewController.m */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 369A336D2AF5EA764AE7E770 /* libPods.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libPods.a; sourceTree = BUILT_PRODUCTS_DIR; }; + 7AD2C5B61C16735E007C3580 /* RMessage.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = RMessage.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 7AD2C5BA1C16735F007C3580 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 7AD2C5BC1C16735F007C3580 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 7AD2C5BD1C16735F007C3580 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 7AD2C5C31C16735F007C3580 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 7AD2C5C51C16735F007C3580 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 7AD2C5CA1C16735F007C3580 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 7AD2C5D31C1673DF007C3580 /* DemoViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DemoViewController.h; path = ../DemoViewController.h; sourceTree = ""; }; + 7AD2C5D41C1673DF007C3580 /* DemoViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = DemoViewController.m; path = ../DemoViewController.m; sourceTree = ""; }; + D9CC742C62BE6C0939CD549E /* Pods.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = Pods.release.xcconfig; path = "Pods/Target Support Files/Pods/Pods.release.xcconfig"; sourceTree = ""; }; + F5834E5A10291127301EF8E4 /* Pods.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = Pods.debug.xcconfig; path = "Pods/Target Support Files/Pods/Pods.debug.xcconfig"; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 7AD2C5B31C16735E007C3580 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 13D35098CB928A2DF0BA1C1A /* libPods.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 1966B751D2BF2A51DBF3588B /* Frameworks */ = { + isa = PBXGroup; + children = ( + 369A336D2AF5EA764AE7E770 /* libPods.a */, + ); + name = Frameworks; + sourceTree = ""; + }; + 7AD2C5AD1C16735E007C3580 = { + isa = PBXGroup; + children = ( + 7AD2C5B81C16735F007C3580 /* Demo */, + 7AD2C5B71C16735E007C3580 /* Products */, + D5809C0B5B5C21856BC5DA8E /* Pods */, + 1966B751D2BF2A51DBF3588B /* Frameworks */, + ); + sourceTree = ""; + }; + 7AD2C5B71C16735E007C3580 /* Products */ = { + isa = PBXGroup; + children = ( + 7AD2C5B61C16735E007C3580 /* RMessage.app */, + ); + name = Products; + sourceTree = ""; + }; + 7AD2C5B81C16735F007C3580 /* Demo */ = { + isa = PBXGroup; + children = ( + 7AD2C5BC1C16735F007C3580 /* AppDelegate.h */, + 7AD2C5BD1C16735F007C3580 /* AppDelegate.m */, + 7AD2C5D31C1673DF007C3580 /* DemoViewController.h */, + 7AD2C5D41C1673DF007C3580 /* DemoViewController.m */, + 7AD2C5C21C16735F007C3580 /* Main.storyboard */, + 7AD2C5C51C16735F007C3580 /* Assets.xcassets */, + 7AD2C5CA1C16735F007C3580 /* Info.plist */, + 7AD2C5B91C16735F007C3580 /* Supporting Files */, + ); + name = Demo; + path = RMessage; + sourceTree = ""; + }; + 7AD2C5B91C16735F007C3580 /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 7AD2C5BA1C16735F007C3580 /* main.m */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; + D5809C0B5B5C21856BC5DA8E /* Pods */ = { + isa = PBXGroup; + children = ( + F5834E5A10291127301EF8E4 /* Pods.debug.xcconfig */, + D9CC742C62BE6C0939CD549E /* Pods.release.xcconfig */, + ); + name = Pods; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 7AD2C5B51C16735E007C3580 /* RMessage */ = { + isa = PBXNativeTarget; + buildConfigurationList = 7AD2C5CD1C16735F007C3580 /* Build configuration list for PBXNativeTarget "RMessage" */; + buildPhases = ( + 56D03E78D6CF2D1E949FF57F /* Check Pods Manifest.lock */, + 7AD2C5B21C16735E007C3580 /* Sources */, + 7AD2C5B31C16735E007C3580 /* Frameworks */, + 7AD2C5B41C16735E007C3580 /* Resources */, + 26C08ACE53590D74F43B5E9D /* Embed Pods Frameworks */, + 2215EA575C91B399E0BDE45F /* Copy Pods Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = RMessage; + productName = RMessage; + productReference = 7AD2C5B61C16735E007C3580 /* RMessage.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 7AD2C5AE1C16735E007C3580 /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0710; + ORGANIZATIONNAME = "Rendezvous Inc."; + TargetAttributes = { + 7AD2C5B51C16735E007C3580 = { + CreatedOnToolsVersion = 7.1.1; + }; + }; + }; + buildConfigurationList = 7AD2C5B11C16735E007C3580 /* Build configuration list for PBXProject "RMessage" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 7AD2C5AD1C16735E007C3580; + productRefGroup = 7AD2C5B71C16735E007C3580 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 7AD2C5B51C16735E007C3580 /* RMessage */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 7AD2C5B41C16735E007C3580 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 7AD2C5C61C16735F007C3580 /* Assets.xcassets in Resources */, + 7AD2C5C41C16735F007C3580 /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 2215EA575C91B399E0BDE45F /* Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Copy Pods Resources"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods/Pods-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; + 26C08ACE53590D74F43B5E9D /* Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Embed Pods Frameworks"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods/Pods-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; + 56D03E78D6CF2D1E949FF57F /* Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Check Pods Manifest.lock"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n"; + showEnvVarsInLog = 0; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 7AD2C5B21C16735E007C3580 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 7AD2C5BE1C16735F007C3580 /* AppDelegate.m in Sources */, + 7AD2C5D51C1673DF007C3580 /* DemoViewController.m in Sources */, + 7AD2C5BB1C16735F007C3580 /* main.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 7AD2C5C21C16735F007C3580 /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 7AD2C5C31C16735F007C3580 /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 7AD2C5CB1C16735F007C3580 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 9.1; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 7AD2C5CC1C16735F007C3580 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 9.1; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 7AD2C5CE1C16735F007C3580 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = F5834E5A10291127301EF8E4 /* Pods.debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + INFOPLIST_FILE = RMessage/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.rendezvous.RMessage; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + 7AD2C5CF1C16735F007C3580 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = D9CC742C62BE6C0939CD549E /* Pods.release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + INFOPLIST_FILE = RMessage/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.rendezvous.RMessage; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 7AD2C5B11C16735E007C3580 /* Build configuration list for PBXProject "RMessage" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 7AD2C5CB1C16735F007C3580 /* Debug */, + 7AD2C5CC1C16735F007C3580 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 7AD2C5CD1C16735F007C3580 /* Build configuration list for PBXNativeTarget "RMessage" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 7AD2C5CE1C16735F007C3580 /* Debug */, + 7AD2C5CF1C16735F007C3580 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 7AD2C5AE1C16735E007C3580 /* Project object */; +} diff --git a/Example/RMessage.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/Example/RMessage.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..9d04848 --- /dev/null +++ b/Example/RMessage.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/Example/RMessage.xcworkspace/contents.xcworkspacedata b/Example/RMessage.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..03f42ee --- /dev/null +++ b/Example/RMessage.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,10 @@ + + + + + + + diff --git a/Example/RMessage/AppDelegate.h b/Example/RMessage/AppDelegate.h new file mode 100644 index 0000000..1f0fea8 --- /dev/null +++ b/Example/RMessage/AppDelegate.h @@ -0,0 +1,17 @@ +// +// AppDelegate.h +// RMessage +// +// Created by Adonis Peralta on 12/7/15. +// Copyright © 2015 Rendezvous Inc. All rights reserved. +// + +#import + +@interface AppDelegate : UIResponder + +@property (strong, nonatomic) UIWindow *window; + + +@end + diff --git a/Example/RMessage/AppDelegate.m b/Example/RMessage/AppDelegate.m new file mode 100644 index 0000000..0fb978a --- /dev/null +++ b/Example/RMessage/AppDelegate.m @@ -0,0 +1,45 @@ +// +// AppDelegate.m +// RMessage +// +// Created by Adonis Peralta on 12/7/15. +// Copyright © 2015 Rendezvous Inc. All rights reserved. +// + +#import "AppDelegate.h" + +@interface AppDelegate () + +@end + +@implementation AppDelegate + + +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + // Override point for customization after application launch. + return YES; +} + +- (void)applicationWillResignActive:(UIApplication *)application { + // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. + // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. +} + +- (void)applicationDidEnterBackground:(UIApplication *)application { + // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. + // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. +} + +- (void)applicationWillEnterForeground:(UIApplication *)application { + // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. +} + +- (void)applicationDidBecomeActive:(UIApplication *)application { + // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. +} + +- (void)applicationWillTerminate:(UIApplication *)application { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. +} + +@end diff --git a/Example/RMessage/Assets.xcassets/AppIcon.appiconset/Contents.json b/Example/RMessage/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..36d2c80 --- /dev/null +++ b/Example/RMessage/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,68 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Example/RMessage/Base.lproj/Main.storyboard b/Example/RMessage/Base.lproj/Main.storyboard new file mode 100644 index 0000000..0e3268b --- /dev/null +++ b/Example/RMessage/Base.lproj/Main.storyboard @@ -0,0 +1,266 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Example/RMessage/Info.plist b/Example/RMessage/Info.plist new file mode 100644 index 0000000..0ca4d80 --- /dev/null +++ b/Example/RMessage/Info.plist @@ -0,0 +1,45 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/Example/RMessage/main.m b/Example/RMessage/main.m new file mode 100644 index 0000000..7ce585f --- /dev/null +++ b/Example/RMessage/main.m @@ -0,0 +1,16 @@ +// +// main.m +// RMessage +// +// Created by Adonis Peralta on 12/7/15. +// Copyright © 2015 Rendezvous Inc. All rights reserved. +// + +#import +#import "AppDelegate.h" + +int main(int argc, char * argv[]) { + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..9e331dd --- /dev/null +++ b/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2014 Rendezvous, Inc. Adonis Peralta + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..9cccc46 --- /dev/null +++ b/README.md @@ -0,0 +1,169 @@ +RMessage +========== + +[![Twitter: @donileo](https://img.shields.io/badge/contact-@donileo-blue.svg?style=flat)](https://twitter.com/donileo) +[![Version](https://img.shields.io/cocoapods/v/RMessage.svg?style=flat)](http://cocoadocs.org/docsets/RMessage) +[![License](https://img.shields.io/cocoapods/l/RMessage.svg?style=flat)](http://cocoadocs.org/docsets/RMessage) +[![Platform](https://img.shields.io/cocoapods/p/RMessage.svg?style=flat)](http://cocoadocs.org/docsets/RMessage) + +# Intro + +Welcome to RMessage! RMessage is a reworking of the original [TSMessages](https://github.com/KrauseFx/TSMessages) library developed by Felix Krause (@KrauseFx). It modernizes/refactors a lot of the old code to be a lot cleaner, simpler to understand and more Objective-C idiomatic. Here are some of the changes: + +* Uses Autolayout instead of error prone spring/struts frame setting :). +* Various bugs have been fixed with regards to positioning of the notification view - For example: The view sizes itself properly under the status bar now allowing the status bar to show. +* Lots of Code Cleanup: + * Code base much cleaner and easier to understand by removing confusing patterns and duplication. + * Methods have been kept down to small LOC though with room for improvement. +* Allows the adding of custom designs without having to subclass the class by just adding new json "theme's" inside a custom design file of your choosing - Custom designs are additive so you still have access to the default designs as well. +* Various new customization options have also been added such as the ability to change: + * The opacity of individual notification messages via the "alpha" key in your custom Designs. + * Title and Subtitle labels no longer need to have the same shadows applied. +* Custom Design icon image no longer needs to be a fixed size. Notification sizes itself accordingly. +* No need to worry about missing a key in your design file. If not specified the default design takes over. +* Removed Old Blur code which was broken when iOS7 was introduced - There is no proper way to properly implement this currently so please dont submit features asking for this to be added until Apple adds an API enabling it. +* Better default view controller detection with use of PPTopMostController. TSMessages would assume the window root view controller would be the default view controller. This could cause issues with showing in modals for example. +* Removed the forcing of a specific design - TSMessages forced an iOS7 design or iOS6. Here there is no distinction - though the library is styled for iOS7 by default. +* Much more im sure :). +* + +# Description +The notification moves from the top of the screen underneath the navigation bar and stays there for a few seconds, depending on the length of the displayed text. To dismiss a notification before the time runs out, the user can swipe it to the top or just tap it. + +There are 4 different types already set up for you: Success, Error, Warning, Normal (take a look at the screenshots) + +It is very easy to add new notification types with a different design. + +1. Add the new type to the messageType enum. +2. Create a new configuration file and add it to RMessage by calling [RMessageView addNotificationDesignFromFile:] +3. Present the notification with your custom design by calling any of the class methods on RMessageView with the type as RMessageTypeCustom and the CustomTypeString equal to the key corresponding to your theme in the configuration file. + +**Take a look at the Example project to see how to use this library.** Make sure to open the workspace, not the project file, since the Example project uses cocoapods. + +Get in contact with the developer on Twitter: [donileo](https://twitter.com/donileo) (Adonis Peralta) + +# Installation + +## From CocoaPods +RMessage is available through [CocoaPods](https://cocoapods.org/). To install +it, simply add the following line to your Podfile: + + pod "RMessage" + +## Manually +Copy the source files RMessageView and RMessage into your project. Also copy the RMessageDesignDefault.json. + +# Usage + +To show notifications use the following code: + +```objective-c + [RMessage showNotificationWithTitle:@"Your Title" + subtitle:@"A description" + type:RMessageNotificationTypeError + customTypeString:nil]; + + + // Add a button inside the message + [RMessage showNotificationInViewController:self + title:@"Update available" + subtitle:@"Please update the app" + image:nil + type:RMessageNotificationTypeNormal + customTypeString:nil + duration:RMessageNotificationDurationAutomatic + callback:nil + buttonTitle:@"Update" + buttonCallback:^{ + NSLog(@"User tapped the button"); + } + atPosition:RMessageNotificationPositionTop + canBeDismissedByUser:YES]; + + + // Use a custom design file must be a json file though no need to include the json extension in the argument + [RMessage addCustomDesignFromFileWithName:@"AlternativeDesign"]; // has an @"alternate-error" key specified with custom design properties + [RMessage showNotificationWithTitle:@"Your Title" + subtitle:@"A description" + type:RMessageNotificationTypeCustom + customTypeString:@"alternate-error"]; +``` + +You can define a default view controller in which the notifications should be displayed: +```objective-c + [RMessage setDefaultViewController:myNavController]; +``` + +You can customize a message view, right before it's displayed, like setting an alpha value, or adding a custom subview +```objective-c + [RMessage setDelegate:self]; + + ... + + - (void)customizeMessageView:(RMessageView *)messageView + { + messageView.alpha = 0.4; + [messageView addSubview:...]; + } +``` + +You can customize message view elements using UIAppearance +```objective-c +#import "RMessageView.h" +@implementation AppDelegate +.... + +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions +{ +//If you want you can override some properties using UIAppearance +[[RMessageView appearance] setTitleFont:[UIFont boldSystemFontOfSize:6]]; +[[RMessageView appearance] setTitleTextColor:[UIColor redColor]]; +[[RMessageView appearance] setContentFont:[UIFont boldSystemFontOfSize:10]]; +[[RMessageView appearance] setContentTextColor:[UIColor greenColor]]; +[[RMessageView appearance] setErrorIcon:[UIImage imageNamed:@"NotificationButtonBackground"]]; +[[RMessageView appearance] setSuccessIcon:[UIImage imageNamed:@"NotificationButtonBackground"]]; +[[RMessageView appearance] setMessageIcon:[UIImage imageNamed:@"NotificationButtonBackground"]]; +[[RMessageView appearance] setWarningIcon:[UIImage imageNamed:@"NotificationButtonBackground"]]; +//End of override + +return YES; +} +``` + +The following properties can be set when creating a new notification: + +* **viewController**: The view controller to show the notification in. This might be the navigation controller. +* **title**: The title of the notification view +* **subtitle**: The text that is displayed underneath the title (optional) +* **image**: A custom icon image that is used instead of the default one (optional) +* **type**: The notification type (Message, Warning, Error, Success, Custom) +* **duration**: The duration the notification should be displayed +* **callback**: The block that should be executed, when the user dismissed the message by tapping on it or swiping it to the top. +* **customTypeString**: When using a custom design that you have added specify the key to use from your design, otherwise set to nil if not using a custom design. + +Except the title and the notification type, all of the listed values are optional + +If you don't want a detailed description (the text underneath the title) you don't need to set one. The notification will automatically resize itself properly. + +## Screenshots + +**Design Examples** + +![Error](http://www.toursprung.com/wp-content/uploads/2013/09/error_ios7.png) + +![Message](http://www.toursprung.com/wp-content/uploads/2013/09/warning_ios7.png) + +![Warning](http://www.toursprung.com/wp-content/uploads/2013/04/iNotificationWarning.png) + +![Success](http://www.toursprung.com/wp-content/uploads/2013/04/iNotificationSuccess.png) + +![Alt-Error](http://www.toursprung.com/wp-content/uploads/2013/04/iNotificationError.png) + +![Alt-Message](http://www.toursprung.com/wp-content/uploads/2013/04/iNotificationMessage.png) + + +# License +RMessage is available under the MIT license. See the LICENSE file for more information. + +# Recent Changes +Can be found in the [releases section](https://github.com/donileo/RMessage/releases) of this repo. diff --git a/RMessage.podspec b/RMessage.podspec new file mode 100644 index 0000000..f7dfe3a --- /dev/null +++ b/RMessage.podspec @@ -0,0 +1,34 @@ +# +# Be sure to run `pod lib lint RMessage.podspec' to ensure this is a +# valid spec and remove all comments before submitting the spec. +# +# Any lines starting with a # are optional, but encouraged +# +# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html +# + +Pod::Spec.new do |s| + s.name = "RMessage" + s.version = "1.0.1" + s.summary = "Easy to use and customizable messages/notifications for iOS à la Tweetbot." + s.description = <<-DESC + This framework provides an easy to use class to show little notification views on the top of the screen. (à la Tweetbot). +The notification moves from the top of the screen underneath the navigation bar and stays there for a few seconds, depending on the length of the displayed text. To dismiss a notification before the time runs out, the user can swipe it to the top or just tap it. +There are 4 different types already set up for you: Success, Error, Warning, Message. + DESC + s.homepage = "https://github.com/donileo/RMessage" + + s.license = 'MIT' + s.author = { "Adonis Peralta" => "donileo@gmail.com" } + s.source = { :git => "https://github.com/donileo/RMessage.git", :tag => s.version.to_s } + s.social_media_url = 'https://twitter.com/donileo' + + s.platform = :ios, '7.0' + s.requires_arc = true + + s.source_files = 'RMessage/**/*.{h,m}' + s.resources = ['RMessage/Resources/**/*.xib', 'RMessage/Assets/**/*.{png,jpg,json}'] + s.public_header_files = 'RMessage/*.h' + s.dependency 'HexColors', '~> 3.0.0' + s.dependency 'PPTopMostController' +end diff --git a/RMessage/Assets/AlternativeDesign.json b/RMessage/Assets/AlternativeDesign.json new file mode 100644 index 0000000..dc33f5f --- /dev/null +++ b/RMessage/Assets/AlternativeDesign.json @@ -0,0 +1,13 @@ +{ + "alternate-error": { + "buttonBackgroundImageName": "NotificationButtonBackground.png", + "buttonTitleTextColor": "#FF0040", + "subtitleFontSize": 14, + "subtitleTextColor": "#FF0040", + "imageName": "NotificationBackgroundErrorIcon.png", + "textColor": "#FF0040", + "titleFontSize": 14, + "backgroundColor": "#FFFFFF", + "opacity": 0.95 + } +} \ No newline at end of file diff --git a/RMessage/Assets/NotificationBackgroundError.png b/RMessage/Assets/NotificationBackgroundError.png new file mode 100755 index 0000000..2a9c763 Binary files /dev/null and b/RMessage/Assets/NotificationBackgroundError.png differ diff --git a/RMessage/Assets/NotificationBackgroundError@2x.png b/RMessage/Assets/NotificationBackgroundError@2x.png new file mode 100755 index 0000000..3c53de6 Binary files /dev/null and b/RMessage/Assets/NotificationBackgroundError@2x.png differ diff --git a/RMessage/Assets/NotificationBackgroundErrorIcon.png b/RMessage/Assets/NotificationBackgroundErrorIcon.png new file mode 100755 index 0000000..f5429a3 Binary files /dev/null and b/RMessage/Assets/NotificationBackgroundErrorIcon.png differ diff --git a/RMessage/Assets/NotificationBackgroundErrorIcon@2x.png b/RMessage/Assets/NotificationBackgroundErrorIcon@2x.png new file mode 100755 index 0000000..dce47d9 Binary files /dev/null and b/RMessage/Assets/NotificationBackgroundErrorIcon@2x.png differ diff --git a/RMessage/Assets/NotificationBackgroundMessage.png b/RMessage/Assets/NotificationBackgroundMessage.png new file mode 100755 index 0000000..1c8cf92 Binary files /dev/null and b/RMessage/Assets/NotificationBackgroundMessage.png differ diff --git a/RMessage/Assets/NotificationBackgroundMessage@2x.png b/RMessage/Assets/NotificationBackgroundMessage@2x.png new file mode 100755 index 0000000..d842f01 Binary files /dev/null and b/RMessage/Assets/NotificationBackgroundMessage@2x.png differ diff --git a/RMessage/Assets/NotificationBackgroundSuccess.png b/RMessage/Assets/NotificationBackgroundSuccess.png new file mode 100755 index 0000000..b9b7e57 Binary files /dev/null and b/RMessage/Assets/NotificationBackgroundSuccess.png differ diff --git a/RMessage/Assets/NotificationBackgroundSuccess@2x.png b/RMessage/Assets/NotificationBackgroundSuccess@2x.png new file mode 100755 index 0000000..61457ad Binary files /dev/null and b/RMessage/Assets/NotificationBackgroundSuccess@2x.png differ diff --git a/RMessage/Assets/NotificationBackgroundSuccessIcon.png b/RMessage/Assets/NotificationBackgroundSuccessIcon.png new file mode 100755 index 0000000..19eddfd Binary files /dev/null and b/RMessage/Assets/NotificationBackgroundSuccessIcon.png differ diff --git a/RMessage/Assets/NotificationBackgroundSuccessIcon@2x.png b/RMessage/Assets/NotificationBackgroundSuccessIcon@2x.png new file mode 100755 index 0000000..01ead80 Binary files /dev/null and b/RMessage/Assets/NotificationBackgroundSuccessIcon@2x.png differ diff --git a/RMessage/Assets/NotificationBackgroundWarning.png b/RMessage/Assets/NotificationBackgroundWarning.png new file mode 100755 index 0000000..e7a0290 Binary files /dev/null and b/RMessage/Assets/NotificationBackgroundWarning.png differ diff --git a/RMessage/Assets/NotificationBackgroundWarning@2x.png b/RMessage/Assets/NotificationBackgroundWarning@2x.png new file mode 100755 index 0000000..3583214 Binary files /dev/null and b/RMessage/Assets/NotificationBackgroundWarning@2x.png differ diff --git a/RMessage/Assets/NotificationBackgroundWarningIcon.png b/RMessage/Assets/NotificationBackgroundWarningIcon.png new file mode 100755 index 0000000..220b3cc Binary files /dev/null and b/RMessage/Assets/NotificationBackgroundWarningIcon.png differ diff --git a/RMessage/Assets/NotificationBackgroundWarningIcon@2x.png b/RMessage/Assets/NotificationBackgroundWarningIcon@2x.png new file mode 100755 index 0000000..ef276e8 Binary files /dev/null and b/RMessage/Assets/NotificationBackgroundWarningIcon@2x.png differ diff --git a/RMessage/Assets/NotificationButtonBackground.png b/RMessage/Assets/NotificationButtonBackground.png new file mode 100755 index 0000000..d59b415 Binary files /dev/null and b/RMessage/Assets/NotificationButtonBackground.png differ diff --git a/RMessage/Assets/NotificationButtonBackground@2x.png b/RMessage/Assets/NotificationButtonBackground@2x.png new file mode 100755 index 0000000..7cda5ca Binary files /dev/null and b/RMessage/Assets/NotificationButtonBackground@2x.png differ diff --git a/RMessage/Assets/RMessageDefaultDesign.json b/RMessage/Assets/RMessageDefaultDesign.json new file mode 100644 index 0000000..5616f8a --- /dev/null +++ b/RMessage/Assets/RMessageDefaultDesign.json @@ -0,0 +1,85 @@ +{ + "success": { + "backgroundColor": "#76CF67", + "borderColor": "#005700", + "borderHeight": 1, + "buttonBackgroundImage": "NotificationButtonBackground.png", + "buttonTitleTextColor": "#FFFFFF", + "buttonTitleShadowColor": "#67B759", + "buttonTitleShadowOffsetX": 0, + "buttonTitleShadowOffsetY": -1, + "titleFontColor": "#FFFFFF", + "titleFontSize": 14, + "subTitleFontSize": 12, + "subTitleFontColor": "#FFFFFF", + "iconImage": "NotificationBackgroundSuccessIcon.png", + "titleShadowColor": "#67B759", + "titleShadowOffsetX": 0, + "titleShadowOffsetY": -1, + "subTitleShadowColor": "#67B759", + "subTitleShadowOffsetX": 0, + "subTitleShadowOffsetY": -1 + }, + "normal": { + "backgroundColor": "#D4DDDF", + "borderColor": "#727C83", + "borderHeight": 1, + "buttonBackgroundImage": "NotificationButtonBackground.png", + "buttonTitleTextColor": "#727C83", + "buttonTitleShadowColor": "#EBEEF1", + "buttonTitleShadowOffsetX": 0, + "buttonTitleShadowOffsetY": 1, + "titleFontColor": "#727C83", + "titleFontSize": 14, + "subTitleFontSize": 12, + "subTitleFontColor": "#727C83", + "titleShadowColor": "#EBEEF1", + "titleShadowOffsetX": 0, + "titleShadowOffsetY": 1, + "subTitleShadowColor": "#EBEEF1", + "subTitleShadowOffsetX": 0, + "subTitleShadowOffsetY": 1 + }, + "warning": { + "backgroundColor": "#DAC43C", + "borderColor": "#A28918", + "borderHeight": 1, + "buttonBackgroundImage": "NotificationButtonBackground.png", + "buttonTitleTextColor": "#484638", + "buttonTitleShadowColor": "#E5D87C", + "buttonTitleShadowOffsetX": 0, + "buttonTitleShadowOffsetY": 1, + "titleFontColor": "#484638", + "titleFontSize": 14, + "subTitleFontSize": 12, + "subTitleFontColor": "#484638", + "iconImage": "NotificationBackgroundWarningIcon.png", + "titleShadowColor": "#E5D87C", + "titleShadowOffsetX": 0, + "titleShadowOffsetY": 1, + "subTitleShadowColor": "#E5D87C", + "subTitleShadowOffsetX": 0, + "subTitleShadowOffsetY": 1, + }, + "error": { + "backgroundColor": "#DD3B41", + "borderColor": "#700000", + "borderHeight": 1, + "buttonBackgroundImage": "NotificationButtonBackground.png", + "buttonTitleTextColor": "#FFFFFF", + "buttonTitleShadowColor": "#812929", + "buttonTitleShadowOffsetX": 0, + "buttonTitleShadowOffsetY": -1, + "titleFontColor": "#FFFFFF", + "titleFontSize": 14, + "subTitleFontSize": 12, + "subTitleFontColor": "#FFFFFF", + "iconImage": "NotificationBackgroundErrorIcon.png", + "titleShadowColor": "#812929", + "titleShadowOffsetX": 0, + "titleShadowOffsetY": -1, + "subTitleShadowColor": "#812929", + "subTitleShadowOffsetX": 0, + "subTitleShadowOffsetY": -1 + } +} \ No newline at end of file diff --git a/RMessage/RMessage.h b/RMessage/RMessage.h new file mode 100644 index 0000000..283ff3a --- /dev/null +++ b/RMessage/RMessage.h @@ -0,0 +1,194 @@ +// +// RMessage.h +// RMessage +// +// Created by Adonis Peralta on 12/7/15. +// Copyright © 2015 Rendezvous Inc. All rights reserved. +// + +#import + +@class RMessageView; + +typedef NS_ENUM(NSInteger, RMessageType) +{ + RMessageTypeNormal = 0, + RMessageTypeWarning, + RMessageTypeError, + RMessageTypeSuccess, + RMessageTypeCustom +}; + +typedef NS_ENUM(NSInteger, RMessagePosition) +{ + RMessagePositionTop = 0, + RMessagePositionNavBarOverlay, + RMessagePositionBottom +}; + +/** This enum can be passed to the duration parameter */ +typedef NS_ENUM(NSInteger, RMessageDuration) +{ + RMessageDurationAutomatic = 0, + RMessageDurationEndless = -1 // The notification is displayed until the user dismissed it or it is dismissed by calling dismissActiveNotification +}; + +/** Define on which position a specific RMessage should be displayed */ +@protocol RMessageProtocol + +@optional + +/** Implement this method to pass a custom position for a specific message */ +- (CGFloat)customVerticalOffsetForMessageView:(RMessageView *)messageView; + +/** You can customize the given RMessageView, like setting its alpha or adding a subview */ +- (void)customizeMessageView:(RMessageView *)messageView; + +@end + +@interface RMessage : NSObject + +/** By setting this delegate it's possible to set a custom offset for the message view */ +@property (nonatomic, assign) id delegate; + ++ (instancetype)sharedMessage; + +/** Shows a notification message + @param message The title of the message view + @param type The message type (Message, Warning, Error, Success) + @param customTypeString The string identifier/key for the custom style to use from specified custom design file. Only use when + specifying an additional custom design file and when the type parameter in this call is RMessageTypeCustom + */ ++ (void)showNotificationWithTitle:(NSString *)message + type:(RMessageType)type + customTypeString:(NSString *)customTypeString; + +/** Shows a notification message + @param title The title of the message view + @param subtitle The text that is displayed underneath the title + @param type The message type (Message, Warning, Error, Success) + @param customTypeString The string identifier/key for the custom style to use from specified custom design file. Only use when + specifying an additional custom design file and when the type parameter in this call is RMessageTypeCustom + */ ++ (void)showNotificationWithTitle:(NSString *)title + subtitle:(NSString *)subtitle + type:(RMessageType)type + customTypeString:(NSString *)customTypeString; + +/** Shows a notification message in a specific view controller + @param viewController The view controller to show the notification in. + You can use +setDefaultViewController: to set the the default one instead + @param title The title of the message view + @param subtitle The text that is displayed underneath the title + @param type The message type (Message, Warning, Error, Success) + @param customTypeString The string identifier/key for the custom style to use from specified custom design file. Only use when + specifying an additional custom design file and when the type parameter in this call is RMessageTypeCustom + */ ++ (void)showNotificationInViewController:(UIViewController *)viewController + title:(NSString *)title + subtitle:(NSString *)subtitle + type:(RMessageType)type + customTypeString:(NSString *)customTypeString; + +/** Shows a notification message in a specific view controller with a specific duration + @param viewController The view controller to show the notification in. + You can use +setDefaultViewController: to set the the default one instead + @param title The title of the message view + @param subtitle The text that is displayed underneath the title + @param type The message type (Message, Warning, Error, Success) + @param customTypeString The string identifier/key for the custom style to use from specified custom design file. Only use when + specifying an additional custom design file and when the type parameter in this call is RMessageTypeCustom + @param duration The duration of the notification being displayed + */ ++ (void)showNotificationInViewController:(UIViewController *)viewController + title:(NSString *)title + subtitle:(NSString *)subtitle + type:(RMessageType)type + customTypeString:(NSString *)customTypeString + duration:(NSTimeInterval)duration; + +/** Shows a notification message in a specific view controller with a specific duration + @param viewController The view controller to show the notification in. + You can use +setDefaultViewController: to set the the default one instead + @param title The title of the message view + @param subtitle The text that is displayed underneath the title + @param type The message type (Message, Warning, Error, Success) + @param customTypeString The string identifier/key for the custom style to use from specified custom design file. Only use when + specifying an additional custom design file and when the type parameter in this call is RMessageTypeCustom + @param duration The duration of the notification being displayed + @param dismissingEnabled Should the message be dismissed when the user taps/swipes it + */ ++ (void)showNotificationInViewController:(UIViewController *)viewController + title:(NSString *)title + subtitle:(NSString *)subtitle + type:(RMessageType)type + customTypeString:(NSString *)customTypeString + duration:(NSTimeInterval)duration + canBeDismissedByUser:(BOOL)dismissingEnabled; + + + +/** Shows a notification message in a specific view controller + @param viewController The view controller to show the notification in. + @param title The title of the message view + @param subtitle The message that is displayed underneath the title (optional) + @param iconImage A custom icon image (optional) + @param type The message type (Message, Warning, Error, Success) + @param customTypeString The string identifier/key for the custom style to use from specified custom design file. Only use when + specifying an additional custom design file and when the type parameter in this call is RMessageTypeCustom + @param duration The duration of the notification being displayed + @param callback The block that should be executed, when the user tapped on the message + @param buttonTitle The title for button (optional) + @param buttonCallback The block that should be executed, when the user tapped on the button + @param messagePosition The position of the message on the screen + @param dismissingEnabled Should the message be dismissed when the user taps/swipes it + */ ++ (void)showNotificationInViewController:(UIViewController *)viewController + title:(NSString *)title + subtitle:(NSString *)subtitle + iconImage:(UIImage *)iconImage + type:(RMessageType)type + customTypeString:(NSString *)customTypeString + duration:(NSTimeInterval)duration + callback:(void (^)())callback + buttonTitle:(NSString *)buttonTitle + buttonCallback:(void (^)())buttonCallback + atPosition:(RMessagePosition)messagePosition + canBeDismissedByUser:(BOOL)dismissingEnabled; + +/** Fades out the currently displayed notification. If another notification is in the queue, + the next one will be displayed automatically + @return YES if the currently displayed notification was successfully dismissed. NO if no notification + was currently displayed. + */ ++ (BOOL)dismissActiveNotification; + +/** Fades out the currently displayed notification with a completion block after the animation has finished. If another notification is in the queue, + the next one will be displayed automatically + @return YES if the currently displayed notification was successfully dismissed. NO if no notification + was currently displayed. + */ ++ (BOOL)dismissActiveNotificationWithCompletion:(void (^)(void))completionBlock; + +/** Use this method to set a default view controller to display the messages in */ ++ (void)setDefaultViewController:(UIViewController *)defaultViewController; + +/** Set a delegate to have full control over the position of the message view */ ++ (void)setDelegate:(id)delegate; + +/** Use this method to use custom designs in your messages. Must be a JSON formatted file but do not include the .json extension + in the name*/ ++ (void)addCustomDesignFromFileWithName:(NSString *)fileName; + +/** Indicates whether a notification is currently active. */ ++ (BOOL)isNotificationActive; + +/** Returns the currently queued array of RMessageView */ ++ (NSArray *)queuedMessages; + +/** Prepares the message view to be displayed in the future. It is queued and then + displayed in fadeInCurrentNotification. + You don't have to use this method. */ ++ (void)prepareNotificationForPresentation:(RMessageView *)messageView; + +@end diff --git a/RMessage/RMessage.m b/RMessage/RMessage.m new file mode 100644 index 0000000..0f059d9 --- /dev/null +++ b/RMessage/RMessage.m @@ -0,0 +1,295 @@ +// +// RMessage.m +// RMessage +// +// Created by Adonis Peralta on 12/7/15. +// Copyright © 2015 Rendezvous Inc. All rights reserved. +// + +#import "RMessage.h" +#import "RMessageView.h" + +static UIViewController *_defaultViewController; + +@interface RMessage () + +/** The queued messages (RMessageView objects) */ +@property (nonatomic, strong) NSMutableArray *messages; + +@property (nonatomic, assign) BOOL notificationActive; + +@end + +@implementation RMessage + +#pragma mark - Class Methods + ++ (instancetype)sharedMessage +{ + static RMessage *sharedMessage; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + sharedMessage = [RMessage new]; + }); + return sharedMessage; +} + ++ (void)showNotificationWithTitle:(NSString *)title + type:(RMessageType)type + customTypeString:(NSString *)customTypeString +{ + [self showNotificationWithTitle:title + subtitle:nil + type:type + customTypeString:(NSString *)customTypeString]; +} + ++ (void)showNotificationWithTitle:(NSString *)title + subtitle:(NSString *)subtitle + type:(RMessageType)type + customTypeString:(NSString *)customTypeString +{ + [self showNotificationInViewController:_defaultViewController + title:title + subtitle:subtitle + type:type + customTypeString:(NSString *)customTypeString]; +} + ++ (void)showNotificationInViewController:(UIViewController *)viewController + title:(NSString *)title + subtitle:(NSString *)subtitle + type:(RMessageType)type + customTypeString:(NSString *)customTypeString + duration:(NSTimeInterval)duration +{ + [self showNotificationInViewController:viewController + title:title + subtitle:subtitle + iconImage:nil + type:type + customTypeString:(NSString *)customTypeString + duration:duration + callback:nil + buttonTitle:nil + buttonCallback:nil + atPosition:RMessagePositionTop + canBeDismissedByUser:YES]; +} + ++ (void)showNotificationInViewController:(UIViewController *)viewController + title:(NSString *)title + subtitle:(NSString *)subtitle + type:(RMessageType)type + customTypeString:(NSString *)customTypeString + duration:(NSTimeInterval)duration + canBeDismissedByUser:(BOOL)dismissingEnabled +{ + [self showNotificationInViewController:viewController + title:title + subtitle:subtitle + iconImage:nil + type:type + customTypeString:(NSString *)customTypeString + duration:duration + callback:nil + buttonTitle:nil + buttonCallback:nil + atPosition:RMessagePositionTop + canBeDismissedByUser:dismissingEnabled]; +} + ++ (void)showNotificationInViewController:(UIViewController *)viewController + title:(NSString *)title + subtitle:(NSString *)subtitle + type:(RMessageType)type + customTypeString:(NSString *)customTypeString +{ + [self showNotificationInViewController:viewController + title:title + subtitle:subtitle + iconImage:nil + type:type + customTypeString:(NSString *)customTypeString + duration:RMessageDurationAutomatic + callback:nil + buttonTitle:nil + buttonCallback:nil + atPosition:RMessagePositionTop + canBeDismissedByUser:YES]; +} + + ++ (void)showNotificationInViewController:(UIViewController *)viewController + title:(NSString *)title + subtitle:(NSString *)subtitle + iconImage:(UIImage *)iconImage + type:(RMessageType)type + customTypeString:(NSString *)customTypeString + duration:(NSTimeInterval)duration + callback:(void (^)())callback + buttonTitle:(NSString *)buttonTitle + buttonCallback:(void (^)())buttonCallback + atPosition:(RMessagePosition)messagePosition + canBeDismissedByUser:(BOOL)dismissingEnabled +{ + // Create the RMessageView + RMessageView *messageView = [[RMessageView alloc] initWithDelegate:[RMessage sharedMessage] + title:title + subtitle:subtitle + iconImage:iconImage + type:type + customTypeString:(NSString *)customTypeString + duration:duration + inViewController:viewController + callback:callback + buttonTitle:buttonTitle + buttonCallback:buttonCallback + atPosition:messagePosition + canBeDismissedByUser:dismissingEnabled]; + [self prepareNotificationForPresentation:messageView]; +} + + ++ (void)prepareNotificationForPresentation:(RMessageView *)messageView +{ + NSString *title = messageView.title; + NSString *subtitle = messageView.subtitle; + + for (RMessageView *messageView in [RMessage sharedMessage].messages) { + if (([messageView.title isEqualToString:title] || (!messageView.title && !title)) && ([messageView.subtitle isEqualToString:subtitle] || (!messageView.subtitle && !subtitle))) { + return; // avoid showing the same messages twice in a row + } + } + + [[RMessage sharedMessage].messages addObject:messageView]; + + if (![RMessage sharedMessage].notificationActive) { + [[RMessage sharedMessage] presentMessageView]; + } +} + ++ (BOOL)dismissActiveNotification +{ + return [self dismissActiveNotificationWithCompletion:nil]; +} + ++ (BOOL)dismissActiveNotificationWithCompletion:(void (^)(void))completionBlock +{ + if ([RMessage sharedMessage].messages.count == 0 || ![RMessage sharedMessage].messages) return NO; + + dispatch_async(dispatch_get_main_queue(), ^{ + RMessageView *currentMessage = [RMessage sharedMessage].messages[0]; + if (currentMessage && currentMessage.messageIsFullyDisplayed) { + [[RMessage sharedMessage] dismissMessageView:currentMessage completion:completionBlock]; + } + }); + return YES; +} + + +#pragma mark Customizing RMessage + ++ (void)setDefaultViewController:(UIViewController *)defaultViewController +{ + _defaultViewController = defaultViewController; +} + ++ (void)setDelegate:(id)delegate +{ + [RMessage sharedMessage].delegate = delegate; +} + ++ (void)addCustomDesignFromFileWithName:(NSString *)fileName +{ + [RMessageView addDesignFromFile:fileName]; +} + +#pragma mark - Misc Methods + ++ (BOOL)isNotificationActive +{ + return [RMessage sharedMessage].notificationActive; +} + ++ (NSArray *)queuedMessages +{ + return [[RMessage sharedMessage].messages copy]; +} + +# pragma mark - Instance Methods + +- (instancetype)init +{ + self = [super init]; + if (self) { + _messages = [NSMutableArray new]; + } + return self; +} + +- (void)presentMessageView +{ + if (self.messages.count == 0) return; + RMessageView *messageView = self.messages[0]; + + if (self.delegate && [self.delegate respondsToSelector:@selector(customizeMessageView:)]) { + [self.delegate customizeMessageView:messageView]; + } + [messageView present]; +} + +- (void)dismissMessageView:(RMessageView *)messageView completion:(void (^) (void))completionBlock +{ + [messageView dismissWithCompletion:^{ + //execute the completion block once the messageView has been truly dismissed + if (completionBlock) { + completionBlock(); + } + }]; +} + +# pragma mark - RMessageView Delegate Methods + +- (void)messageViewDidPresent:(RMessageView *)messageView +{ + self.notificationActive = YES; +} + +- (void)messageViewDidDismiss:(RMessageView *)messageView +{ + if (self.messages.count > 0) { + [self.messages removeObjectAtIndex:0]; + } + self.notificationActive = NO; + if (self.messages.count > 0) { + [self presentMessageView]; + } +} + +- (CGFloat)customVerticalOffsetForMessageView:(RMessageView *)messageView +{ + if (self.delegate && [self.delegate respondsToSelector:@selector(customVerticalOffsetForMessageView:)]) { + return [self.delegate customVerticalOffsetForMessageView:messageView]; + } + return 0.f; +} + +- (void)windowChangedForMessageView:(RMessageView *)messageView +{ + [self dismissMessageView:messageView completion:nil]; +} + +- (void)didSwipeToDismissMessageView:(RMessageView *)messageView +{ + [self dismissMessageView:messageView completion:nil]; +} + +- (void)didTapMessageView:(RMessageView *)messageView +{ + [self dismissMessageView:messageView completion:^{ + [messageView executeMessageViewCallBack]; + }]; +} + +@end diff --git a/RMessage/RMessageView.h b/RMessage/RMessageView.h new file mode 100644 index 0000000..90a5603 --- /dev/null +++ b/RMessage/RMessageView.h @@ -0,0 +1,108 @@ +// +// RMessageView.h +// RMessage +// +// Created by Adonis Peralta on 12/7/15. +// Copyright © 2015 Rendezvous Inc. All rights reserved. +// + +#import +#import "RMessage.h" + +@protocol RMessageViewProtocol + +- (void)messageViewDidPresent:(RMessageView *)messageView; + +- (void)messageViewDidDismiss:(RMessageView *)messageView; + +- (CGFloat)customVerticalOffsetForMessageView:(RMessageView *)messageView; + +- (void)windowChangedForMessageView:(RMessageView *)messageView; + +- (void)didSwipeToDismissMessageView:(RMessageView *)messageView; + +- (void)didTapMessageView:(RMessageView *)messageView; + +@end + +@interface RMessageView : UIView + +@property (nonatomic, weak) id delegate; + +/** The displayed title of this message */ +@property (nonatomic, readonly) NSString *title; + +/** The displayed subtitle of this message */ +@property (nonatomic, readonly) NSString *subtitle; + +/** The view controller this message is displayed in */ +@property (nonatomic, readonly) UIViewController *viewController; + +/** The duration of the displayed message. If it is 0.0, it will automatically be calculated */ +@property (nonatomic, assign) CGFloat duration; + +/** The position of the message (top or bottom) */ +@property (nonatomic, assign) RMessagePosition messagePosition; + +/** The opacity of the message view */ +@property (nonatomic, assign, readonly) CGFloat messageOpacity; + +/** Is the message currently fully displayed? Is set as soon as the message is really fully visible */ +@property (nonatomic, assign) BOOL messageIsFullyDisplayed; + +/** Customize title font using Apperance */ +@property (nonatomic, strong) UIFont *titleFont UI_APPEARANCE_SELECTOR; +@property (nonatomic, strong) UIColor *titleTextColor UI_APPEARANCE_SELECTOR; +@property (nonatomic, strong) UIFont *subtitleFont UI_APPEARANCE_SELECTOR; +@property (nonatomic, strong) UIColor *subtitleTextColor UI_APPEARANCE_SELECTOR; +@property (nonatomic, strong) UIImage *messageIcon UI_APPEARANCE_SELECTOR; +@property (nonatomic, strong) UIImage *errorIcon UI_APPEARANCE_SELECTOR; +@property (nonatomic, strong) UIImage *successIcon UI_APPEARANCE_SELECTOR; +@property (nonatomic, strong) UIImage *warningIcon UI_APPEARANCE_SELECTOR; + +/** Inits the message view. Do not call this from outside this library. + @param title The title of the message view + @param subtitle The subtitle of the message view (optional) + @param iconImage A custom icon image (optional) + @param messageType The type of message view + @param duration The duration this notification should be displayed (optional) + @param viewController The view controller this message should be displayed in + @param callback The block that should be executed, when the user tapped on the message + @param buttonTitle The title for button (optional) + @param buttonCallback The block that should be executed, when the user tapped on the button + @param position The position of the message on the screen + @param dismissingEnabled Should this message be dismissed when the user taps/swipes it? + */ +- (instancetype)initWithDelegate:(id)delegate + title:(NSString *)title + subtitle:(NSString *)subtitle + iconImage:(UIImage *)iconImage + type:(RMessageType)messageType + customTypeString:(NSString *)customTypeString + duration:(CGFloat)duration + inViewController:(UIViewController *)viewController + callback:(void (^)())callback + buttonTitle:(NSString *)buttonTitle + buttonCallback:(void (^)())buttonCallback + atPosition:(RMessagePosition)position + canBeDismissedByUser:(BOOL)dismissingEnabled; + +/** Use this method to load a custom design file */ ++ (void)addDesignFromFile:(NSString *)file; + +/** Execute the message view call back if set */ +- (void)executeMessageViewCallBack; + +/** Execute the message view button call back if set */ +- (void)executeMessageViewButtonCallBack; + +- (void)present; + +- (void)dismissWithCompletion:(void (^) (void))completionBlock; + +///** Indicates whether the current navigationBar is hidden by isNavigationBarHidden +// on the UINavigationController or isHidden on the navigationBar of the current +// UINavigationController */ +//+ (BOOL)isNavigationBarHiddenForNavigationController:(UINavigationController *)navController; + +@end diff --git a/RMessage/RMessageView.m b/RMessage/RMessageView.m new file mode 100644 index 0000000..3dd47c5 --- /dev/null +++ b/RMessage/RMessageView.m @@ -0,0 +1,663 @@ +// +// RMessageView.m +// RMessage +// +// Created by Adonis Peralta on 12/7/15. +// Copyright © 2015 Rendezvous Inc. All rights reserved. +// + +#import "RMessageView.h" +#import "HexColors.h" +#import "UIViewController+PPTopMostController.h" + +static NSString *const RDesignFileName = @"RMessageDefaultDesign"; + +/** animation constants */ +static double const kRMessageAnimationDuration = 0.3f; +static double const kRMessageDisplayTime = 1.5f; +static double const kRMessageExtraDisplayTimePerPixel = 0.04f; + +/** Contains the global design dictionary specified in the entire design RDesignFile */ +static NSMutableDictionary *globalDesignDictionary; + +@interface RMessageView () + +@property (nonatomic, weak) IBOutlet UIImageView *iconImageView; +@property (nonatomic, weak) IBOutlet UIImageView *backgroundImageView; +@property (nonatomic, weak) IBOutlet UIView *titleSubtitleContainerView; +@property (nonatomic, weak) IBOutlet UILabel *titleLabel; +@property (nonatomic, weak) IBOutlet UILabel *subtitleLabel; +@property (nonatomic, unsafe_unretained) IBOutlet NSLayoutConstraint *titleSubtitleContainerViewTopLayoutConstraint; + +@property (nonatomic, strong) UIImage *iconImage; + +/** Contains the appropriate design dictionary for the specified message view type */ +@property (nonatomic, strong) NSDictionary *messageViewDesignDictionary; + +/** The displayed title of this message */ +@property (nonatomic, strong) NSString *title; + +/** The displayed subtitle of this message view */ +@property (nonatomic, strong) NSString *subtitle; + +/** The title of the added button */ +@property (nonatomic, strong) NSString *buttonTitle; + +/** The view controller this message is displayed in */ +@property (nonatomic, strong) UIViewController *viewController; + +/** The vertical space between the message view top to its view controller top */ +@property (nonatomic, strong) NSLayoutConstraint *topToVCLayoutConstraint; + +@property (nonatomic, copy) void (^callback)(); + +@property (nonatomic, copy) void (^buttonCallback)(); + +/** The starting constant value that should be set for the topToVCTopLayoutConstraint when animating */ +@property (nonatomic, assign) CGFloat topToVCStartConstant; + +/** The final constant value that should be set for the topToVCTopLayoutConstraint when animating */ +@property (nonatomic, assign) CGFloat topToVCFinalConstant; + +@property (nonatomic, assign) RMessageType messageType; + +@property (nonatomic, assign) CGFloat messageOpacity; + +@end + +@implementation RMessageView + +#pragma mark - Class Methods + ++ (NSError *)setupGlobalDesignDictionary +{ + if (!globalDesignDictionary) { + NSString *path = [[NSBundle bundleForClass:self.class] pathForResource:RDesignFileName ofType:@"json"]; + NSData *data = [NSData dataWithContentsOfFile:path]; + NSAssert(data != nil, @"Could not read RMessage config file from main bundle with name %@.json", RDesignFileName); + if (!data) { + NSString *configFileErrorMessage = [NSString stringWithFormat:@"There seems to be an error with the %@ configuration file", RDesignFileName]; + return [NSError errorWithDomain:[NSBundle mainBundle].bundleIdentifier code:0 userInfo:@{NSLocalizedDescriptionKey:configFileErrorMessage}]; + } + globalDesignDictionary = [NSMutableDictionary dictionaryWithDictionary:[NSJSONSerialization JSONObjectWithData:data + options:kNilOptions + error:nil]]; + } + return nil; +} + ++ (void)addDesignFromFile:(NSString *)filename +{ + [RMessageView setupGlobalDesignDictionary]; + NSString *path = [[NSBundle bundleForClass:self.class] pathForResource:filename ofType:@"json"]; + if ([[NSFileManager defaultManager] fileExistsAtPath:path]) { + NSDictionary *newDesignStyle = [NSJSONSerialization JSONObjectWithData:[NSData dataWithContentsOfFile:path] + options:kNilOptions + error:nil]; + [globalDesignDictionary addEntriesFromDictionary:newDesignStyle]; + } else { + NSAssert(NO, @"Error loading design file with name %@", filename); + } +} + ++ (BOOL)isNavigationBarHiddenForNavigationController:(UINavigationController *)navController +{ + if (navController.navigationBarHidden) { + return YES; + } else if (navController.navigationBar.isHidden) { + return YES; + } else { + return NO; + } +} + ++ (BOOL)runtimeIsIos7OrHigher +{ +#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 70000 + return YES; +#else + return NO; +#endif +} + ++ (UIViewController *)defaultViewController +{ + UIViewController *viewController = [UIViewController topMostController]; + if (!viewController) { + viewController = [UIApplication sharedApplication].keyWindow.rootViewController; + } + return viewController; +} + +#pragma mark - Get Image From Resource Bundle + ++ (UIImage *)bundledImageNamed:(NSString*)name +{ + NSBundle *bundle = [NSBundle bundleForClass:[RMessageView class]]; + NSString *imagePath = [bundle pathForResource:name ofType:nil]; + return [[UIImage alloc] initWithContentsOfFile:imagePath]; +} + +#pragma mark - Instance Methods + +- (instancetype)initWithDelegate:(id)delegate + title:(NSString *)title + subtitle:(NSString *)subtitle + iconImage:(UIImage *)iconImage + type:(RMessageType)messageType + customTypeString:(NSString *)customTypeString + duration:(CGFloat)duration + inViewController:(UIViewController *)viewController + callback:(void (^)())callback + buttonTitle:(NSString *)buttonTitle + buttonCallback:(void (^)())buttonCallback + atPosition:(RMessagePosition)position + canBeDismissedByUser:(BOOL)dismissingEnabled +{ + self = [[NSBundle mainBundle] loadNibNamed:@"RMessageView" owner:self options:nil].firstObject; + if (self) { + _delegate = delegate; + _title = title; + _subtitle = subtitle; + _messageOpacity = 0.97f; + //_buttonTitle = buttonTitle; + _iconImage = iconImage; + _duration = duration; + viewController ? _viewController = viewController : (_viewController = [RMessageView defaultViewController]); + _messagePosition = position; + _callback = callback; + _messageType = messageType; + _buttonCallback = buttonCallback; + + NSError *designError = [self setupDesignDictionariesWithMessageType:_messageType customTypeString:customTypeString]; + if (designError) { + return nil; + } + + [self setupDesign]; + if (dismissingEnabled) { + [self setupGestureRecognizers]; + } + } + return self; +} + +- (CGSize)intrinsicContentSize +{ + CGSize standardSize = CGSizeMake(self.viewController.view.bounds.size.width, self.titleSubtitleContainerView.bounds.size.height + 20.f); + return standardSize; +} + +- (void)setSubtitleFont:(UIFont *)subtitleFont +{ + _subtitleFont = subtitleFont; + [self.subtitleLabel setFont:subtitleFont]; +} + +- (void)setSubtitleTextColor:(UIColor *)subtitleTextColor +{ + _subtitleTextColor = subtitleTextColor; + [self.subtitleLabel setTextColor:_subtitleTextColor]; +} + +- (void)setTitleFont:(UIFont *)aTitleFont +{ + _titleFont = aTitleFont; + [self.titleLabel setFont:_titleFont]; +} + +- (void)setTitleTextColor:(UIColor *)aTextColor +{ + _titleTextColor = aTextColor; + [self.titleLabel setTextColor:_titleTextColor]; +} + +- (void)setMessageIcon:(UIImage *)messageIcon +{ + _messageIcon = messageIcon; + [self updateCurrentIconIfNeeded]; +} + +- (void)setErrorIcon:(UIImage *)errorIcon +{ + _errorIcon = errorIcon; + [self updateCurrentIconIfNeeded]; +} + +- (void)setSuccessIcon:(UIImage *)successIcon +{ + _successIcon = successIcon; + [self updateCurrentIconIfNeeded]; +} + +- (void)setWarningIcon:(UIImage *)warningIcon +{ + _warningIcon = warningIcon; + [self updateCurrentIconIfNeeded]; +} + +- (void)updateCurrentIconIfNeeded +{ + UIImage *image = nil; + switch (self.messageType) { + case RMessageTypeNormal: + { + image = _messageIcon; + self.iconImageView.image = _messageIcon; + break; + } + case RMessageTypeError: + { + image = _errorIcon; + self.iconImageView.image = _errorIcon; + break; + } + case RMessageTypeSuccess: + { + image = _successIcon; + self.iconImageView.image = _successIcon; + break; + } + case RMessageTypeWarning: + { + image = _warningIcon; + self.iconImageView.image = _warningIcon; + break; + } + default: + break; + } +} + +- (NSError *)setupDesignDictionariesWithMessageType:(RMessageType)messageType + customTypeString:(NSString *)customTypeString +{ + [RMessageView setupGlobalDesignDictionary]; + NSString *messageTypeDesignString; + switch (messageType) { + case RMessageTypeNormal: + messageTypeDesignString = @"normal"; + break; + case RMessageTypeError: + messageTypeDesignString = @"error"; + break; + case RMessageTypeSuccess: + messageTypeDesignString = @"success"; + break; + case RMessageTypeWarning: + messageTypeDesignString = @"warning"; + break; + case RMessageTypeCustom: + NSParameterAssert(customTypeString != nil); + NSParameterAssert(![customTypeString isEqualToString: @""]); + if (!customTypeString || [customTypeString isEqualToString:@""]) { + return [NSError errorWithDomain:[NSBundle mainBundle].bundleIdentifier code:0 userInfo:@{NSLocalizedDescriptionKey:@"When specifying a type RMessageTypeCustom make sure to pass in a valid argument for customTypeString parameter. This string should match a Key in your custom design file."}]; + } + messageTypeDesignString = customTypeString; + break; + default: + break; + } + + _messageViewDesignDictionary = [globalDesignDictionary valueForKey:messageTypeDesignString]; + NSParameterAssert(_messageViewDesignDictionary != nil); + if (!_messageViewDesignDictionary) { + return [NSError errorWithDomain:[NSBundle mainBundle].bundleIdentifier code:0 userInfo:@{NSLocalizedDescriptionKey:@"When specifying a type RMessageTypeCustom make sure to pass in a valid argument for customTypeString parameter. This string should match a Key in your custom design file."}]; + } + return nil; +} + +- (void)setupDesign +{ + self.translatesAutoresizingMaskIntoConstraints = NO; + if (self.messagePosition != RMessagePositionBottom) { + self.topToVCStartConstant = -self.bounds.size.height; + self.topToVCLayoutConstraint = [NSLayoutConstraint constraintWithItem:self + attribute:NSLayoutAttributeTop + relatedBy:NSLayoutRelationEqual + toItem:self.viewController.view + attribute:NSLayoutAttributeTop + multiplier:1.f + constant:self.topToVCStartConstant]; + } else { + self.topToVCStartConstant = 0; + self.topToVCLayoutConstraint = [NSLayoutConstraint constraintWithItem:self + attribute:NSLayoutAttributeTop + relatedBy:NSLayoutRelationEqual + toItem:self.viewController.view + attribute:NSLayoutAttributeBottom + multiplier:1.f + constant:0]; + } + + [self setupDesignDefaults]; + [self setupImagesAndBackground]; + [self setupTitleLabel]; + [self setupSubTitleLabel]; +} + +- (void)executeMessageViewCallBack +{ + if (self.callback) { + self.callback(); + } +} + +- (void)executeMessageViewButtonCallBack +{ + if (self.buttonCallback) { + self.buttonCallback(); + } +} + +- (void)didMoveToWindow +{ + //called when adding adding to a new subview programmatically + [super didMoveToWindow]; + if (self.duration == RMessageDurationEndless && self.superview && !self.window) { + if (self.delegate && [self.delegate respondsToSelector:@selector(windowChangedForMessageView:)]) { + [self.delegate performSelector:@selector(windowChangedForMessageView:)]; + } + } +} + +- (void)setupDesignDefaults +{ + self.backgroundColor = [UIColor lightGrayColor]; + self.alpha = _messageOpacity; + _titleLabel.numberOfLines = 0; + _titleLabel.lineBreakMode = NSLineBreakByWordWrapping; + _titleLabel.font = [UIFont boldSystemFontOfSize:14.f]; + _titleLabel.textColor = [UIColor blackColor]; + _titleLabel.shadowColor = nil; + _titleLabel.shadowOffset = CGSizeZero; + _titleLabel.backgroundColor = nil; + + _subtitleLabel.numberOfLines = 0; + _subtitleLabel.lineBreakMode = NSLineBreakByWordWrapping; + _subtitleLabel.font = [UIFont boldSystemFontOfSize:12.f]; + _subtitleLabel.textColor = [UIColor darkGrayColor]; + _subtitleLabel.shadowColor = nil; + _subtitleLabel.shadowOffset = CGSizeZero; + _subtitleLabel.backgroundColor = nil; +} + +- (void)setupImagesAndBackground +{ + UIColor *backgroundColor = [UIColor hx_colorWithHexString:_messageViewDesignDictionary[@"backgroundColor"]]; + if (backgroundColor) self.backgroundColor = backgroundColor; + id messageOpacity = _messageViewDesignDictionary[@"opacity"]; + if (messageOpacity) { + _messageOpacity = [messageOpacity floatValue]; + self.alpha = _messageOpacity; + } + + if (!_iconImage && ((NSString*)[_messageViewDesignDictionary valueForKey:@"iconImage"]).length > 0) { + _iconImage = [RMessageView bundledImageNamed:[_messageViewDesignDictionary valueForKey:@"iconImage"]]; + if (!_iconImage) { + _iconImage = [UIImage imageNamed:[_messageViewDesignDictionary valueForKey:@"iconImage"]]; + } + } + + if (_iconImage) _iconImageView.image = _iconImage; + + UIImage *backgroundImage = [RMessageView bundledImageNamed:[_messageViewDesignDictionary valueForKey:@"backgroundImage"]]; + if (backgroundImage) { + backgroundImage = [backgroundImage resizableImageWithCapInsets:UIEdgeInsetsMake(0, 0, 0, 0) resizingMode:UIImageResizingModeStretch]; + _backgroundImageView.image = backgroundImage; + } +} + +- (void)setupTitleLabel +{ + UIColor *titleFontColor = [UIColor hx_colorWithHexString:[_messageViewDesignDictionary valueForKey:@"titleFontColor"]]; + _titleLabel.text = _title ? _title : @""; + if (titleFontColor) _titleLabel.textColor = titleFontColor; + + CGFloat titleFontSize = [[_messageViewDesignDictionary valueForKey:@"titleFontSize"] floatValue]; + NSString *titleFontName = [_messageViewDesignDictionary valueForKey:@"titleFontName"]; + if (titleFontName) { + _titleLabel.font = [UIFont fontWithName:titleFontName size:titleFontSize]; + } else if (titleFontSize) { + _titleLabel.font = [UIFont boldSystemFontOfSize:titleFontSize]; + } + UIColor *titleShadowColor= [UIColor hx_colorWithHexString:[_messageViewDesignDictionary valueForKey:@"titleShadowColor"]]; + if (titleShadowColor) _titleLabel.shadowColor = titleShadowColor; + id titleShadowOffsetX = [_messageViewDesignDictionary valueForKey:@"titleShadowOffsetX"]; + id titleShadowOffsetY = [_messageViewDesignDictionary valueForKey:@"titleShadowOffsetY"]; + if (titleShadowOffsetX && titleShadowOffsetY) { + _titleLabel.shadowOffset = CGSizeMake([titleShadowOffsetX floatValue], [titleShadowOffsetY floatValue]); + } + _titleLabel.preferredMaxLayoutWidth = self.viewController.view.bounds.size.width - _iconImage.size.width - 70.f; +} + +- (void)setupSubTitleLabel +{ + UIColor *subTitleFontColor = [UIColor hx_colorWithHexString:[_messageViewDesignDictionary valueForKey:@"subTitleFontColor"]]; + if (!subTitleFontColor) { + subTitleFontColor = [UIColor hx_colorWithHexString:[_messageViewDesignDictionary valueForKey:@"subtitleFontColor"]]; + } + if (!subTitleFontColor) { + subTitleFontColor = _titleLabel.textColor; + } + + id subTitleFontSizeValue = [_messageViewDesignDictionary valueForKey:@"subTitleFontSize"]; + if (!subTitleFontSizeValue) { + subTitleFontSizeValue = [_messageViewDesignDictionary valueForKey:@"subtitleFontSize"]; + } + + CGFloat subTitleFontSize = [subTitleFontSizeValue floatValue]; + NSString *subTitleFontName = [_messageViewDesignDictionary valueForKey:@"subTitleFontName"]; + if (!subTitleFontName) { + subTitleFontName = [_messageViewDesignDictionary valueForKey:@"subtitleFontName"]; + } + + _subtitleLabel.numberOfLines = 0; + _subtitleLabel.lineBreakMode = NSLineBreakByWordWrapping; + _subtitleLabel.text = _subtitle ? _subtitle : @""; + if (subTitleFontColor) _subtitleLabel.textColor = subTitleFontColor; + + UIColor *subTitleShadowColor= [UIColor hx_colorWithHexString:[_messageViewDesignDictionary valueForKey:@"subTitleShadowColor"]]; + if (!subTitleShadowColor) { + subTitleShadowColor = [UIColor hx_colorWithHexString:[_messageViewDesignDictionary valueForKey:@"subtitleShadowColor"]]; + } + + if (subTitleShadowColor) _subtitleLabel.shadowColor = subTitleShadowColor; + id subTitleShadowOffsetX = [_messageViewDesignDictionary valueForKey:@"subTitleShadowOffsetX"]; + id subTitleShadowOffsetY = [_messageViewDesignDictionary valueForKey:@"subTitleShadowOffsetY"]; + if (!subTitleShadowOffsetX) { + subTitleShadowOffsetX = [_messageViewDesignDictionary valueForKey:@"subtitleShadowOffsetX"]; + } + if (!subTitleShadowOffsetY) { + subTitleShadowOffsetY = [_messageViewDesignDictionary valueForKey:@"subtitleShadowOffsetY"]; + } + if (subTitleShadowOffsetX && subTitleShadowOffsetY) { + _subtitleLabel.shadowOffset = CGSizeMake([subTitleShadowOffsetX floatValue], [subTitleShadowOffsetY floatValue]); + } + + if (subTitleFontName) { + _subtitleLabel.font = [UIFont fontWithName:subTitleFontName size:subTitleFontSize]; + } else if (subTitleFontSize) { + _subtitleLabel.font = [UIFont systemFontOfSize:subTitleFontSize]; + } + _subtitleLabel.preferredMaxLayoutWidth = _titleLabel.preferredMaxLayoutWidth; +} + +- (void)setupGestureRecognizers +{ + UISwipeGestureRecognizer *gestureRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self + action:@selector(didSwipeToDismissMessageView:)]; + [gestureRecognizer setDirection:(self.messagePosition == RMessagePositionTop ? + UISwipeGestureRecognizerDirectionUp : + UISwipeGestureRecognizerDirectionDown)]; + [self addGestureRecognizer:gestureRecognizer]; + + UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self + action:@selector(didTapMessageView:)]; + [self addGestureRecognizer:tapRecognizer]; +} + +#pragma mark - Gesture Recognizers + +/** called after the following gesture depending on message position during initialization + UISwipeGestureRecognizerDirectionUp when message position set to Top, UISwipeGestureRecognizerDirectionDown when + message position set to Bottom */ +- (void)didSwipeToDismissMessageView:(UISwipeGestureRecognizer *)swipeGesture +{ + if (self.delegate && [self.delegate respondsToSelector:@selector(didSwipeToDismissMessageView:)]) { + [self.delegate performSelector:@selector(didSwipeToDismissMessageView:) withObject:self]; + } +} + +- (void)didTapMessageView:(UITapGestureRecognizer *)tapGesture +{ + if (self.delegate && [self.delegate respondsToSelector:@selector(didTapMessageView:)]) { + [self.delegate performSelector:@selector(didTapMessageView:) withObject:self]; + } +} + +#pragma mark - Presentation Methods + + +- (void)present +{ + if ([self.viewController isKindOfClass:[UINavigationController class]] || [self.viewController.parentViewController isKindOfClass:[UINavigationController class]]) { + [self handleNavigationControllerPresentation]; + } else { + [self handleNormalPresentation]; + } + + if (self.duration == RMessageDurationAutomatic) { + self.duration = kRMessageAnimationDuration + kRMessageDisplayTime + self.frame.size.height * kRMessageExtraDisplayTimePerPixel; + } + + if (self.duration != RMessageDurationEndless) { + dispatch_async(dispatch_get_main_queue(), ^{ + [self performSelector:@selector(dismiss) + withObject:self + afterDelay:self.duration]; + }); + } +} + +- (void)handleNavigationControllerPresentation +{ + UINavigationController *messageNavigationController; + + if ([self.viewController isKindOfClass:[UINavigationController class]]) { + messageNavigationController = (UINavigationController *)self.viewController; + } else { + messageNavigationController = (UINavigationController *)self.viewController.parentViewController; + } + + BOOL messageNavigationBarHidden = [RMessageView isNavigationBarHiddenForNavigationController:messageNavigationController]; + //BOOL viewIsUnderStatusBar = messageNavigationController.childViewControllers.firstObject.extendedLayoutIncludesOpaqueBars; + + // navigation bar is shown and we are being asked to show below nav bar (!not as an overlay) + if (!messageNavigationBarHidden && self.messagePosition != RMessagePositionNavBarOverlay) { + // position notification below nav bar so it animates from below the nav bar + [messageNavigationController.view insertSubview:self + belowSubview:messageNavigationController.navigationBar]; + [messageNavigationController.view addConstraint:self.topToVCLayoutConstraint]; + self.topToVCFinalConstant = [UIApplication sharedApplication].statusBarFrame.size.height + messageNavigationController.navigationBar.bounds.size.height; + } else { + //navigation bar hidden and we are being asked to show below just the status bar + UIView *presentationView = self.viewController.view; + [presentationView addSubview:self]; + [presentationView addConstraint:self.topToVCLayoutConstraint]; + + self.titleSubtitleContainerViewTopLayoutConstraint.constant = [UIApplication sharedApplication].statusBarFrame.size.height; + self.topToVCFinalConstant = 0.f; + } + + // asking to animate from bottom up.. set the topToVCFinalConstant here. + if (self.messagePosition == RMessagePositionBottom) { + CGFloat offset = -self.bounds.size.height; + if (messageNavigationController && !messageNavigationController.isToolbarHidden) { + // if tool bar present animate above toolbar + offset -= messageNavigationController.toolbar.bounds.size.height; + } + self.topToVCFinalConstant = offset; + } + + [self handleAnimationWithNavigationController:messageNavigationController]; +} + +- (void)handleNormalPresentation +{ + UIView *presentationView = self.viewController.view; + [presentationView addSubview:self]; + [presentationView addConstraint:self.topToVCLayoutConstraint]; + [self handleAnimationWithNavigationController:nil]; +} + +- (void)handleAnimationWithNavigationController:(UINavigationController *)navigationController +{ + //if nil navigation controller passed simply animate normally + [self layoutIfNeeded]; + self.alpha = 0.f; + if ([RMessageView runtimeIsIos7OrHigher]) { + [UIView animateWithDuration:kRMessageAnimationDuration + 0.2 + delay:0.f + usingSpringWithDamping:0.7 + initialSpringVelocity:0.f + options:UIViewAnimationOptionCurveEaseInOut | UIViewAnimationOptionBeginFromCurrentState | UIViewAnimationOptionAllowUserInteraction + animations:^{ + self.alpha = self.messageOpacity; + self.topToVCLayoutConstraint.constant = self.topToVCFinalConstant; + [self layoutIfNeeded]; + //self.center = toPoint; + } + completion:^(BOOL finished) { + self.messageIsFullyDisplayed = YES; + if ([self.delegate respondsToSelector:@selector(messageViewDidPresent:)]) { + [self.delegate messageViewDidPresent:self]; + } + }]; + + } else { + [UIView animateWithDuration:kRMessageAnimationDuration + 0.2 + delay:0.f + options:UIViewAnimationOptionCurveEaseInOut | UIViewAnimationOptionBeginFromCurrentState | UIViewAnimationOptionAllowUserInteraction + animations:^{ + self.alpha = self.messageOpacity; + self.topToVCLayoutConstraint.constant = self.topToVCFinalConstant; + [self layoutIfNeeded]; + //self.center = toPoint; + } completion:^(BOOL finished) { + self.messageIsFullyDisplayed = YES; + if ([self.delegate respondsToSelector:@selector(messageViewDidPresent:)]) { + [self.delegate messageViewDidPresent:self]; + } + }]; + } +} + +- (void)dismiss +{ + [self dismissWithCompletion:nil]; +} + +- (void)dismissWithCompletion:(void (^) (void))completionBlock +{ + self.messageIsFullyDisplayed = NO; + [NSObject cancelPreviousPerformRequestsWithTarget:self + selector:@selector(dismiss) + object:self]; + + [UIView animateWithDuration:kRMessageAnimationDuration animations:^{ + self.alpha = 0.f; + self.topToVCLayoutConstraint.constant = self.topToVCStartConstant; + [self layoutIfNeeded]; + } completion:^(BOOL finished) { + [self removeFromSuperview]; + if ([self.delegate respondsToSelector:@selector(messageViewDidDismiss:)]) { + [self.delegate messageViewDidDismiss:self]; + } + if (completionBlock) { + completionBlock(); + } + }]; +} + +@end diff --git a/RMessage/Resources/RMessageView.xib b/RMessage/Resources/RMessageView.xib new file mode 100644 index 0000000..29c40e4 --- /dev/null +++ b/RMessage/Resources/RMessageView.xib @@ -0,0 +1,72 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +