├── Pod └── Classes │ ├── .gitkeep │ ├── AFMInfoBanner.h │ └── AFMInfoBanner.m ├── Example ├── Tests │ ├── en.lproj │ │ └── InfoPlist.strings │ ├── ReferenceImages │ │ ├── AFMInfoBannerSpec │ │ │ ├── AFMInfoBanner_view__should_show_long_red_one-320@2x.png │ │ │ ├── AFMInfoBanner_view__should_show_long_red_one-375@2x.png │ │ │ ├── AFMInfoBanner_view__should_show_long_red_one-414@3x.png │ │ │ ├── AFMInfoBanner_view__should_show_compact_red_one-320@2x.png │ │ │ ├── AFMInfoBanner_view__should_show_compact_red_one-375@2x.png │ │ │ ├── AFMInfoBanner_view__should_show_compact_red_one-414@3x.png │ │ │ ├── AFMInfoBanner_view__should_show_compact_green_one-320@2x.png │ │ │ ├── AFMInfoBanner_view__should_show_compact_green_one-375@2x.png │ │ │ └── AFMInfoBanner_view__should_show_compact_green_one-414@3x.png │ │ └── AFMInfoBannerAppearanceSpec │ │ │ ├── AFMInfoBanner_UIAppearance__should_configure_font-320@2x.png │ │ │ ├── AFMInfoBanner_UIAppearance__should_configure_font-375@2x.png │ │ │ ├── AFMInfoBanner_UIAppearance__should_configure_font-414@3x.png │ │ │ ├── AFMInfoBanner_UIAppearance__should_configure_info_look-320@2x.png │ │ │ ├── AFMInfoBanner_UIAppearance__should_configure_info_look-375@2x.png │ │ │ ├── AFMInfoBanner_UIAppearance__should_configure_info_look-414@3x.png │ │ │ ├── AFMInfoBanner_UIAppearance__should_configure_error_look-320@2x.png │ │ │ ├── AFMInfoBanner_UIAppearance__should_configure_error_look-375@2x.png │ │ │ ├── AFMInfoBanner_UIAppearance__should_configure_error_look-414@3x.png │ │ │ ├── AFMInfoBanner_UIAppearance__should_prioritise_custom_look_over_UIAppearance_looks-320@2x.png │ │ │ ├── AFMInfoBanner_UIAppearance__should_prioritise_custom_look_over_UIAppearance_looks-375@2x.png │ │ │ ├── AFMInfoBanner_UIAppearance__should_prioritise_custom_look_over_UIAppearance_looks-414@3x.png │ │ │ ├── AFMInfoBanner_UIAppearance__should_use_default_style_look_for_text_color_if_its_not_customised-320@2x.png │ │ │ ├── AFMInfoBanner_UIAppearance__should_use_default_style_look_for_text_color_if_its_not_customised-375@2x.png │ │ │ ├── AFMInfoBanner_UIAppearance__should_use_default_style_look_for_text_color_if_its_not_customised-414@3x.png │ │ │ ├── AFMInfoBanner_UIAppearance__should_use_default_style_look_for_text_or_font_if_its_not_customised-320@2x.png │ │ │ ├── AFMInfoBanner_UIAppearance__should_use_default_style_look_for_background_color_if_its_not_customised-320@2x.png │ │ │ ├── AFMInfoBanner_UIAppearance__should_use_default_style_look_for_background_color_if_its_not_customised-375@2x.png │ │ │ └── AFMInfoBanner_UIAppearance__should_use_default_style_look_for_background_color_if_its_not_customised-414@3x.png │ ├── Tests-Prefix.pch │ ├── AFMTestCommons.h │ ├── Tests-Info.plist │ ├── AFMTestCommons.m │ ├── AFMInfoBannerAppearanceSpec.m │ └── AFMInfoBannerSpec.m ├── AFMInfoBanner │ ├── en.lproj │ │ └── InfoPlist.strings │ ├── AFMViewController.h │ ├── AFMModalViewController.h │ ├── AFMInitialViewController.h │ ├── AFMAppDelegate.h │ ├── AFMInfoBanner-Prefix.pch │ ├── main.m │ ├── AFMAppDelegate.m │ ├── AFMModalViewController.m │ ├── Images.xcassets │ │ ├── AppIcon.appiconset │ │ │ └── Contents.json │ │ └── LaunchImage.launchimage │ │ │ └── Contents.json │ ├── AFMViewController.m │ ├── AFMInitialViewController.m │ ├── AFMInfoBanner-Info.plist │ └── Base.lproj │ │ └── Main.storyboard ├── AFMInfoBanner.xcodeproj │ ├── project.xcworkspace │ │ └── contents.xcworkspacedata │ ├── xcshareddata │ │ └── xcschemes │ │ │ ├── Tests.xcscheme │ │ │ └── AFMInfoBanner.xcscheme │ └── project.pbxproj ├── AFMInfoBanner.xcworkspace │ └── contents.xcworkspacedata ├── Podfile └── Podfile.lock ├── res ├── red_banner.gif └── red_banner.png ├── .travis.yml ├── .gitignore ├── LICENSE ├── AFMInfoBanner.podspec └── README.md /Pod/Classes/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Example/Tests/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /res/red_banner.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ask-fm/AFMInfoBanner/HEAD/res/red_banner.gif -------------------------------------------------------------------------------- /res/red_banner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ask-fm/AFMInfoBanner/HEAD/res/red_banner.png -------------------------------------------------------------------------------- /Example/AFMInfoBanner/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /Example/AFMInfoBanner.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Example/Tests/ReferenceImages/AFMInfoBannerSpec/AFMInfoBanner_view__should_show_long_red_one-320@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ask-fm/AFMInfoBanner/HEAD/Example/Tests/ReferenceImages/AFMInfoBannerSpec/AFMInfoBanner_view__should_show_long_red_one-320@2x.png -------------------------------------------------------------------------------- /Example/Tests/ReferenceImages/AFMInfoBannerSpec/AFMInfoBanner_view__should_show_long_red_one-375@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ask-fm/AFMInfoBanner/HEAD/Example/Tests/ReferenceImages/AFMInfoBannerSpec/AFMInfoBanner_view__should_show_long_red_one-375@2x.png -------------------------------------------------------------------------------- /Example/Tests/ReferenceImages/AFMInfoBannerSpec/AFMInfoBanner_view__should_show_long_red_one-414@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ask-fm/AFMInfoBanner/HEAD/Example/Tests/ReferenceImages/AFMInfoBannerSpec/AFMInfoBanner_view__should_show_long_red_one-414@3x.png -------------------------------------------------------------------------------- /Example/Tests/ReferenceImages/AFMInfoBannerSpec/AFMInfoBanner_view__should_show_compact_red_one-320@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ask-fm/AFMInfoBanner/HEAD/Example/Tests/ReferenceImages/AFMInfoBannerSpec/AFMInfoBanner_view__should_show_compact_red_one-320@2x.png -------------------------------------------------------------------------------- /Example/Tests/ReferenceImages/AFMInfoBannerSpec/AFMInfoBanner_view__should_show_compact_red_one-375@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ask-fm/AFMInfoBanner/HEAD/Example/Tests/ReferenceImages/AFMInfoBannerSpec/AFMInfoBanner_view__should_show_compact_red_one-375@2x.png -------------------------------------------------------------------------------- /Example/Tests/ReferenceImages/AFMInfoBannerSpec/AFMInfoBanner_view__should_show_compact_red_one-414@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ask-fm/AFMInfoBanner/HEAD/Example/Tests/ReferenceImages/AFMInfoBannerSpec/AFMInfoBanner_view__should_show_compact_red_one-414@3x.png -------------------------------------------------------------------------------- /Example/Tests/ReferenceImages/AFMInfoBannerSpec/AFMInfoBanner_view__should_show_compact_green_one-320@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ask-fm/AFMInfoBanner/HEAD/Example/Tests/ReferenceImages/AFMInfoBannerSpec/AFMInfoBanner_view__should_show_compact_green_one-320@2x.png -------------------------------------------------------------------------------- /Example/Tests/ReferenceImages/AFMInfoBannerSpec/AFMInfoBanner_view__should_show_compact_green_one-375@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ask-fm/AFMInfoBanner/HEAD/Example/Tests/ReferenceImages/AFMInfoBannerSpec/AFMInfoBanner_view__should_show_compact_green_one-375@2x.png -------------------------------------------------------------------------------- /Example/Tests/ReferenceImages/AFMInfoBannerSpec/AFMInfoBanner_view__should_show_compact_green_one-414@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ask-fm/AFMInfoBanner/HEAD/Example/Tests/ReferenceImages/AFMInfoBannerSpec/AFMInfoBanner_view__should_show_compact_green_one-414@3x.png -------------------------------------------------------------------------------- /Example/Tests/ReferenceImages/AFMInfoBannerAppearanceSpec/AFMInfoBanner_UIAppearance__should_configure_font-320@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ask-fm/AFMInfoBanner/HEAD/Example/Tests/ReferenceImages/AFMInfoBannerAppearanceSpec/AFMInfoBanner_UIAppearance__should_configure_font-320@2x.png -------------------------------------------------------------------------------- /Example/Tests/ReferenceImages/AFMInfoBannerAppearanceSpec/AFMInfoBanner_UIAppearance__should_configure_font-375@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ask-fm/AFMInfoBanner/HEAD/Example/Tests/ReferenceImages/AFMInfoBannerAppearanceSpec/AFMInfoBanner_UIAppearance__should_configure_font-375@2x.png -------------------------------------------------------------------------------- /Example/Tests/ReferenceImages/AFMInfoBannerAppearanceSpec/AFMInfoBanner_UIAppearance__should_configure_font-414@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ask-fm/AFMInfoBanner/HEAD/Example/Tests/ReferenceImages/AFMInfoBannerAppearanceSpec/AFMInfoBanner_UIAppearance__should_configure_font-414@3x.png -------------------------------------------------------------------------------- /Example/Tests/ReferenceImages/AFMInfoBannerAppearanceSpec/AFMInfoBanner_UIAppearance__should_configure_info_look-320@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ask-fm/AFMInfoBanner/HEAD/Example/Tests/ReferenceImages/AFMInfoBannerAppearanceSpec/AFMInfoBanner_UIAppearance__should_configure_info_look-320@2x.png -------------------------------------------------------------------------------- /Example/Tests/ReferenceImages/AFMInfoBannerAppearanceSpec/AFMInfoBanner_UIAppearance__should_configure_info_look-375@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ask-fm/AFMInfoBanner/HEAD/Example/Tests/ReferenceImages/AFMInfoBannerAppearanceSpec/AFMInfoBanner_UIAppearance__should_configure_info_look-375@2x.png -------------------------------------------------------------------------------- /Example/Tests/ReferenceImages/AFMInfoBannerAppearanceSpec/AFMInfoBanner_UIAppearance__should_configure_info_look-414@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ask-fm/AFMInfoBanner/HEAD/Example/Tests/ReferenceImages/AFMInfoBannerAppearanceSpec/AFMInfoBanner_UIAppearance__should_configure_info_look-414@3x.png -------------------------------------------------------------------------------- /Example/Tests/ReferenceImages/AFMInfoBannerAppearanceSpec/AFMInfoBanner_UIAppearance__should_configure_error_look-320@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ask-fm/AFMInfoBanner/HEAD/Example/Tests/ReferenceImages/AFMInfoBannerAppearanceSpec/AFMInfoBanner_UIAppearance__should_configure_error_look-320@2x.png -------------------------------------------------------------------------------- /Example/Tests/ReferenceImages/AFMInfoBannerAppearanceSpec/AFMInfoBanner_UIAppearance__should_configure_error_look-375@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ask-fm/AFMInfoBanner/HEAD/Example/Tests/ReferenceImages/AFMInfoBannerAppearanceSpec/AFMInfoBanner_UIAppearance__should_configure_error_look-375@2x.png -------------------------------------------------------------------------------- /Example/Tests/ReferenceImages/AFMInfoBannerAppearanceSpec/AFMInfoBanner_UIAppearance__should_configure_error_look-414@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ask-fm/AFMInfoBanner/HEAD/Example/Tests/ReferenceImages/AFMInfoBannerAppearanceSpec/AFMInfoBanner_UIAppearance__should_configure_error_look-414@3x.png -------------------------------------------------------------------------------- /Example/AFMInfoBanner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Example/AFMInfoBanner/AFMViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // AFMViewController.h 3 | // AFMInfoBanner 4 | // 5 | // Created by Romans Karpelcevs on 11/17/2014. 6 | // Copyright (c) 2014 Ask.fm Europe, Ltd. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AFMViewController : UIViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Example/Podfile: -------------------------------------------------------------------------------- 1 | source 'https://github.com/CocoaPods/Specs.git' 2 | 3 | target 'AFMInfoBanner' do 4 | pod "AFMInfoBanner", :path => "../" 5 | end 6 | 7 | target 'Tests' do 8 | pod "AFMInfoBanner", :path => "../" 9 | 10 | pod 'Specta' 11 | pod 'Expecta' 12 | pod 'FBSnapshotTestCase/Core' 13 | pod 'Expecta+Snapshots' 14 | end 15 | -------------------------------------------------------------------------------- /Example/Tests/ReferenceImages/AFMInfoBannerAppearanceSpec/AFMInfoBanner_UIAppearance__should_prioritise_custom_look_over_UIAppearance_looks-320@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ask-fm/AFMInfoBanner/HEAD/Example/Tests/ReferenceImages/AFMInfoBannerAppearanceSpec/AFMInfoBanner_UIAppearance__should_prioritise_custom_look_over_UIAppearance_looks-320@2x.png -------------------------------------------------------------------------------- /Example/Tests/ReferenceImages/AFMInfoBannerAppearanceSpec/AFMInfoBanner_UIAppearance__should_prioritise_custom_look_over_UIAppearance_looks-375@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ask-fm/AFMInfoBanner/HEAD/Example/Tests/ReferenceImages/AFMInfoBannerAppearanceSpec/AFMInfoBanner_UIAppearance__should_prioritise_custom_look_over_UIAppearance_looks-375@2x.png -------------------------------------------------------------------------------- /Example/Tests/ReferenceImages/AFMInfoBannerAppearanceSpec/AFMInfoBanner_UIAppearance__should_prioritise_custom_look_over_UIAppearance_looks-414@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ask-fm/AFMInfoBanner/HEAD/Example/Tests/ReferenceImages/AFMInfoBannerAppearanceSpec/AFMInfoBanner_UIAppearance__should_prioritise_custom_look_over_UIAppearance_looks-414@3x.png -------------------------------------------------------------------------------- /Example/AFMInfoBanner/AFMModalViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // AFMModalViewController.h 3 | // AFMInfoBanner 4 | // 5 | // Created by Romans Karpelcevs on 10/03/15. 6 | // Copyright (c) 2015 Romans Karpelcevs. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AFMModalViewController : UIViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Example/AFMInfoBanner/AFMInitialViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // AFMInitialViewController.h 3 | // AFMInfoBanner 4 | // 5 | // Created by Romans Karpelcevs on 10/03/15. 6 | // Copyright (c) 2015 Romans Karpelcevs. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AFMInitialViewController : UIViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Example/Tests/ReferenceImages/AFMInfoBannerAppearanceSpec/AFMInfoBanner_UIAppearance__should_use_default_style_look_for_text_color_if_its_not_customised-320@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ask-fm/AFMInfoBanner/HEAD/Example/Tests/ReferenceImages/AFMInfoBannerAppearanceSpec/AFMInfoBanner_UIAppearance__should_use_default_style_look_for_text_color_if_its_not_customised-320@2x.png -------------------------------------------------------------------------------- /Example/Tests/ReferenceImages/AFMInfoBannerAppearanceSpec/AFMInfoBanner_UIAppearance__should_use_default_style_look_for_text_color_if_its_not_customised-375@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ask-fm/AFMInfoBanner/HEAD/Example/Tests/ReferenceImages/AFMInfoBannerAppearanceSpec/AFMInfoBanner_UIAppearance__should_use_default_style_look_for_text_color_if_its_not_customised-375@2x.png -------------------------------------------------------------------------------- /Example/Tests/ReferenceImages/AFMInfoBannerAppearanceSpec/AFMInfoBanner_UIAppearance__should_use_default_style_look_for_text_color_if_its_not_customised-414@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ask-fm/AFMInfoBanner/HEAD/Example/Tests/ReferenceImages/AFMInfoBannerAppearanceSpec/AFMInfoBanner_UIAppearance__should_use_default_style_look_for_text_color_if_its_not_customised-414@3x.png -------------------------------------------------------------------------------- /Example/Tests/ReferenceImages/AFMInfoBannerAppearanceSpec/AFMInfoBanner_UIAppearance__should_use_default_style_look_for_text_or_font_if_its_not_customised-320@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ask-fm/AFMInfoBanner/HEAD/Example/Tests/ReferenceImages/AFMInfoBannerAppearanceSpec/AFMInfoBanner_UIAppearance__should_use_default_style_look_for_text_or_font_if_its_not_customised-320@2x.png -------------------------------------------------------------------------------- /Example/Tests/ReferenceImages/AFMInfoBannerAppearanceSpec/AFMInfoBanner_UIAppearance__should_use_default_style_look_for_background_color_if_its_not_customised-320@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ask-fm/AFMInfoBanner/HEAD/Example/Tests/ReferenceImages/AFMInfoBannerAppearanceSpec/AFMInfoBanner_UIAppearance__should_use_default_style_look_for_background_color_if_its_not_customised-320@2x.png -------------------------------------------------------------------------------- /Example/Tests/ReferenceImages/AFMInfoBannerAppearanceSpec/AFMInfoBanner_UIAppearance__should_use_default_style_look_for_background_color_if_its_not_customised-375@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ask-fm/AFMInfoBanner/HEAD/Example/Tests/ReferenceImages/AFMInfoBannerAppearanceSpec/AFMInfoBanner_UIAppearance__should_use_default_style_look_for_background_color_if_its_not_customised-375@2x.png -------------------------------------------------------------------------------- /Example/Tests/ReferenceImages/AFMInfoBannerAppearanceSpec/AFMInfoBanner_UIAppearance__should_use_default_style_look_for_background_color_if_its_not_customised-414@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ask-fm/AFMInfoBanner/HEAD/Example/Tests/ReferenceImages/AFMInfoBannerAppearanceSpec/AFMInfoBanner_UIAppearance__should_use_default_style_look_for_background_color_if_its_not_customised-414@3x.png -------------------------------------------------------------------------------- /Example/AFMInfoBanner/AFMAppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AFMAppDelegate.h 3 | // AFMInfoBanner 4 | // 5 | // Created by CocoaPods on 11/17/2014. 6 | // Copyright (c) 2014 Ask.fm Europe, Ltd. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AFMAppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /Example/Tests/Tests-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header 3 | // 4 | // The contents of this file are implicitly included at the beginning of every test case source file. 5 | // 6 | 7 | #ifdef __OBJC__ 8 | 9 | #define EXP_SHORTHAND 10 | #import 11 | #import 12 | #import 13 | #import 14 | 15 | #endif 16 | -------------------------------------------------------------------------------- /Example/AFMInfoBanner/AFMInfoBanner-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header 3 | // 4 | // The contents of this file are implicitly included at the beginning of every source file. 5 | // 6 | 7 | #import 8 | 9 | #ifndef __IPHONE_5_0 10 | #warning "This project uses features only available in iOS SDK 5.0 and later." 11 | #endif 12 | 13 | #ifdef __OBJC__ 14 | #import 15 | #import 16 | #endif 17 | -------------------------------------------------------------------------------- /Example/AFMInfoBanner/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // AFMInfoBanner 4 | // 5 | // Created by Romans Karpelcevs on 11/17/2014. 6 | // Copyright (c) 2014 Ask.fm Europe, Ltd. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "AFMAppDelegate.h" 12 | 13 | int main(int argc, char * argv[]) 14 | { 15 | @autoreleasepool { 16 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AFMAppDelegate class])); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Example/AFMInfoBanner/AFMAppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AFMAppDelegate.m 3 | // AFMInfoBanner 4 | // 5 | // Created by CocoaPods on 11/17/2014. 6 | // Copyright (c) 2014 Ask.fm Europe, Ltd. All rights reserved. 7 | // 8 | 9 | #import "AFMAppDelegate.h" 10 | 11 | @implementation AFMAppDelegate 12 | 13 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 14 | { 15 | [application setStatusBarStyle:UIStatusBarStyleLightContent]; 16 | return YES; 17 | } 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /Example/Tests/AFMTestCommons.h: -------------------------------------------------------------------------------- 1 | // 2 | // AFMTestCommons.h 3 | // AFMInfoBanner 4 | // 5 | // Created by Romans Karpelcevs on 22/11/14. 6 | // Copyright (c) 2014 Ask.fm Europe, Ltd. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "AFMInfoBanner.h" 11 | 12 | extern NSString *const kShortBannerText; 13 | extern NSString *const kLongBannerText; 14 | 15 | NSString *sanitizedTestName(); 16 | NSString *deviceSpecificName(); 17 | 18 | AFMInfoBanner *bannerManual(NSString *text, AFMInfoBannerStyle style); 19 | AFMInfoBanner *bannerFromHelper(NSString *text, AFMInfoBannerStyle style); 20 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | # reference: http://www.objc.io/issue-6/travis-ci.html 2 | rvm: 2.3.1 3 | osx_image: xcode8.2 4 | language: objective-c 5 | 6 | before_install: 7 | - gem install cocoapods -v '= 1.1.1' 8 | - cd Example && pod install && cd - 9 | script: 10 | - xcodebuild -workspace Example/AFMInfoBanner.xcworkspace -scheme Tests -destination 'platform=iOS Simulator,name=iPhone SE,OS=10.1' clean test 11 | - xcodebuild -workspace Example/AFMInfoBanner.xcworkspace -scheme Tests -destination 'platform=iOS Simulator,name=iPhone 7,OS=10.1' clean test 12 | - xcodebuild -workspace Example/AFMInfoBanner.xcworkspace -scheme Tests -destination 'platform=iOS Simulator,name=iPhone 7 Plus,OS=10.1' clean test 13 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # OS X 2 | .DS_Store 3 | 4 | # Xcode 5 | build/ 6 | *.pbxuser 7 | !default.pbxuser 8 | *.mode1v3 9 | !default.mode1v3 10 | *.mode2v3 11 | !default.mode2v3 12 | *.perspectivev3 13 | !default.perspectivev3 14 | xcuserdata 15 | *.xccheckout 16 | profile 17 | *.moved-aside 18 | DerivedData 19 | *.hmap 20 | *.ipa 21 | 22 | # Bundler 23 | .bundle 24 | 25 | # We recommend against adding the Pods directory to your .gitignore. However 26 | # you should judge for yourself, the pros and cons are mentioned at: 27 | # http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control 28 | # 29 | # Note: if you ignore the Pods directory, make sure to uncomment 30 | # `pod install` in .travis.yml 31 | # 32 | Pods/ 33 | -------------------------------------------------------------------------------- /Example/Tests/Tests-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundlePackageType 14 | BNDL 15 | CFBundleShortVersionString 16 | 1.0 17 | CFBundleSignature 18 | ???? 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /Example/AFMInfoBanner/AFMModalViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // AFMModalViewController.m 3 | // AFMInfoBanner 4 | // 5 | // Created by Romans Karpelcevs on 10/03/15. 6 | // Copyright (c) 2015 Romans Karpelcevs. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "AFMModalViewController.h" 11 | 12 | @interface AFMModalViewController () 13 | 14 | @property (nonatomic) IBOutlet UITextView *textView; 15 | 16 | @end 17 | 18 | @implementation AFMModalViewController 19 | 20 | - (IBAction)showGreen:(id)sender 21 | { 22 | [AFMInfoBanner showAndHideWithText:self.textView.text style:AFMInfoBannerStyleInfo]; 23 | } 24 | 25 | - (IBAction)showRed:(id)sender 26 | { 27 | [AFMInfoBanner showAndHideWithText:self.textView.text style:AFMInfoBannerStyleError]; 28 | } 29 | 30 | - (IBAction)dismiss:(id)sender 31 | { 32 | [self.presentingViewController dismissViewControllerAnimated:YES completion:nil]; 33 | } 34 | 35 | @end 36 | -------------------------------------------------------------------------------- /Example/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - AFMInfoBanner (1.2.1): 3 | - CVKHierarchySearcher (~> 0.2) 4 | - CVKHierarchySearcher (0.2.0) 5 | - Expecta (1.0.5) 6 | - Expecta+Snapshots (3.0.0): 7 | - Expecta (~> 1.0) 8 | - FBSnapshotTestCase/Core (~> 2.0) 9 | - Specta (~> 1.0) 10 | - FBSnapshotTestCase/Core (2.1.4) 11 | - Specta (1.0.5) 12 | 13 | DEPENDENCIES: 14 | - AFMInfoBanner (from `../`) 15 | - Expecta 16 | - Expecta+Snapshots 17 | - FBSnapshotTestCase/Core 18 | - Specta 19 | 20 | EXTERNAL SOURCES: 21 | AFMInfoBanner: 22 | :path: "../" 23 | 24 | SPEC CHECKSUMS: 25 | AFMInfoBanner: a7bcfd409faa624f043e604ae4fb789c84b22815 26 | CVKHierarchySearcher: 7be8d3bcbcc6f86ff07f785e6c632b5e40da2553 27 | Expecta: e1c022fcd33910b6be89c291d2775b3fe27a89fe 28 | Expecta+Snapshots: c343f410c7a6392f3e22e78f94c44b6c0749a516 29 | FBSnapshotTestCase: 094f9f314decbabe373b87cc339bea235a63e07a 30 | Specta: ac94d110b865115fe60ff2c6d7281053c6f8e8a2 31 | 32 | PODFILE CHECKSUM: c0ab804d6293d0e8f9b9223ffccffb43d85ade77 33 | 34 | COCOAPODS: 1.1.1 35 | -------------------------------------------------------------------------------- /Example/AFMInfoBanner/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "40x40", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "60x60", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "ipad", 20 | "size" : "29x29", 21 | "scale" : "1x" 22 | }, 23 | { 24 | "idiom" : "ipad", 25 | "size" : "29x29", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "ipad", 30 | "size" : "40x40", 31 | "scale" : "1x" 32 | }, 33 | { 34 | "idiom" : "ipad", 35 | "size" : "40x40", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "ipad", 40 | "size" : "76x76", 41 | "scale" : "1x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "76x76", 46 | "scale" : "2x" 47 | } 48 | ], 49 | "info" : { 50 | "version" : 1, 51 | "author" : "xcode" 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014 Ask.fm Europe, Ltd. 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /Example/AFMInfoBanner/AFMViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // AFMViewController.m 3 | // AFMInfoBanner 4 | // 5 | // Created by Romans Karpelcevs on 11/17/2014. 6 | // Copyright (c) 2014 Ask.fm Europe, Ltd. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "AFMViewController.h" 11 | 12 | @interface AFMViewController () 13 | 14 | @property (nonatomic) IBOutlet UITextView *textView; 15 | 16 | @end 17 | 18 | @implementation AFMViewController 19 | 20 | - (IBAction)showGreen:(id)sender 21 | { 22 | [AFMInfoBanner showAndHideWithText:self.textView.text style:AFMInfoBannerStyleInfo]; 23 | } 24 | 25 | - (IBAction)showRed:(id)sender 26 | { 27 | [AFMInfoBanner showAndHideWithText:self.textView.text style:AFMInfoBannerStyleError]; 28 | } 29 | 30 | - (IBAction)presentModal:(id)sender 31 | { 32 | UIViewController *modalVC = [self.storyboard instantiateViewControllerWithIdentifier:@"modalVC"]; 33 | [self presentViewController:modalVC animated:YES completion:nil]; 34 | } 35 | 36 | - (IBAction)dismiss:(id)sender 37 | { 38 | [self.presentingViewController dismissViewControllerAnimated:YES completion:nil]; 39 | } 40 | 41 | @end 42 | -------------------------------------------------------------------------------- /Example/AFMInfoBanner/AFMInitialViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // AFMInitialViewController.m 3 | // AFMInfoBanner 4 | // 5 | // Created by Romans Karpelcevs on 10/03/15. 6 | // Copyright (c) 2015 Romans Karpelcevs. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "AFMInitialViewController.h" 11 | 12 | @interface AFMInitialViewController () 13 | 14 | @property (nonatomic) IBOutlet UITextView *textView; 15 | 16 | @end 17 | 18 | @implementation AFMInitialViewController 19 | 20 | - (void)viewDidAppear:(BOOL)animated 21 | { 22 | [super viewDidAppear:animated]; 23 | 24 | static BOOL firstTime = YES; 25 | if (firstTime) { 26 | firstTime = NO; 27 | UIViewController *newVC = [self.storyboard instantiateViewControllerWithIdentifier:@"navVC"]; 28 | [self presentViewController:newVC animated:YES completion:nil]; 29 | } 30 | } 31 | 32 | - (IBAction)showGreen:(id)sender 33 | { 34 | [AFMInfoBanner showAndHideWithText:self.textView.text style:AFMInfoBannerStyleInfo]; 35 | } 36 | 37 | - (IBAction)showRed:(id)sender 38 | { 39 | [AFMInfoBanner showAndHideWithText:self.textView.text style:AFMInfoBannerStyleError]; 40 | } 41 | 42 | @end 43 | -------------------------------------------------------------------------------- /AFMInfoBanner.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = "AFMInfoBanner" 3 | s.version = "1.2.1" 4 | s.summary = "Easy to use auto-hiding notice bar below Navigation Bar." 5 | s.description = <<-DESC 6 | Red or green banner with text sliding from below the Navigation Bar 7 | and hiding itself after a small timeout. 8 | 9 | Good for notices or error messages. Auto-sizes itself to fit all 10 | text. Colours are customisable by UIAppearance. 11 | DESC 12 | s.homepage = "https://github.com/ask-fm/AFMInfoBanner" 13 | s.screenshots = "https://raw.githubusercontent.com/ask-fm/AFMInfoBanner/master/res/red_banner.gif", "https://raw.githubusercontent.com/ask-fm/AFMInfoBanner/master/res/red_banner.png" 14 | s.license = 'MIT' 15 | s.author = { "Romans Karpelcevs" => "roman@ask.fm" } 16 | s.source = { :git => "https://github.com/ask-fm/AFMInfoBanner.git", :tag => s.version.to_s } 17 | s.social_media_url = 'https://twitter.com/cvbk' 18 | 19 | s.platform = :ios, '8.0' 20 | s.requires_arc = true 21 | 22 | s.source_files = 'Pod/Classes' 23 | s.frameworks = 'UIKit' 24 | s.dependency 'CVKHierarchySearcher', '~> 0.2' 25 | end 26 | -------------------------------------------------------------------------------- /Example/AFMInfoBanner/Images.xcassets/LaunchImage.launchimage/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "orientation" : "portrait", 5 | "idiom" : "iphone", 6 | "extent" : "full-screen", 7 | "minimum-system-version" : "7.0", 8 | "scale" : "2x" 9 | }, 10 | { 11 | "orientation" : "portrait", 12 | "idiom" : "iphone", 13 | "subtype" : "retina4", 14 | "extent" : "full-screen", 15 | "minimum-system-version" : "7.0", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "orientation" : "portrait", 20 | "idiom" : "ipad", 21 | "extent" : "full-screen", 22 | "minimum-system-version" : "7.0", 23 | "scale" : "1x" 24 | }, 25 | { 26 | "orientation" : "landscape", 27 | "idiom" : "ipad", 28 | "extent" : "full-screen", 29 | "minimum-system-version" : "7.0", 30 | "scale" : "1x" 31 | }, 32 | { 33 | "orientation" : "portrait", 34 | "idiom" : "ipad", 35 | "extent" : "full-screen", 36 | "minimum-system-version" : "7.0", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "orientation" : "landscape", 41 | "idiom" : "ipad", 42 | "extent" : "full-screen", 43 | "minimum-system-version" : "7.0", 44 | "scale" : "2x" 45 | } 46 | ], 47 | "info" : { 48 | "version" : 1, 49 | "author" : "xcode" 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /Example/Tests/AFMTestCommons.m: -------------------------------------------------------------------------------- 1 | // 2 | // AFMTestCommons.m 3 | // AFMInfoBanner 4 | // 5 | // Created by Romans Karpelcevs on 22/11/14. 6 | // Copyright (c) 2014 Ask.fm Europe, Ltd. All rights reserved. 7 | // 8 | 9 | #import "AFMTestCommons.h" 10 | 11 | NSString *const kShortBannerText = @"Short error text"; 12 | NSString *const kLongBannerText = @"Longer text which definitely would be shown on multiple lines and wrap."; 13 | 14 | NSString *sanitizedTestName() 15 | { 16 | SPTSpec *currrentSpec = [[NSThread currentThread] threadDictionary][@"SPTCurrentSpec"]; 17 | NSString *name = [[[currrentSpec.name componentsSeparatedByString:@" test_"] lastObject] stringByReplacingOccurrencesOfString:@"]" withString:@""]; 18 | return name; 19 | } 20 | 21 | NSString *deviceSpecificName() 22 | { 23 | return [NSString stringWithFormat:@"%@-%.0f", 24 | sanitizedTestName(), 25 | CGRectGetWidth([[UIScreen mainScreen] bounds])]; 26 | } 27 | 28 | AFMInfoBanner *bannerManual(NSString *text, AFMInfoBannerStyle style) 29 | { 30 | AFMInfoBanner *banner = [[AFMInfoBanner alloc] init]; 31 | banner.text = text; 32 | banner.style = style; 33 | [banner show:YES]; 34 | return banner; 35 | } 36 | 37 | AFMInfoBanner *bannerFromHelper(NSString *text, AFMInfoBannerStyle style) 38 | { 39 | return [AFMInfoBanner showAndHideWithText:text style:style]; 40 | } 41 | -------------------------------------------------------------------------------- /Example/AFMInfoBanner/AFMInfoBanner-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | ${PRODUCT_NAME} 9 | CFBundleExecutable 10 | ${EXECUTABLE_NAME} 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | ${PRODUCT_NAME} 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1.0 25 | LSRequiresIPhoneOS 26 | 27 | UILaunchStoryboardName 28 | Main 29 | UIMainStoryboardFile 30 | Main 31 | UIRequiredDeviceCapabilities 32 | 33 | armv7 34 | 35 | UIStatusBarStyle 36 | UIStatusBarStyleLightContent 37 | UISupportedInterfaceOrientations 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationLandscapeLeft 41 | UIInterfaceOrientationLandscapeRight 42 | 43 | UIViewControllerBasedStatusBarAppearance 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /Pod/Classes/AFMInfoBanner.h: -------------------------------------------------------------------------------- 1 | // 2 | // AFMInfoBanner.h 3 | // AFMInfoBanner 4 | // 5 | // Created by Romans Karpelcevs on 6/14/13. 6 | // Copyright (c) 2013 Ask.fm Europe, Ltd. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | typedef NS_ENUM(NSUInteger, AFMInfoBannerStyle) { 12 | AFMInfoBannerStyleError = 0, 13 | AFMInfoBannerStyleInfo, 14 | }; 15 | 16 | @interface AFMInfoBanner : UIView 17 | 18 | @property (nonatomic, readonly, getter=isShown) BOOL shown; 19 | 20 | @property (nonatomic) AFMInfoBannerStyle style; 21 | @property (nonatomic) NSString *text; 22 | 23 | @property (nonatomic, copy) void (^showCompletionBlock)(); 24 | @property (nonatomic, copy) void (^hideCompletionBlock)(); 25 | @property (nonatomic, copy) void (^tappedBlock)(); 26 | 27 | @property (nonatomic) UIFont *font UI_APPEARANCE_SELECTOR; 28 | @property (nonatomic) UIColor *errorBackgroundColor UI_APPEARANCE_SELECTOR; 29 | @property (nonatomic) UIColor *infoBackgroundColor UI_APPEARANCE_SELECTOR; 30 | @property (nonatomic) UIColor *errorTextColor UI_APPEARANCE_SELECTOR; 31 | @property (nonatomic) UIColor *infoTextColor UI_APPEARANCE_SELECTOR; 32 | @property (nonatomic) CGFloat topSpacing UI_APPEARANCE_SELECTOR; 33 | @property (nonatomic) UIColor *customBackgroundColor; 34 | @property (nonatomic) UIColor *customTextColor; 35 | 36 | - (id)initWithTargetView:(UIView *)targetView 37 | viewAboveBanner:(UIView *)viewAboveBanner 38 | additionalTopSpacing:(CGFloat)additionalTopSpacing; 39 | 40 | - (void)show:(BOOL)animated; 41 | - (void)hide:(BOOL)animated; 42 | - (void)show:(BOOL)animated withCompletion:(void (^)())completionBlock; 43 | - (void)hide:(BOOL)animated withCompletion:(void (^)())completionBlock; 44 | - (void)showAndHideAfter:(NSTimeInterval)timeout animated:(BOOL)animated; 45 | 46 | + (instancetype)showWithText:(NSString *)text 47 | style:(AFMInfoBannerStyle)style 48 | andHideAfter:(NSTimeInterval)timeout; 49 | + (instancetype)showWithText:(NSString *)text 50 | style:(AFMInfoBannerStyle)style 51 | animated:(BOOL)animated; 52 | + (instancetype)showAndHideWithText:(NSString *)text 53 | style:(AFMInfoBannerStyle)style; 54 | + (void)hideAll; 55 | 56 | @end 57 | -------------------------------------------------------------------------------- /Example/Tests/AFMInfoBannerAppearanceSpec.m: -------------------------------------------------------------------------------- 1 | // 2 | // AFMInfoBannerAppearanceSpec.m 3 | // AFMInfoBanner 4 | // 5 | // Created by Romans Karpelcevs on 22/11/14. 6 | // Copyright (c) 2014 Ask.fm Europe, Ltd. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | #import "AFMTestCommons.h" 12 | 13 | SpecBegin(AFMInfoBannerAppearance) 14 | 15 | describe(@"AFMInfoBanner UIAppearance", ^{ 16 | __block AFMInfoBanner *banner; 17 | 18 | it(@"should configure error look", ^{ 19 | [[AFMInfoBanner appearance] setErrorBackgroundColor:[UIColor blueColor]]; 20 | [[AFMInfoBanner appearance] setErrorTextColor:[UIColor blackColor]]; 21 | 22 | banner = bannerFromHelper(kShortBannerText, AFMInfoBannerStyleError); 23 | expect(banner).will.haveValidSnapshotNamed(deviceSpecificName()); 24 | }); 25 | 26 | it(@"should configure info look", ^{ 27 | [[AFMInfoBanner appearance] setInfoBackgroundColor:[UIColor blackColor]]; 28 | [[AFMInfoBanner appearance] setInfoTextColor:[UIColor yellowColor]]; 29 | 30 | banner = bannerFromHelper(kShortBannerText, AFMInfoBannerStyleInfo); 31 | expect(banner).will.haveValidSnapshotNamed(deviceSpecificName()); 32 | }); 33 | 34 | it(@"should configure font", ^{ 35 | [[AFMInfoBanner appearance] setFont:[UIFont systemFontOfSize:20]]; 36 | 37 | banner = bannerFromHelper(kLongBannerText, AFMInfoBannerStyleError); 38 | expect(banner).will.haveValidSnapshotNamed(deviceSpecificName()); 39 | }); 40 | 41 | it(@"should prioritise custom look over UIAppearance looks", ^{ 42 | [[AFMInfoBanner appearance] setInfoBackgroundColor:[UIColor blackColor]]; 43 | [[AFMInfoBanner appearance] setInfoTextColor:[UIColor yellowColor]]; 44 | 45 | banner = bannerFromHelper(kShortBannerText, AFMInfoBannerStyleInfo); 46 | banner.customBackgroundColor = [UIColor cyanColor]; 47 | banner.customTextColor = [UIColor yellowColor]; 48 | expect(banner).will.haveValidSnapshotNamed(deviceSpecificName()); 49 | }); 50 | 51 | it(@"should use default style look for background color if it's not customised", ^{ 52 | [[AFMInfoBanner appearance] setInfoTextColor:[UIColor yellowColor]]; 53 | 54 | banner = bannerFromHelper(kShortBannerText, AFMInfoBannerStyleInfo); 55 | expect(banner).will.haveValidSnapshotNamed(deviceSpecificName()); 56 | }); 57 | 58 | it(@"should use default style look for text color if it's not customised", ^{ 59 | [[AFMInfoBanner appearance] setErrorBackgroundColor:[UIColor purpleColor]]; 60 | 61 | banner = bannerFromHelper(kShortBannerText, AFMInfoBannerStyleError); 62 | expect(banner).will.haveValidSnapshotNamed(deviceSpecificName()); 63 | }); 64 | 65 | afterEach(^{ 66 | [banner removeFromSuperview]; 67 | 68 | [[AFMInfoBanner appearance] setErrorBackgroundColor:nil]; 69 | [[AFMInfoBanner appearance] setErrorTextColor:nil]; 70 | [[AFMInfoBanner appearance] setInfoBackgroundColor:nil]; 71 | [[AFMInfoBanner appearance] setInfoTextColor:nil]; 72 | [[AFMInfoBanner appearance] setFont:nil]; 73 | }); 74 | }); 75 | 76 | SpecEnd 77 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # AFMInfoBanner 2 | 3 | [![CI Status](http://img.shields.io/travis/ask-fm/AFMInfoBanner.svg?style=flat)](https://travis-ci.org/ask-fm/AFMInfoBanner) 4 | [![Version](https://img.shields.io/cocoapods/v/AFMInfoBanner.svg?style=flat)](http://cocoadocs.org/docsets/AFMInfoBanner) 5 | [![License](https://img.shields.io/cocoapods/l/AFMInfoBanner.svg?style=flat)](http://cocoadocs.org/docsets/AFMInfoBanner) 6 | [![Platform](https://img.shields.io/cocoapods/p/AFMInfoBanner.svg?style=flat)](http://cocoadocs.org/docsets/AFMInfoBanner) 7 | 8 | AFMInfoBanner can be used to unobtrusively notify users about successful or erroneous events which do not require any specific action or UI locking. Good examples are network errors on the screens which can be functional even without the data that failed. 9 | 10 | Default error case looks like this: 11 | 12 | ![Animated Example](https://raw.githubusercontent.com/ask-fm/AFMInfoBanner/master/res/red_banner.gif) 13 | 14 | View is trying to find a navigation bar and show itself beneath it. If that fails, it shows from top of the window, adjusting height to be below status bar. View is resized to any text, but auto-hiding interval makes long text hard to read, so it's better to keep it short. 15 | 16 | Background and text colours, as well as font are customisable through `UIAppearance`. 17 | 18 | ## Usage 19 | 20 | There are two styles: `AFMInfoBannerStyleError` for error messages and `AFMInfoBannerStyleInfo` for other, like info or success notices. By default error is red and info is green. 21 | 22 | Easiest way to use it is calling a class method passing text and kind of message: 23 | 24 | ```objective-c 25 | [AFMInfoBanner showAndHideWithText:@"Error text" style:AFMInfoBannerStyleError]; 26 | ``` 27 | 28 | If you need another hiding interval, you can pass it like this: 29 | 30 | ```objective-c 31 | [AFMInfoBanner showWithText:@"Error text" style:AFMInfoBannerStyleError andHideAfter:1.0]; 32 | ``` 33 | 34 | If you want to create or show it yourself, as well as have a overriding point in case of inheritance, there are `-show:` and `-hide:` methods available. 35 | 36 | If you need to hide any possibly showing banner, use `+[AFMInfoBanner hideAll]`. Possible case for this is navigating away from the page. Without this banner is going to stay visible during navigation because it is attached to navigation bar's view. 37 | 38 | You can use Example project to play around with AFMInfoBanner. To run the example project, clone the repo, and run `pod install` from the Example directory first. 39 | 40 | ## Requirements 41 | 42 | iOS 8 and up. 43 | 44 | Usage of `UINavigationBar` or `UINavigationController` for navigation bar. 45 | 46 | Algorithm uses view controller hierarchy ([CVKHierarchySearcher](https://github.com/coverback/CVKHierarchySearcher)) to find navigation bar on the topmost view controller. First it checks the topmost controller's first level of subviews for `UINavigationBar`. If this fails, searches for topmost available `UINavigationController`. If that fails as well, shows from the status bar. Because of this logic, might work strangely with custom navigation bar replacements. 47 | 48 | ## Installation 49 | 50 | AFMInfoBanner is available through [CocoaPods](http://cocoapods.org). To install 51 | it, simply add the following line to your Podfile: 52 | 53 | pod 'AFMInfoBanner' 54 | 55 | ## License 56 | 57 | AFMInfoBanner is available under the MIT license. See the LICENSE file for more info. 58 | 59 | -------------------------------------------------------------------------------- /Example/AFMInfoBanner.xcodeproj/xcshareddata/xcschemes/Tests.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 14 | 15 | 17 | 23 | 24 | 25 | 26 | 27 | 33 | 34 | 35 | 36 | 37 | 38 | 48 | 50 | 56 | 57 | 58 | 59 | 60 | 61 | 67 | 68 | 74 | 75 | 76 | 77 | 79 | 80 | 83 | 84 | 85 | -------------------------------------------------------------------------------- /Example/Tests/AFMInfoBannerSpec.m: -------------------------------------------------------------------------------- 1 | // 2 | // AFMInfoBannerSpec.m 3 | // AFMInfoBanner 4 | // 5 | // Created by Romans Karpelcevs on 18/11/14. 6 | // Copyright (c) 2014 Ask.fm Europe, Ltd. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | #import "AFMInfoBanner.h" 12 | #import "AFMTestCommons.h" 13 | 14 | SpecBegin(AFMInfoBanner) 15 | 16 | __block AFMInfoBanner *banner; 17 | 18 | describe(@"AFMInfoBanner view", ^{ 19 | 20 | it(@"should show compact red one", ^{ 21 | banner = bannerFromHelper(kShortBannerText, AFMInfoBannerStyleError); 22 | expect(banner).will.haveValidSnapshotNamed(deviceSpecificName()); 23 | [banner removeFromSuperview]; 24 | banner = bannerManual(kShortBannerText, AFMInfoBannerStyleError); 25 | expect(banner).will.haveValidSnapshotNamed(deviceSpecificName()); 26 | }); 27 | 28 | it(@"should show long red one", ^{ 29 | banner = bannerFromHelper(kLongBannerText, AFMInfoBannerStyleError); 30 | expect(banner).will.haveValidSnapshotNamed(deviceSpecificName()); 31 | [banner removeFromSuperview]; 32 | banner = bannerManual(kLongBannerText, AFMInfoBannerStyleError); 33 | expect(banner).will.haveValidSnapshotNamed(deviceSpecificName()); 34 | }); 35 | 36 | it(@"should show compact green one", ^{ 37 | banner = bannerFromHelper(kShortBannerText, AFMInfoBannerStyleInfo); 38 | expect(banner).will.haveValidSnapshotNamed(deviceSpecificName()); 39 | [banner removeFromSuperview]; 40 | banner = bannerManual(kShortBannerText, AFMInfoBannerStyleInfo); 41 | expect(banner).will.haveValidSnapshotNamed(deviceSpecificName()); 42 | }); 43 | }); 44 | 45 | describe(@"AFMInfoBanner show block", ^{ 46 | 47 | it(@"should be called when shown without animation", ^{ 48 | banner = [[AFMInfoBanner alloc] init]; 49 | 50 | __block BOOL blockCalled = NO; 51 | void (^block)() = ^void() { blockCalled = YES; }; 52 | 53 | [banner setShowCompletionBlock:block]; 54 | [banner show:NO]; 55 | expect(blockCalled).will.beTruthy(); 56 | 57 | blockCalled = NO; 58 | [banner show:NO withCompletion:block]; 59 | expect(blockCalled).will.beTruthy(); 60 | }); 61 | 62 | it(@"should be called when shown with animation", ^{ 63 | banner = [[AFMInfoBanner alloc] init]; 64 | 65 | __block BOOL blockCalled = NO; 66 | void (^block)() = ^void() { blockCalled = YES; }; 67 | 68 | [banner setShowCompletionBlock:block]; 69 | [banner show:YES]; 70 | expect(blockCalled).will.beTruthy(); 71 | 72 | blockCalled = NO; 73 | [banner show:YES withCompletion:block]; 74 | expect(blockCalled).will.beTruthy(); 75 | }); 76 | }); 77 | 78 | describe(@"AFMInfoBanner hide block", ^{ 79 | 80 | it(@"should be called when hidden without animation", ^{ 81 | banner = [[AFMInfoBanner alloc] init]; 82 | 83 | __block BOOL blockCalled = NO; 84 | void (^block)() = ^void() { blockCalled = YES; }; 85 | 86 | [banner setHideCompletionBlock:block]; 87 | [banner show:NO]; 88 | [banner hide:NO]; 89 | expect(blockCalled).will.beTruthy(); 90 | 91 | blockCalled = NO; 92 | [banner show:NO]; 93 | [banner hide:NO withCompletion:block]; 94 | expect(blockCalled).will.beTruthy(); 95 | }); 96 | 97 | it(@"should be called when hidden with animation", ^{ 98 | banner = [[AFMInfoBanner alloc] init]; 99 | 100 | __block BOOL blockCalled = NO; 101 | void (^block)() = ^void() { blockCalled = YES; }; 102 | 103 | [banner setHideCompletionBlock:block]; 104 | [banner show:NO]; 105 | [banner hide:YES]; 106 | expect(blockCalled).will.beTruthy(); 107 | 108 | blockCalled = NO; 109 | [banner show:NO]; 110 | [banner hide:YES withCompletion:block]; 111 | expect(blockCalled).will.beTruthy(); 112 | }); 113 | 114 | }); 115 | 116 | afterEach(^{ 117 | [banner removeFromSuperview]; 118 | }); 119 | 120 | SpecEnd 121 | -------------------------------------------------------------------------------- /Example/AFMInfoBanner.xcodeproj/xcshareddata/xcschemes/AFMInfoBanner.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 42 | 43 | 49 | 50 | 51 | 52 | 53 | 54 | 64 | 66 | 72 | 73 | 74 | 75 | 76 | 77 | 83 | 85 | 91 | 92 | 93 | 94 | 96 | 97 | 100 | 101 | 102 | -------------------------------------------------------------------------------- /Pod/Classes/AFMInfoBanner.m: -------------------------------------------------------------------------------- 1 | // 2 | // AFMInfoBanner.m 3 | // AFMInfoBanner 4 | // 5 | // Created by Romans Karpelcevs on 6/14/13. 6 | // Copyright (c) 2013 Ask.fm Europe, Ltd. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "AFMInfoBanner.h" 11 | 12 | #ifdef UIColorFromRGB 13 | #undef UIColorFromRGB 14 | #endif 15 | 16 | #define UIColorFromRGB(rgbValue) [UIColor colorWithRed:((((rgbValue) & 0xFF0000) >> 16))/255.f \ 17 | green:((((rgbValue) & 0xFF00) >> 8))/255.f \ 18 | blue:(((rgbValue) & 0xFF))/255.f alpha:1.0] 19 | 20 | static const CGFloat kMargin = 10.f; 21 | static const NSTimeInterval kAnimationDuration = 0.3; 22 | static const int kRedBannerColor = 0xff0000; 23 | static const int kGreenBannerColor = 0x008000; 24 | static const int kDefaultTextColor = 0xffffff; 25 | static const CGFloat kFontSize = 13.f; 26 | static const CGFloat kDefaultHideInterval = 2.0; 27 | 28 | @interface AFMInfoBanner () 29 | 30 | @property (nonatomic, readwrite) BOOL shown; 31 | 32 | @property (nonatomic) UILabel *textLabel; 33 | @property (nonatomic) UIView *targetView; 34 | @property (nonatomic) UIView *viewAboveBanner; 35 | @property (nonatomic) CGFloat additionalTopSpacing; 36 | @property (nonatomic) NSLayoutConstraint *topSpacingConstraint; 37 | @property (nonatomic) NSLayoutConstraint *topMarginConstraint; 38 | 39 | @property (nonatomic) NSTimer *hideTimer; 40 | 41 | @property (nonatomic) BOOL needsToSetupViews; 42 | 43 | @end 44 | 45 | @implementation AFMInfoBanner 46 | 47 | - (id)initWithFrame:(CGRect)frame 48 | { 49 | self = [super initWithFrame:frame]; 50 | if (self) { 51 | [self setUp]; 52 | } 53 | return self; 54 | } 55 | 56 | - (id)initWithCoder:(NSCoder *)aDecoder 57 | { 58 | self = [super initWithCoder:aDecoder]; 59 | if (self) { 60 | [self setUp]; 61 | } 62 | return self; 63 | } 64 | 65 | - (id)initWithTargetView:(UIView *)targetView 66 | viewAboveBanner:(UIView *)viewAboveBanner 67 | additionalTopSpacing:(CGFloat)additionalTopSpacing 68 | { 69 | self = [self init]; 70 | if (self) { 71 | [self setUp]; 72 | self.targetView = targetView; 73 | self.viewAboveBanner = viewAboveBanner; 74 | self.additionalTopSpacing = additionalTopSpacing; 75 | self.needsToSetupViews = NO; 76 | } 77 | return self; 78 | } 79 | 80 | - (void)setStyle:(AFMInfoBannerStyle)style 81 | { 82 | _style = style; 83 | [self applyStyle]; 84 | } 85 | 86 | - (void)applyStyle 87 | { 88 | [self applyBackgroundColor]; 89 | [self applyTextColor]; 90 | [self.textLabel setFont:self.font ?: [UIFont boldSystemFontOfSize:kFontSize]]; 91 | } 92 | 93 | - (void)applyBackgroundColor 94 | { 95 | if (self.customBackgroundColor) { 96 | [self setBackgroundColor:self.customBackgroundColor]; 97 | } else { 98 | if (self.style == AFMInfoBannerStyleError) 99 | [self setBackgroundColor:self.errorBackgroundColor ?: UIColorFromRGB(kRedBannerColor)]; 100 | else 101 | [self setBackgroundColor:self.infoBackgroundColor ?: UIColorFromRGB(kGreenBannerColor)]; 102 | } 103 | } 104 | 105 | - (void)applyTextColor 106 | { 107 | if (self.customTextColor) { 108 | [self.textLabel setTextColor:self.customTextColor]; 109 | } else { 110 | if (self.style == AFMInfoBannerStyleError) 111 | [self.textLabel setTextColor:self.errorTextColor ?: UIColorFromRGB(kDefaultTextColor)]; 112 | else 113 | [self.textLabel setTextColor:self.infoTextColor ?: UIColorFromRGB(kDefaultTextColor)]; 114 | } 115 | } 116 | 117 | - (void)setText:(NSString *)text 118 | { 119 | _text = text; 120 | [self.textLabel setText:text]; 121 | [self setNeedsLayout]; 122 | } 123 | 124 | - (void)setErrorBackgroundColor:(UIColor *)errorBackgroundColor 125 | { 126 | _errorBackgroundColor = errorBackgroundColor; 127 | [self applyStyle]; 128 | } 129 | 130 | - (void)setInfoBackgroundColor:(UIColor *)infoBackgroundColor 131 | { 132 | _infoBackgroundColor = infoBackgroundColor; 133 | [self applyStyle]; 134 | } 135 | 136 | - (void)setCustomBackgroundColor:(UIColor *)customBackgroundColor 137 | { 138 | _customBackgroundColor = customBackgroundColor; 139 | [self applyStyle]; 140 | } 141 | 142 | - (void)setErrorTextColor:(UIColor *)errorTextColor 143 | { 144 | _errorTextColor = errorTextColor; 145 | [self applyStyle]; 146 | } 147 | 148 | - (void)setInfoTextColor:(UIColor *)infoTextColor 149 | { 150 | _infoTextColor = infoTextColor; 151 | [self applyStyle]; 152 | } 153 | 154 | - (void)setCustomTextColor:(UIColor *)customTextColor 155 | { 156 | _customTextColor = customTextColor; 157 | [self applyStyle]; 158 | } 159 | 160 | - (void)setFont:(UIFont *)font 161 | { 162 | _font = font; 163 | [self applyStyle]; 164 | } 165 | 166 | - (void)setUp 167 | { 168 | [self setTranslatesAutoresizingMaskIntoConstraints:NO]; 169 | 170 | UILabel *label = [[UILabel alloc] init]; 171 | [self setTextLabel:label]; 172 | [self configureLabel]; 173 | [self configureTaps]; 174 | [self addSubview:label]; 175 | [self setupConstraints]; 176 | self.topSpacing = 0; 177 | self.needsToSetupViews = YES; 178 | } 179 | 180 | - (void)configureLabel 181 | { 182 | [self.textLabel setTranslatesAutoresizingMaskIntoConstraints:NO]; 183 | [self.textLabel setBackgroundColor:[UIColor clearColor]]; 184 | [self.textLabel setTextAlignment:NSTextAlignmentCenter]; 185 | [self.textLabel setNumberOfLines:0]; 186 | } 187 | 188 | - (void)configureTaps 189 | { 190 | UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTap)]; 191 | [self addGestureRecognizer:tap]; 192 | } 193 | 194 | - (void)handleTap 195 | { 196 | if (self.tappedBlock) 197 | self.tappedBlock(); 198 | } 199 | 200 | - (void)setupConstraints 201 | { 202 | // Position label correctly 203 | [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-[label]-|" 204 | options:0 metrics:nil views:@{@"label": self.textLabel}]]; 205 | CGFloat topMargin = kMargin + self.additionalTopSpacing; 206 | NSArray *labelConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-(top)-[label]-(bottom)-|" 207 | options:0 208 | metrics:@{@"top": @(topMargin), @"bottom": @(kMargin)} 209 | views:@{@"label": self.textLabel}]; 210 | self.topMarginConstraint = [labelConstraints firstObject]; 211 | [self addConstraints:labelConstraints]; 212 | } 213 | 214 | - (void)setupParentConstraints 215 | { 216 | // Expand to the superview's width 217 | [self.superview addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[self]|" 218 | options:0 metrics:nil views:@{@"self": self}]]; 219 | 220 | // Place initial constraint exactly one frame above the bottom line of view above us 221 | // or above top of screen, if there is no such view. Assign it to property to animate later. 222 | CGFloat topOffset = -self.frame.size.height; 223 | if (self.viewAboveBanner) 224 | topOffset += CGRectGetMaxY(self.viewAboveBanner.frame); 225 | NSArray *topConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-(offset)-[self]" 226 | options:0 227 | metrics:@{@"offset": @(topOffset)} 228 | views:@{@"self": self}]; 229 | self.topSpacingConstraint = [topConstraints firstObject]; 230 | 231 | [self.superview addConstraints:topConstraints]; 232 | } 233 | 234 | - (void)updateConstraints 235 | { 236 | [super updateConstraints]; 237 | 238 | self.topMarginConstraint.constant = kMargin + self.additionalTopSpacing; 239 | self.topSpacingConstraint.constant = 0; 240 | 241 | if (self.viewAboveBanner) 242 | self.topSpacingConstraint.constant = CGRectGetMaxY(self.viewAboveBanner.frame); 243 | 244 | if ([self isShown]) { 245 | self.topSpacingConstraint.constant += self.topSpacing; 246 | } else { 247 | self.topSpacingConstraint.constant += -self.frame.size.height; 248 | } 249 | } 250 | 251 | - (void)layoutSubviews 252 | { 253 | [super layoutSubviews]; 254 | self.textLabel.preferredMaxLayoutWidth = self.textLabel.frame.size.width; 255 | [super layoutSubviews]; 256 | } 257 | 258 | - (void)updateUI 259 | { 260 | // First pass calculates the height correctly with existing constraints. 261 | [self updateConstraintsIfNeeded]; 262 | [self layoutIfNeeded]; 263 | 264 | // New pass to take frame and new top constraint, position frame before the animation 265 | [self setNeedsUpdateConstraints]; 266 | [self updateConstraintsIfNeeded]; 267 | [self layoutIfNeeded]; 268 | } 269 | 270 | - (void)show:(BOOL)animated withCompletion:(void (^)())completionBlock 271 | { 272 | self.showCompletionBlock = completionBlock; 273 | [self show:animated]; 274 | } 275 | 276 | - (void)hide:(BOOL)animated withCompletion:(void (^)())completionBlock 277 | { 278 | self.hideCompletionBlock = completionBlock; 279 | [self hide:animated]; 280 | } 281 | 282 | - (void)show 283 | { 284 | [self show:YES]; 285 | } 286 | 287 | - (void)show:(BOOL)animated 288 | { 289 | 290 | if (self.hideTimer) { 291 | [self.hideTimer invalidate]; 292 | self.hideTimer = nil; 293 | } 294 | 295 | if ([self superview]) { 296 | if (self.showCompletionBlock) 297 | self.showCompletionBlock(); 298 | return; 299 | } 300 | 301 | [self applyStyle]; 302 | 303 | if (self.needsToSetupViews) 304 | [self setupViewsAndFrames]; 305 | 306 | // In previously indicated, send subview to be below another view. 307 | // This is used when showing below navigation bar 308 | if (self.viewAboveBanner) 309 | [self.targetView insertSubview:self belowSubview:self.viewAboveBanner]; 310 | else 311 | [self.targetView addSubview:self]; 312 | 313 | [self setupParentConstraints]; 314 | 315 | [self setHidden:NO]; 316 | 317 | self.shown = YES; 318 | [self updateUI]; 319 | 320 | if (animated) { 321 | self.transform = CGAffineTransformMakeTranslation(0, -(self.topSpacing + self.frame.size.height)); 322 | 323 | [UIView animateWithDuration:kAnimationDuration animations:^{ 324 | self.transform = CGAffineTransformIdentity; 325 | } completion:^(BOOL finished) { 326 | if (self.showCompletionBlock) 327 | self.showCompletionBlock(); 328 | }]; 329 | } else { 330 | if (self.showCompletionBlock) 331 | self.showCompletionBlock(); 332 | } 333 | } 334 | 335 | - (void)showAndHideAfter:(NSTimeInterval)timeout animated:(BOOL)animated 336 | { 337 | [self show:animated]; 338 | 339 | self.hideTimer = [NSTimer scheduledTimerWithTimeInterval:timeout 340 | target:self 341 | selector:@selector(scheduledHide:) 342 | userInfo:@(animated) 343 | repeats:NO]; 344 | } 345 | 346 | - (void)scheduledHide:(NSTimer *)timer 347 | { 348 | BOOL animated = [timer userInfo]; 349 | [self hide:animated]; 350 | } 351 | 352 | - (void)setupViewsAndFrames 353 | { 354 | CVKHierarchySearcher *searcher = [[CVKHierarchySearcher alloc] init]; 355 | UIViewController *topmostVC = [searcher topmostViewController]; 356 | UINavigationBar *possibleBar = [self navigationBarFor:topmostVC]; 357 | if (possibleBar && !possibleBar.translucent) { 358 | [self setupViewsForNavigationBar:possibleBar]; 359 | } else { 360 | UINavigationController *navVC = [searcher topmostNavigationController]; 361 | if (navVC && navVC.navigationBar.superview && !navVC.navigationBar.translucent) { 362 | [self setupViewsForNavigationBar:navVC.navigationBar]; 363 | } else { 364 | [self setupViewsToShowInWindow]; 365 | } 366 | } 367 | } 368 | 369 | - (void)setupViewsForNavigationBar:(UINavigationBar *)possibleBar 370 | { 371 | self.targetView = possibleBar.superview; 372 | self.viewAboveBanner = possibleBar; 373 | } 374 | 375 | - (void)setupViewsToShowInWindow 376 | { 377 | // If there isn't a navigation controller with a bar, show in window instead. 378 | UIWindow *window = [[UIApplication sharedApplication] keyWindow]; 379 | CGRect statusBarFrame = [[UIApplication sharedApplication] statusBarFrame]; 380 | // Forget the frame convertions, smallest is the height, no doubt 381 | CGFloat statusBarHeight = MIN(statusBarFrame.size.width, statusBarFrame.size.height); 382 | 383 | self.additionalTopSpacing = statusBarHeight; 384 | self.targetView = window; 385 | } 386 | 387 | - (void)hide 388 | { 389 | [self hide:YES]; 390 | } 391 | 392 | - (void)hide:(BOOL)animated 393 | { 394 | if (self.hideTimer) { 395 | [self.hideTimer invalidate]; 396 | self.hideTimer = nil; 397 | } 398 | 399 | self.shown = NO; 400 | [self updateUI]; 401 | 402 | if (animated) { 403 | self.transform = CGAffineTransformMakeTranslation(0, self.topSpacing + self.frame.size.height); 404 | 405 | [UIView animateWithDuration:kAnimationDuration animations:^{ 406 | self.transform = CGAffineTransformIdentity; 407 | } completion:^(BOOL finished) { 408 | [self removeFromSuperview]; 409 | if (self.hideCompletionBlock) 410 | self.hideCompletionBlock(); 411 | }]; 412 | } else { 413 | [self removeFromSuperview]; 414 | if (self.hideCompletionBlock) 415 | self.hideCompletionBlock(); 416 | } 417 | } 418 | 419 | + (instancetype)showAndHideWithText:(NSString *)text 420 | style:(AFMInfoBannerStyle)style 421 | { 422 | return [self showWithText:text style:style andHideAfter:kDefaultHideInterval]; 423 | } 424 | 425 | + (instancetype)showWithText:(NSString *)text 426 | style:(AFMInfoBannerStyle)style 427 | andHideAfter:(NSTimeInterval)timeout 428 | { 429 | AFMInfoBanner *banner = [[AFMInfoBanner alloc] init]; 430 | banner.style = style; 431 | banner.text = text; 432 | [banner showAndHideAfter:timeout animated:YES]; 433 | return banner; 434 | } 435 | 436 | + (instancetype)showWithText:(NSString *)text 437 | style:(AFMInfoBannerStyle)style 438 | animated:(BOOL)animated 439 | { 440 | AFMInfoBanner *banner = [[[self class] alloc] init]; 441 | [banner setText:text]; 442 | [banner setStyle:style]; 443 | 444 | [banner show:animated]; 445 | return banner; 446 | } 447 | 448 | + (void)hideAll 449 | { 450 | UINavigationController *navVC = [[[CVKHierarchySearcher alloc] init] topmostNavigationController]; 451 | [self hideAllInView:navVC.navigationBar.superview]; 452 | UIWindow *window = [[UIApplication sharedApplication] keyWindow]; 453 | [self hideAllInView:window]; 454 | } 455 | 456 | + (void)hideAllInView:(UIView *)view 457 | { 458 | for (AFMInfoBanner *subview in view.subviews) { 459 | if ([subview isKindOfClass:[self class]]) { 460 | [subview hide:NO]; 461 | } 462 | } 463 | } 464 | 465 | - (UINavigationBar *)navigationBarFor:(UIViewController *)viewController 466 | { 467 | for (UIView *view in viewController.view.subviews) { 468 | if ([view isKindOfClass:[UINavigationBar class]]) { 469 | return (UINavigationBar *)view; 470 | } 471 | } 472 | return nil; 473 | } 474 | 475 | @end 476 | -------------------------------------------------------------------------------- /Example/AFMInfoBanner/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 43 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 123 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 196 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | -------------------------------------------------------------------------------- /Example/AFMInfoBanner.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 6003F58E195388D20070C39A /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6003F58D195388D20070C39A /* Foundation.framework */; }; 11 | 6003F590195388D20070C39A /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6003F58F195388D20070C39A /* CoreGraphics.framework */; }; 12 | 6003F592195388D20070C39A /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6003F591195388D20070C39A /* UIKit.framework */; }; 13 | 6003F598195388D20070C39A /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 6003F596195388D20070C39A /* InfoPlist.strings */; }; 14 | 6003F59A195388D20070C39A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 6003F599195388D20070C39A /* main.m */; }; 15 | 6003F59E195388D20070C39A /* AFMAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 6003F59D195388D20070C39A /* AFMAppDelegate.m */; }; 16 | 6003F5A1195388D20070C39A /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 6003F59F195388D20070C39A /* Main.storyboard */; }; 17 | 6003F5A7195388D20070C39A /* AFMViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6003F5A6195388D20070C39A /* AFMViewController.m */; }; 18 | 6003F5A9195388D20070C39A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6003F5A8195388D20070C39A /* Images.xcassets */; }; 19 | 6003F5B0195388D20070C39A /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6003F5AF195388D20070C39A /* XCTest.framework */; }; 20 | 6003F5B1195388D20070C39A /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6003F58D195388D20070C39A /* Foundation.framework */; }; 21 | 6003F5B2195388D20070C39A /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6003F591195388D20070C39A /* UIKit.framework */; }; 22 | 6003F5BA195388D20070C39A /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 6003F5B8195388D20070C39A /* InfoPlist.strings */; }; 23 | 9C2BCB8B1A1B4BA000DD0B82 /* AFMInfoBannerSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 9C2BCB8A1A1B4BA000DD0B82 /* AFMInfoBannerSpec.m */; }; 24 | 9C406A061AAF258F00943AE1 /* AFMModalViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 9C406A051AAF258F00943AE1 /* AFMModalViewController.m */; }; 25 | 9C406A091AAF301400943AE1 /* AFMInitialViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 9C406A081AAF301400943AE1 /* AFMInitialViewController.m */; }; 26 | 9CA1D7A41A210E5700A4532C /* AFMInfoBannerAppearanceSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 9CA1D7A31A210E5700A4532C /* AFMInfoBannerAppearanceSpec.m */; }; 27 | 9CA1D7A71A210EA300A4532C /* AFMTestCommons.m in Sources */ = {isa = PBXBuildFile; fileRef = 9CA1D7A61A210EA300A4532C /* AFMTestCommons.m */; }; 28 | B357F87AB9F8B6E58AE8E9EF /* libPods-Tests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = AC7D37E0AB006C1C068FC2D3 /* libPods-Tests.a */; }; 29 | EADC3A34DD061A2AB13F955C /* libPods-AFMInfoBanner.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D8AB382BF1D8761A1A5CA4EA /* libPods-AFMInfoBanner.a */; }; 30 | /* End PBXBuildFile section */ 31 | 32 | /* Begin PBXContainerItemProxy section */ 33 | 6003F5B3195388D20070C39A /* PBXContainerItemProxy */ = { 34 | isa = PBXContainerItemProxy; 35 | containerPortal = 6003F582195388D10070C39A /* Project object */; 36 | proxyType = 1; 37 | remoteGlobalIDString = 6003F589195388D20070C39A; 38 | remoteInfo = AFMInfoBanner; 39 | }; 40 | /* End PBXContainerItemProxy section */ 41 | 42 | /* Begin PBXFileReference section */ 43 | 01058693383E6207AC293750 /* Pods-Tests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Tests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Tests/Pods-Tests.debug.xcconfig"; sourceTree = ""; }; 44 | 400DE1602380F5C26E80C775 /* Pods-AFMInfoBanner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AFMInfoBanner.release.xcconfig"; path = "Pods/Target Support Files/Pods-AFMInfoBanner/Pods-AFMInfoBanner.release.xcconfig"; sourceTree = ""; }; 45 | 58C95B2735B812F013B573B7 /* Pods-AFMInfoBanner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AFMInfoBanner.debug.xcconfig"; path = "Pods/Target Support Files/Pods-AFMInfoBanner/Pods-AFMInfoBanner.debug.xcconfig"; sourceTree = ""; }; 46 | 6003F58A195388D20070C39A /* AFMInfoBanner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = AFMInfoBanner.app; sourceTree = BUILT_PRODUCTS_DIR; }; 47 | 6003F58D195388D20070C39A /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 48 | 6003F58F195388D20070C39A /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; 49 | 6003F591195388D20070C39A /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 50 | 6003F595195388D20070C39A /* AFMInfoBanner-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "AFMInfoBanner-Info.plist"; sourceTree = ""; }; 51 | 6003F597195388D20070C39A /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 52 | 6003F599195388D20070C39A /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 53 | 6003F59B195388D20070C39A /* AFMInfoBanner-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "AFMInfoBanner-Prefix.pch"; sourceTree = ""; }; 54 | 6003F59C195388D20070C39A /* AFMAppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AFMAppDelegate.h; sourceTree = ""; }; 55 | 6003F59D195388D20070C39A /* AFMAppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AFMAppDelegate.m; sourceTree = ""; }; 56 | 6003F5A0195388D20070C39A /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 57 | 6003F5A5195388D20070C39A /* AFMViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AFMViewController.h; sourceTree = ""; }; 58 | 6003F5A6195388D20070C39A /* AFMViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AFMViewController.m; sourceTree = ""; }; 59 | 6003F5A8195388D20070C39A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 60 | 6003F5AE195388D20070C39A /* Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = Tests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 61 | 6003F5AF195388D20070C39A /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; }; 62 | 6003F5B7195388D20070C39A /* Tests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "Tests-Info.plist"; sourceTree = ""; }; 63 | 6003F5B9195388D20070C39A /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 64 | 606FC2411953D9B200FFA9A0 /* Tests-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Tests-Prefix.pch"; sourceTree = ""; }; 65 | 712CC540F5FF1404ED2F78A5 /* LICENSE */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = LICENSE; path = ../LICENSE; sourceTree = ""; }; 66 | 9C2BCB8A1A1B4BA000DD0B82 /* AFMInfoBannerSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AFMInfoBannerSpec.m; sourceTree = ""; }; 67 | 9C406A041AAF258E00943AE1 /* AFMModalViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AFMModalViewController.h; sourceTree = ""; }; 68 | 9C406A051AAF258F00943AE1 /* AFMModalViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AFMModalViewController.m; sourceTree = ""; }; 69 | 9C406A071AAF301400943AE1 /* AFMInitialViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AFMInitialViewController.h; sourceTree = ""; }; 70 | 9C406A081AAF301400943AE1 /* AFMInitialViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AFMInitialViewController.m; sourceTree = ""; }; 71 | 9CA1D7A31A210E5700A4532C /* AFMInfoBannerAppearanceSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AFMInfoBannerAppearanceSpec.m; sourceTree = ""; }; 72 | 9CA1D7A51A210EA300A4532C /* AFMTestCommons.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AFMTestCommons.h; sourceTree = ""; }; 73 | 9CA1D7A61A210EA300A4532C /* AFMTestCommons.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AFMTestCommons.m; sourceTree = ""; }; 74 | AC7D37E0AB006C1C068FC2D3 /* libPods-Tests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Tests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 75 | CB2D0DCE3845514F565FFCF6 /* README.md */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = net.daringfireball.markdown; name = README.md; path = ../README.md; sourceTree = ""; }; 76 | CC17BA0748FC6853F85B01C4 /* AFMInfoBanner.podspec */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = AFMInfoBanner.podspec; path = ../AFMInfoBanner.podspec; sourceTree = ""; }; 77 | D8AB382BF1D8761A1A5CA4EA /* libPods-AFMInfoBanner.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-AFMInfoBanner.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 78 | F9B178953474A48CE50EF50C /* Pods-Tests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Tests.release.xcconfig"; path = "Pods/Target Support Files/Pods-Tests/Pods-Tests.release.xcconfig"; sourceTree = ""; }; 79 | /* End PBXFileReference section */ 80 | 81 | /* Begin PBXFrameworksBuildPhase section */ 82 | 6003F587195388D20070C39A /* Frameworks */ = { 83 | isa = PBXFrameworksBuildPhase; 84 | buildActionMask = 2147483647; 85 | files = ( 86 | 6003F590195388D20070C39A /* CoreGraphics.framework in Frameworks */, 87 | 6003F592195388D20070C39A /* UIKit.framework in Frameworks */, 88 | 6003F58E195388D20070C39A /* Foundation.framework in Frameworks */, 89 | EADC3A34DD061A2AB13F955C /* libPods-AFMInfoBanner.a in Frameworks */, 90 | ); 91 | runOnlyForDeploymentPostprocessing = 0; 92 | }; 93 | 6003F5AB195388D20070C39A /* Frameworks */ = { 94 | isa = PBXFrameworksBuildPhase; 95 | buildActionMask = 2147483647; 96 | files = ( 97 | 6003F5B0195388D20070C39A /* XCTest.framework in Frameworks */, 98 | 6003F5B2195388D20070C39A /* UIKit.framework in Frameworks */, 99 | 6003F5B1195388D20070C39A /* Foundation.framework in Frameworks */, 100 | B357F87AB9F8B6E58AE8E9EF /* libPods-Tests.a in Frameworks */, 101 | ); 102 | runOnlyForDeploymentPostprocessing = 0; 103 | }; 104 | /* End PBXFrameworksBuildPhase section */ 105 | 106 | /* Begin PBXGroup section */ 107 | 6003F581195388D10070C39A = { 108 | isa = PBXGroup; 109 | children = ( 110 | 60FF7A9C1954A5C5007DD14C /* Podspec Metadata */, 111 | 6003F593195388D20070C39A /* AFMInfoBanner */, 112 | 6003F5B5195388D20070C39A /* Tests */, 113 | 6003F58C195388D20070C39A /* Frameworks */, 114 | 6003F58B195388D20070C39A /* Products */, 115 | B8D48527BFAAD519778B8C85 /* Pods */, 116 | ); 117 | sourceTree = ""; 118 | }; 119 | 6003F58B195388D20070C39A /* Products */ = { 120 | isa = PBXGroup; 121 | children = ( 122 | 6003F58A195388D20070C39A /* AFMInfoBanner.app */, 123 | 6003F5AE195388D20070C39A /* Tests.xctest */, 124 | ); 125 | name = Products; 126 | sourceTree = ""; 127 | }; 128 | 6003F58C195388D20070C39A /* Frameworks */ = { 129 | isa = PBXGroup; 130 | children = ( 131 | 6003F58D195388D20070C39A /* Foundation.framework */, 132 | 6003F58F195388D20070C39A /* CoreGraphics.framework */, 133 | 6003F591195388D20070C39A /* UIKit.framework */, 134 | 6003F5AF195388D20070C39A /* XCTest.framework */, 135 | D8AB382BF1D8761A1A5CA4EA /* libPods-AFMInfoBanner.a */, 136 | AC7D37E0AB006C1C068FC2D3 /* libPods-Tests.a */, 137 | ); 138 | name = Frameworks; 139 | sourceTree = ""; 140 | }; 141 | 6003F593195388D20070C39A /* AFMInfoBanner */ = { 142 | isa = PBXGroup; 143 | children = ( 144 | 6003F59C195388D20070C39A /* AFMAppDelegate.h */, 145 | 6003F59D195388D20070C39A /* AFMAppDelegate.m */, 146 | 6003F59F195388D20070C39A /* Main.storyboard */, 147 | 6003F5A5195388D20070C39A /* AFMViewController.h */, 148 | 6003F5A6195388D20070C39A /* AFMViewController.m */, 149 | 9C406A041AAF258E00943AE1 /* AFMModalViewController.h */, 150 | 9C406A051AAF258F00943AE1 /* AFMModalViewController.m */, 151 | 9C406A071AAF301400943AE1 /* AFMInitialViewController.h */, 152 | 9C406A081AAF301400943AE1 /* AFMInitialViewController.m */, 153 | 6003F5A8195388D20070C39A /* Images.xcassets */, 154 | 6003F594195388D20070C39A /* Supporting Files */, 155 | ); 156 | path = AFMInfoBanner; 157 | sourceTree = ""; 158 | }; 159 | 6003F594195388D20070C39A /* Supporting Files */ = { 160 | isa = PBXGroup; 161 | children = ( 162 | 6003F595195388D20070C39A /* AFMInfoBanner-Info.plist */, 163 | 6003F596195388D20070C39A /* InfoPlist.strings */, 164 | 6003F599195388D20070C39A /* main.m */, 165 | 6003F59B195388D20070C39A /* AFMInfoBanner-Prefix.pch */, 166 | ); 167 | name = "Supporting Files"; 168 | sourceTree = ""; 169 | }; 170 | 6003F5B5195388D20070C39A /* Tests */ = { 171 | isa = PBXGroup; 172 | children = ( 173 | 6003F5B6195388D20070C39A /* Supporting Files */, 174 | 9C2BCB8A1A1B4BA000DD0B82 /* AFMInfoBannerSpec.m */, 175 | 9CA1D7A31A210E5700A4532C /* AFMInfoBannerAppearanceSpec.m */, 176 | 9CA1D7A51A210EA300A4532C /* AFMTestCommons.h */, 177 | 9CA1D7A61A210EA300A4532C /* AFMTestCommons.m */, 178 | ); 179 | path = Tests; 180 | sourceTree = ""; 181 | }; 182 | 6003F5B6195388D20070C39A /* Supporting Files */ = { 183 | isa = PBXGroup; 184 | children = ( 185 | 6003F5B7195388D20070C39A /* Tests-Info.plist */, 186 | 6003F5B8195388D20070C39A /* InfoPlist.strings */, 187 | 606FC2411953D9B200FFA9A0 /* Tests-Prefix.pch */, 188 | ); 189 | name = "Supporting Files"; 190 | sourceTree = ""; 191 | }; 192 | 60FF7A9C1954A5C5007DD14C /* Podspec Metadata */ = { 193 | isa = PBXGroup; 194 | children = ( 195 | CC17BA0748FC6853F85B01C4 /* AFMInfoBanner.podspec */, 196 | CB2D0DCE3845514F565FFCF6 /* README.md */, 197 | 712CC540F5FF1404ED2F78A5 /* LICENSE */, 198 | ); 199 | name = "Podspec Metadata"; 200 | sourceTree = ""; 201 | }; 202 | B8D48527BFAAD519778B8C85 /* Pods */ = { 203 | isa = PBXGroup; 204 | children = ( 205 | 58C95B2735B812F013B573B7 /* Pods-AFMInfoBanner.debug.xcconfig */, 206 | 400DE1602380F5C26E80C775 /* Pods-AFMInfoBanner.release.xcconfig */, 207 | 01058693383E6207AC293750 /* Pods-Tests.debug.xcconfig */, 208 | F9B178953474A48CE50EF50C /* Pods-Tests.release.xcconfig */, 209 | ); 210 | name = Pods; 211 | sourceTree = ""; 212 | }; 213 | /* End PBXGroup section */ 214 | 215 | /* Begin PBXNativeTarget section */ 216 | 6003F589195388D20070C39A /* AFMInfoBanner */ = { 217 | isa = PBXNativeTarget; 218 | buildConfigurationList = 6003F5BF195388D20070C39A /* Build configuration list for PBXNativeTarget "AFMInfoBanner" */; 219 | buildPhases = ( 220 | 8C6773E5C409B53BE25A94B9 /* [CP] Check Pods Manifest.lock */, 221 | 6003F586195388D20070C39A /* Sources */, 222 | 6003F587195388D20070C39A /* Frameworks */, 223 | 6003F588195388D20070C39A /* Resources */, 224 | 3021FE50F6B43D8246D73704 /* [CP] Embed Pods Frameworks */, 225 | 1D564E5826C2C4EB60C55DED /* [CP] Copy Pods Resources */, 226 | ); 227 | buildRules = ( 228 | ); 229 | dependencies = ( 230 | ); 231 | name = AFMInfoBanner; 232 | productName = AFMInfoBanner; 233 | productReference = 6003F58A195388D20070C39A /* AFMInfoBanner.app */; 234 | productType = "com.apple.product-type.application"; 235 | }; 236 | 6003F5AD195388D20070C39A /* Tests */ = { 237 | isa = PBXNativeTarget; 238 | buildConfigurationList = 6003F5C2195388D20070C39A /* Build configuration list for PBXNativeTarget "Tests" */; 239 | buildPhases = ( 240 | 534987ADA89D4DFF29092C9F /* [CP] Check Pods Manifest.lock */, 241 | 6003F5AA195388D20070C39A /* Sources */, 242 | 6003F5AB195388D20070C39A /* Frameworks */, 243 | 6003F5AC195388D20070C39A /* Resources */, 244 | 32E5E839A1EFD8DD262AB68E /* [CP] Embed Pods Frameworks */, 245 | 703CD31BBDFB429E7C8EEB50 /* [CP] Copy Pods Resources */, 246 | ); 247 | buildRules = ( 248 | ); 249 | dependencies = ( 250 | 6003F5B4195388D20070C39A /* PBXTargetDependency */, 251 | ); 252 | name = Tests; 253 | productName = AFMInfoBannerTests; 254 | productReference = 6003F5AE195388D20070C39A /* Tests.xctest */; 255 | productType = "com.apple.product-type.bundle.unit-test"; 256 | }; 257 | /* End PBXNativeTarget section */ 258 | 259 | /* Begin PBXProject section */ 260 | 6003F582195388D10070C39A /* Project object */ = { 261 | isa = PBXProject; 262 | attributes = { 263 | CLASSPREFIX = AFM; 264 | LastUpgradeCheck = 0820; 265 | ORGANIZATIONNAME = "Romans Karpelcevs"; 266 | TargetAttributes = { 267 | 6003F5AD195388D20070C39A = { 268 | TestTargetID = 6003F589195388D20070C39A; 269 | }; 270 | }; 271 | }; 272 | buildConfigurationList = 6003F585195388D10070C39A /* Build configuration list for PBXProject "AFMInfoBanner" */; 273 | compatibilityVersion = "Xcode 3.2"; 274 | developmentRegion = English; 275 | hasScannedForEncodings = 0; 276 | knownRegions = ( 277 | en, 278 | Base, 279 | ); 280 | mainGroup = 6003F581195388D10070C39A; 281 | productRefGroup = 6003F58B195388D20070C39A /* Products */; 282 | projectDirPath = ""; 283 | projectRoot = ""; 284 | targets = ( 285 | 6003F589195388D20070C39A /* AFMInfoBanner */, 286 | 6003F5AD195388D20070C39A /* Tests */, 287 | ); 288 | }; 289 | /* End PBXProject section */ 290 | 291 | /* Begin PBXResourcesBuildPhase section */ 292 | 6003F588195388D20070C39A /* Resources */ = { 293 | isa = PBXResourcesBuildPhase; 294 | buildActionMask = 2147483647; 295 | files = ( 296 | 6003F5A9195388D20070C39A /* Images.xcassets in Resources */, 297 | 6003F5A1195388D20070C39A /* Main.storyboard in Resources */, 298 | 6003F598195388D20070C39A /* InfoPlist.strings in Resources */, 299 | ); 300 | runOnlyForDeploymentPostprocessing = 0; 301 | }; 302 | 6003F5AC195388D20070C39A /* Resources */ = { 303 | isa = PBXResourcesBuildPhase; 304 | buildActionMask = 2147483647; 305 | files = ( 306 | 6003F5BA195388D20070C39A /* InfoPlist.strings in Resources */, 307 | ); 308 | runOnlyForDeploymentPostprocessing = 0; 309 | }; 310 | /* End PBXResourcesBuildPhase section */ 311 | 312 | /* Begin PBXShellScriptBuildPhase section */ 313 | 1D564E5826C2C4EB60C55DED /* [CP] Copy Pods Resources */ = { 314 | isa = PBXShellScriptBuildPhase; 315 | buildActionMask = 2147483647; 316 | files = ( 317 | ); 318 | inputPaths = ( 319 | ); 320 | name = "[CP] Copy Pods Resources"; 321 | outputPaths = ( 322 | ); 323 | runOnlyForDeploymentPostprocessing = 0; 324 | shellPath = /bin/sh; 325 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-AFMInfoBanner/Pods-AFMInfoBanner-resources.sh\"\n"; 326 | showEnvVarsInLog = 0; 327 | }; 328 | 3021FE50F6B43D8246D73704 /* [CP] Embed Pods Frameworks */ = { 329 | isa = PBXShellScriptBuildPhase; 330 | buildActionMask = 2147483647; 331 | files = ( 332 | ); 333 | inputPaths = ( 334 | ); 335 | name = "[CP] Embed Pods Frameworks"; 336 | outputPaths = ( 337 | ); 338 | runOnlyForDeploymentPostprocessing = 0; 339 | shellPath = /bin/sh; 340 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-AFMInfoBanner/Pods-AFMInfoBanner-frameworks.sh\"\n"; 341 | showEnvVarsInLog = 0; 342 | }; 343 | 32E5E839A1EFD8DD262AB68E /* [CP] Embed Pods Frameworks */ = { 344 | isa = PBXShellScriptBuildPhase; 345 | buildActionMask = 2147483647; 346 | files = ( 347 | ); 348 | inputPaths = ( 349 | ); 350 | name = "[CP] Embed Pods Frameworks"; 351 | outputPaths = ( 352 | ); 353 | runOnlyForDeploymentPostprocessing = 0; 354 | shellPath = /bin/sh; 355 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-Tests/Pods-Tests-frameworks.sh\"\n"; 356 | showEnvVarsInLog = 0; 357 | }; 358 | 534987ADA89D4DFF29092C9F /* [CP] Check Pods Manifest.lock */ = { 359 | isa = PBXShellScriptBuildPhase; 360 | buildActionMask = 2147483647; 361 | files = ( 362 | ); 363 | inputPaths = ( 364 | ); 365 | name = "[CP] Check Pods Manifest.lock"; 366 | outputPaths = ( 367 | ); 368 | runOnlyForDeploymentPostprocessing = 0; 369 | shellPath = /bin/sh; 370 | shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n"; 371 | showEnvVarsInLog = 0; 372 | }; 373 | 703CD31BBDFB429E7C8EEB50 /* [CP] Copy Pods Resources */ = { 374 | isa = PBXShellScriptBuildPhase; 375 | buildActionMask = 2147483647; 376 | files = ( 377 | ); 378 | inputPaths = ( 379 | ); 380 | name = "[CP] Copy Pods Resources"; 381 | outputPaths = ( 382 | ); 383 | runOnlyForDeploymentPostprocessing = 0; 384 | shellPath = /bin/sh; 385 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-Tests/Pods-Tests-resources.sh\"\n"; 386 | showEnvVarsInLog = 0; 387 | }; 388 | 8C6773E5C409B53BE25A94B9 /* [CP] Check Pods Manifest.lock */ = { 389 | isa = PBXShellScriptBuildPhase; 390 | buildActionMask = 2147483647; 391 | files = ( 392 | ); 393 | inputPaths = ( 394 | ); 395 | name = "[CP] Check Pods Manifest.lock"; 396 | outputPaths = ( 397 | ); 398 | runOnlyForDeploymentPostprocessing = 0; 399 | shellPath = /bin/sh; 400 | shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n"; 401 | showEnvVarsInLog = 0; 402 | }; 403 | /* End PBXShellScriptBuildPhase section */ 404 | 405 | /* Begin PBXSourcesBuildPhase section */ 406 | 6003F586195388D20070C39A /* Sources */ = { 407 | isa = PBXSourcesBuildPhase; 408 | buildActionMask = 2147483647; 409 | files = ( 410 | 6003F59E195388D20070C39A /* AFMAppDelegate.m in Sources */, 411 | 9C406A091AAF301400943AE1 /* AFMInitialViewController.m in Sources */, 412 | 6003F5A7195388D20070C39A /* AFMViewController.m in Sources */, 413 | 6003F59A195388D20070C39A /* main.m in Sources */, 414 | 9C406A061AAF258F00943AE1 /* AFMModalViewController.m in Sources */, 415 | ); 416 | runOnlyForDeploymentPostprocessing = 0; 417 | }; 418 | 6003F5AA195388D20070C39A /* Sources */ = { 419 | isa = PBXSourcesBuildPhase; 420 | buildActionMask = 2147483647; 421 | files = ( 422 | 9CA1D7A71A210EA300A4532C /* AFMTestCommons.m in Sources */, 423 | 9C2BCB8B1A1B4BA000DD0B82 /* AFMInfoBannerSpec.m in Sources */, 424 | 9CA1D7A41A210E5700A4532C /* AFMInfoBannerAppearanceSpec.m in Sources */, 425 | ); 426 | runOnlyForDeploymentPostprocessing = 0; 427 | }; 428 | /* End PBXSourcesBuildPhase section */ 429 | 430 | /* Begin PBXTargetDependency section */ 431 | 6003F5B4195388D20070C39A /* PBXTargetDependency */ = { 432 | isa = PBXTargetDependency; 433 | target = 6003F589195388D20070C39A /* AFMInfoBanner */; 434 | targetProxy = 6003F5B3195388D20070C39A /* PBXContainerItemProxy */; 435 | }; 436 | /* End PBXTargetDependency section */ 437 | 438 | /* Begin PBXVariantGroup section */ 439 | 6003F596195388D20070C39A /* InfoPlist.strings */ = { 440 | isa = PBXVariantGroup; 441 | children = ( 442 | 6003F597195388D20070C39A /* en */, 443 | ); 444 | name = InfoPlist.strings; 445 | sourceTree = ""; 446 | }; 447 | 6003F59F195388D20070C39A /* Main.storyboard */ = { 448 | isa = PBXVariantGroup; 449 | children = ( 450 | 6003F5A0195388D20070C39A /* Base */, 451 | ); 452 | name = Main.storyboard; 453 | sourceTree = ""; 454 | }; 455 | 6003F5B8195388D20070C39A /* InfoPlist.strings */ = { 456 | isa = PBXVariantGroup; 457 | children = ( 458 | 6003F5B9195388D20070C39A /* en */, 459 | ); 460 | name = InfoPlist.strings; 461 | sourceTree = ""; 462 | }; 463 | /* End PBXVariantGroup section */ 464 | 465 | /* Begin XCBuildConfiguration section */ 466 | 6003F5BD195388D20070C39A /* Debug */ = { 467 | isa = XCBuildConfiguration; 468 | buildSettings = { 469 | ALWAYS_SEARCH_USER_PATHS = NO; 470 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 471 | CLANG_CXX_LIBRARY = "libc++"; 472 | CLANG_ENABLE_MODULES = YES; 473 | CLANG_ENABLE_OBJC_ARC = YES; 474 | CLANG_WARN_BOOL_CONVERSION = YES; 475 | CLANG_WARN_CONSTANT_CONVERSION = YES; 476 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 477 | CLANG_WARN_EMPTY_BODY = YES; 478 | CLANG_WARN_ENUM_CONVERSION = YES; 479 | CLANG_WARN_INFINITE_RECURSION = YES; 480 | CLANG_WARN_INT_CONVERSION = YES; 481 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 482 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 483 | CLANG_WARN_UNREACHABLE_CODE = YES; 484 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 485 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 486 | COPY_PHASE_STRIP = NO; 487 | ENABLE_STRICT_OBJC_MSGSEND = YES; 488 | ENABLE_TESTABILITY = YES; 489 | GCC_C_LANGUAGE_STANDARD = gnu99; 490 | GCC_DYNAMIC_NO_PIC = NO; 491 | GCC_NO_COMMON_BLOCKS = YES; 492 | GCC_OPTIMIZATION_LEVEL = 0; 493 | GCC_PREPROCESSOR_DEFINITIONS = ( 494 | "DEBUG=1", 495 | "$(inherited)", 496 | ); 497 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 498 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 499 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 500 | GCC_WARN_UNDECLARED_SELECTOR = YES; 501 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 502 | GCC_WARN_UNUSED_FUNCTION = YES; 503 | GCC_WARN_UNUSED_VARIABLE = YES; 504 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 505 | ONLY_ACTIVE_ARCH = YES; 506 | SDKROOT = iphoneos; 507 | TARGETED_DEVICE_FAMILY = "1,2"; 508 | }; 509 | name = Debug; 510 | }; 511 | 6003F5BE195388D20070C39A /* Release */ = { 512 | isa = XCBuildConfiguration; 513 | buildSettings = { 514 | ALWAYS_SEARCH_USER_PATHS = NO; 515 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 516 | CLANG_CXX_LIBRARY = "libc++"; 517 | CLANG_ENABLE_MODULES = YES; 518 | CLANG_ENABLE_OBJC_ARC = YES; 519 | CLANG_WARN_BOOL_CONVERSION = YES; 520 | CLANG_WARN_CONSTANT_CONVERSION = YES; 521 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 522 | CLANG_WARN_EMPTY_BODY = YES; 523 | CLANG_WARN_ENUM_CONVERSION = YES; 524 | CLANG_WARN_INFINITE_RECURSION = YES; 525 | CLANG_WARN_INT_CONVERSION = YES; 526 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 527 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 528 | CLANG_WARN_UNREACHABLE_CODE = YES; 529 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 530 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 531 | COPY_PHASE_STRIP = YES; 532 | ENABLE_NS_ASSERTIONS = NO; 533 | ENABLE_STRICT_OBJC_MSGSEND = YES; 534 | GCC_C_LANGUAGE_STANDARD = gnu99; 535 | GCC_NO_COMMON_BLOCKS = YES; 536 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 537 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 538 | GCC_WARN_UNDECLARED_SELECTOR = YES; 539 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 540 | GCC_WARN_UNUSED_FUNCTION = YES; 541 | GCC_WARN_UNUSED_VARIABLE = YES; 542 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 543 | SDKROOT = iphoneos; 544 | TARGETED_DEVICE_FAMILY = "1,2"; 545 | VALIDATE_PRODUCT = YES; 546 | }; 547 | name = Release; 548 | }; 549 | 6003F5C0195388D20070C39A /* Debug */ = { 550 | isa = XCBuildConfiguration; 551 | baseConfigurationReference = 58C95B2735B812F013B573B7 /* Pods-AFMInfoBanner.debug.xcconfig */; 552 | buildSettings = { 553 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 554 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; 555 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 556 | GCC_PREFIX_HEADER = "AFMInfoBanner/AFMInfoBanner-Prefix.pch"; 557 | INFOPLIST_FILE = "AFMInfoBanner/AFMInfoBanner-Info.plist"; 558 | PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.demo.${PRODUCT_NAME:rfc1034identifier}"; 559 | PRODUCT_NAME = "$(TARGET_NAME)"; 560 | TARGETED_DEVICE_FAMILY = 1; 561 | WRAPPER_EXTENSION = app; 562 | }; 563 | name = Debug; 564 | }; 565 | 6003F5C1195388D20070C39A /* Release */ = { 566 | isa = XCBuildConfiguration; 567 | baseConfigurationReference = 400DE1602380F5C26E80C775 /* Pods-AFMInfoBanner.release.xcconfig */; 568 | buildSettings = { 569 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 570 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; 571 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 572 | GCC_PREFIX_HEADER = "AFMInfoBanner/AFMInfoBanner-Prefix.pch"; 573 | INFOPLIST_FILE = "AFMInfoBanner/AFMInfoBanner-Info.plist"; 574 | PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.demo.${PRODUCT_NAME:rfc1034identifier}"; 575 | PRODUCT_NAME = "$(TARGET_NAME)"; 576 | TARGETED_DEVICE_FAMILY = 1; 577 | WRAPPER_EXTENSION = app; 578 | }; 579 | name = Release; 580 | }; 581 | 6003F5C3195388D20070C39A /* Debug */ = { 582 | isa = XCBuildConfiguration; 583 | baseConfigurationReference = 01058693383E6207AC293750 /* Pods-Tests.debug.xcconfig */; 584 | buildSettings = { 585 | BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/AFMInfoBanner.app/AFMInfoBanner"; 586 | FRAMEWORK_SEARCH_PATHS = ( 587 | "$(SDKROOT)/Developer/Library/Frameworks", 588 | "$(inherited)", 589 | "$(DEVELOPER_FRAMEWORKS_DIR)", 590 | ); 591 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 592 | GCC_PREFIX_HEADER = "Tests/Tests-Prefix.pch"; 593 | GCC_PREPROCESSOR_DEFINITIONS = ( 594 | "DEBUG=1", 595 | "$(inherited)", 596 | ); 597 | INFOPLIST_FILE = "Tests/Tests-Info.plist"; 598 | PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.demo.${PRODUCT_NAME:rfc1034identifier}"; 599 | PRODUCT_NAME = "$(TARGET_NAME)"; 600 | TEST_HOST = "$(BUNDLE_LOADER)"; 601 | WRAPPER_EXTENSION = xctest; 602 | }; 603 | name = Debug; 604 | }; 605 | 6003F5C4195388D20070C39A /* Release */ = { 606 | isa = XCBuildConfiguration; 607 | baseConfigurationReference = F9B178953474A48CE50EF50C /* Pods-Tests.release.xcconfig */; 608 | buildSettings = { 609 | BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/AFMInfoBanner.app/AFMInfoBanner"; 610 | FRAMEWORK_SEARCH_PATHS = ( 611 | "$(SDKROOT)/Developer/Library/Frameworks", 612 | "$(inherited)", 613 | "$(DEVELOPER_FRAMEWORKS_DIR)", 614 | ); 615 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 616 | GCC_PREFIX_HEADER = "Tests/Tests-Prefix.pch"; 617 | INFOPLIST_FILE = "Tests/Tests-Info.plist"; 618 | PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.demo.${PRODUCT_NAME:rfc1034identifier}"; 619 | PRODUCT_NAME = "$(TARGET_NAME)"; 620 | TEST_HOST = "$(BUNDLE_LOADER)"; 621 | WRAPPER_EXTENSION = xctest; 622 | }; 623 | name = Release; 624 | }; 625 | /* End XCBuildConfiguration section */ 626 | 627 | /* Begin XCConfigurationList section */ 628 | 6003F585195388D10070C39A /* Build configuration list for PBXProject "AFMInfoBanner" */ = { 629 | isa = XCConfigurationList; 630 | buildConfigurations = ( 631 | 6003F5BD195388D20070C39A /* Debug */, 632 | 6003F5BE195388D20070C39A /* Release */, 633 | ); 634 | defaultConfigurationIsVisible = 0; 635 | defaultConfigurationName = Release; 636 | }; 637 | 6003F5BF195388D20070C39A /* Build configuration list for PBXNativeTarget "AFMInfoBanner" */ = { 638 | isa = XCConfigurationList; 639 | buildConfigurations = ( 640 | 6003F5C0195388D20070C39A /* Debug */, 641 | 6003F5C1195388D20070C39A /* Release */, 642 | ); 643 | defaultConfigurationIsVisible = 0; 644 | defaultConfigurationName = Release; 645 | }; 646 | 6003F5C2195388D20070C39A /* Build configuration list for PBXNativeTarget "Tests" */ = { 647 | isa = XCConfigurationList; 648 | buildConfigurations = ( 649 | 6003F5C3195388D20070C39A /* Debug */, 650 | 6003F5C4195388D20070C39A /* Release */, 651 | ); 652 | defaultConfigurationIsVisible = 0; 653 | defaultConfigurationName = Release; 654 | }; 655 | /* End XCConfigurationList section */ 656 | }; 657 | rootObject = 6003F582195388D10070C39A /* Project object */; 658 | } 659 | --------------------------------------------------------------------------------