├── 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 | [](https://travis-ci.org/ask-fm/AFMInfoBanner)
4 | [](http://cocoadocs.org/docsets/AFMInfoBanner)
5 | [](http://cocoadocs.org/docsets/AFMInfoBanner)
6 | [](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 | 
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 |
--------------------------------------------------------------------------------