├── SWCrawlViewExample
├── SWCrawlViewExample
│ ├── SWCrawlView
│ │ ├── Assets
│ │ │ ├── Images
│ │ │ │ ├── mask.png
│ │ │ │ └── starBg.png
│ │ │ └── Fonts
│ │ │ │ ├── Starjedi.ttf
│ │ │ │ ├── Starjhol.ttf
│ │ │ │ ├── SWCrawlBody.ttf
│ │ │ │ ├── StarJediBig.ttf
│ │ │ │ ├── SWCrawlTitle.ttf
│ │ │ │ ├── Star_Jedi_Rounded.ttf
│ │ │ │ └── Franklin_Gothic_Book.ttf
│ │ ├── Crawl View
│ │ │ ├── BorderLabel
│ │ │ │ ├── SWStrokedLogoLabel.h
│ │ │ │ └── SWStrokedLogoLabel.m
│ │ │ ├── SWCrawlView.h
│ │ │ ├── SWCrawlView.xib
│ │ │ └── SWCrawlView.m
│ │ ├── Crawl
│ │ │ ├── SWCrawl.h
│ │ │ └── SWCrawl.m
│ │ └── Constants
│ │ │ ├── SWConstants.h
│ │ │ └── SWConstants.m
│ ├── ViewController.h
│ ├── AppDelegate.h
│ ├── main.m
│ ├── Images.xcassets
│ │ └── AppIcon.appiconset
│ │ │ └── Contents.json
│ ├── ViewController.m
│ ├── Info.plist
│ ├── AppDelegate.m
│ └── Base.lproj
│ │ ├── Main.storyboard
│ │ └── LaunchScreen.xib
├── SWCrawlViewExample.xcodeproj
│ ├── project.xcworkspace
│ │ └── contents.xcworkspacedata
│ └── project.pbxproj
└── SWCrawlViewExampleTests
│ ├── Info.plist
│ └── SWCrawlViewExampleTests.m
├── .gitignore
├── LICENSE
└── README.md
/SWCrawlViewExample/SWCrawlViewExample/SWCrawlView/Assets/Images/mask.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MattFoley/SWCrawlView/HEAD/SWCrawlViewExample/SWCrawlViewExample/SWCrawlView/Assets/Images/mask.png
--------------------------------------------------------------------------------
/SWCrawlViewExample/SWCrawlViewExample/SWCrawlView/Assets/Fonts/Starjedi.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MattFoley/SWCrawlView/HEAD/SWCrawlViewExample/SWCrawlViewExample/SWCrawlView/Assets/Fonts/Starjedi.ttf
--------------------------------------------------------------------------------
/SWCrawlViewExample/SWCrawlViewExample/SWCrawlView/Assets/Fonts/Starjhol.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MattFoley/SWCrawlView/HEAD/SWCrawlViewExample/SWCrawlViewExample/SWCrawlView/Assets/Fonts/Starjhol.ttf
--------------------------------------------------------------------------------
/SWCrawlViewExample/SWCrawlViewExample/SWCrawlView/Assets/Images/starBg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MattFoley/SWCrawlView/HEAD/SWCrawlViewExample/SWCrawlViewExample/SWCrawlView/Assets/Images/starBg.png
--------------------------------------------------------------------------------
/SWCrawlViewExample/SWCrawlViewExample/SWCrawlView/Assets/Fonts/SWCrawlBody.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MattFoley/SWCrawlView/HEAD/SWCrawlViewExample/SWCrawlViewExample/SWCrawlView/Assets/Fonts/SWCrawlBody.ttf
--------------------------------------------------------------------------------
/SWCrawlViewExample/SWCrawlViewExample/SWCrawlView/Assets/Fonts/StarJediBig.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MattFoley/SWCrawlView/HEAD/SWCrawlViewExample/SWCrawlViewExample/SWCrawlView/Assets/Fonts/StarJediBig.ttf
--------------------------------------------------------------------------------
/SWCrawlViewExample/SWCrawlViewExample/SWCrawlView/Assets/Fonts/SWCrawlTitle.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MattFoley/SWCrawlView/HEAD/SWCrawlViewExample/SWCrawlViewExample/SWCrawlView/Assets/Fonts/SWCrawlTitle.ttf
--------------------------------------------------------------------------------
/SWCrawlViewExample/SWCrawlViewExample/SWCrawlView/Assets/Fonts/Star_Jedi_Rounded.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MattFoley/SWCrawlView/HEAD/SWCrawlViewExample/SWCrawlViewExample/SWCrawlView/Assets/Fonts/Star_Jedi_Rounded.ttf
--------------------------------------------------------------------------------
/SWCrawlViewExample/SWCrawlViewExample/SWCrawlView/Assets/Fonts/Franklin_Gothic_Book.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MattFoley/SWCrawlView/HEAD/SWCrawlViewExample/SWCrawlViewExample/SWCrawlView/Assets/Fonts/Franklin_Gothic_Book.ttf
--------------------------------------------------------------------------------
/SWCrawlViewExample/SWCrawlViewExample.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/SWCrawlViewExample/SWCrawlViewExample/ViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.h
3 | // SWCrawlViewExample
4 | //
5 | // Created by TJ Fallon on 5/21/15.
6 | // Copyright (c) 2015 TJ Fallon. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface ViewController : UIViewController
12 |
13 |
14 | @end
15 |
16 |
--------------------------------------------------------------------------------
/SWCrawlViewExample/SWCrawlViewExample/AppDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.h
3 | // SWCrawlViewExample
4 | //
5 | // Created by TJ Fallon on 5/21/15.
6 | // Copyright (c) 2015 TJ Fallon. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface AppDelegate : UIResponder
12 |
13 | @property (strong, nonatomic) UIWindow *window;
14 |
15 |
16 | @end
17 |
18 |
--------------------------------------------------------------------------------
/SWCrawlViewExample/SWCrawlViewExample/main.m:
--------------------------------------------------------------------------------
1 | //
2 | // main.m
3 | // SWCrawlViewExample
4 | //
5 | // Created by TJ Fallon on 5/21/15.
6 | // Copyright (c) 2015 TJ Fallon. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "AppDelegate.h"
11 |
12 | int main(int argc, char * argv[]) {
13 | @autoreleasepool {
14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/SWCrawlViewExample/SWCrawlViewExample/SWCrawlView/Crawl View/BorderLabel/SWStrokedLogoLabel.h:
--------------------------------------------------------------------------------
1 | //
2 | // SWStrokedLogoLabel.h
3 | //
4 | // Created by Tj on 5/16/15.
5 | // Copyright (c) 2015 Tj. All rights reserved.
6 | //
7 |
8 | #import
9 |
10 | @interface SWStrokedLogoLabel : UILabel
11 |
12 | /**
13 | * This class is used for the main logo.
14 | */
15 | @property IBInspectable UIColor *strokeColor;
16 | @property IBInspectable NSInteger strokeWidth;
17 |
18 | @end
19 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Xcode
2 | #
3 | build/
4 | *.pbxuser
5 | !default.pbxuser
6 | *.mode1v3
7 | !default.mode1v3
8 | *.mode2v3
9 | !default.mode2v3
10 | *.perspectivev3
11 | !default.perspectivev3
12 | xcuserdata
13 | *.xccheckout
14 | *.moved-aside
15 | DerivedData
16 | *.hmap
17 | *.ipa
18 | *.xcuserstate
19 |
20 | # CocoaPods
21 | #
22 | # We recommend against adding the Pods directory to your .gitignore. However
23 | # you should judge for yourself, the pros and cons are mentioned at:
24 | # http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control
25 | #
26 | #Pods/
27 |
--------------------------------------------------------------------------------
/SWCrawlViewExample/SWCrawlViewExampleTests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | foleyproductions.$(PRODUCT_NAME:rfc1034identifier)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | BNDL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 |
24 |
25 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * ----------------------------------------------------------------------------
4 | * "THE BEER-WARE LICENSE" (Revision 501):
5 | * wrote this repo. As long as you retain this notice you
6 | * can do whatever you want with this stuff. If we meet some day, and you think
7 | * this stuff is worth it, you can buy me a beer in return. Tj Fallon
8 | * ----------------------------------------------------------------------------
9 | */
10 |
11 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
12 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
13 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
14 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
15 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT
16 | OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
17 | THE USE OR OTHER DEALINGS IN THE SOFTWARE.
18 |
--------------------------------------------------------------------------------
/SWCrawlViewExample/SWCrawlViewExample/SWCrawlView/Crawl/SWCrawl.h:
--------------------------------------------------------------------------------
1 | //
2 | // SWCrawl.h
3 | // CrawlCreator2.0
4 | //
5 | // Created by Tj on 5/17/15.
6 | // Copyright (c) 2015 Tj. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 |
12 | /**
13 | * This class exists to pass around data describing a Crawl object.
14 | */
15 | @interface SWCrawl : NSObject
16 |
17 | @property NSString *introText;
18 | @property NSString *logoText;
19 | @property NSString *episodeNumberText;
20 | @property NSString *episodeTitleText;
21 | @property NSString *bodyText;
22 |
23 | @property UIFont *logoFont;
24 | @property UIFont *episodeTitleFont;
25 | @property UIFont *episodeNumberFont;
26 | @property UIFont *bodyFont;
27 |
28 | @property UIColor *logoStrokeColor;
29 | @property UIColor *episodeTitleColor;
30 | @property UIColor *episodeNumberColor;
31 | @property UIColor *bodyColor;
32 |
33 | - (NSAttributedString *)composedCrawlString;
34 |
35 | @end
36 |
--------------------------------------------------------------------------------
/SWCrawlViewExample/SWCrawlViewExample/SWCrawlView/Crawl View/BorderLabel/SWStrokedLogoLabel.m:
--------------------------------------------------------------------------------
1 | //
2 | // SWStrokedLogoLabel.m
3 | //
4 | // Created by Tj on 5/16/15.
5 | // Copyright (c) 2015 Tj. All rights reserved.
6 | //
7 |
8 | #import "SWStrokedLogoLabel.h"
9 |
10 | @implementation SWStrokedLogoLabel
11 |
12 | - (void)drawTextInRect:(CGRect)rect {
13 |
14 | CGSize shadowOffset = self.shadowOffset;
15 | UIColor *textColor = self.textColor;
16 |
17 | CGContextRef c = UIGraphicsGetCurrentContext();
18 | CGContextSetLineWidth(c, self.strokeWidth);
19 | CGContextSetLineJoin(c, kCGLineJoinMiter);
20 |
21 | CGContextSetTextDrawingMode(c, kCGTextStroke);
22 | self.textColor = self.strokeColor;
23 | [super drawTextInRect:rect];
24 |
25 | CGContextSetTextDrawingMode(c, kCGTextFill);
26 | self.textColor = textColor;
27 | self.shadowOffset = CGSizeMake(0, 0);
28 | [super drawTextInRect:rect];
29 |
30 | self.shadowOffset = shadowOffset;
31 | }
32 |
33 | @end
34 |
--------------------------------------------------------------------------------
/SWCrawlViewExample/SWCrawlViewExampleTests/SWCrawlViewExampleTests.m:
--------------------------------------------------------------------------------
1 | //
2 | // SWCrawlViewExampleTests.m
3 | // SWCrawlViewExampleTests
4 | //
5 | // Created by TJ Fallon on 5/21/15.
6 | // Copyright (c) 2015 TJ Fallon. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 |
12 | @interface SWCrawlViewExampleTests : XCTestCase
13 |
14 | @end
15 |
16 | @implementation SWCrawlViewExampleTests
17 |
18 | - (void)setUp {
19 | [super setUp];
20 | // Put setup code here. This method is called before the invocation of each test method in the class.
21 | }
22 |
23 | - (void)tearDown {
24 | // Put teardown code here. This method is called after the invocation of each test method in the class.
25 | [super tearDown];
26 | }
27 |
28 | - (void)testExample {
29 | // This is an example of a functional test case.
30 | XCTAssert(YES, @"Pass");
31 | }
32 |
33 | - (void)testPerformanceExample {
34 | // This is an example of a performance test case.
35 | [self measureBlock:^{
36 | // Put the code you want to measure the time of here.
37 | }];
38 | }
39 |
40 | @end
41 |
--------------------------------------------------------------------------------
/SWCrawlViewExample/SWCrawlViewExample/SWCrawlView/Constants/SWConstants.h:
--------------------------------------------------------------------------------
1 | //
2 | // SWConstants.h
3 | // CrawlCreator2.0
4 | //
5 | // Created by Tj on 5/16/15.
6 | // Copyright (c) 2015 Tj. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 |
12 | /**
13 | * These constants are designed to look as close to the theatrical Crawls as possible, using free to use fonts.
14 | * Improvements could be made by purchasing a mobile license to the Franklin Gothic Demi family, as is specified here:
15 | * http://www.theforce.net/fanfilms/postproduction/crawl/opening.asp
16 | *
17 | * Also, the StarJedi font that's being used seems to have some glyph sizing issues.
18 | * I've attempted to modify the font file to clean it up, but you may notice it act strangely.
19 | */
20 |
21 | @interface SWConstants : NSObject
22 |
23 | UIColor* UIColorFromRGB(unsigned int rgbValue) ;
24 |
25 | + (UIColor *)starWarsLogoColor;
26 | + (UIFont *)starWarsLogoFont:(NSInteger)size;
27 |
28 | + (UIColor *)introTextColor;
29 | + (UIFont *)introTextFont:(NSInteger)size;
30 |
31 | + (UIColor *)crawlTextColor;
32 |
33 | + (UIFont *)bodyTextFont:(NSInteger)size;
34 | + (UIFont *)episodeTitleFont:(NSInteger)size;
35 | + (UIFont *)episodeNumberFont:(NSInteger)size;
36 |
37 | @end
38 |
--------------------------------------------------------------------------------
/SWCrawlViewExample/SWCrawlViewExample/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" : "29x29",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "40x40",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "40x40",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "60x60",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "60x60",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "ipad",
35 | "size" : "29x29",
36 | "scale" : "1x"
37 | },
38 | {
39 | "idiom" : "ipad",
40 | "size" : "29x29",
41 | "scale" : "2x"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "size" : "40x40",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "size" : "40x40",
51 | "scale" : "2x"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "size" : "76x76",
56 | "scale" : "1x"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "size" : "76x76",
61 | "scale" : "2x"
62 | }
63 | ],
64 | "info" : {
65 | "version" : 1,
66 | "author" : "xcode"
67 | }
68 | }
--------------------------------------------------------------------------------
/SWCrawlViewExample/SWCrawlViewExample/SWCrawlView/Constants/SWConstants.m:
--------------------------------------------------------------------------------
1 | //
2 | // SWConstants.m
3 | // CrawlCreator2.0
4 | //
5 | // Created by Tj on 5/16/15.
6 | // Copyright (c) 2015 Tj. All rights reserved.
7 | //
8 |
9 | #import "SWConstants.h"
10 |
11 | @implementation SWConstants
12 |
13 | UIColor* UIColorFromRGB(unsigned int rgbValue) {
14 | return [UIColor colorWithRed:((float)((rgbValue & 0xFF0000) >> 16))/255.0
15 | green:((float)((rgbValue & 0xFF00) >> 8))/255.0
16 | blue:((float)(rgbValue & 0xFF))/255.0 alpha:1.0];
17 | }
18 |
19 |
20 | + (UIColor *)starWarsLogoColor
21 | {
22 | return UIColorFromRGB(0xe5b13a);
23 | }
24 |
25 | + (UIFont *)starWarsLogoFont:(NSInteger)size
26 | {
27 | return [UIFont fontWithName:@"StarJedi" size:size];
28 | }
29 |
30 | + (UIColor *)introTextColor
31 | {
32 | return UIColorFromRGB(0x4bd5ee);
33 | }
34 |
35 | + (UIFont *)introTextFont:(NSInteger)size
36 | {
37 | return [UIFont fontWithName:@"Franklin Gothic Book" size:size];
38 | }
39 |
40 | + (UIColor *)crawlTextColor
41 | {
42 | return UIColorFromRGB(0xe5b13a);
43 | }
44 |
45 | + (UIFont *)bodyTextFont:(NSInteger)size
46 | {
47 | return [UIFont fontWithName:@"SW Crawl Body" size:size];
48 | }
49 |
50 | + (UIFont *)episodeTitleFont:(NSInteger)size
51 | {
52 | return [UIFont fontWithName:@"SW Crawl Title" size:size];
53 | }
54 |
55 | + (UIFont *)episodeNumberFont:(NSInteger)size
56 | {
57 | return [UIFont fontWithName:@"SW Crawl Body" size:size];
58 | }
59 |
60 | @end
61 |
--------------------------------------------------------------------------------
/SWCrawlViewExample/SWCrawlViewExample/ViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.m
3 | // SWCrawlViewExample
4 | //
5 | // Created by TJ Fallon on 5/21/15.
6 | // Copyright (c) 2015 TJ Fallon. All rights reserved.
7 | //
8 |
9 | #import "ViewController.h"
10 | #import "SWCrawlView.h"
11 | #import "SWCrawl.h"
12 |
13 | @interface ViewController ()
14 |
15 | @property (weak) IBOutlet SWCrawlView *crawlView;
16 |
17 | @end
18 |
19 | @implementation ViewController
20 |
21 | - (void)viewDidLoad {
22 | [super viewDidLoad];
23 |
24 | SWCrawl *crawl = [SWCrawl new];
25 |
26 | //Funny casing to use the characters in SW Jedi font that we need.
27 | [crawl setLogoText:@"Crawl\nWars"];
28 |
29 | [crawl setEpisodeNumberText:@"Episode 6+"];
30 |
31 | //Lowercase string because SW Title font has a couple funny characters in it. Check out the font.
32 | [crawl setEpisodeTitleText:@"Lorem Ipsum Strikes Back".lowercaseString];
33 | [crawl setBodyText:@"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."];
34 |
35 | [self.crawlView updateTextViaCrawl:crawl];
36 | }
37 |
38 | - (UIStatusBarStyle)preferredStatusBarStyle
39 | {
40 | return UIStatusBarStyleLightContent;
41 | }
42 |
43 | @end
44 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # SWCrawlView
2 |
3 | This control provides a realistic and interactive version of the original Theatrical Crawl for use in any app. The control is fully customizable, fonts, colors, text, etc can all be modified. It supports all iOS Devices (not the watch yet, sorry.), and both orientations. Very specific implementations may require source code tweaking.
4 |
5 |
6 |
7 | #### Background
8 | A long time ago, in a city far, far away (Chicago, I miss you), I built an app that let you create and export HD crawl videos and could mux it with your own music files. The app has fallen into heavy neglect, and hasn't been updated since 2013. It barely works right now, but if you're curious, you can check it out [here.](https://itunes.apple.com/us/app/star-wars-crawl-creator/id494406923?mt=8)
9 |
10 | As you can tell from the more recent reviews, having been built for iOS 4, Crawl Creator needs a serious over haul. So, I'm rebuilding her from the ground up, and as part of that, I'm open sourcing the SWCrawlView that I've rebuilt. I may follow up by open sourcing the .MP4 creation and YouTube uploading when that's ready.
11 |
12 | ### How To Use It:
13 |
14 | It can be created either via a xib or initWithFrame. You can then edit it either one property at a time, or by creating a SWCrawl object and passing that in. Comments exist in the various headers to explain functionality, but the main class of interest will be "SWCrawlView" and "SWCrawl", the few others are just supporting files.
15 |
16 | If you want to use the default fonts that match the movie, you'll need to add the "Fonts provided by application" key to your info.plist file. The view will begin customized to match the movies, but all properties can be changed and a redraw will be forced when any property is changed.
17 |
18 | See the Info.plist of the SWCrawlViewExample project to see the "Fonts provided by application".
19 |
20 | A more detailed example project and documentation will follow soon.
21 |
--------------------------------------------------------------------------------
/SWCrawlViewExample/SWCrawlViewExample/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | foleyproductions.$(PRODUCT_NAME:rfc1034identifier)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 | LSRequiresIPhoneOS
24 |
25 | UIAppFonts
26 |
27 | Franklin_Gothic_Book.ttf
28 | StarJediBig.ttf
29 | SWCrawlBody.ttf
30 | Starjhol.ttf
31 | Star_Jedi_Rounded.ttf
32 | SWCrawlTitle.ttf
33 |
34 | UILaunchStoryboardName
35 | LaunchScreen
36 | UIMainStoryboardFile
37 | Main
38 | UIRequiredDeviceCapabilities
39 |
40 | armv7
41 |
42 | UISupportedInterfaceOrientations
43 |
44 | UIInterfaceOrientationPortrait
45 | UIInterfaceOrientationLandscapeLeft
46 | UIInterfaceOrientationLandscapeRight
47 |
48 | UISupportedInterfaceOrientations~ipad
49 |
50 | UIInterfaceOrientationPortrait
51 | UIInterfaceOrientationPortraitUpsideDown
52 | UIInterfaceOrientationLandscapeLeft
53 | UIInterfaceOrientationLandscapeRight
54 |
55 |
56 |
57 |
--------------------------------------------------------------------------------
/SWCrawlViewExample/SWCrawlViewExample/AppDelegate.m:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.m
3 | // SWCrawlViewExample
4 | //
5 | // Created by TJ Fallon on 5/21/15.
6 | // Copyright (c) 2015 TJ Fallon. All rights reserved.
7 | //
8 |
9 | #import "AppDelegate.h"
10 |
11 | @interface AppDelegate ()
12 |
13 | @end
14 |
15 | @implementation AppDelegate
16 |
17 |
18 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
19 | // Override point for customization after application launch.
20 | return YES;
21 | }
22 |
23 | - (void)applicationWillResignActive:(UIApplication *)application {
24 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
25 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
26 | }
27 |
28 | - (void)applicationDidEnterBackground:(UIApplication *)application {
29 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
30 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
31 | }
32 |
33 | - (void)applicationWillEnterForeground:(UIApplication *)application {
34 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
35 | }
36 |
37 | - (void)applicationDidBecomeActive:(UIApplication *)application {
38 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
39 | }
40 |
41 | - (void)applicationWillTerminate:(UIApplication *)application {
42 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
43 | }
44 |
45 | @end
46 |
--------------------------------------------------------------------------------
/SWCrawlViewExample/SWCrawlViewExample/SWCrawlView/Crawl View/SWCrawlView.h:
--------------------------------------------------------------------------------
1 | //
2 | // MFLCrawlView.h
3 | // CrawlCreator2.0
4 | //
5 | // Created by Tj on 5/16/15.
6 | // Copyright (c) 2015 Tj. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "SWCrawl.h"
11 |
12 | //I know, it should really have a three letter class prefix, but I couldn't resist.
13 | @interface SWCrawlView : UIView
14 |
15 | #pragma mark Text Customization
16 | /**
17 | * e.g.:
18 | * STAR
19 | * WARS
20 | *
21 | * @param logoText Use new lines, it will not line break automatically. Will respect logoStrokeColor/Font, will always fill black.
22 | */
23 | - (void)setLogoText:(NSString *)logoText;
24 |
25 | /**
26 | * e.g.:
27 | * Episode V
28 | *
29 | * @param numberText Number text to be set, can be nil. Will respect episodeNumberFont/Color
30 | */
31 | - (void)setEpisodeNumberText:(NSString *)numberText;
32 |
33 | /**
34 | * e.g.:
35 | * THE EMPIRE STRIKES BACK
36 | *
37 | * @param titleText Title text to be set, can be nil. Will respect episodeTitleFont/Color
38 | */
39 | - (void)setEpisodeTitleText:(NSString *)titleText;
40 |
41 | /**
42 | * e.g.:
43 | *
44 | * It is a dark time for the
45 | * Rebellion. Although the Death
46 | * Star has been destroyed.
47 | *
48 | * @param bodyText Text will be justified and broken into lines for you. Will respect bodyTextFont/Color
49 | */
50 | - (void)setBodyText:(NSString *)bodyText;
51 |
52 | #pragma Update via SWCrawl
53 | /**
54 | * You can set all cusotmization values by creating an SWCrawl object and passing it in here.
55 | * Text values which are nil will be used, but font and color values which are nil will be ignored in favor of currently set values.
56 | *
57 | * @param crawl Customized SWCrawl object.
58 | */
59 | - (void)updateTextViaCrawl:(SWCrawl *)crawl;
60 |
61 |
62 | /**
63 | * This method will return a SWCrawl object with all the current properties of the view set.
64 | *
65 | * @return Customized SWCrawl object
66 | */
67 | - (SWCrawl *)crawlForCurrentText;
68 |
69 |
70 | /**
71 | * This will return an NSAttributedString of the episode number, episode title, and crawl body merged together.
72 | * This string is used internally to display the crawl.
73 | *
74 | * @return Crawl string, including all text style customizations.
75 | */
76 | - (NSAttributedString *)composedCrawlString;
77 |
78 | #pragma mark Font/Color Customization
79 |
80 | /**
81 | * See above text comments for descriptions of each value in the crawl. Setting any of these will update the force a redraw on the crawl view.
82 | */
83 | @property (nonatomic) UIFont *logoFont;
84 | @property (nonatomic) UIFont *episodeTitleFont;
85 | @property (nonatomic) UIFont *episodeNumberFont;
86 | @property (nonatomic) UIFont *bodyFont;
87 |
88 | @property (nonatomic) UIColor *logoStrokeColor;
89 | @property (nonatomic) UIColor *episodeTitleColor;
90 | @property (nonatomic) UIColor *episodeNumberColor;
91 | @property (nonatomic) UIColor *bodyColor;
92 |
93 | @property (readonly) BOOL isAnimating;
94 |
95 | - (void)redisplayAfterScrollOut;
96 | - (void)scrollOutWithDuration:(CGFloat)duration
97 | completion:(void(^)(void))completion;
98 |
99 | @end
100 |
--------------------------------------------------------------------------------
/SWCrawlViewExample/SWCrawlViewExample/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 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
--------------------------------------------------------------------------------
/SWCrawlViewExample/SWCrawlViewExample/Base.lproj/LaunchScreen.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
20 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/SWCrawlViewExample/SWCrawlViewExample/SWCrawlView/Crawl/SWCrawl.m:
--------------------------------------------------------------------------------
1 | //
2 | // SWCrawl.m
3 | // CrawlCreator2.0
4 | //
5 | // Created by Tj on 5/17/15.
6 | // Copyright (c) 2015 Tj. All rights reserved.
7 | //
8 |
9 | #import "SWCrawl.h"
10 | #import
11 |
12 | @implementation SWCrawl
13 |
14 | - (id)copyWithZone:(NSZone *)zone
15 | {
16 | SWCrawl *newCrawl = [[[self class] allocWithZone:zone] init];
17 |
18 | if (newCrawl) {
19 | newCrawl.introText = self.introText;
20 | newCrawl.logoText = self.logoText;
21 | newCrawl.episodeNumberText = self.episodeNumberText;
22 | newCrawl.episodeTitleText = self.episodeTitleText;
23 | newCrawl.bodyText = self.bodyText;
24 |
25 | newCrawl.logoFont = self.logoFont;
26 | newCrawl.episodeTitleFont = self.episodeTitleFont;
27 | newCrawl.episodeNumberFont = self.episodeNumberFont;
28 | newCrawl.bodyFont = self.bodyFont;
29 |
30 | newCrawl.logoStrokeColor = self.logoStrokeColor;
31 | newCrawl.episodeTitleColor = self.episodeTitleColor;
32 | newCrawl.episodeNumberColor = self.episodeNumberColor;
33 | newCrawl.bodyColor = self.bodyColor;
34 | }
35 |
36 | return newCrawl;
37 | }
38 |
39 |
40 | - (NSAttributedString *)composedCrawlString
41 | {
42 | NSMutableAttributedString *fullCrawlString = [NSMutableAttributedString new];
43 |
44 | if (self.episodeNumberText.length) {
45 | NSMutableParagraphStyle *numberTextParagraphStyle = [NSMutableParagraphStyle new];
46 | numberTextParagraphStyle.alignment = NSTextAlignmentCenter;
47 |
48 | NSDictionary *numberAttributes = @{ NSParagraphStyleAttributeName : numberTextParagraphStyle,
49 | NSForegroundColorAttributeName : self.episodeNumberColor,
50 | NSFontAttributeName : self.episodeNumberFont};
51 |
52 | NSString *spacedNumberString = [NSString stringWithFormat:@"%@\n\n", self.episodeNumberText];
53 | NSAttributedString *numberString = [[NSAttributedString alloc] initWithString:spacedNumberString
54 | attributes:numberAttributes];
55 |
56 | [fullCrawlString appendAttributedString:numberString];
57 | }
58 |
59 | if (self.episodeTitleText.length) {
60 | NSMutableParagraphStyle *titleTextParagraphStyle = [NSMutableParagraphStyle new];
61 | titleTextParagraphStyle.alignment = NSTextAlignmentCenter;
62 |
63 | NSDictionary *titleAttributes = @{ NSParagraphStyleAttributeName : titleTextParagraphStyle,
64 | NSForegroundColorAttributeName : self.episodeTitleColor,
65 | NSFontAttributeName : self.episodeTitleFont};
66 | NSString *spacedTitleString = [NSString stringWithFormat:@"%@\n\n", self.episodeTitleText];
67 | NSAttributedString *titleString = [[NSAttributedString alloc] initWithString:spacedTitleString
68 | attributes:titleAttributes];
69 |
70 | [fullCrawlString appendAttributedString:titleString];
71 | }
72 |
73 | if (self.bodyText.length) {
74 | NSMutableParagraphStyle *bodyTextParagraphStyle = [NSMutableParagraphStyle new];
75 | bodyTextParagraphStyle.alignment = NSTextAlignmentJustified;
76 | bodyTextParagraphStyle.firstLineHeadIndent = 0.05; // "Very IMP" said original comment, why? Tj-
77 |
78 | NSDictionary *bodyAttributes = @{ NSParagraphStyleAttributeName : bodyTextParagraphStyle,
79 | NSForegroundColorAttributeName : self.bodyColor,
80 | NSFontAttributeName : self.bodyFont };
81 |
82 | NSAttributedString *bodyString = [[NSAttributedString alloc] initWithString:self.bodyText
83 | attributes:bodyAttributes];
84 | [fullCrawlString appendAttributedString:bodyString];
85 | }
86 |
87 | return fullCrawlString;
88 | }
89 |
90 | @end
91 |
--------------------------------------------------------------------------------
/SWCrawlViewExample/SWCrawlViewExample/SWCrawlView/Crawl View/SWCrawlView.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | StarJedi
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 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
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 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
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 |
--------------------------------------------------------------------------------
/SWCrawlViewExample/SWCrawlViewExample/SWCrawlView/Crawl View/SWCrawlView.m:
--------------------------------------------------------------------------------
1 | //
2 | // MFLCrawlView.m
3 | // CrawlCreator2.0
4 | //
5 | // Created by Tj on 5/16/15.
6 | // Copyright (c) 2015 Tj. All rights reserved.
7 | //
8 |
9 | #import "SWCrawlView.h"
10 | #import "SWConstants.h"
11 | #import "SWStrokedLogoLabel.h"
12 | #import
13 |
14 | #ifndef UIInterfaceIdiomIsPad
15 | #define UIInterfaceIdiomIsPad() (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
16 | #endif
17 |
18 | const CGFloat logoStrokeSizeForFontPointSizeMultiplier = .165;
19 |
20 | @interface SWCrawlView ()
21 |
22 | @property (weak) IBOutlet UIView *xibView;
23 | @property (weak) IBOutlet UIView *screenSizeScaleView;
24 |
25 | @property (weak) IBOutlet UIImageView *maskImageView;
26 | @property (weak) IBOutlet UIScrollView *scrollView;
27 | @property (weak) IBOutlet UIScrollView *controlView;
28 |
29 | @property (weak) IBOutlet UILabel *crawlTextView;
30 | @property (weak) IBOutlet NSLayoutConstraint *crawlTextTopSpacingConstraint;
31 | @property (weak) IBOutlet NSLayoutConstraint *crawlTextBottomSpacingConstraint;
32 |
33 | @property (weak) IBOutlet SWStrokedLogoLabel *logoLabel;
34 | @property (weak) IBOutlet NSLayoutConstraint *logoWidthConstraint;
35 | @property (weak) IBOutlet NSLayoutConstraint *logoHeightConstraint;
36 | @property (weak) IBOutlet UILabel *titleLabel;
37 |
38 | @property (readwrite) BOOL isAnimating;
39 |
40 | @property SWCrawl *crawl;
41 |
42 | @end
43 |
44 | @implementation SWCrawlView
45 |
46 | #pragma mark Init
47 | - (id)initWithFrame:(CGRect)frame
48 | {
49 | self = [super initWithFrame:frame];
50 |
51 | if (self) {
52 | [self sharedInit];
53 | }
54 |
55 | return self;
56 | }
57 |
58 | - (id)initWithCoder:(NSCoder *)aDecoder
59 | {
60 | self = [super initWithCoder:aDecoder];
61 |
62 | if (self) {
63 | [self sharedInit];
64 | }
65 |
66 | return self;
67 | }
68 |
69 | - (void)sharedInit
70 | {
71 | _crawl = [SWCrawl new];
72 |
73 | _crawl.logoStrokeColor = [SWConstants starWarsLogoColor];
74 | _crawl.episodeNumberColor = [SWConstants crawlTextColor];
75 | _crawl.episodeTitleColor = [SWConstants crawlTextColor];
76 | _crawl.bodyColor = [SWConstants crawlTextColor];
77 |
78 | _crawl.logoFont = [SWConstants starWarsLogoFont:UIInterfaceIdiomIsPad() ? 140 : 48];
79 | _crawl.episodeNumberFont = [SWConstants episodeNumberFont:20];
80 | _crawl.episodeTitleFont = [SWConstants episodeTitleFont:40];
81 | _crawl.bodyFont = [SWConstants bodyTextFont:20];
82 |
83 | [self unwrapNib];
84 |
85 | [self startObservingScrollChanges];
86 | [self beginOrientationObserving];
87 |
88 | [self orientationDidChange:nil];
89 | }
90 |
91 | - (void)unwrapNib
92 | {
93 | [[NSBundle mainBundle] loadNibNamed:NSStringFromClass(self.class)
94 | owner:self
95 | options:nil];
96 |
97 | [self.xibView setTranslatesAutoresizingMaskIntoConstraints:NO];
98 | [self.xibView setBackgroundColor:[UIColor colorWithPatternImage:[UIImage imageNamed:@"starBg.png"]]];
99 | [self addSubview:self.xibView];
100 |
101 | NSDictionary *views = NSDictionaryOfVariableBindings(_xibView);
102 | [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[_xibView]|"
103 | options:0
104 | metrics:nil
105 | views:views]];
106 | [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[_xibView]|"
107 | options:0
108 | metrics:nil
109 | views:views]];
110 | }
111 |
112 | #pragma mark Customization
113 |
114 | - (void)updateTextViaCrawl:(SWCrawl *)crawl
115 | {
116 | [self setLogoText:crawl.logoText];
117 | [self setLogoFont:crawl.logoFont];
118 | [self setLogoStrokeColor:crawl.logoStrokeColor];
119 |
120 | [self setEpisodeNumberText:crawl.episodeNumberText];
121 | [self setEpisodeNumberFont:crawl.episodeNumberFont];
122 | [self setEpisodeNumberColor:crawl.episodeNumberColor];
123 |
124 | [self setEpisodeTitleText:crawl.episodeTitleText];
125 | [self setEpisodeTitleColor:crawl.episodeTitleColor];
126 | [self setEpisodeTitleFont:crawl.episodeTitleFont];
127 |
128 | [self setBodyText:crawl.bodyText];
129 | [self setBodyColor:crawl.bodyColor];
130 | [self setBodyFont:crawl.bodyFont];
131 | }
132 |
133 | - (SWCrawl *)crawlForCurrentText
134 | {
135 | return self.crawl;
136 | }
137 |
138 | - (NSAttributedString *)composedCrawlString
139 | {
140 | return [self.crawl composedCrawlString];
141 | }
142 |
143 | - (void)updateCrawlingText
144 | {
145 | [self.crawlTextView setAttributedText:[self composedCrawlString]];
146 |
147 | [self setNeedsUpdateConstraints];
148 | [self layoutIfNeeded];
149 |
150 | [self scrollViewDidScroll:self.scrollView];
151 | }
152 |
153 | #pragma mark Setters
154 |
155 | - (void)setEpisodeNumberText:(NSString *)numberText
156 | {
157 | self.crawl.episodeNumberText = numberText;
158 | [self updateCrawlingText];
159 | }
160 |
161 | - (void)setEpisodeTitleText:(NSString *)titleText
162 | {
163 | self.crawl.episodeTitleText = titleText;
164 | [self updateCrawlingText];
165 | }
166 |
167 | - (void)setBodyText:(NSString *)bodyText
168 | {
169 | self.crawl.bodyText = bodyText;
170 | [self updateCrawlingText];
171 | }
172 |
173 | - (void)setLogoText:(NSString *)logoText
174 | {
175 | [self.logoLabel setStrokeColor:self.crawl.logoStrokeColor];
176 | [self.logoLabel setFont:self.crawl.logoFont];
177 | [self.logoLabel setText:logoText];
178 | [self.logoLabel setStrokeWidth:self.crawl.logoFont.pointSize * logoStrokeSizeForFontPointSizeMultiplier];
179 | [self.crawl setLogoText:logoText];
180 | }
181 |
182 | - (void)setLogoFont:(UIFont *)logoFont
183 | {
184 | if (logoFont) {
185 | _logoFont = logoFont;
186 |
187 | self.crawl.logoFont = logoFont;
188 | [self updateCrawlingText];
189 | }
190 | }
191 |
192 | - (void)setBodyFont:(UIFont *)bodyFont
193 | {
194 | if (bodyFont) {
195 | _bodyFont = bodyFont;
196 |
197 | self.crawl.bodyFont = bodyFont;
198 | [self updateCrawlingText];
199 | }
200 | }
201 |
202 | - (void)setEpisodeTitleFont:(UIFont *)episodeTitleFont
203 | {
204 | if (episodeTitleFont) {
205 | _episodeTitleFont = episodeTitleFont;
206 |
207 | self.crawl.episodeTitleFont = episodeTitleFont;
208 | [self updateCrawlingText];
209 | }
210 | }
211 |
212 | - (void)setEpisodeNumberFont:(UIFont *)episodeNumberFont
213 | {
214 | if (episodeNumberFont) {
215 | _episodeNumberFont = episodeNumberFont;
216 |
217 | self.crawl.episodeNumberFont = episodeNumberFont;
218 | [self updateCrawlingText];
219 | }
220 | }
221 |
222 | - (void)setLogoStrokeColor:(UIColor *)logoStrokeColor
223 | {
224 | if (logoStrokeColor) {
225 | _logoStrokeColor = logoStrokeColor;
226 |
227 | self.crawl.logoStrokeColor = logoStrokeColor;
228 | [self updateCrawlingText];
229 | }
230 | }
231 |
232 | - (void)setBodyColor:(UIColor *)bodyColor
233 | {
234 | if (bodyColor) {
235 | _bodyColor = bodyColor;
236 |
237 | self.crawl.bodyColor = bodyColor;
238 | [self updateCrawlingText];
239 | }
240 | }
241 |
242 | - (void)setEpisodeTitleColor:(UIColor *)episodeTitleColor
243 | {
244 | if (episodeTitleColor) {
245 | _episodeTitleColor = episodeTitleColor;
246 |
247 | self.crawl.episodeTitleColor = episodeTitleColor;
248 | [self updateCrawlingText];
249 | }
250 | }
251 |
252 | - (void)setEpisodeNumberColor:(UIColor *)episodeNumberColor
253 | {
254 | if (episodeNumberColor) {
255 | _episodeNumberColor = episodeNumberColor;
256 |
257 | self.crawl.episodeNumberColor = episodeNumberColor;
258 | [self updateCrawlingText];
259 | }
260 | }
261 |
262 | #pragma mark Scroll Handling
263 |
264 | - (void)scrollViewDidScroll:(UIScrollView *)scrollView
265 | {
266 | if (!self.isAnimating) {
267 | CGFloat distanceFromVisible = (scrollView.contentOffset.y * 2) + CGRectGetHeight(self.frame);
268 | CGFloat logoScaleTransformValue = (1.0 - (distanceFromVisible / self.crawlTextTopSpacingConstraint.constant)) *
269 | [self logoScaleForScreenSize];
270 |
271 | [self.logoLabel setHidden:(logoScaleTransformValue <= 0)];
272 |
273 | if (logoScaleTransformValue > 0) {
274 | CGAffineTransform scaleTransform = CGAffineTransformMakeScale(logoScaleTransformValue,
275 | logoScaleTransformValue);
276 |
277 | [self.logoLabel setTransform:scaleTransform];
278 | }
279 | }
280 | }
281 |
282 | static int kObservingContentSizeChangesContext;
283 | static int kObservingContentOffsetChangesContext;
284 |
285 | - (void)startObservingScrollChanges
286 | {
287 | [self.scrollView addObserver:self
288 | forKeyPath:@"contentSize"
289 | options:0
290 | context:&kObservingContentSizeChangesContext];
291 | [self.controlView addObserver:self
292 | forKeyPath:@"contentOffset"
293 | options:0
294 | context:&kObservingContentOffsetChangesContext];
295 | }
296 |
297 | - (void)stopObservingScrollChanges
298 | {
299 | [self.controlView removeObserver:self
300 | forKeyPath:@"contentOffset"
301 | context:&kObservingContentOffsetChangesContext];
302 |
303 | [self.scrollView removeObserver:self
304 | forKeyPath:@"contentSize"
305 | context:&kObservingContentSizeChangesContext];
306 | }
307 |
308 | - (void)observeValueForKeyPath:(NSString *)keyPath
309 | ofObject:(id)object
310 | change:(NSDictionary *)change
311 | context:(void *)context
312 | {
313 | UIScrollView *scrollView = object;
314 | if (context == &kObservingContentSizeChangesContext) {
315 | [self.controlView setContentSize:scrollView.contentSize];
316 | } else if (context == &kObservingContentOffsetChangesContext) {
317 | [self.scrollView setContentOffset:scrollView.contentOffset animated:NO];
318 | } else {
319 | [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
320 | }
321 | }
322 |
323 | #pragma mark Orientation Handling
324 |
325 | - (void)beginOrientationObserving
326 | {
327 | [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
328 | [[NSNotificationCenter defaultCenter] addObserver:self
329 | selector:@selector(orientationDidChange:)
330 | name:UIDeviceOrientationDidChangeNotification object:nil];
331 | }
332 |
333 | - (void)orientationDidChange:(id)sender
334 | {
335 | UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];
336 |
337 | if (UIInterfaceOrientationIsLandscape(orientation)) {
338 | [self setupTransformsForLandscape];
339 | } else {
340 | [self setupTranformsForPortrait];
341 | }
342 | }
343 |
344 |
345 | //These transforms, which modify the m34, are how we acheive the perspective effect.
346 | //I was never very good at matrix math, so that's the best explanation I have.
347 |
348 | //This transform is not as movie accurate, but is more readable for portrait.
349 | - (void)setupTranformsForPortrait
350 | {
351 | CATransform3D rotationAndPerspectiveTransform = CATransform3DIdentity;
352 | rotationAndPerspectiveTransform.m34 = 1.0 / -550;
353 | rotationAndPerspectiveTransform = CATransform3DRotate(rotationAndPerspectiveTransform,
354 | 80.0f * M_PI / 165.0f, 1.0f, 0.0f, 0.0f);
355 | rotationAndPerspectiveTransform = CATransform3DScale(rotationAndPerspectiveTransform, [self crawlScaleforScreenSize],
356 | [self crawlScaleforScreenSize], 1);
357 | rotationAndPerspectiveTransform = CATransform3DTranslate(rotationAndPerspectiveTransform, 0, 0, -250);
358 |
359 | CABasicAnimation *transformAnimation = [CABasicAnimation animationWithKeyPath: @"transform"];
360 | transformAnimation.fromValue = [NSValue valueWithCATransform3D:[((CALayer *)self.scrollView.layer.presentationLayer) transform]];
361 | transformAnimation.toValue = [NSValue valueWithCATransform3D:rotationAndPerspectiveTransform];
362 | transformAnimation.duration = 3;
363 | [self.scrollView.layer addAnimation:transformAnimation forKey:@"transform"];
364 | [self.scrollView.layer setTransform:rotationAndPerspectiveTransform];
365 |
366 | [self.logoLabel.layer setZPosition:1000];
367 | [self.maskImageView.layer setZPosition:1000];
368 | }
369 |
370 | //This transform more accurately reflects the movie's angle.
371 | - (void)setupTransformsForLandscape
372 | {
373 | CATransform3D rotationAndPerspectiveTransform = CATransform3DIdentity;
374 | rotationAndPerspectiveTransform.m34 = 1.0 / -700;
375 | rotationAndPerspectiveTransform = CATransform3DRotate(rotationAndPerspectiveTransform,
376 | 80.0f * M_PI / 155.0f, 1.0f, 0.0f, 0.0f);
377 | rotationAndPerspectiveTransform = CATransform3DScale(rotationAndPerspectiveTransform, [self crawlScaleforScreenSize],
378 | [self crawlScaleforScreenSize], 1);
379 | rotationAndPerspectiveTransform = CATransform3DTranslate(rotationAndPerspectiveTransform, 0, 0, -250);
380 |
381 | CABasicAnimation *transformAnimation = [CABasicAnimation animationWithKeyPath: @"transform"];
382 | transformAnimation.fromValue = [NSValue valueWithCATransform3D:[((CALayer *)self.scrollView.layer.presentationLayer) transform]];
383 | transformAnimation.toValue = [NSValue valueWithCATransform3D:rotationAndPerspectiveTransform];
384 | transformAnimation.duration = 3;
385 | [self.scrollView.layer addAnimation:transformAnimation forKey:@"transform"];
386 | [self.scrollView.layer setTransform:rotationAndPerspectiveTransform];
387 |
388 | [self.logoLabel.layer setZPosition:1000];
389 | [self.maskImageView.layer setZPosition:1000];
390 | }
391 |
392 | #pragma mark Device Specific Tweaks
393 |
394 | - (CGFloat)crawlScaleforScreenSize
395 | {
396 | CGFloat scaleSize = 1;
397 | if (UIInterfaceIdiomIsPad()) {
398 | scaleSize = 1.4;
399 | } else {
400 | scaleSize = 1;
401 | }
402 |
403 | return scaleSize;
404 | }
405 |
406 | - (CGFloat)logoScaleForScreenSize
407 | {
408 | CGFloat scaleSize;
409 | UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];
410 | if (UIInterfaceOrientationIsLandscape(orientation)) {
411 | scaleSize = UIInterfaceIdiomIsPad() ? 2.0 : 2.0;
412 | } else {
413 | scaleSize = UIInterfaceIdiomIsPad() ? 3.0 : 2.5;
414 | }
415 | return scaleSize;
416 | }
417 |
418 | - (void)redisplayAfterScrollOut
419 | {
420 | [UIView animateWithDuration:1.0 animations:^{
421 | [self.scrollView setAlpha:1];
422 | [self.logoLabel setAlpha:1];
423 | [self.controlView setContentOffset:CGPointMake(0, 0)];
424 | }];
425 | }
426 |
427 | - (void)scrollOutWithDuration:(CGFloat)duration
428 | completion:(void(^)(void))completion;
429 | {
430 | self.isAnimating = YES;
431 | CGFloat delay = 0.0;
432 | CGFloat visibleTextOffset = (self.crawlTextTopSpacingConstraint.constant - CGRectGetHeight(self.bounds));
433 | if (self.scrollView.contentOffset.y < visibleTextOffset) {
434 | CGFloat distanceToGo = visibleTextOffset - self.scrollView.contentOffset.y;
435 | CGFloat percentageOfWholeDistance = distanceToGo / self.scrollView.contentSize.height;
436 | delay = duration * percentageOfWholeDistance;
437 |
438 | [UIView animateWithDuration:delay animations:^{
439 | [self.logoLabel setTransform:CGAffineTransformMakeScale(.001, .001)];
440 | }];
441 | }
442 |
443 | [UIView animateWithDuration:duration
444 | delay:0.0
445 | options:UIViewAnimationOptionCurveEaseIn
446 | animations:^{
447 | [self.controlView setContentOffset:CGPointMake(0, (self.controlView.contentSize.height))];
448 | } completion:^(BOOL finished) {
449 | if (completion) {
450 | completion();
451 | }
452 | self.isAnimating = NO;
453 | [self.scrollView setAlpha:0];
454 | [self.logoLabel setAlpha:0];
455 | }];
456 | }
457 |
458 | @end
459 |
--------------------------------------------------------------------------------
/SWCrawlViewExample/SWCrawlViewExample.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | D933DF2A1B0E155100050E6B /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = D933DF291B0E155100050E6B /* main.m */; };
11 | D933DF2D1B0E155100050E6B /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = D933DF2C1B0E155100050E6B /* AppDelegate.m */; };
12 | D933DF301B0E155100050E6B /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = D933DF2F1B0E155100050E6B /* ViewController.m */; };
13 | D933DF331B0E155100050E6B /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = D933DF311B0E155100050E6B /* Main.storyboard */; };
14 | D933DF351B0E155100050E6B /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = D933DF341B0E155100050E6B /* Images.xcassets */; };
15 | D933DF381B0E155100050E6B /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = D933DF361B0E155100050E6B /* LaunchScreen.xib */; };
16 | D933DF441B0E155100050E6B /* SWCrawlViewExampleTests.m in Sources */ = {isa = PBXBuildFile; fileRef = D933DF431B0E155100050E6B /* SWCrawlViewExampleTests.m */; };
17 | D933DF581B0E165D00050E6B /* SWConstants.m in Sources */ = {isa = PBXBuildFile; fileRef = D933DF501B0E165D00050E6B /* SWConstants.m */; };
18 | D933DF591B0E165D00050E6B /* SWCrawl.m in Sources */ = {isa = PBXBuildFile; fileRef = D933DF531B0E165D00050E6B /* SWCrawl.m */; };
19 | D933DF5A1B0E165D00050E6B /* SWCrawlView.m in Sources */ = {isa = PBXBuildFile; fileRef = D933DF561B0E165D00050E6B /* SWCrawlView.m */; };
20 | D933DF5B1B0E165D00050E6B /* SWCrawlView.xib in Resources */ = {isa = PBXBuildFile; fileRef = D933DF571B0E165D00050E6B /* SWCrawlView.xib */; };
21 | D933DF6E1B0E18C700050E6B /* SWStrokedLogoLabel.m in Sources */ = {isa = PBXBuildFile; fileRef = D933DF6D1B0E18C700050E6B /* SWStrokedLogoLabel.m */; };
22 | D9A13BF81B0E5484000ED3E7 /* Franklin_Gothic_Book.ttf in Resources */ = {isa = PBXBuildFile; fileRef = D9A13BEE1B0E5483000ED3E7 /* Franklin_Gothic_Book.ttf */; };
23 | D9A13BF91B0E5484000ED3E7 /* Star_Jedi_Rounded.ttf in Resources */ = {isa = PBXBuildFile; fileRef = D9A13BEF1B0E5483000ED3E7 /* Star_Jedi_Rounded.ttf */; };
24 | D9A13BFA1B0E5484000ED3E7 /* Starjedi.ttf in Resources */ = {isa = PBXBuildFile; fileRef = D9A13BF01B0E5483000ED3E7 /* Starjedi.ttf */; };
25 | D9A13BFB1B0E5484000ED3E7 /* StarJediBig.ttf in Resources */ = {isa = PBXBuildFile; fileRef = D9A13BF11B0E5483000ED3E7 /* StarJediBig.ttf */; };
26 | D9A13BFC1B0E5484000ED3E7 /* Starjhol.ttf in Resources */ = {isa = PBXBuildFile; fileRef = D9A13BF21B0E5483000ED3E7 /* Starjhol.ttf */; };
27 | D9A13BFD1B0E5484000ED3E7 /* SWCrawlBody.ttf in Resources */ = {isa = PBXBuildFile; fileRef = D9A13BF31B0E5483000ED3E7 /* SWCrawlBody.ttf */; };
28 | D9A13BFE1B0E5484000ED3E7 /* SWCrawlTitle.ttf in Resources */ = {isa = PBXBuildFile; fileRef = D9A13BF41B0E5484000ED3E7 /* SWCrawlTitle.ttf */; };
29 | D9A13BFF1B0E5484000ED3E7 /* mask.png in Resources */ = {isa = PBXBuildFile; fileRef = D9A13BF61B0E5484000ED3E7 /* mask.png */; };
30 | D9A13C001B0E5484000ED3E7 /* starBg.png in Resources */ = {isa = PBXBuildFile; fileRef = D9A13BF71B0E5484000ED3E7 /* starBg.png */; };
31 | /* End PBXBuildFile section */
32 |
33 | /* Begin PBXContainerItemProxy section */
34 | D933DF3E1B0E155100050E6B /* PBXContainerItemProxy */ = {
35 | isa = PBXContainerItemProxy;
36 | containerPortal = D933DF1C1B0E155100050E6B /* Project object */;
37 | proxyType = 1;
38 | remoteGlobalIDString = D933DF231B0E155100050E6B;
39 | remoteInfo = SWCrawlViewExample;
40 | };
41 | /* End PBXContainerItemProxy section */
42 |
43 | /* Begin PBXFileReference section */
44 | D933DF241B0E155100050E6B /* SWCrawlViewExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SWCrawlViewExample.app; sourceTree = BUILT_PRODUCTS_DIR; };
45 | D933DF281B0E155100050E6B /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
46 | D933DF291B0E155100050E6B /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; };
47 | D933DF2B1B0E155100050E6B /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; };
48 | D933DF2C1B0E155100050E6B /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; };
49 | D933DF2E1B0E155100050E6B /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; };
50 | D933DF2F1B0E155100050E6B /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; };
51 | D933DF321B0E155100050E6B /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
52 | D933DF341B0E155100050E6B /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; };
53 | D933DF371B0E155100050E6B /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; };
54 | D933DF3D1B0E155100050E6B /* SWCrawlViewExampleTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SWCrawlViewExampleTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
55 | D933DF421B0E155100050E6B /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
56 | D933DF431B0E155100050E6B /* SWCrawlViewExampleTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SWCrawlViewExampleTests.m; sourceTree = ""; };
57 | D933DF4F1B0E165D00050E6B /* SWConstants.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SWConstants.h; sourceTree = ""; };
58 | D933DF501B0E165D00050E6B /* SWConstants.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SWConstants.m; sourceTree = ""; };
59 | D933DF521B0E165D00050E6B /* SWCrawl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SWCrawl.h; sourceTree = ""; };
60 | D933DF531B0E165D00050E6B /* SWCrawl.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SWCrawl.m; sourceTree = ""; };
61 | D933DF551B0E165D00050E6B /* SWCrawlView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SWCrawlView.h; sourceTree = ""; };
62 | D933DF561B0E165D00050E6B /* SWCrawlView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SWCrawlView.m; sourceTree = ""; };
63 | D933DF571B0E165D00050E6B /* SWCrawlView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = SWCrawlView.xib; sourceTree = ""; };
64 | D933DF6C1B0E18C700050E6B /* SWStrokedLogoLabel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SWStrokedLogoLabel.h; sourceTree = ""; };
65 | D933DF6D1B0E18C700050E6B /* SWStrokedLogoLabel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SWStrokedLogoLabel.m; sourceTree = ""; };
66 | D9A13BEE1B0E5483000ED3E7 /* Franklin_Gothic_Book.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = Franklin_Gothic_Book.ttf; sourceTree = ""; };
67 | D9A13BEF1B0E5483000ED3E7 /* Star_Jedi_Rounded.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = Star_Jedi_Rounded.ttf; sourceTree = ""; };
68 | D9A13BF01B0E5483000ED3E7 /* Starjedi.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = Starjedi.ttf; sourceTree = ""; };
69 | D9A13BF11B0E5483000ED3E7 /* StarJediBig.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = StarJediBig.ttf; sourceTree = ""; };
70 | D9A13BF21B0E5483000ED3E7 /* Starjhol.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = Starjhol.ttf; sourceTree = ""; };
71 | D9A13BF31B0E5483000ED3E7 /* SWCrawlBody.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = SWCrawlBody.ttf; sourceTree = ""; };
72 | D9A13BF41B0E5484000ED3E7 /* SWCrawlTitle.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = SWCrawlTitle.ttf; sourceTree = ""; };
73 | D9A13BF61B0E5484000ED3E7 /* mask.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = mask.png; sourceTree = ""; };
74 | D9A13BF71B0E5484000ED3E7 /* starBg.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = starBg.png; sourceTree = ""; };
75 | /* End PBXFileReference section */
76 |
77 | /* Begin PBXFrameworksBuildPhase section */
78 | D933DF211B0E155100050E6B /* Frameworks */ = {
79 | isa = PBXFrameworksBuildPhase;
80 | buildActionMask = 2147483647;
81 | files = (
82 | );
83 | runOnlyForDeploymentPostprocessing = 0;
84 | };
85 | D933DF3A1B0E155100050E6B /* Frameworks */ = {
86 | isa = PBXFrameworksBuildPhase;
87 | buildActionMask = 2147483647;
88 | files = (
89 | );
90 | runOnlyForDeploymentPostprocessing = 0;
91 | };
92 | /* End PBXFrameworksBuildPhase section */
93 |
94 | /* Begin PBXGroup section */
95 | D933DF1B1B0E155100050E6B = {
96 | isa = PBXGroup;
97 | children = (
98 | D933DF261B0E155100050E6B /* SWCrawlViewExample */,
99 | D933DF401B0E155100050E6B /* SWCrawlViewExampleTests */,
100 | D933DF251B0E155100050E6B /* Products */,
101 | );
102 | sourceTree = "";
103 | };
104 | D933DF251B0E155100050E6B /* Products */ = {
105 | isa = PBXGroup;
106 | children = (
107 | D933DF241B0E155100050E6B /* SWCrawlViewExample.app */,
108 | D933DF3D1B0E155100050E6B /* SWCrawlViewExampleTests.xctest */,
109 | );
110 | name = Products;
111 | sourceTree = "";
112 | };
113 | D933DF261B0E155100050E6B /* SWCrawlViewExample */ = {
114 | isa = PBXGroup;
115 | children = (
116 | D933DF2B1B0E155100050E6B /* AppDelegate.h */,
117 | D933DF2C1B0E155100050E6B /* AppDelegate.m */,
118 | D933DF2E1B0E155100050E6B /* ViewController.h */,
119 | D933DF2F1B0E155100050E6B /* ViewController.m */,
120 | D933DF4D1B0E165D00050E6B /* SWCrawlView */,
121 | D933DF311B0E155100050E6B /* Main.storyboard */,
122 | D933DF341B0E155100050E6B /* Images.xcassets */,
123 | D933DF361B0E155100050E6B /* LaunchScreen.xib */,
124 | D933DF271B0E155100050E6B /* Supporting Files */,
125 | );
126 | path = SWCrawlViewExample;
127 | sourceTree = "";
128 | };
129 | D933DF271B0E155100050E6B /* Supporting Files */ = {
130 | isa = PBXGroup;
131 | children = (
132 | D933DF281B0E155100050E6B /* Info.plist */,
133 | D933DF291B0E155100050E6B /* main.m */,
134 | );
135 | name = "Supporting Files";
136 | sourceTree = "";
137 | };
138 | D933DF401B0E155100050E6B /* SWCrawlViewExampleTests */ = {
139 | isa = PBXGroup;
140 | children = (
141 | D933DF431B0E155100050E6B /* SWCrawlViewExampleTests.m */,
142 | D933DF411B0E155100050E6B /* Supporting Files */,
143 | );
144 | path = SWCrawlViewExampleTests;
145 | sourceTree = "";
146 | };
147 | D933DF411B0E155100050E6B /* Supporting Files */ = {
148 | isa = PBXGroup;
149 | children = (
150 | D933DF421B0E155100050E6B /* Info.plist */,
151 | );
152 | name = "Supporting Files";
153 | sourceTree = "";
154 | };
155 | D933DF4D1B0E165D00050E6B /* SWCrawlView */ = {
156 | isa = PBXGroup;
157 | children = (
158 | D9A13BEC1B0E5483000ED3E7 /* Assets */,
159 | D933DF4E1B0E165D00050E6B /* Constants */,
160 | D933DF511B0E165D00050E6B /* Crawl */,
161 | D933DF541B0E165D00050E6B /* Crawl View */,
162 | );
163 | path = SWCrawlView;
164 | sourceTree = "";
165 | };
166 | D933DF4E1B0E165D00050E6B /* Constants */ = {
167 | isa = PBXGroup;
168 | children = (
169 | D933DF4F1B0E165D00050E6B /* SWConstants.h */,
170 | D933DF501B0E165D00050E6B /* SWConstants.m */,
171 | );
172 | path = Constants;
173 | sourceTree = "";
174 | };
175 | D933DF511B0E165D00050E6B /* Crawl */ = {
176 | isa = PBXGroup;
177 | children = (
178 | D933DF521B0E165D00050E6B /* SWCrawl.h */,
179 | D933DF531B0E165D00050E6B /* SWCrawl.m */,
180 | );
181 | path = Crawl;
182 | sourceTree = "";
183 | };
184 | D933DF541B0E165D00050E6B /* Crawl View */ = {
185 | isa = PBXGroup;
186 | children = (
187 | D933DF6B1B0E18C700050E6B /* Logo Label */,
188 | D933DF551B0E165D00050E6B /* SWCrawlView.h */,
189 | D933DF561B0E165D00050E6B /* SWCrawlView.m */,
190 | D933DF571B0E165D00050E6B /* SWCrawlView.xib */,
191 | );
192 | path = "Crawl View";
193 | sourceTree = "";
194 | };
195 | D933DF6B1B0E18C700050E6B /* Logo Label */ = {
196 | isa = PBXGroup;
197 | children = (
198 | D933DF6C1B0E18C700050E6B /* SWStrokedLogoLabel.h */,
199 | D933DF6D1B0E18C700050E6B /* SWStrokedLogoLabel.m */,
200 | );
201 | name = "Logo Label";
202 | path = BorderLabel;
203 | sourceTree = "";
204 | };
205 | D9A13BEC1B0E5483000ED3E7 /* Assets */ = {
206 | isa = PBXGroup;
207 | children = (
208 | D9A13BED1B0E5483000ED3E7 /* Fonts */,
209 | D9A13BF51B0E5484000ED3E7 /* Images */,
210 | );
211 | path = Assets;
212 | sourceTree = "";
213 | };
214 | D9A13BED1B0E5483000ED3E7 /* Fonts */ = {
215 | isa = PBXGroup;
216 | children = (
217 | D9A13BEE1B0E5483000ED3E7 /* Franklin_Gothic_Book.ttf */,
218 | D9A13BEF1B0E5483000ED3E7 /* Star_Jedi_Rounded.ttf */,
219 | D9A13BF01B0E5483000ED3E7 /* Starjedi.ttf */,
220 | D9A13BF11B0E5483000ED3E7 /* StarJediBig.ttf */,
221 | D9A13BF21B0E5483000ED3E7 /* Starjhol.ttf */,
222 | D9A13BF31B0E5483000ED3E7 /* SWCrawlBody.ttf */,
223 | D9A13BF41B0E5484000ED3E7 /* SWCrawlTitle.ttf */,
224 | );
225 | path = Fonts;
226 | sourceTree = "";
227 | };
228 | D9A13BF51B0E5484000ED3E7 /* Images */ = {
229 | isa = PBXGroup;
230 | children = (
231 | D9A13BF61B0E5484000ED3E7 /* mask.png */,
232 | D9A13BF71B0E5484000ED3E7 /* starBg.png */,
233 | );
234 | path = Images;
235 | sourceTree = "";
236 | };
237 | /* End PBXGroup section */
238 |
239 | /* Begin PBXNativeTarget section */
240 | D933DF231B0E155100050E6B /* SWCrawlViewExample */ = {
241 | isa = PBXNativeTarget;
242 | buildConfigurationList = D933DF471B0E155100050E6B /* Build configuration list for PBXNativeTarget "SWCrawlViewExample" */;
243 | buildPhases = (
244 | D933DF201B0E155100050E6B /* Sources */,
245 | D933DF211B0E155100050E6B /* Frameworks */,
246 | D933DF221B0E155100050E6B /* Resources */,
247 | );
248 | buildRules = (
249 | );
250 | dependencies = (
251 | );
252 | name = SWCrawlViewExample;
253 | productName = SWCrawlViewExample;
254 | productReference = D933DF241B0E155100050E6B /* SWCrawlViewExample.app */;
255 | productType = "com.apple.product-type.application";
256 | };
257 | D933DF3C1B0E155100050E6B /* SWCrawlViewExampleTests */ = {
258 | isa = PBXNativeTarget;
259 | buildConfigurationList = D933DF4A1B0E155100050E6B /* Build configuration list for PBXNativeTarget "SWCrawlViewExampleTests" */;
260 | buildPhases = (
261 | D933DF391B0E155100050E6B /* Sources */,
262 | D933DF3A1B0E155100050E6B /* Frameworks */,
263 | D933DF3B1B0E155100050E6B /* Resources */,
264 | );
265 | buildRules = (
266 | );
267 | dependencies = (
268 | D933DF3F1B0E155100050E6B /* PBXTargetDependency */,
269 | );
270 | name = SWCrawlViewExampleTests;
271 | productName = SWCrawlViewExampleTests;
272 | productReference = D933DF3D1B0E155100050E6B /* SWCrawlViewExampleTests.xctest */;
273 | productType = "com.apple.product-type.bundle.unit-test";
274 | };
275 | /* End PBXNativeTarget section */
276 |
277 | /* Begin PBXProject section */
278 | D933DF1C1B0E155100050E6B /* Project object */ = {
279 | isa = PBXProject;
280 | attributes = {
281 | LastUpgradeCheck = 0630;
282 | ORGANIZATIONNAME = "TJ Fallon";
283 | TargetAttributes = {
284 | D933DF231B0E155100050E6B = {
285 | CreatedOnToolsVersion = 6.3;
286 | };
287 | D933DF3C1B0E155100050E6B = {
288 | CreatedOnToolsVersion = 6.3;
289 | TestTargetID = D933DF231B0E155100050E6B;
290 | };
291 | };
292 | };
293 | buildConfigurationList = D933DF1F1B0E155100050E6B /* Build configuration list for PBXProject "SWCrawlViewExample" */;
294 | compatibilityVersion = "Xcode 3.2";
295 | developmentRegion = English;
296 | hasScannedForEncodings = 0;
297 | knownRegions = (
298 | en,
299 | Base,
300 | );
301 | mainGroup = D933DF1B1B0E155100050E6B;
302 | productRefGroup = D933DF251B0E155100050E6B /* Products */;
303 | projectDirPath = "";
304 | projectRoot = "";
305 | targets = (
306 | D933DF231B0E155100050E6B /* SWCrawlViewExample */,
307 | D933DF3C1B0E155100050E6B /* SWCrawlViewExampleTests */,
308 | );
309 | };
310 | /* End PBXProject section */
311 |
312 | /* Begin PBXResourcesBuildPhase section */
313 | D933DF221B0E155100050E6B /* Resources */ = {
314 | isa = PBXResourcesBuildPhase;
315 | buildActionMask = 2147483647;
316 | files = (
317 | D9A13BF91B0E5484000ED3E7 /* Star_Jedi_Rounded.ttf in Resources */,
318 | D933DF331B0E155100050E6B /* Main.storyboard in Resources */,
319 | D9A13C001B0E5484000ED3E7 /* starBg.png in Resources */,
320 | D933DF381B0E155100050E6B /* LaunchScreen.xib in Resources */,
321 | D9A13BFB1B0E5484000ED3E7 /* StarJediBig.ttf in Resources */,
322 | D9A13BFC1B0E5484000ED3E7 /* Starjhol.ttf in Resources */,
323 | D933DF5B1B0E165D00050E6B /* SWCrawlView.xib in Resources */,
324 | D9A13BFD1B0E5484000ED3E7 /* SWCrawlBody.ttf in Resources */,
325 | D9A13BF81B0E5484000ED3E7 /* Franklin_Gothic_Book.ttf in Resources */,
326 | D9A13BFA1B0E5484000ED3E7 /* Starjedi.ttf in Resources */,
327 | D933DF351B0E155100050E6B /* Images.xcassets in Resources */,
328 | D9A13BFE1B0E5484000ED3E7 /* SWCrawlTitle.ttf in Resources */,
329 | D9A13BFF1B0E5484000ED3E7 /* mask.png in Resources */,
330 | );
331 | runOnlyForDeploymentPostprocessing = 0;
332 | };
333 | D933DF3B1B0E155100050E6B /* Resources */ = {
334 | isa = PBXResourcesBuildPhase;
335 | buildActionMask = 2147483647;
336 | files = (
337 | );
338 | runOnlyForDeploymentPostprocessing = 0;
339 | };
340 | /* End PBXResourcesBuildPhase section */
341 |
342 | /* Begin PBXSourcesBuildPhase section */
343 | D933DF201B0E155100050E6B /* Sources */ = {
344 | isa = PBXSourcesBuildPhase;
345 | buildActionMask = 2147483647;
346 | files = (
347 | D933DF5A1B0E165D00050E6B /* SWCrawlView.m in Sources */,
348 | D933DF301B0E155100050E6B /* ViewController.m in Sources */,
349 | D933DF591B0E165D00050E6B /* SWCrawl.m in Sources */,
350 | D933DF2D1B0E155100050E6B /* AppDelegate.m in Sources */,
351 | D933DF2A1B0E155100050E6B /* main.m in Sources */,
352 | D933DF581B0E165D00050E6B /* SWConstants.m in Sources */,
353 | D933DF6E1B0E18C700050E6B /* SWStrokedLogoLabel.m in Sources */,
354 | );
355 | runOnlyForDeploymentPostprocessing = 0;
356 | };
357 | D933DF391B0E155100050E6B /* Sources */ = {
358 | isa = PBXSourcesBuildPhase;
359 | buildActionMask = 2147483647;
360 | files = (
361 | D933DF441B0E155100050E6B /* SWCrawlViewExampleTests.m in Sources */,
362 | );
363 | runOnlyForDeploymentPostprocessing = 0;
364 | };
365 | /* End PBXSourcesBuildPhase section */
366 |
367 | /* Begin PBXTargetDependency section */
368 | D933DF3F1B0E155100050E6B /* PBXTargetDependency */ = {
369 | isa = PBXTargetDependency;
370 | target = D933DF231B0E155100050E6B /* SWCrawlViewExample */;
371 | targetProxy = D933DF3E1B0E155100050E6B /* PBXContainerItemProxy */;
372 | };
373 | /* End PBXTargetDependency section */
374 |
375 | /* Begin PBXVariantGroup section */
376 | D933DF311B0E155100050E6B /* Main.storyboard */ = {
377 | isa = PBXVariantGroup;
378 | children = (
379 | D933DF321B0E155100050E6B /* Base */,
380 | );
381 | name = Main.storyboard;
382 | sourceTree = "";
383 | };
384 | D933DF361B0E155100050E6B /* LaunchScreen.xib */ = {
385 | isa = PBXVariantGroup;
386 | children = (
387 | D933DF371B0E155100050E6B /* Base */,
388 | );
389 | name = LaunchScreen.xib;
390 | sourceTree = "";
391 | };
392 | /* End PBXVariantGroup section */
393 |
394 | /* Begin XCBuildConfiguration section */
395 | D933DF451B0E155100050E6B /* Debug */ = {
396 | isa = XCBuildConfiguration;
397 | buildSettings = {
398 | ALWAYS_SEARCH_USER_PATHS = NO;
399 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
400 | CLANG_CXX_LIBRARY = "libc++";
401 | CLANG_ENABLE_MODULES = YES;
402 | CLANG_ENABLE_OBJC_ARC = YES;
403 | CLANG_WARN_BOOL_CONVERSION = YES;
404 | CLANG_WARN_CONSTANT_CONVERSION = YES;
405 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
406 | CLANG_WARN_EMPTY_BODY = YES;
407 | CLANG_WARN_ENUM_CONVERSION = YES;
408 | CLANG_WARN_INT_CONVERSION = YES;
409 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
410 | CLANG_WARN_UNREACHABLE_CODE = YES;
411 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
412 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
413 | COPY_PHASE_STRIP = NO;
414 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
415 | ENABLE_STRICT_OBJC_MSGSEND = YES;
416 | GCC_C_LANGUAGE_STANDARD = gnu99;
417 | GCC_DYNAMIC_NO_PIC = NO;
418 | GCC_NO_COMMON_BLOCKS = YES;
419 | GCC_OPTIMIZATION_LEVEL = 0;
420 | GCC_PREPROCESSOR_DEFINITIONS = (
421 | "DEBUG=1",
422 | "$(inherited)",
423 | );
424 | GCC_SYMBOLS_PRIVATE_EXTERN = NO;
425 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
426 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
427 | GCC_WARN_UNDECLARED_SELECTOR = YES;
428 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
429 | GCC_WARN_UNUSED_FUNCTION = YES;
430 | GCC_WARN_UNUSED_VARIABLE = YES;
431 | IPHONEOS_DEPLOYMENT_TARGET = 8.3;
432 | MTL_ENABLE_DEBUG_INFO = YES;
433 | ONLY_ACTIVE_ARCH = YES;
434 | SDKROOT = iphoneos;
435 | TARGETED_DEVICE_FAMILY = "1,2";
436 | };
437 | name = Debug;
438 | };
439 | D933DF461B0E155100050E6B /* Release */ = {
440 | isa = XCBuildConfiguration;
441 | buildSettings = {
442 | ALWAYS_SEARCH_USER_PATHS = NO;
443 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
444 | CLANG_CXX_LIBRARY = "libc++";
445 | CLANG_ENABLE_MODULES = YES;
446 | CLANG_ENABLE_OBJC_ARC = YES;
447 | CLANG_WARN_BOOL_CONVERSION = YES;
448 | CLANG_WARN_CONSTANT_CONVERSION = YES;
449 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
450 | CLANG_WARN_EMPTY_BODY = YES;
451 | CLANG_WARN_ENUM_CONVERSION = YES;
452 | CLANG_WARN_INT_CONVERSION = YES;
453 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
454 | CLANG_WARN_UNREACHABLE_CODE = YES;
455 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
456 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
457 | COPY_PHASE_STRIP = NO;
458 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
459 | ENABLE_NS_ASSERTIONS = NO;
460 | ENABLE_STRICT_OBJC_MSGSEND = YES;
461 | GCC_C_LANGUAGE_STANDARD = gnu99;
462 | GCC_NO_COMMON_BLOCKS = YES;
463 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
464 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
465 | GCC_WARN_UNDECLARED_SELECTOR = YES;
466 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
467 | GCC_WARN_UNUSED_FUNCTION = YES;
468 | GCC_WARN_UNUSED_VARIABLE = YES;
469 | IPHONEOS_DEPLOYMENT_TARGET = 8.3;
470 | MTL_ENABLE_DEBUG_INFO = NO;
471 | SDKROOT = iphoneos;
472 | TARGETED_DEVICE_FAMILY = "1,2";
473 | VALIDATE_PRODUCT = YES;
474 | };
475 | name = Release;
476 | };
477 | D933DF481B0E155100050E6B /* Debug */ = {
478 | isa = XCBuildConfiguration;
479 | buildSettings = {
480 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
481 | INFOPLIST_FILE = SWCrawlViewExample/Info.plist;
482 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
483 | PRODUCT_NAME = "$(TARGET_NAME)";
484 | };
485 | name = Debug;
486 | };
487 | D933DF491B0E155100050E6B /* Release */ = {
488 | isa = XCBuildConfiguration;
489 | buildSettings = {
490 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
491 | INFOPLIST_FILE = SWCrawlViewExample/Info.plist;
492 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
493 | PRODUCT_NAME = "$(TARGET_NAME)";
494 | };
495 | name = Release;
496 | };
497 | D933DF4B1B0E155100050E6B /* Debug */ = {
498 | isa = XCBuildConfiguration;
499 | buildSettings = {
500 | BUNDLE_LOADER = "$(TEST_HOST)";
501 | FRAMEWORK_SEARCH_PATHS = (
502 | "$(SDKROOT)/Developer/Library/Frameworks",
503 | "$(inherited)",
504 | );
505 | GCC_PREPROCESSOR_DEFINITIONS = (
506 | "DEBUG=1",
507 | "$(inherited)",
508 | );
509 | INFOPLIST_FILE = SWCrawlViewExampleTests/Info.plist;
510 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
511 | PRODUCT_NAME = "$(TARGET_NAME)";
512 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/SWCrawlViewExample.app/SWCrawlViewExample";
513 | };
514 | name = Debug;
515 | };
516 | D933DF4C1B0E155100050E6B /* Release */ = {
517 | isa = XCBuildConfiguration;
518 | buildSettings = {
519 | BUNDLE_LOADER = "$(TEST_HOST)";
520 | FRAMEWORK_SEARCH_PATHS = (
521 | "$(SDKROOT)/Developer/Library/Frameworks",
522 | "$(inherited)",
523 | );
524 | INFOPLIST_FILE = SWCrawlViewExampleTests/Info.plist;
525 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
526 | PRODUCT_NAME = "$(TARGET_NAME)";
527 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/SWCrawlViewExample.app/SWCrawlViewExample";
528 | };
529 | name = Release;
530 | };
531 | /* End XCBuildConfiguration section */
532 |
533 | /* Begin XCConfigurationList section */
534 | D933DF1F1B0E155100050E6B /* Build configuration list for PBXProject "SWCrawlViewExample" */ = {
535 | isa = XCConfigurationList;
536 | buildConfigurations = (
537 | D933DF451B0E155100050E6B /* Debug */,
538 | D933DF461B0E155100050E6B /* Release */,
539 | );
540 | defaultConfigurationIsVisible = 0;
541 | defaultConfigurationName = Release;
542 | };
543 | D933DF471B0E155100050E6B /* Build configuration list for PBXNativeTarget "SWCrawlViewExample" */ = {
544 | isa = XCConfigurationList;
545 | buildConfigurations = (
546 | D933DF481B0E155100050E6B /* Debug */,
547 | D933DF491B0E155100050E6B /* Release */,
548 | );
549 | defaultConfigurationIsVisible = 0;
550 | defaultConfigurationName = Release;
551 | };
552 | D933DF4A1B0E155100050E6B /* Build configuration list for PBXNativeTarget "SWCrawlViewExampleTests" */ = {
553 | isa = XCConfigurationList;
554 | buildConfigurations = (
555 | D933DF4B1B0E155100050E6B /* Debug */,
556 | D933DF4C1B0E155100050E6B /* Release */,
557 | );
558 | defaultConfigurationIsVisible = 0;
559 | defaultConfigurationName = Release;
560 | };
561 | /* End XCConfigurationList section */
562 | };
563 | rootObject = D933DF1C1B0E155100050E6B /* Project object */;
564 | }
565 |
--------------------------------------------------------------------------------