├── .gitignore ├── TWCatalog ├── Resources │ ├── Icon.png │ ├── Default.png │ ├── iTunesArtwork │ ├── placeholder.png │ └── TWCatalog-Info.plist ├── Classes │ ├── TCRootViewController.h │ ├── TCLineViewDemoViewController.h │ ├── TCPickerDetailViewController.h │ ├── TCMessagesDemoViewController.h │ ├── TCPickerDemoViewController.h │ ├── TCHUDViewDemoViewController.h │ ├── TCGradientViewDemoViewController.h │ ├── TCAppDelegate.h │ ├── TCPieProgressViewDemoViewController.h │ ├── TCLineViewDemoViewController.m │ ├── TCAppDelegate.m │ ├── TCHUDViewDemoViewController.m │ ├── TCPickerDetailViewController.m │ ├── TCGradientViewDemoViewController.m │ ├── TCMessagesDemoViewController.m │ ├── TCPickerDemoViewController.m │ ├── TCPieProgressViewDemoViewController.m │ └── TCRootViewController.m ├── Other Sources │ ├── TWCatalog_Prefix.pch │ └── main.m └── TWCatalog.xcodeproj │ └── project.pbxproj ├── Resources └── TWToolkit.bundle │ └── images │ ├── TWViewControllerFormBackground.png │ ├── TWViewControllerModalVignetteiPad.png │ ├── TWMessageTableViewCellBackgroundGray.png │ ├── TWMessageTableViewCellBackgroundGreen.png │ ├── TWMessagesViewControllerSendButtonBackground.png │ └── TWMessagesViewControllerTextFieldBackground.png ├── TWToolkit ├── NSData+TWToolkitAdditions.h ├── UIColor+TWToolkitAdditions.h ├── UIDevice+TWToolkitAdditions.h ├── NSArray+TWToolkitAdditions.h ├── NSURL+TWToolkitAdditions.h ├── UIControl+TWToolkitAdditions.h ├── TWTextField.h ├── TWConcurrentOperation.h ├── UIScrollView+TWToolkitAdditions.h ├── UIViewController+TWToolkitAdditions.h ├── TWDrawingMacros.h ├── UIColor+TWToolkitAdditions.m ├── TWTextView.h ├── UIDevice+TWToolkitAdditions.m ├── UIControl+TWToolkitAdditions.m ├── UIImage+TWToolkitAdditions.h ├── TWLineView.h ├── UIScrollView+TWToolkitAdditions.m ├── NSDate+TWToolkitAdditions.h ├── TWModalViewController.h ├── TWMessageTableViewCell.h ├── TWLoadingView.h ├── NSData+TWToolkitAdditions.m ├── TWIndicatorLabel.h ├── TWPieProgressView.h ├── NSArray+TWToolkitAdditions.m ├── TWLabel.h ├── TWTextField.m ├── NSString+TWToolkitAdditions.h ├── TWMessageTableViewCellBubbleView.h ├── UIViewController+TWToolkitAdditions.m ├── TWCategories.h ├── UIView+TWToolkitAdditions.h ├── TWPickerViewController.h ├── TWToolkit.h ├── NSURL+TWToolkitAdditions.m ├── TWViewController.h ├── TWHUDView.h ├── TWKeychain.h ├── TWMessagesViewController.h ├── TWConcurrentOperation.m ├── TWLabel.m ├── UIImage+TWToolkitAdditions.m ├── TWMessageTableViewCell.m ├── TWGradientView.h ├── TWTextView.m ├── UIView+TWToolkitAdditions.m ├── TWLineView.m ├── TWIndicatorLabel.m ├── TWPickerViewController.m ├── TWMessageTableViewCellBubbleView.m ├── NSDate+TWToolkitAdditions.m ├── TWWebView.h ├── TWPieProgressView.m ├── TWKeychain.m ├── TWLoadingView.m ├── TWHUDView.m ├── TWMessagesViewController.m ├── TWGradientView.m ├── TWViewController.m ├── NSString+TWToolkitAdditions.m └── TWWebView.m ├── Other Sources └── TWToolkit_Prefix.pch ├── LICENSE ├── Readme.markdown └── TWToolkit.xcodeproj └── project.pbxproj /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | build 3 | *.mode1v3 4 | *.pbxuser 5 | *.perspectivev3 6 | *.xcworkspace 7 | xcuserdata 8 | -------------------------------------------------------------------------------- /TWCatalog/Resources/Icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tastefulworks/twtoolkit/HEAD/TWCatalog/Resources/Icon.png -------------------------------------------------------------------------------- /TWCatalog/Resources/Default.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tastefulworks/twtoolkit/HEAD/TWCatalog/Resources/Default.png -------------------------------------------------------------------------------- /TWCatalog/Resources/iTunesArtwork: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tastefulworks/twtoolkit/HEAD/TWCatalog/Resources/iTunesArtwork -------------------------------------------------------------------------------- /TWCatalog/Resources/placeholder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tastefulworks/twtoolkit/HEAD/TWCatalog/Resources/placeholder.png -------------------------------------------------------------------------------- /Resources/TWToolkit.bundle/images/TWViewControllerFormBackground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tastefulworks/twtoolkit/HEAD/Resources/TWToolkit.bundle/images/TWViewControllerFormBackground.png -------------------------------------------------------------------------------- /Resources/TWToolkit.bundle/images/TWViewControllerModalVignetteiPad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tastefulworks/twtoolkit/HEAD/Resources/TWToolkit.bundle/images/TWViewControllerModalVignetteiPad.png -------------------------------------------------------------------------------- /Resources/TWToolkit.bundle/images/TWMessageTableViewCellBackgroundGray.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tastefulworks/twtoolkit/HEAD/Resources/TWToolkit.bundle/images/TWMessageTableViewCellBackgroundGray.png -------------------------------------------------------------------------------- /Resources/TWToolkit.bundle/images/TWMessageTableViewCellBackgroundGreen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tastefulworks/twtoolkit/HEAD/Resources/TWToolkit.bundle/images/TWMessageTableViewCellBackgroundGreen.png -------------------------------------------------------------------------------- /Resources/TWToolkit.bundle/images/TWMessagesViewControllerSendButtonBackground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tastefulworks/twtoolkit/HEAD/Resources/TWToolkit.bundle/images/TWMessagesViewControllerSendButtonBackground.png -------------------------------------------------------------------------------- /Resources/TWToolkit.bundle/images/TWMessagesViewControllerTextFieldBackground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tastefulworks/twtoolkit/HEAD/Resources/TWToolkit.bundle/images/TWMessagesViewControllerTextFieldBackground.png -------------------------------------------------------------------------------- /TWToolkit/NSData+TWToolkitAdditions.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSData+TWToolkitAdditions.h 3 | // TWToolkit 4 | // 5 | // Created by Sam Soffes on 9/29/08. 6 | // Copyright 2009 Tasteful Works, Inc. All rights reserved. 7 | // 8 | 9 | @interface NSData (TWToolkitAdditions) 10 | 11 | - (NSString *)MD5Sum; 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /TWToolkit/UIColor+TWToolkitAdditions.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIColor+TWToolkitAdditions.h 3 | // TWToolkit 4 | // 5 | // Created by Sam Soffes on 4/19/10. 6 | // Copyright 2010 Tasteful Works, Inc. All rights reserved. 7 | // 8 | 9 | @interface UIColor (TWToolkitAdditions) 10 | 11 | - (CGFloat)alpha; 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /TWToolkit/UIDevice+TWToolkitAdditions.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIDevice+TWToolkitAdditions.h 3 | // TWToolkit 4 | // 5 | // Created by Sam Soffes on 7/13/09. 6 | // Copyright 2009 Tasteful Works, Inc. All rights reserved. 7 | // 8 | 9 | @interface UIDevice (TWToolkitAdditions) 10 | 11 | - (BOOL)isSimulator; 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /TWToolkit/NSArray+TWToolkitAdditions.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSArray+TWToolkitAdditions.h 3 | // TWToolkit 4 | // 5 | // Created by Sam Soffes on 8/19/09. 6 | // Copyright 2009 Tasteful Works, Inc. All rights reserved. 7 | // 8 | 9 | @interface NSArray (TWToolkitAdditions) 10 | 11 | - (NSArray *)shuffledArray; 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /TWToolkit/NSURL+TWToolkitAdditions.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSURL+TWToolkitAdditions.h 3 | // TWToolkit 4 | // 5 | // Created by Sam Soffes on 4/27/10. 6 | // Copyright 2010 Tasteful Works, Inc. All rights reserved. 7 | // 8 | 9 | @interface NSURL (TWToolkitAdditions) 10 | 11 | - (NSDictionary *)queryDictionary; 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /TWToolkit/UIControl+TWToolkitAdditions.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIControl+TWToolkitAdditions.h 3 | // TWToolkit 4 | // 5 | // Created by Sam Soffes on 4/19/10. 6 | // Copyright 2010 Tasteful Works, Inc. All rights reserved. 7 | // 8 | 9 | @interface UIControl (TWToolkitAdditions) 10 | 11 | - (void)removeAllTargets; 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /TWCatalog/Classes/TCRootViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // TCRootViewController.h 3 | // TWCatalog 4 | // 5 | // Created by Sam Soffes on 10/9/09. 6 | // Copyright 2009 Tasteful Works, Inc. All rights reserved. 7 | // 8 | 9 | @interface TCRootViewController : UITableViewController { 10 | 11 | NSArray *data; 12 | } 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /TWCatalog/Classes/TCLineViewDemoViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // TCLineViewDemoViewController.h 3 | // TWCatalog 4 | // 5 | // Created by Sam Soffes on 4/19/10. 6 | // Copyright 2010 Tasteful Works, Inc. All rights reserved. 7 | // 8 | 9 | @interface TCLineViewDemoViewController : UIViewController { 10 | 11 | } 12 | 13 | + (NSString *)title; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /TWToolkit/TWTextField.h: -------------------------------------------------------------------------------- 1 | // 2 | // TWTextField.h 3 | // TWToolkit 4 | // 5 | // Created by Sam Soffes on 3/11/10. 6 | // Copyright 2010 Tasteful Works, Inc. All rights reserved. 7 | // 8 | 9 | @interface TWTextField : UITextField { 10 | 11 | UIEdgeInsets _textInsets; 12 | } 13 | 14 | @property (nonatomic, assign) UIEdgeInsets textInsets; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /TWToolkit/TWConcurrentOperation.h: -------------------------------------------------------------------------------- 1 | // 2 | // TWConcurrentOperation.h 3 | // TWToolkit 4 | // 5 | // Created by Sam Soffes on 8/5/10. 6 | // Copyright 2010 Sam Soffes. All rights reserved. 7 | // 8 | 9 | @interface TWConcurrentOperation : NSOperation { 10 | 11 | BOOL _isExecuting; 12 | BOOL _isFinished; 13 | } 14 | 15 | - (void)finish; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /TWCatalog/Classes/TCPickerDetailViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // TCPickerDetailViewController.h 3 | // TWCatalog 4 | // 5 | // Created by Sam Soffes on 10/9/09. 6 | // Copyright 2009 Tasteful Works, Inc. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface TCPickerDetailViewController : TWPickerViewController { 12 | 13 | } 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /TWToolkit/UIScrollView+TWToolkitAdditions.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIScrollView+TWToolkitAdditions.h 3 | // TWToolkit 4 | // 5 | // Created by Sam Soffes on 4/12/10. 6 | // Copyright 2010 Tasteful Works, Inc. All rights reserved. 7 | // 8 | 9 | @interface UIScrollView (TWToolkitAdditions) 10 | 11 | - (void)scrollToTop; 12 | - (void)scrollToTopAnimated:(BOOL)animated; 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /TWCatalog/Classes/TCMessagesDemoViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // TCMessagesDemoViewController.h 3 | // TWCataglog 4 | // 5 | // Created by Sam Soffes on 3/10/10. 6 | // Copyright 2010 Tasteful Works. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface TCMessagesDemoViewController : TWMessagesViewController { 12 | 13 | } 14 | 15 | + (NSString *)title; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /TWToolkit/UIViewController+TWToolkitAdditions.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIViewController+TWToolkitAdditions.h 3 | // TWToolkit 4 | // 5 | // Created by Sam Soffes on 6/21/10. 6 | // Copyright 2010 Tasteful Works, Inc. All rights reserved. 7 | // 8 | 9 | @interface UIViewController (TWToolkitAdditions) 10 | 11 | - (void)displayError:(NSError *)error; 12 | - (void)displayErrorString:(NSString *)string; 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /Other Sources/TWToolkit_Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // TWToolkit_Prefix.pch 3 | // TWToolkit 4 | // 5 | // Created by Sam Soffes on 9/9/09. 6 | // Copyright 2009 Tasteful Works, Inc. All rights reserved. 7 | // 8 | // Prefix header for all source files of the 'TWToolkit' target in the 'TWToolkit' project. 9 | // 10 | 11 | #ifdef __OBJC__ 12 | #import 13 | #import 14 | #endif 15 | -------------------------------------------------------------------------------- /TWToolkit/TWDrawingMacros.h: -------------------------------------------------------------------------------- 1 | // 2 | // TWDrawingMacros.h 3 | // TWToolkit 4 | // 5 | // Created by Sam Soffes on 4/22/10. 6 | // Copyright 2010 Tasteful Works, Inc. All rights reserved. 7 | // 8 | 9 | #ifndef DEGREES_TO_RADIANS 10 | #define DEGREES_TO_RADIANS(d) ((d) * 0.0174532925199432958) 11 | #endif 12 | 13 | #ifndef RADIANS_TO_DEGREES 14 | #define RADIANS_TO_DEGREES(r) ((r) * 57.29577951308232) 15 | #endif 16 | -------------------------------------------------------------------------------- /TWToolkit/UIColor+TWToolkitAdditions.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIColor+TWToolkitAdditions.m 3 | // TWToolkit 4 | // 5 | // Created by Sam Soffes on 4/19/10. 6 | // Copyright 2010 Tasteful Works, Inc. All rights reserved. 7 | // 8 | 9 | #import "UIColor+TWToolkitAdditions.h" 10 | 11 | @implementation UIColor (TWToolkitAdditions) 12 | 13 | - (CGFloat)alpha { 14 | return CGColorGetAlpha(self.CGColor); 15 | } 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /TWCatalog/Other Sources/TWCatalog_Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // TWCatalog_Prefix.pch 3 | // TWCatalog 4 | // 5 | // Created by Sam Soffes on 9/21/09. 6 | // Copyright 2009 Tasteful Works, Inc. All rights reserved. 7 | // 8 | // Prefix header for all source files of the 'TWCatalog' target in the 'TWCatalog' project 9 | // 10 | 11 | #ifdef __OBJC__ 12 | #import 13 | #import 14 | #endif 15 | -------------------------------------------------------------------------------- /TWCatalog/Classes/TCPickerDemoViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // TCPickerDemoViewController.h 3 | // TWCatalog 4 | // 5 | // Created by Sam Soffes on 10/9/09. 6 | // Copyright 2009 Tasteful Works, Inc. All rights reserved. 7 | // 8 | 9 | @interface TCPickerDemoViewController : UITableViewController { 10 | 11 | NSString *selectedAbbreviation; 12 | } 13 | 14 | @property (nonatomic, retain) NSString *selectedAbbreviation; 15 | 16 | + (NSString *)title; 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /TWCatalog/Classes/TCHUDViewDemoViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // TCHUDViewDemoViewController.h 3 | // TWCatalog 4 | // 5 | // Created by Sam Soffes on 11/18/09. 6 | // Copyright 2009 Tasteful Works, Inc. All rights reserved. 7 | // 8 | 9 | @class TWHUDView; 10 | 11 | @interface TCHUDViewDemoViewController : UIViewController { 12 | 13 | TWHUDView *hud; 14 | } 15 | 16 | + (NSString *)title; 17 | 18 | - (void)complete:(id)sender; 19 | - (void)pop:(id)sender; 20 | 21 | @end 22 | -------------------------------------------------------------------------------- /TWCatalog/Other Sources/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // TWCatalog 4 | // 5 | // Created by Sam Soffes on 9/21/09. 6 | // Copyright 2009 Tasteful Works, Inc. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | int main(int argc, char *argv[]) { 12 | 13 | NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; 14 | int retVal = UIApplicationMain(argc, argv, nil, @"TCAppDelegate"); 15 | [pool release]; 16 | return retVal; 17 | } 18 | -------------------------------------------------------------------------------- /TWCatalog/Classes/TCGradientViewDemoViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // TCGradientViewDemoViewController.h 3 | // TWCatalog 4 | // 5 | // Created by Sam Soffes on 10/27/09. 6 | // Copyright 2009 Tasteful Works, Inc. All rights reserved. 7 | // 8 | 9 | @class TWGradientView; 10 | 11 | @interface TCGradientViewDemoViewController : UIViewController { 12 | 13 | TWGradientView *gradientView; 14 | } 15 | 16 | + (NSString *)title; 17 | 18 | - (void)changeColor:(id)sender; 19 | 20 | @end 21 | -------------------------------------------------------------------------------- /TWToolkit/TWTextView.h: -------------------------------------------------------------------------------- 1 | // 2 | // TWTextView.h 3 | // TWToolkit 4 | // 5 | // Created by Sam Soffes on 8/18/10. 6 | // Copyright 2010 Tasteful Works, Inc. All rights reserved. 7 | // 8 | 9 | @interface TWTextView : UITextView { 10 | 11 | NSString *_placeholder; 12 | UIColor *_placeholderColor; 13 | 14 | BOOL _shouldDrawPlaceholder; 15 | } 16 | 17 | @property (nonatomic, retain) NSString *placeholder; 18 | @property (nonatomic, retain) UIColor *placeholderColor; 19 | 20 | @end 21 | -------------------------------------------------------------------------------- /TWToolkit/UIDevice+TWToolkitAdditions.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIDevice+TWToolkitAdditions.m 3 | // TWToolkit 4 | // 5 | // Created by Sam Soffes on 7/13/09. 6 | // Copyright 2009 Tasteful Works, Inc. All rights reserved. 7 | // 8 | 9 | #import "UIDevice+TWToolkitAdditions.h" 10 | 11 | @implementation UIDevice (TWToolkitAdditions) 12 | 13 | - (BOOL)isSimulator { 14 | 15 | static NSString *simulatorModel = @"iPhone Simulator"; 16 | 17 | return [[self model] isEqual:simulatorModel]; 18 | } 19 | 20 | @end 21 | -------------------------------------------------------------------------------- /TWCatalog/Classes/TCAppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // TCAppDelegate.h 3 | // TWCatalog 4 | // 5 | // Created by Sam Soffes on 9/21/09. 6 | // Copyright 2009 Tasteful Works, Inc. All rights reserved. 7 | // 8 | 9 | @interface TCAppDelegate : NSObject { 10 | 11 | UIWindow *window; 12 | UINavigationController *navigationController; 13 | } 14 | 15 | @property (nonatomic, retain) UIWindow *window; 16 | @property (nonatomic, retain) UINavigationController *navigationController; 17 | 18 | @end 19 | 20 | -------------------------------------------------------------------------------- /TWToolkit/UIControl+TWToolkitAdditions.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIControl+TWToolkitAdditions.m 3 | // TWToolkit 4 | // 5 | // Created by Sam Soffes on 4/19/10. 6 | // Copyright 2010 Tasteful Works, Inc. All rights reserved. 7 | // 8 | 9 | #import "UIControl+TWToolkitAdditions.h" 10 | 11 | @implementation UIControl (TWToolkitAdditions) 12 | 13 | - (void)removeAllTargets { 14 | for (id target in [self allTargets]) { 15 | [self removeTarget:target action:NULL forControlEvents:UIControlEventAllEvents]; 16 | } 17 | } 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /TWCatalog/Classes/TCPieProgressViewDemoViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // TCPieProgressViewDemoViewController.h 3 | // TWCatalog 4 | // 5 | // Created by Sam Soffes on 4/22/10. 6 | // Copyright 2010 Tasteful Works, Inc. All rights reserved. 7 | // 8 | 9 | @class TWPieProgressView; 10 | 11 | @interface TCPieProgressViewDemoViewController : UIViewController { 12 | 13 | TWPieProgressView *progressView7; 14 | NSTimer *timer; 15 | } 16 | 17 | + (NSString *)title; 18 | 19 | - (void)incrementProgress:(NSTimer *)timer; 20 | 21 | @end 22 | -------------------------------------------------------------------------------- /TWToolkit/UIImage+TWToolkitAdditions.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIImage+TWToolkitAdditions.h 3 | // TWToolkit 4 | // 5 | // Created by Sam Soffes on 11/17/09. 6 | // Copyright 2009 Tasteful Works, Inc. All rights reserved. 7 | // 8 | 9 | @interface UIImage (TWToolkitAdditions) 10 | 11 | + (UIImage *)imageNamed:(NSString *)imageName bundle:(NSString *)bundleName; 12 | 13 | - (UIImage *)initWithImage:(UIImage *)image croppedToRect:(CGRect)rect; 14 | - (UIImage *)imageCroppedToRect:(CGRect)rect; 15 | 16 | - (UIImage *)squareImage; 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /TWToolkit/TWLineView.h: -------------------------------------------------------------------------------- 1 | // 2 | // TWLineView.h 3 | // TWToolkit 4 | // 5 | // Created by Sam Soffes on 4/12/10. 6 | // Copyright 2010 Tasteful Works, Inc. All rights reserved. 7 | // 8 | 9 | @interface TWLineView : UIView { 10 | 11 | UIColor *_lineColor; 12 | UIColor *_insetColor; 13 | BOOL _showInset; 14 | 15 | @private 16 | 17 | BOOL _hasDrawn; 18 | } 19 | 20 | @property (nonatomic, retain) UIColor *lineColor; 21 | @property (nonatomic, retain) UIColor *insetColor; 22 | @property (nonatomic, assign) BOOL showInset; 23 | 24 | @end 25 | -------------------------------------------------------------------------------- /TWToolkit/UIScrollView+TWToolkitAdditions.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIScrollView+TWToolkitAdditions.m 3 | // TWToolkit 4 | // 5 | // Created by Sam Soffes on 4/12/10. 6 | // Copyright 2010 Tasteful Works, Inc. All rights reserved. 7 | // 8 | 9 | #import "UIScrollView+TWToolkitAdditions.h" 10 | 11 | @implementation UIScrollView (TWToolkitAdditions) 12 | 13 | - (void)scrollToTop { 14 | [self scrollToTopAnimated:NO]; 15 | } 16 | 17 | 18 | - (void)scrollToTopAnimated:(BOOL)animated { 19 | [self setContentOffset:CGPointMake(0.0, 0.0) animated:animated]; 20 | } 21 | 22 | @end 23 | -------------------------------------------------------------------------------- /TWToolkit/NSDate+TWToolkitAdditions.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSDate+TWToolkitAdditions.h 3 | // TWToolkit 4 | // 5 | // Created by Sam Soffes on 5/26/10. 6 | // Copyright 2010 Tasteful Works, Inc. All rights reserved. 7 | // 8 | 9 | @interface NSDate (TWToolkitAdditions) 10 | 11 | + (NSDate *)dateFromISO8601String:(NSString *)string; 12 | - (NSString *)ISO8601String; 13 | 14 | // Adapted from http://github.com/gabriel/gh-kit/blob/master/Classes/GHNSString+TimeInterval.m 15 | - (NSString *)timeAgoInWords; 16 | - (NSString *)timeAgoInWordsIncludingSeconds:(BOOL)includeSeconds; 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /TWToolkit/TWModalViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // TWModalViewController.h 3 | // TWToolkit 4 | // 5 | // Created by Sam Soffes on 7/14/10. 6 | // Copyright 2010 Tasteful Works. All rights reserved. 7 | // 8 | 9 | @class TWViewController; 10 | 11 | @protocol TWModalViewController 12 | 13 | @required 14 | 15 | @property (nonatomic, assign) TWViewController *modalParentViewController; 16 | 17 | - (UIView *)view; 18 | 19 | @optional 20 | 21 | - (void)viewWillAppear:(BOOL)animated; 22 | - (void)viewDidAppear:(BOOL)animated; 23 | - (void)viewWillDisappear:(BOOL)animated; 24 | - (void)viewDidDisappear:(BOOL)animated; 25 | 26 | @end 27 | -------------------------------------------------------------------------------- /TWToolkit/TWMessageTableViewCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // TWMessageTableViewCell.h 3 | // Messages 4 | // 5 | // Created by Sam Soffes on 3/10/10. 6 | // Copyright 2010 Tasteful Works. All rights reserved. 7 | // 8 | 9 | typedef enum { 10 | TWMessageTableViewCellMessageStyleGray = 0, 11 | TWMessageTableViewCellMessageStyleGreen = 1 12 | } TWMessageTableViewCellMessageStyle; 13 | 14 | @class TWMessageTableViewCellBubbleView; 15 | 16 | @interface TWMessageTableViewCell : UITableViewCell { 17 | 18 | TWMessageTableViewCellBubbleView *bubbleView; 19 | } 20 | 21 | @property (nonatomic, copy) NSString *messageText; 22 | @property (nonatomic, assign) TWMessageTableViewCellMessageStyle messageStyle; 23 | 24 | @end 25 | -------------------------------------------------------------------------------- /TWToolkit/TWLoadingView.h: -------------------------------------------------------------------------------- 1 | // 2 | // TWLoadingView.h 3 | // TWToolkit 4 | // 5 | // Created by Sam Soffes on 7/8/09. 6 | // Copyright 2009 Tasteful Works, Inc. All rights reserved. 7 | // 8 | 9 | @interface TWLoadingView : UIView { 10 | 11 | UIActivityIndicatorView *_activityIndicator; 12 | NSString *_text; 13 | UIFont *_font; 14 | UIColor *_textColor; 15 | UIColor *_shadowColor; 16 | } 17 | 18 | @property (nonatomic, retain, readonly) UIActivityIndicatorView *activityIndicator; 19 | @property (nonatomic, copy) NSString *text; 20 | @property (nonatomic, retain) UIFont *font; 21 | @property (nonatomic, retain) UIColor *textColor; 22 | @property (nonatomic, retain) UIColor *shadowColor; 23 | 24 | @end 25 | -------------------------------------------------------------------------------- /TWToolkit/NSData+TWToolkitAdditions.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSData+TWToolkitAdditions.m 3 | // TWToolkit 4 | // 5 | // Created by Sam Soffes on 9/29/08. 6 | // Copyright 2009 Tasteful Works, Inc. All rights reserved. 7 | // 8 | 9 | #import "NSData+TWToolkitAdditions.h" 10 | #include 11 | 12 | @implementation NSData (TWToolkitAdditions) 13 | 14 | - (NSString *)MD5Sum { 15 | unsigned char digest[CC_MD5_DIGEST_LENGTH], i; 16 | CC_MD5([self bytes], [self length], digest); 17 | NSMutableString *ms = [NSMutableString string]; 18 | for (i = 0; i < CC_MD5_DIGEST_LENGTH; i++) { 19 | [ms appendFormat: @"%02x", (int)(digest[i])]; 20 | } 21 | return [[ms copy] autorelease]; 22 | } 23 | 24 | @end 25 | -------------------------------------------------------------------------------- /TWToolkit/TWIndicatorLabel.h: -------------------------------------------------------------------------------- 1 | // 2 | // TWIndicatorLabel.h 3 | // TWToolkit 4 | // 5 | // Created by Sam Soffes on 7/13/10. 6 | // Copyright 2010 Tasteful Works, Inc. All rights reserved. 7 | // 8 | 9 | @interface TWIndicatorLabel : UIView { 10 | 11 | UILabel *_label; 12 | UIActivityIndicatorView *_indicator; 13 | BOOL _loading; 14 | } 15 | 16 | @property (nonatomic, retain, readonly) UILabel *label; 17 | @property (nonatomic, retain, readonly) UIActivityIndicatorView *indicator; 18 | @property (nonatomic, assign, getter=isLoading) BOOL loading; 19 | 20 | + (CGSize)indicatorSize; 21 | + (CGFloat)padding; 22 | 23 | - (void)startWithText:(NSString *)text; 24 | - (void)completeWithText:(NSString *)text; 25 | 26 | @end 27 | -------------------------------------------------------------------------------- /TWToolkit/TWPieProgressView.h: -------------------------------------------------------------------------------- 1 | // 2 | // TWPieProgressView.h 3 | // TWToolkit 4 | // 5 | // Created by Sam Soffes on 4/22/10. 6 | // Copyright 2010 Tasteful Works, Inc. All rights reserved. 7 | // 8 | 9 | @interface TWPieProgressView : UIView { 10 | 11 | CGFloat _progress; 12 | CGFloat _pieBorderWidth; 13 | UIColor *_pieBorderColor; 14 | UIColor *_pieFillColor; 15 | UIColor *_pieBackgroundColor; 16 | 17 | @private 18 | 19 | BOOL _hasDrawn; 20 | } 21 | 22 | @property (nonatomic, assign) CGFloat progress; 23 | @property (nonatomic, assign) CGFloat pieBorderWidth; 24 | @property (nonatomic, retain) UIColor *pieBorderColor; 25 | @property (nonatomic, retain) UIColor *pieFillColor; 26 | @property (nonatomic, retain) UIColor *pieBackgroundColor; 27 | 28 | @end 29 | -------------------------------------------------------------------------------- /TWToolkit/NSArray+TWToolkitAdditions.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSArray+TWToolkitAdditions.m 3 | // TWToolkit 4 | // 5 | // Created by Sam Soffes on 8/19/09. 6 | // Copyright 2009 Tasteful Works, Inc. All rights reserved. 7 | // 8 | 9 | #import "NSArray+TWToolkitAdditions.h" 10 | 11 | @implementation NSArray (TWToolkitAdditions) 12 | 13 | - (NSArray *)shuffledArray { 14 | 15 | NSMutableArray *array = [NSMutableArray arrayWithCapacity:[self count]]; 16 | 17 | NSMutableArray *copy = [self mutableCopy]; 18 | while ([copy count] > 0) { 19 | int index = arc4random() % [copy count]; 20 | id objectToMove = [copy objectAtIndex:index]; 21 | [array addObject:objectToMove]; 22 | [copy removeObjectAtIndex:index]; 23 | } 24 | 25 | [copy release]; 26 | return array; 27 | } 28 | 29 | @end 30 | -------------------------------------------------------------------------------- /TWToolkit/TWLabel.h: -------------------------------------------------------------------------------- 1 | // 2 | // TWLabel.h 3 | // TWToolkit 4 | // 5 | // Created by Sam Soffes on 7/12/10. 6 | // Copyright 2010 Tasteful Works, Inc. All rights reserved. 7 | // 8 | 9 | typedef enum { 10 | TWLabelVerticalTextAlignmentCenter = UIControlContentVerticalAlignmentCenter, 11 | TWLabelVerticalTextAlignmentTop = UIControlContentVerticalAlignmentTop, 12 | TWLabelVerticalTextAlignmentBottom = UIControlContentVerticalAlignmentBottom 13 | } TWLabelVerticalTextAlignment; 14 | 15 | @interface TWLabel : UILabel { 16 | 17 | TWLabelVerticalTextAlignment _verticalTextAlignment; 18 | UIEdgeInsets _textInsets; 19 | } 20 | 21 | @property (nonatomic, assign) TWLabelVerticalTextAlignment verticalTextAlignment; 22 | @property (nonatomic, assign) UIEdgeInsets textInsets; 23 | 24 | @end 25 | -------------------------------------------------------------------------------- /TWToolkit/TWTextField.m: -------------------------------------------------------------------------------- 1 | // 2 | // TWTextField.m 3 | // TWToolkit 4 | // 5 | // Created by Sam Soffes on 3/11/10. 6 | // Copyright 2010 Tasteful Works, Inc. All rights reserved. 7 | // 8 | 9 | #import "TWTextField.h" 10 | 11 | @implementation TWTextField 12 | 13 | @synthesize textInsets = _textInsets; 14 | 15 | #pragma mark UIView 16 | 17 | - (id)initWithFrame:(CGRect)frame { 18 | if ((self = [super initWithFrame:frame])) { 19 | self.textInsets = UIEdgeInsetsZero; 20 | } 21 | return self; 22 | } 23 | 24 | #pragma mark UITextField 25 | 26 | - (CGRect)textRectForBounds:(CGRect)bounds { 27 | return UIEdgeInsetsInsetRect(bounds, self.textInsets); 28 | } 29 | 30 | 31 | - (CGRect)editingRectForBounds:(CGRect)bounds { 32 | return [self textRectForBounds:bounds]; 33 | } 34 | 35 | @end 36 | -------------------------------------------------------------------------------- /TWToolkit/NSString+TWToolkitAdditions.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSString+TWToolkitAdditions.h 3 | // TWToolkit 4 | // 5 | // Created by Sam Soffes on 6/22/09. 6 | // Copyright 2009 Tasteful Works, Inc. All rights reserved. 7 | // 8 | 9 | @interface NSString (TWToolkitAdditions) 10 | 11 | - (BOOL)containsString:(NSString *)string; 12 | - (NSString *)MD5Sum; 13 | - (NSComparisonResult)compareToVersionString:(NSString *)version; 14 | 15 | // Localization 16 | + (NSString *)localizedString:(NSString*)key; 17 | 18 | // HTML 19 | - (NSString *)escapeHTML; 20 | - (NSString *)unescapeHTML; 21 | 22 | // URL 23 | - (NSString *)URLEncodedString; 24 | - (NSString *)URLEncodedParameterString; 25 | - (NSString *)URLDecodedString; 26 | - (NSString *)removeQuotes; 27 | 28 | // Base64 29 | - (NSString *)base64EncodedString; 30 | 31 | @end 32 | -------------------------------------------------------------------------------- /TWToolkit/TWMessageTableViewCellBubbleView.h: -------------------------------------------------------------------------------- 1 | // 2 | // TWMessageTableViewCellBubbleView.h 3 | // Messages 4 | // 5 | // Created by Sam Soffes on 3/10/10. 6 | // Copyright 2010 Tasteful Works. All rights reserved. 7 | // 8 | 9 | #import "TWMessageTableViewCell.h" 10 | 11 | @interface TWMessageTableViewCellBubbleView : UIView { 12 | 13 | NSString *messageText; 14 | TWMessageTableViewCellMessageStyle messageStyle; 15 | } 16 | 17 | @property (nonatomic, copy) NSString *messageText; 18 | @property (nonatomic, assign) TWMessageTableViewCellMessageStyle messageStyle; 19 | 20 | + (UIImage *)bubbleImageForMessageStyle:(TWMessageTableViewCellMessageStyle)aMessageStyle; 21 | + (CGSize)textSizeForText:(NSString *)text; 22 | + (CGSize)bubbleSizeForText:(NSString *)text; 23 | + (CGFloat)cellHeightForText:(NSString *)text; 24 | 25 | @end 26 | -------------------------------------------------------------------------------- /TWToolkit/UIViewController+TWToolkitAdditions.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIViewController+TWToolkitAdditions.m 3 | // TWToolkit 4 | // 5 | // Created by Sam Soffes on 6/21/10. 6 | // Copyright 2010 Tasteful Works, Inc. All rights reserved. 7 | // 8 | 9 | #import "UIViewController+TWToolkitAdditions.h" 10 | 11 | @implementation UIViewController (TWToolkitAdditions) 12 | 13 | - (void)displayError:(NSError *)error { 14 | if (!error) { 15 | return; 16 | } 17 | 18 | [self displayErrorString:[error localizedDescription]]; 19 | } 20 | 21 | 22 | - (void)displayErrorString:(NSString *)string { 23 | if (!string || [string length] < 1) { 24 | return; 25 | } 26 | 27 | UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error" message:string delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil]; 28 | [alert show]; 29 | [alert release]; 30 | } 31 | 32 | @end 33 | -------------------------------------------------------------------------------- /TWToolkit/TWCategories.h: -------------------------------------------------------------------------------- 1 | // 2 | // TWCategories.h 3 | // TWToolkit 4 | // 5 | // Created by Sam Soffes on 9/17/09. 6 | // Copyright 2009 Tasteful Works, Inc. All rights reserved. 7 | // 8 | 9 | // Foundation 10 | #import 11 | #import 12 | #import 13 | #import 14 | #import 15 | 16 | // UIKit 17 | #import 18 | #import 19 | #import 20 | #import 21 | #import 22 | #import 23 | #import 24 | -------------------------------------------------------------------------------- /TWToolkit/UIView+TWToolkitAdditions.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+imageRepresentation.h 3 | // TWToolkit 4 | // 5 | // Created by Sam Soffes on 2/15/10. 6 | // Copyright 2010 Tasteful Works. All rights reserved. 7 | // 8 | 9 | @interface UIView (imageRepresentation) 10 | 11 | - (UIImage *)imageRepresentation; 12 | 13 | - (void)hide; 14 | - (void)show; 15 | 16 | - (void)fadeOut; 17 | - (void)fadeOutAndPerformSelector:(SEL)selector; 18 | - (void)fadeOutAndPerformSelector:(SEL)selector withObject:(id)object; 19 | 20 | - (void)fadeIn; 21 | - (void)fadeInAndPerformSelector:(SEL)selector; 22 | - (void)fadeInAndPerformSelector:(SEL)selector withObject:(id)object; 23 | 24 | - (void)fadeAlphaTo:(CGFloat)targetAlpha; 25 | - (void)fadeAlphaTo:(CGFloat)targetAlpha andPerformSelector:(SEL)selector; 26 | - (void)fadeAlphaTo:(CGFloat)targetAlpha andPerformSelector:(SEL)selector withObject:(id)object; 27 | 28 | @end 29 | -------------------------------------------------------------------------------- /TWToolkit/TWPickerViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // TWPickerViewController.h 3 | // TWToolkit 4 | // 5 | // This is an abstract class for displaying a UITableView with 6 | // a list of items for the user to choose. A subclass should 7 | // override the - (void)loadObjects and 8 | // - (NSString *)cellTextForObject:(id)anObject methods to 9 | // customize this class. 10 | // 11 | // Created by Sam Soffes on 10/9/08. 12 | // Copyright 2009 Tasteful Works, Inc. All rights reserved. 13 | // 14 | 15 | @interface TWPickerViewController : UITableViewController { 16 | 17 | NSArray *_keys; 18 | NSString *_selectedKey; 19 | NSIndexPath *_currentIndexPath; 20 | } 21 | 22 | @property (nonatomic, retain) NSArray *keys; 23 | @property (nonatomic, retain) NSString *selectedKey; 24 | @property (nonatomic, retain) NSIndexPath *currentIndexPath; 25 | 26 | - (void)loadKeys; 27 | - (NSString *)cellTextForKey:(NSString *)key; 28 | 29 | @end 30 | -------------------------------------------------------------------------------- /TWToolkit/TWToolkit.h: -------------------------------------------------------------------------------- 1 | // 2 | // TWToolkit.h 3 | // TWToolkit 4 | // 5 | // Created by Sam Soffes on 3/19/09. 6 | // Copyright 2009 Tasteful Works, Inc. All rights reserved. 7 | // 8 | 9 | // Views 10 | #import 11 | #import 12 | #import 13 | #import 14 | #import 15 | #import 16 | #import 17 | #import 18 | #import 19 | #import 20 | 21 | // View Controllers 22 | #import 23 | #import 24 | #import 25 | #import 26 | 27 | // Drawing 28 | #import 29 | 30 | // Misc 31 | #import 32 | #import 33 | -------------------------------------------------------------------------------- /TWToolkit/NSURL+TWToolkitAdditions.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSURL+TWToolkitAdditions.m 3 | // TWToolkit 4 | // 5 | // Created by Sam Soffes on 4/27/10. 6 | // Copyright 2010 Tasteful Works, Inc. All rights reserved. 7 | // 8 | 9 | #import "NSURL+TWToolkitAdditions.h" 10 | 11 | @implementation NSURL (TWToolkitAdditions) 12 | 13 | // Not a perfect implementation, but will work for most cases 14 | - (NSDictionary *)queryDictionary { 15 | NSArray *components = [[self query] componentsSeparatedByString:@"&"]; 16 | NSMutableDictionary *dictionary = [[NSMutableDictionary alloc] initWithCapacity:[components count]]; 17 | for (NSString *component in components) { 18 | NSArray *keyValue = [component componentsSeparatedByString:@"="]; 19 | [dictionary setObject:[[keyValue objectAtIndex:1] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding] forKey:[[keyValue objectAtIndex:0] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding]]; 20 | } 21 | return [dictionary autorelease]; 22 | } 23 | 24 | @end 25 | -------------------------------------------------------------------------------- /TWCatalog/Resources/TWCatalog-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | English 7 | CFBundleDisplayName 8 | ${PRODUCT_NAME} 9 | CFBundleExecutable 10 | ${EXECUTABLE_NAME} 11 | CFBundleIconFile 12 | Icon.png 13 | UIPrerenderedIcon 14 | 15 | CFBundleIdentifier 16 | com.tastefulworks.twcatalog 17 | CFBundleInfoDictionaryVersion 18 | 6.0 19 | CFBundleName 20 | ${PRODUCT_NAME} 21 | CFBundlePackageType 22 | APPL 23 | CFBundleSignature 24 | ???? 25 | CFBundleVersion 26 | 1.0 27 | LSRequiresIPhoneOS 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /TWToolkit/TWViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // TWViewController.h 3 | // TWToolkit 4 | // 5 | // Created by Sam Soffes on 7/14/10. 6 | // Copyright 2010 Tasteful Works. All rights reserved. 7 | // 8 | // TODO: Support iPhone and iPhone 4 9 | // 10 | 11 | #import "TWModalViewController.h" 12 | 13 | @interface TWViewController : UIViewController { 14 | 15 | TWViewController *_modalParentViewController; 16 | 17 | id _customModalViewController; 18 | UIView *_modalContainerView; 19 | UIImageView *_modalContainerBackgroundView; 20 | UIImageView *_vignetteView; 21 | } 22 | 23 | @property (nonatomic, assign) TWViewController *modalParentViewController; 24 | @property (nonatomic, retain, readonly) UIViewController *customModalViewController; 25 | 26 | - (void)layoutViews; 27 | - (void)layoutViewsWithOrientation:(UIInterfaceOrientation)orientation; 28 | 29 | - (void)presentCustomModalViewController:(id)viewController; 30 | - (void)dismissCustomModalViewController; 31 | 32 | @end 33 | -------------------------------------------------------------------------------- /TWToolkit/TWHUDView.h: -------------------------------------------------------------------------------- 1 | // 2 | // TWHUDView.h 3 | // TWToolkit 4 | // 5 | // Created by Sam Soffes on 9/29/09. 6 | // Copyright 2009 Tasteful Works, Inc. All rights reserved. 7 | // 8 | 9 | @interface TWHUDView : UIAlertView { 10 | 11 | UILabel *_textLabel; 12 | UIActivityIndicatorView *_activityIndicator; 13 | BOOL _loading; 14 | BOOL _successful; 15 | } 16 | 17 | @property (nonatomic, retain, readonly) UILabel *textLabel; 18 | @property (nonatomic, retain, readonly) UIActivityIndicatorView *activityIndicator; 19 | @property (nonatomic, assign, getter=isLoading) BOOL loading; 20 | @property (nonatomic, assign, getter=isSuccessful) BOOL successful; 21 | 22 | - (id)initWithTitle:(NSString *)aTitle; 23 | - (id)initWithTitle:(NSString *)aTitle loading:(BOOL)isLoading; 24 | - (void)completeWithTitle:(NSString *)aTitle; 25 | - (void)completeAndDismissWithTitle:(NSString *)aTitle; 26 | - (void)failWithTitle:(NSString *)aTitle; 27 | - (void)failAndDismissWithTitle:(NSString *)aTitle; 28 | - (void)dismiss; 29 | - (void)dismissAnimated:(BOOL)animated; 30 | 31 | @end 32 | -------------------------------------------------------------------------------- /TWToolkit/TWKeychain.h: -------------------------------------------------------------------------------- 1 | // 2 | // TWKeychain.h 3 | // TWToolkit 4 | // 5 | // Created by Sam Soffes on 5/19/10. 6 | // Copyright 2009 Tasteful Works, Inc. All rights reserved. 7 | // 8 | 9 | enum { 10 | TWKeychainErrorBadArguments = -1001, 11 | TWKeychainErrorNoPassword = -1002 12 | }; 13 | 14 | extern NSString *TWKeychainErrorDomain; 15 | 16 | @interface TWKeychain : NSObject 17 | 18 | + (TWKeychain *)defaultKeychain; 19 | 20 | + (NSString *)passwordForService:(NSString *)service account:(NSString *)account; 21 | + (NSString *)passwordForService:(NSString *)service account:(NSString *)account error:(NSError **)error; 22 | 23 | + (BOOL)deletePasswordForService:(NSString *)service account:(NSString *)account; 24 | + (BOOL)deletePasswordForService:(NSString *)service account:(NSString *)account error:(NSError **)error; 25 | 26 | + (BOOL)setPassword:(NSString *)password forService:(NSString *)service account:(NSString *)account; 27 | + (BOOL)setPassword:(NSString *)password forService:(NSString *)service account:(NSString *)account error:(NSError **)error; 28 | 29 | @end 30 | -------------------------------------------------------------------------------- /TWToolkit/TWMessagesViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // TWMessagesViewController.h 3 | // Messages 4 | // 5 | // This is an abstract class for displaying a UI similar 6 | // to Apple's SMS application. A subclass should 7 | // override the messageStyleForRowAtIndexPath: and 8 | // textForRowAtIndexPath: to customize this class. 9 | // 10 | // This is still a work in progress and likely to change 11 | // at any time. 12 | // 13 | // Created by Sam Soffes on 3/10/10. 14 | // Copyright 2010 Tasteful Works. All rights reserved. 15 | // 16 | 17 | #import "TWMessageTableViewCell.h" 18 | 19 | @class TWGradientView; 20 | 21 | @interface TWMessagesViewController : UIViewController { 22 | 23 | UITableView *_tableView; 24 | TWGradientView *_inputView; 25 | UIButton *_sendButton; 26 | } 27 | 28 | @property (nonatomic, retain, readonly) UITableView *tableView; 29 | 30 | - (TWMessageTableViewCellMessageStyle)messageStyleForRowAtIndexPath:(NSIndexPath *)indexPath; 31 | - (NSString *)textForRowAtIndexPath:(NSIndexPath *)indexPath; 32 | 33 | @end 34 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2010 Tasteful Works, Inc. 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /TWCatalog/Classes/TCLineViewDemoViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // TCLineViewDemoViewController.m 3 | // TWCatalog 4 | // 5 | // Created by Sam Soffes on 4/19/10. 6 | // Copyright 2010 Tasteful Works, Inc. All rights reserved. 7 | // 8 | 9 | #import "TCLineViewDemoViewController.h" 10 | #import 11 | 12 | @implementation TCLineViewDemoViewController 13 | 14 | #pragma mark - 15 | #pragma mark Class Methods 16 | #pragma mark - 17 | 18 | + (NSString *)title { 19 | return @"Line View"; 20 | } 21 | 22 | 23 | #pragma mark - 24 | #pragma mark UIViewController 25 | #pragma mark - 26 | 27 | - (void)viewDidLoad { 28 | [super viewDidLoad]; 29 | self.title = [[self class] title]; 30 | self.view.backgroundColor = [UIColor groupTableViewBackgroundColor]; 31 | 32 | TWLineView *lineView1 = [[TWLineView alloc] initWithFrame:CGRectMake(20.0, 20.0, 280.0, 2.0)]; 33 | [self.view addSubview:lineView1]; 34 | [lineView1 release]; 35 | 36 | TWLineView *lineView2 = [[TWLineView alloc] initWithFrame:CGRectMake(20.0, 42.0, 280.0, 2.0)]; 37 | lineView2.lineColor = [UIColor blueColor]; 38 | [self.view addSubview:lineView2]; 39 | [lineView2 release]; 40 | } 41 | 42 | @end 43 | -------------------------------------------------------------------------------- /TWToolkit/TWConcurrentOperation.m: -------------------------------------------------------------------------------- 1 | // 2 | // TWConcurrentOperation.m 3 | // TWToolkit 4 | // 5 | // Created by Sam Soffes on 8/5/10. 6 | // Copyright 2010 Sam Soffes. All rights reserved. 7 | // 8 | 9 | #import "TWConcurrentOperation.h" 10 | 11 | @implementation TWConcurrentOperation 12 | 13 | #pragma mark NSObject 14 | 15 | - (id)init { 16 | if ((self = [super init])) { 17 | _isExecuting = NO; 18 | _isFinished = NO; 19 | } 20 | return self; 21 | } 22 | 23 | 24 | #pragma mark NSOperation 25 | 26 | - (BOOL)isConcurrent { 27 | return YES; 28 | } 29 | 30 | 31 | - (BOOL)isExecuting { 32 | return _isExecuting; 33 | } 34 | 35 | 36 | - (BOOL)isFinished { 37 | return _isFinished; 38 | } 39 | 40 | 41 | - (void)start { 42 | [self willChangeValueForKey:@"isExecuting"]; 43 | _isExecuting = YES; 44 | [self didChangeValueForKey:@"isExecuting"]; 45 | } 46 | 47 | 48 | #pragma mark TWConcurrentOperation 49 | 50 | - (void)finish { 51 | [self willChangeValueForKey:@"isExecuting"]; 52 | [self willChangeValueForKey:@"isFinished"]; 53 | 54 | _isExecuting = NO; 55 | _isFinished = YES; 56 | 57 | [self didChangeValueForKey:@"isExecuting"]; 58 | [self didChangeValueForKey:@"isFinished"]; 59 | } 60 | 61 | 62 | @end 63 | -------------------------------------------------------------------------------- /TWCatalog/Classes/TCAppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // TCAppDelegate.m 3 | // TWCatalog 4 | // 5 | // Created by Sam Soffes on 9/21/09. 6 | // Copyright 2009 Tasteful Works, Inc. All rights reserved. 7 | // 8 | 9 | #import "TCAppDelegate.h" 10 | #import "TCRootViewController.h" 11 | 12 | @implementation TCAppDelegate 13 | 14 | @synthesize window; 15 | @synthesize navigationController; 16 | 17 | #pragma mark - 18 | #pragma mark NSObject 19 | #pragma mark - 20 | 21 | - (void)dealloc { 22 | [navigationController release]; 23 | [window release]; 24 | [super dealloc]; 25 | } 26 | 27 | 28 | #pragma mark - 29 | #pragma mark UIApplicationDelegate 30 | #pragma mark - 31 | 32 | - (void)applicationDidFinishLaunching:(UIApplication *)application { 33 | 34 | window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; 35 | 36 | TCRootViewController *viewController = [[TCRootViewController alloc] initWithStyle:UITableViewStyleGrouped]; 37 | UINavigationController *aNavigationController = [[UINavigationController alloc] initWithRootViewController:viewController]; 38 | 39 | self.navigationController = aNavigationController; 40 | 41 | [viewController release]; 42 | [aNavigationController release]; 43 | 44 | [window addSubview:navigationController.view]; 45 | [window makeKeyAndVisible]; 46 | } 47 | 48 | @end 49 | -------------------------------------------------------------------------------- /TWToolkit/TWLabel.m: -------------------------------------------------------------------------------- 1 | // 2 | // TWLabel.m 3 | // TWToolkit 4 | // 5 | // Created by Sam Soffes on 7/12/10. 6 | // Copyright 2010 Tasteful Works, Inc. All rights reserved. 7 | // 8 | 9 | #import "TWLabel.h" 10 | 11 | @implementation TWLabel 12 | 13 | @synthesize verticalTextAlignment = _verticalTextAlignment; 14 | @synthesize textInsets = _textInsets; 15 | 16 | #pragma mark UIView 17 | 18 | - (id)initWithFrame:(CGRect)aFrame { 19 | if ((self = [super initWithFrame:aFrame])) { 20 | self.verticalTextAlignment = TWLabelVerticalTextAlignmentTop; 21 | self.textInsets = UIEdgeInsetsZero; 22 | } 23 | return self; 24 | } 25 | 26 | #pragma mark UILabel 27 | 28 | - (void)drawTextInRect:(CGRect)rect { 29 | rect = UIEdgeInsetsInsetRect(rect, self.textInsets); 30 | 31 | if (self.verticalTextAlignment == TWLabelVerticalTextAlignmentTop) { 32 | CGSize sizeThatFits = [self sizeThatFits:rect.size]; 33 | rect = CGRectMake(rect.origin.x, rect.origin.y, rect.size.width, sizeThatFits.height); 34 | } else if (self.verticalTextAlignment == TWLabelVerticalTextAlignmentBottom) { 35 | CGSize sizeThatFits = [self sizeThatFits:rect.size]; 36 | rect = CGRectMake(rect.origin.x, rect.origin.y + (rect.size.height - sizeThatFits.height), rect.size.width, sizeThatFits.height); 37 | } 38 | 39 | [super drawTextInRect:rect]; 40 | } 41 | 42 | @end 43 | -------------------------------------------------------------------------------- /TWCatalog/Classes/TCHUDViewDemoViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // TCHUDViewDemoViewController.m 3 | // TWCatalog 4 | // 5 | // Created by Sam Soffes on 11/18/09. 6 | // Copyright 2009 Tasteful Works, Inc. All rights reserved. 7 | // 8 | 9 | #import "TCHUDViewDemoViewController.h" 10 | #import 11 | 12 | @implementation TCHUDViewDemoViewController 13 | 14 | #pragma mark - 15 | #pragma mark Class Methods 16 | #pragma mark - 17 | 18 | + (NSString *)title { 19 | return @"HUD View"; 20 | } 21 | 22 | 23 | #pragma mark - 24 | #pragma mark NSObject 25 | #pragma mark - 26 | 27 | - (void)dealloc { 28 | [hud release]; 29 | [super dealloc]; 30 | } 31 | 32 | 33 | #pragma mark - 34 | #pragma mark UIViewController 35 | #pragma mark - 36 | 37 | - (void)viewDidLoad { 38 | [super viewDidLoad]; 39 | self.title = [[self class] title]; 40 | 41 | self.view.backgroundColor = [UIColor whiteColor]; 42 | 43 | // Show HUD 44 | hud = [[TWHUDView alloc] initWithTitle:@"Custom Message"]; 45 | [hud show]; 46 | 47 | // After 3 seconds, complete action 48 | [self performSelector:@selector(complete:) withObject:nil afterDelay:2.0]; 49 | } 50 | 51 | 52 | #pragma mark - 53 | #pragma mark Actions 54 | #pragma mark - 55 | 56 | - (void)complete:(id)sender { 57 | [hud completeWithTitle:@"Finished!"]; 58 | [self performSelector:@selector(pop:) withObject:nil afterDelay:0.7]; 59 | } 60 | 61 | 62 | - (void)pop:(id)sender { 63 | [hud dismiss]; 64 | [self.navigationController popViewControllerAnimated:YES]; 65 | } 66 | 67 | @end 68 | -------------------------------------------------------------------------------- /TWToolkit/UIImage+TWToolkitAdditions.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIImage+TWToolkitAdditions.m 3 | // TWToolkit 4 | // 5 | // Created by Sam Soffes on 11/17/09. 6 | // Copyright 2009 Tasteful Works, Inc. All rights reserved. 7 | // 8 | 9 | #import "UIImage+TWToolkitAdditions.h" 10 | 11 | @implementation UIImage (TWToolkitAdditions) 12 | 13 | + (UIImage *)imageNamed:(NSString *)imageName bundle:(NSString *)bundleName { 14 | NSString *resourcePath = [[NSBundle mainBundle] resourcePath]; 15 | NSString *bundlePath = [resourcePath stringByAppendingPathComponent:bundleName]; 16 | NSString *imagePath = [bundlePath stringByAppendingPathComponent:imageName]; 17 | return [UIImage imageWithContentsOfFile:imagePath]; 18 | } 19 | 20 | 21 | - (UIImage *)initWithImage:(UIImage *)image croppedToRect:(CGRect)rect { 22 | CGImageRef imageRef = CGImageCreateWithImageInRect([self CGImage], rect); 23 | UIImage *cropped = [[UIImage alloc] initWithCGImage:imageRef]; 24 | CGImageRelease(imageRef); 25 | return cropped; // retained 26 | } 27 | 28 | 29 | - (UIImage *)imageCroppedToRect:(CGRect)rect { 30 | CGImageRef imageRef = CGImageCreateWithImageInRect([self CGImage], rect); 31 | UIImage *cropped = [UIImage imageWithCGImage:imageRef]; 32 | CGImageRelease(imageRef); 33 | return cropped; // autoreleased 34 | } 35 | 36 | 37 | - (UIImage *)squareImage { 38 | CGFloat shortestSide = self.size.width <= self.size.height ? self.size.width : self.size.height; 39 | return [self imageCroppedToRect:CGRectMake(0.0, 0.0, shortestSide, shortestSide)]; 40 | } 41 | 42 | @end 43 | -------------------------------------------------------------------------------- /TWCatalog/Classes/TCPickerDetailViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // TCPickerDetailViewController.m 3 | // TWCatalog 4 | // 5 | // Created by Sam Soffes on 10/9/09. 6 | // Copyright 2009 Tasteful Works, Inc. All rights reserved. 7 | // 8 | 9 | #import "TCPickerDetailViewController.h" 10 | #import "TCPickerDemoViewController.h" 11 | 12 | @implementation TCPickerDetailViewController 13 | 14 | #pragma mark - 15 | #pragma mark UIViewController 16 | #pragma mark - 17 | 18 | - (void)viewDidLoad { 19 | [super viewDidLoad]; 20 | self.title = @"Choose"; 21 | } 22 | 23 | 24 | #pragma mark - 25 | #pragma mark TWPickerViewController 26 | #pragma mark - 27 | 28 | - (void)loadKeys { 29 | self.keys = [[NSTimeZone abbreviationDictionary] allKeys]; 30 | } 31 | 32 | 33 | - (NSString *)cellTextForKey:(NSString *)key { 34 | return [[NSTimeZone timeZoneWithAbbreviation:key] name]; 35 | } 36 | 37 | 38 | #pragma mark - 39 | #pragma mark UITableViewDelegate 40 | #pragma mark - 41 | 42 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 43 | [super tableView:tableView didSelectRowAtIndexPath:indexPath]; 44 | 45 | // Notify the parent view controller of the change 46 | TCPickerDemoViewController *viewController = (TCPickerDemoViewController *)[self.navigationController.viewControllers objectAtIndex:([self.navigationController.viewControllers count] - 2)]; 47 | viewController.selectedAbbreviation = [self.keys objectAtIndex:indexPath.row]; 48 | 49 | [self.navigationController popViewControllerAnimated:YES]; 50 | } 51 | 52 | @end 53 | -------------------------------------------------------------------------------- /TWToolkit/TWMessageTableViewCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // TWMessageTableViewCell.m 3 | // Messages 4 | // 5 | // Created by Sam Soffes on 3/10/10. 6 | // Copyright 2010 Tasteful Works. All rights reserved. 7 | // 8 | 9 | #import "TWMessageTableViewCell.h" 10 | #import "TWMessageTableViewCellBubbleView.h" 11 | 12 | @implementation TWMessageTableViewCell 13 | 14 | #pragma mark NSObject 15 | 16 | - (void)dealloc { 17 | [bubbleView release]; 18 | [super dealloc]; 19 | } 20 | 21 | #pragma mark UITableViewCell 22 | 23 | - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier { 24 | if ((self = [super initWithStyle:UITableViewCellStyleDefault reuseIdentifier:reuseIdentifier])) { 25 | self.selectionStyle = UITableViewCellSelectionStyleNone; 26 | self.textLabel.hidden = YES; 27 | 28 | bubbleView = [[TWMessageTableViewCellBubbleView alloc] initWithFrame:CGRectMake(0.0, 0.0, self.contentView.frame.size.width, self.contentView.frame.size.height)]; 29 | bubbleView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; 30 | [self.contentView addSubview:bubbleView]; 31 | [self.contentView sendSubviewToBack:bubbleView]; 32 | } 33 | return self; 34 | } 35 | 36 | #pragma mark Getters 37 | 38 | - (TWMessageTableViewCellMessageStyle)messageStyle { 39 | return bubbleView.messageStyle; 40 | } 41 | 42 | 43 | - (NSString *)messageText { 44 | return bubbleView.messageText; 45 | } 46 | 47 | #pragma mark Setters 48 | 49 | - (void)setMessageStyle:(TWMessageTableViewCellMessageStyle)aMessageStyle { 50 | bubbleView.messageStyle = aMessageStyle; 51 | } 52 | 53 | 54 | - (void)setMessageText:(NSString *)text { 55 | bubbleView.messageText = text; 56 | } 57 | 58 | @end 59 | -------------------------------------------------------------------------------- /TWCatalog/Classes/TCGradientViewDemoViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // TCGradientViewDemoViewController.m 3 | // TWCatalog 4 | // 5 | // Created by Sam Soffes on 10/27/09. 6 | // Copyright 2009 Tasteful Works, Inc. All rights reserved. 7 | // 8 | 9 | #import "TCGradientViewDemoViewController.h" 10 | #import "TWToolkit/TWGradientView.h" 11 | 12 | @implementation TCGradientViewDemoViewController 13 | 14 | #pragma mark - 15 | #pragma mark Class Methods 16 | #pragma mark - 17 | 18 | + (NSString *)title { 19 | return @"Gradient View"; 20 | } 21 | 22 | 23 | #pragma mark - 24 | #pragma mark NSObject 25 | #pragma mark - 26 | 27 | - (void)dealloc { 28 | [gradientView release]; 29 | [super dealloc]; 30 | } 31 | 32 | 33 | #pragma mark - 34 | #pragma mark UIViewController 35 | #pragma mark - 36 | 37 | - (void)viewDidLoad { 38 | [super viewDidLoad]; 39 | self.title = [[self class] title]; 40 | self.view.backgroundColor = [UIColor whiteColor]; 41 | 42 | // Gradient view 43 | gradientView = [[TWGradientView alloc] initWithFrame:CGRectMake(20.0, 20.0, 280.0, 280.0)]; 44 | [self.view addSubview:gradientView]; 45 | 46 | UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect]; 47 | button.frame = CGRectMake(20.0, 320.0, 280.0, 37.0); 48 | [button setTitle:@"Change Color" forState:UIControlStateNormal]; 49 | [button addTarget:self action:@selector(changeColor:) forControlEvents:UIControlEventTouchUpInside]; 50 | [self.view addSubview:button]; 51 | 52 | } 53 | 54 | 55 | #pragma mark - 56 | #pragma mark Actions 57 | #pragma mark - 58 | 59 | - (void)changeColor:(id)sender { 60 | if ([gradientView.topColor isEqual:[TWGradientView defaultTopColor]]) { 61 | gradientView.topColor = [UIColor whiteColor]; 62 | gradientView.bottomColor = [UIColor grayColor]; 63 | } else { 64 | gradientView.topColor = [TWGradientView defaultTopColor]; 65 | gradientView.bottomColor = [TWGradientView defaultBottomColor]; 66 | } 67 | } 68 | 69 | @end 70 | -------------------------------------------------------------------------------- /TWCatalog/Classes/TCMessagesDemoViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // TCMessagesDemoViewController.m 3 | // TWCatalog 4 | // 5 | // Created by Sam Soffes on 3/10/10. 6 | // Copyright 2010 Tasteful Works. All rights reserved. 7 | // 8 | 9 | #import "TCMessagesDemoViewController.h" 10 | 11 | @implementation TCMessagesDemoViewController 12 | 13 | NSString *lorem[] = { 14 | @"Hi", 15 | @"Lorem ipsum dolor sit amet.", 16 | @"Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam.", 17 | @"Quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.", 18 | @"Duis aute irure dolor in reprehenderit.", 19 | @"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.", 20 | 21 | }; 22 | 23 | 24 | #pragma mark - 25 | #pragma mark Class Methods 26 | #pragma mark - 27 | 28 | + (NSString *)title { 29 | return @"Messages"; 30 | } 31 | 32 | 33 | #pragma mark - 34 | #pragma mark UIViewController 35 | #pragma mark - 36 | 37 | - (void)viewDidLoad { 38 | [super viewDidLoad]; 39 | self.title = [[self class] title]; 40 | } 41 | 42 | 43 | #pragma mark - 44 | #pragma mark TWMessagesViewController 45 | #pragma mark - 46 | 47 | - (TWMessageTableViewCellMessageStyle)messageStyleForRowAtIndexPath:(NSIndexPath *)indexPath { 48 | if (indexPath.row % 2) { 49 | return TWMessageTableViewCellMessageStyleGreen; 50 | } 51 | return TWMessageTableViewCellMessageStyleGray; 52 | } 53 | 54 | 55 | - (NSString *)textForRowAtIndexPath:(NSIndexPath *)indexPath { 56 | return lorem[indexPath.row]; 57 | } 58 | 59 | 60 | #pragma mark - 61 | #pragma mark UITableViewDataSource 62 | #pragma mark - 63 | 64 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 65 | return sizeof(lorem) / sizeof(NSString *); 66 | } 67 | 68 | @end 69 | -------------------------------------------------------------------------------- /TWToolkit/TWGradientView.h: -------------------------------------------------------------------------------- 1 | // 2 | // TWGradientView.h 3 | // TWToolkit 4 | // 5 | // Created by Sam Soffes on 10/27/09. 6 | // Copyright 2009 Tasteful Works, Inc. All rights reserved. 7 | // 8 | // Greatly inspired by BWGradientBox. http://brandonwalkin.com/bwtoolkit 9 | // 10 | // Known bugs: 11 | // * startColor and endColor must be in the same colorspace. The colorspace 12 | // of the first color is used to draw the gradient. If you did a gradient 13 | // from white to blue, it would look like a gradient from white to black 14 | // because the first color, white, is in the gray color space, not the RGB 15 | // color space. If you did it from blue to white, it would look like blue 16 | // to black because white in the gray colorspace isn't a valid color in 17 | // the RGB colorspace (because there are only 2 components in the gray 18 | // colorspace and 4 in the RGB colorspace). Automatic colorspace 19 | // conversions are planned for the future. 20 | // 21 | 22 | @interface TWGradientView : UIView { 23 | 24 | UIColor *_topColor; 25 | UIColor *_bottomColor; 26 | UIColor *_topBorderColor; 27 | UIColor *_bottomBorderColor; 28 | CGFloat _topInsetAlpha; 29 | CGFloat _bottomInsetAlpha; 30 | BOOL _hasTopBorder; 31 | BOOL _hasBottomBorder; 32 | BOOL _showsInsets; 33 | 34 | @private 35 | 36 | BOOL _hasDrawn; 37 | CGGradientRef _gradient; 38 | } 39 | 40 | @property (nonatomic, retain) UIColor *topColor; 41 | @property (nonatomic, retain) UIColor *bottomColor; 42 | @property (nonatomic, retain) UIColor *topBorderColor; 43 | @property (nonatomic, retain) UIColor *bottomBorderColor; 44 | @property (nonatomic, assign) CGFloat topInsetAlpha; 45 | @property (nonatomic, assign) CGFloat bottomInsetAlpha; 46 | @property (nonatomic, assign) BOOL hasTopBorder; 47 | @property (nonatomic, assign) BOOL hasBottomBorder; 48 | @property (nonatomic, assign) BOOL showsInsets; 49 | 50 | + (UIColor *)defaultTopColor; 51 | + (UIColor *)defaultBottomColor; 52 | + (UIColor *)defaultTopBorderColor; 53 | + (UIColor *)defaultBottomBorderColor; 54 | + (CGFloat)defaultTopInsetAlpha; 55 | + (CGFloat)defaultBottomInsetAlpha; 56 | 57 | @end 58 | -------------------------------------------------------------------------------- /TWToolkit/TWTextView.m: -------------------------------------------------------------------------------- 1 | // 2 | // TWTextView.m 3 | // TWToolkit 4 | // 5 | // Created by Sam Soffes on 8/18/10. 6 | // Copyright 2010 Tasteful Works, Inc. All rights reserved. 7 | // 8 | 9 | #import "TWTextView.h" 10 | 11 | @interface TWTextView (PrivateMethods) 12 | - (void)_updateShouldDrawPlaceholder; 13 | - (void)_textChanged:(NSNotification *)notification; 14 | @end 15 | 16 | 17 | @implementation TWTextView 18 | 19 | @synthesize placeholder = _placeholder; 20 | @synthesize placeholderColor = _placeholderColor; 21 | 22 | #pragma mark NSObject 23 | 24 | - (void)dealloc { 25 | [[NSNotificationCenter defaultCenter] removeObserver:self name:UITextViewTextDidChangeNotification object:self]; 26 | 27 | [_placeholder release]; 28 | [_placeholderColor release]; 29 | [super dealloc]; 30 | } 31 | 32 | 33 | #pragma mark UIView 34 | 35 | - (id)initWithFrame:(CGRect)frame { 36 | if (self = [super initWithFrame:frame]) { 37 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_textChanged:) name:UITextViewTextDidChangeNotification object:self]; 38 | 39 | self.placeholderColor = [UIColor lightGrayColor]; 40 | _shouldDrawPlaceholder = NO; 41 | } 42 | return self; 43 | } 44 | 45 | 46 | - (void)drawRect:(CGRect)rect { 47 | [super drawRect:rect]; 48 | 49 | if (_shouldDrawPlaceholder) { 50 | [_placeholderColor set]; 51 | [_placeholder drawInRect:CGRectMake(8.0, 8.0, self.frame.size.width - 16.0, self.frame.size.height - 16.0) withFont:self.font]; 52 | } 53 | } 54 | 55 | 56 | #pragma mark Setters 57 | 58 | - (void)setPlaceholder:(NSString *)string { 59 | if ([string isEqual:_placeholder]) { 60 | return; 61 | } 62 | 63 | [_placeholder release]; 64 | _placeholder = [string retain]; 65 | 66 | [self _updateShouldDrawPlaceholder]; 67 | } 68 | 69 | 70 | #pragma mark Private Methods 71 | 72 | - (void)_updateShouldDrawPlaceholder { 73 | BOOL prev = _shouldDrawPlaceholder; 74 | _shouldDrawPlaceholder = self.placeholder && self.placeholderColor && self.text.length == 0; 75 | 76 | if (prev != _shouldDrawPlaceholder) { 77 | [self setNeedsDisplay]; 78 | } 79 | } 80 | 81 | 82 | - (void)_textChanged:(NSNotification *)notificaiton { 83 | [self _updateShouldDrawPlaceholder]; 84 | } 85 | 86 | @end 87 | -------------------------------------------------------------------------------- /TWToolkit/UIView+TWToolkitAdditions.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+TWToolkitAdditions.m 3 | // TWToolkit 4 | // 5 | // Created by Sam Soffes on 2/15/10. 6 | // Copyright 2010 Tasteful Works. All rights reserved. 7 | // 8 | 9 | #import "UIView+TWToolkitAdditions.h" 10 | #import 11 | 12 | @implementation UIView (TWToolkitAdditions) 13 | 14 | - (UIImage *)imageRepresentation { 15 | UIGraphicsBeginImageContext(self.bounds.size); 16 | [self.layer renderInContext:UIGraphicsGetCurrentContext()]; 17 | UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); 18 | UIGraphicsEndImageContext(); 19 | return image; 20 | } 21 | 22 | 23 | - (void)hide { 24 | self.alpha = 0.0; 25 | } 26 | 27 | 28 | - (void)show { 29 | self.alpha = 1.0; 30 | } 31 | 32 | 33 | - (void)fadeOut { 34 | [self fadeAlphaTo:0.0 andPerformSelector:NULL withObject:nil]; 35 | } 36 | 37 | 38 | - (void)fadeOutAndPerformSelector:(SEL)selector { 39 | [self fadeAlphaTo:0.0 andPerformSelector:selector withObject:nil]; 40 | } 41 | 42 | 43 | - (void)fadeOutAndPerformSelector:(SEL)selector withObject:(id)object { 44 | [self fadeAlphaTo:0.0 andPerformSelector:selector withObject:object]; 45 | } 46 | 47 | 48 | - (void)fadeIn { 49 | [self fadeAlphaTo:1.0 andPerformSelector:NULL withObject:nil]; 50 | } 51 | 52 | 53 | - (void)fadeInAndPerformSelector:(SEL)selector { 54 | [self fadeAlphaTo:1.0 andPerformSelector:selector withObject:nil]; 55 | } 56 | 57 | 58 | - (void)fadeInAndPerformSelector:(SEL)selector withObject:(id)object { 59 | [self fadeAlphaTo:1.0 andPerformSelector:selector withObject:object]; 60 | } 61 | 62 | 63 | - (void)fadeAlphaTo:(CGFloat)targetAlpha { 64 | [self fadeAlphaTo:targetAlpha andPerformSelector:NULL withObject:nil]; 65 | } 66 | 67 | 68 | - (void)fadeAlphaTo:(CGFloat)targetAlpha andPerformSelector:(SEL)selector { 69 | [self fadeAlphaTo:targetAlpha andPerformSelector:selector withObject:nil]; 70 | } 71 | 72 | 73 | - (void)fadeAlphaTo:(CGFloat)targetAlpha andPerformSelector:(SEL)selector withObject:(id)object { 74 | // Don't fade and perform selector if alpha is already target alpha 75 | if (self.alpha == targetAlpha) { 76 | return; 77 | } 78 | 79 | // Perform fade 80 | [UIView beginAnimations:@"fadealpha" context:nil]; 81 | self.alpha = targetAlpha; 82 | [UIView commitAnimations]; 83 | 84 | // Perform selector after animation 85 | if (selector) { 86 | [self performSelector:selector withObject:object afterDelay:0.21]; 87 | } 88 | } 89 | 90 | 91 | @end 92 | -------------------------------------------------------------------------------- /TWToolkit/TWLineView.m: -------------------------------------------------------------------------------- 1 | // 2 | // TWLineView.m 3 | // TWToolkit 4 | // 5 | // Created by Sam Soffes on 4/12/10. 6 | // Copyright 2010 Tasteful Works, Inc. All rights reserved. 7 | // 8 | 9 | #import "TWLineView.h" 10 | 11 | @implementation TWLineView 12 | 13 | @synthesize lineColor = _lineColor; 14 | @synthesize insetColor = _insetColor; 15 | @synthesize showInset = _showInset; 16 | 17 | #pragma mark NSObject 18 | 19 | - (void)dealloc { 20 | self.lineColor = nil; 21 | [super dealloc]; 22 | } 23 | 24 | #pragma mark UIView 25 | 26 | - (id)initWithFrame:(CGRect)frame { 27 | if ((self = [super initWithFrame:frame])) { 28 | self.backgroundColor = [UIColor clearColor]; 29 | self.opaque = NO; 30 | self.autoresizingMask = UIViewAutoresizingFlexibleWidth; 31 | 32 | self.lineColor = [UIColor grayColor]; 33 | self.insetColor = [UIColor colorWithWhite:1.0 alpha:0.5]; 34 | 35 | _showInset = YES; 36 | _hasDrawn = NO; 37 | } 38 | return self; 39 | } 40 | 41 | 42 | - (void)drawRect:(CGRect)rect { 43 | if (!_hasDrawn) { 44 | // Add observers 45 | [self addObserver:self forKeyPath:@"lineColor" options:NSKeyValueObservingOptionNew context:nil]; 46 | [self addObserver:self forKeyPath:@"insetColor" options:NSKeyValueObservingOptionNew context:nil]; 47 | [self addObserver:self forKeyPath:@"showInset" options:NSKeyValueObservingOptionNew context:nil]; 48 | _hasDrawn = YES; 49 | } 50 | 51 | CGContextRef context = UIGraphicsGetCurrentContext(); 52 | CGContextClipToRect(context, rect); 53 | CGContextSetLineWidth(context, 2.0); 54 | 55 | // Inset 56 | if (self.showInset && self.insetColor) { 57 | CGContextSetStrokeColorWithColor(context, _insetColor.CGColor); 58 | CGContextMoveToPoint(context, 0.0, 1.0); 59 | CGContextAddLineToPoint(context, rect.size.width, 1.0); 60 | CGContextStrokePath(context); 61 | } 62 | 63 | // Top border 64 | CGContextSetStrokeColorWithColor(context, _lineColor.CGColor); 65 | CGContextMoveToPoint(context, 0.0, 0.0); 66 | CGContextAddLineToPoint(context, rect.size.width, 0.0); 67 | CGContextStrokePath(context); 68 | } 69 | 70 | #pragma mark Observer 71 | 72 | - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { 73 | // Redraw if colors changed 74 | if ([keyPath isEqualToString:@"lineColor"] || [keyPath isEqualToString:@"insetColor"] || [keyPath isEqualToString:@"showInset"]) { 75 | [self setNeedsDisplay]; 76 | return; 77 | } 78 | 79 | [super observeValueForKeyPath:keyPath ofObject:object change:change context:context]; 80 | } 81 | 82 | @end 83 | -------------------------------------------------------------------------------- /TWCatalog/Classes/TCPickerDemoViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // TCPickerDemoViewController.m 3 | // TWCatalog 4 | // 5 | // Created by Sam Soffes on 10/9/09. 6 | // Copyright 2009 Tasteful Works, Inc. All rights reserved. 7 | // 8 | 9 | #import "TCPickerDemoViewController.h" 10 | #import "TCPickerDetailViewController.h" 11 | 12 | @implementation TCPickerDemoViewController 13 | 14 | @synthesize selectedAbbreviation; 15 | 16 | #pragma mark - 17 | #pragma mark Class Methods 18 | #pragma mark - 19 | 20 | + (NSString *)title { 21 | return @"Settings Picker"; 22 | } 23 | 24 | 25 | #pragma mark - 26 | #pragma mark NSObject 27 | #pragma mark - 28 | 29 | - (id)init { 30 | return self = [super initWithStyle:UITableViewStyleGrouped]; 31 | } 32 | 33 | 34 | - (void)dealloc { 35 | [selectedAbbreviation release]; 36 | [super dealloc]; 37 | } 38 | 39 | 40 | #pragma mark - 41 | #pragma mark UIViewController 42 | #pragma mark - 43 | 44 | - (void)viewDidLoad { 45 | [super viewDidLoad]; 46 | self.title = [[self class] title]; 47 | self.selectedAbbreviation = [[NSTimeZone defaultTimeZone] abbreviation]; 48 | } 49 | 50 | 51 | - (void)viewWillAppear:(BOOL)animated { 52 | [super viewWillAppear:animated]; 53 | [self.tableView reloadData]; 54 | } 55 | 56 | 57 | #pragma mark - 58 | #pragma mark UITableViewDataSource 59 | #pragma mark - 60 | 61 | - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { 62 | return 1; 63 | } 64 | 65 | 66 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 67 | return 1; 68 | } 69 | 70 | 71 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 72 | static NSString *cellIdentifier = @"cell"; 73 | 74 | UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier]; 75 | if (cell == nil) { 76 | cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:cellIdentifier] autorelease]; 77 | } 78 | 79 | cell.textLabel.text = @"Picker Value"; 80 | cell.detailTextLabel.text = [[NSTimeZone timeZoneWithAbbreviation:self.selectedAbbreviation] name]; 81 | cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; 82 | 83 | return cell; 84 | } 85 | 86 | 87 | #pragma mark - 88 | #pragma mark UITableViewDelegate 89 | #pragma mark - 90 | 91 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 92 | TCPickerDetailViewController *viewController = [[TCPickerDetailViewController alloc] initWithStyle:UITableViewStyleGrouped]; 93 | viewController.selectedKey = self.selectedAbbreviation; 94 | [self.navigationController pushViewController:viewController animated:YES]; 95 | [viewController release]; 96 | } 97 | 98 | @end 99 | -------------------------------------------------------------------------------- /TWToolkit/TWIndicatorLabel.m: -------------------------------------------------------------------------------- 1 | // 2 | // TWIndicatorLabel.m 3 | // TWToolkit 4 | // 5 | // Created by Sam Soffes on 7/13/10. 6 | // Copyright 2010 Tasteful Works, Inc. All rights reserved. 7 | // 8 | 9 | #import "TWIndicatorLabel.h" 10 | 11 | @implementation TWIndicatorLabel 12 | 13 | @synthesize label = _label; 14 | @synthesize indicator = _indicator; 15 | @synthesize loading = _loading; 16 | 17 | #pragma mark Class Methods 18 | 19 | + (CGSize)indicatorSize { 20 | return CGSizeMake(20.0, 20.0); 21 | } 22 | 23 | 24 | + (CGFloat)padding { 25 | return 6.0; 26 | } 27 | 28 | #pragma mark NSObject 29 | 30 | - (void)dealloc { 31 | [_label release]; 32 | [_indicator release]; 33 | [super dealloc]; 34 | } 35 | 36 | #pragma mark UIView 37 | 38 | - (id)initWithFrame:(CGRect)rect { 39 | if ((self = [super initWithFrame:rect])) { 40 | self.clipsToBounds = YES; 41 | 42 | _label = [[UILabel alloc] initWithFrame:CGRectZero]; 43 | [self addSubview:_label]; 44 | 45 | _indicator = [[UIActivityIndicatorView alloc] initWithFrame:CGRectZero]; 46 | [_indicator startAnimating]; 47 | [self addSubview:_indicator]; 48 | 49 | _loading = NO; 50 | [self layoutSubviews]; 51 | } 52 | return self; 53 | } 54 | 55 | 56 | - (void)layoutSubviews { 57 | CGRect rect = self.frame; 58 | CGSize size = [[self class] indicatorSize]; 59 | CGFloat x = size.width + [[self class] padding]; 60 | 61 | // Loading 62 | if (_loading) { 63 | _label.frame = CGRectMake(x, 0.0, rect.size.width - x, size.height); 64 | _indicator.frame = CGRectMake(0.0, 0.0, size.width, size.height); 65 | } 66 | 67 | // Not loading 68 | else { 69 | _label.frame = CGRectMake(0.0, 0.0, rect.size.width, size.height); 70 | _indicator.frame = CGRectMake(-x, 0.0, size.width, size.height); 71 | } 72 | } 73 | 74 | 75 | - (void)setBackgroundColor:(UIColor *)color { 76 | [super setBackgroundColor:color]; 77 | _label.backgroundColor = color; 78 | _indicator.backgroundColor = color; 79 | } 80 | 81 | 82 | - (void)setOpaque:(BOOL)o { 83 | [super setOpaque:o]; 84 | _label.opaque = o; 85 | _indicator.opaque = o; 86 | } 87 | 88 | #pragma mark Status 89 | 90 | - (void)startWithText:(NSString *)text { 91 | self.loading = YES; 92 | _label.text = text; 93 | } 94 | 95 | - (void)completeWithText:(NSString *)text { 96 | self.loading = NO; 97 | _label.text = text; 98 | } 99 | 100 | #pragma mark Custom Setters 101 | 102 | - (void)setLoading:(BOOL)l { 103 | if (_loading == l) { 104 | return; 105 | } 106 | 107 | [UIView beginAnimations:@"loading" context:nil]; 108 | _loading = l; 109 | [self layoutSubviews]; 110 | [UIView commitAnimations]; 111 | } 112 | 113 | @end 114 | -------------------------------------------------------------------------------- /TWCatalog/Classes/TCPieProgressViewDemoViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // TCPieProgressViewDemoViewController.m 3 | // TWCatalog 4 | // 5 | // Created by Sam Soffes on 4/22/10. 6 | // Copyright 2010 Tasteful Works, Inc. All rights reserved. 7 | // 8 | 9 | #import "TCPieProgressViewDemoViewController.h" 10 | #import 11 | 12 | @implementation TCPieProgressViewDemoViewController 13 | 14 | #pragma mark - 15 | #pragma mark Class Methods 16 | #pragma mark - 17 | 18 | + (NSString *)title { 19 | return @"Pie Progress View"; 20 | } 21 | 22 | #pragma mark - 23 | #pragma mark UIViewController 24 | #pragma mark - 25 | 26 | - (void)viewDidLoad { 27 | [super viewDidLoad]; 28 | self.title = [[self class] title]; 29 | self.view.backgroundColor = [UIColor groupTableViewBackgroundColor]; 30 | 31 | TWPieProgressView *progressView1 = [[TWPieProgressView alloc] initWithFrame:CGRectMake(20.0, 20.0, 55.0, 55.0)]; 32 | progressView1.progress = 0.25; 33 | [self.view addSubview:progressView1]; 34 | [progressView1 release]; 35 | 36 | TWPieProgressView *progressView2 = [[TWPieProgressView alloc] initWithFrame:CGRectMake(95.0, 20.0, 55.0, 55.0)]; 37 | progressView2.progress = 0.50; 38 | [self.view addSubview:progressView2]; 39 | [progressView2 release]; 40 | 41 | TWPieProgressView *progressView3 = [[TWPieProgressView alloc] initWithFrame:CGRectMake(170.0, 20.0, 55.0, 55.0)]; 42 | progressView3.progress = 0.75; 43 | [self.view addSubview:progressView3]; 44 | [progressView3 release]; 45 | 46 | TWPieProgressView *progressView4 = [[TWPieProgressView alloc] initWithFrame:CGRectMake(245.0, 20.0, 55.0, 55.0)]; 47 | progressView4.progress = 1.0; 48 | [self.view addSubview:progressView4]; 49 | [progressView4 release]; 50 | 51 | TWPieProgressView *progressView5 = [[TWPieProgressView alloc] initWithFrame:CGRectMake(20.0, 95.0, 130.0, 130.0)]; 52 | progressView5.progress = 0.33; 53 | [self.view addSubview:progressView5]; 54 | [progressView5 release]; 55 | 56 | TWPieProgressView *progressView6 = [[TWPieProgressView alloc] initWithFrame:CGRectMake(170.0, 95.0, 130.0, 130.0)]; 57 | progressView6.progress = 0.66; 58 | [self.view addSubview:progressView6]; 59 | [progressView6 release]; 60 | 61 | progressView7 = [[TWPieProgressView alloc] initWithFrame:CGRectMake(95.0, 245.0, 130.0, 130.0)]; 62 | [self.view addSubview:progressView7]; 63 | [progressView7 release]; 64 | 65 | timer = [NSTimer scheduledTimerWithTimeInterval:0.05 target:self selector:@selector(incrementProgress:) userInfo:nil repeats:YES]; 66 | } 67 | 68 | 69 | - (void)viewDidUnload { 70 | [super viewDidUnload]; 71 | [timer invalidate]; 72 | } 73 | 74 | 75 | #pragma mark - 76 | #pragma mark Timer 77 | #pragma mark - 78 | 79 | - (void)incrementProgress:(NSTimer *)timer { 80 | progressView7.progress = progressView7.progress + 0.01; 81 | if (progressView7.progress == 1.0) { 82 | progressView7.progress = 0.0; 83 | } 84 | } 85 | 86 | @end 87 | -------------------------------------------------------------------------------- /TWToolkit/TWPickerViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // TWPickerViewController.m 3 | // TWToolkit 4 | // 5 | // Created by Sam Soffes on 10/9/08. 6 | // Copyright 2009 Tasteful Works, Inc. All rights reserved. 7 | // 8 | 9 | #import "TWPickerViewController.h" 10 | 11 | @implementation TWPickerViewController 12 | 13 | @synthesize selectedKey = _selectedKey; 14 | @synthesize keys = _keys; 15 | @synthesize currentIndexPath = _currentIndexPath; 16 | 17 | #pragma mark NSObject 18 | 19 | - (id)init { 20 | self = [super initWithStyle:UITableViewStyleGrouped]; 21 | return self; 22 | } 23 | 24 | 25 | - (void)dealloc { 26 | [_keys release]; 27 | [_selectedKey release]; 28 | [_currentIndexPath release]; 29 | [super dealloc]; 30 | } 31 | 32 | #pragma mark UIViewController Methods 33 | 34 | - (void)viewDidLoad { 35 | [super viewDidLoad]; 36 | 37 | [self loadKeys]; 38 | 39 | if(self.selectedKey != nil) { 40 | self.currentIndexPath = [[NSIndexPath indexPathForRow:[self.keys indexOfObject:self.selectedKey] inSection:0] retain]; 41 | [self.tableView reloadData]; 42 | [self.tableView scrollToRowAtIndexPath:self.currentIndexPath atScrollPosition:UITableViewScrollPositionMiddle animated:NO]; 43 | } 44 | } 45 | 46 | #pragma mark TWPickerViewController 47 | 48 | // This method should be overridden by a subclass 49 | - (void)loadKeys { 50 | self.keys = nil; 51 | self.selectedKey = nil; 52 | } 53 | 54 | 55 | // This method should be overridden by a subclass 56 | - (NSString *)cellTextForKey:(NSString *)key { 57 | return key; 58 | } 59 | 60 | #pragma mark UITableViewDelegate 61 | 62 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 63 | [[tableView cellForRowAtIndexPath:indexPath] setAccessoryType:UITableViewCellAccessoryCheckmark]; 64 | [tableView deselectRowAtIndexPath:indexPath animated:YES]; 65 | self.currentIndexPath = indexPath; 66 | } 67 | 68 | #pragma mark UITableViewDataSource 69 | 70 | - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { 71 | return 1; 72 | } 73 | 74 | 75 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 76 | return [self.keys count]; 77 | } 78 | 79 | 80 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 81 | 82 | static NSString *cellIdentifier = @"cellIdentifier"; 83 | 84 | UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier]; 85 | if (cell == nil) { 86 | cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:cellIdentifier] autorelease]; 87 | } 88 | NSString *key = [self.keys objectAtIndex:indexPath.row]; 89 | cell.textLabel.text = [self cellTextForKey:key]; 90 | if([key isEqual:self.selectedKey] == YES) { 91 | cell.accessoryType = UITableViewCellAccessoryCheckmark; 92 | } else { 93 | cell.accessoryType = UITableViewCellAccessoryNone; 94 | } 95 | return cell; 96 | } 97 | 98 | @end 99 | -------------------------------------------------------------------------------- /TWToolkit/TWMessageTableViewCellBubbleView.m: -------------------------------------------------------------------------------- 1 | // 2 | // TWMessageTableViewCellBubbleView.m 3 | // Messages 4 | // 5 | // Created by Sam Soffes on 3/10/10. 6 | // Copyright 2010 Tasteful Works. All rights reserved. 7 | // 8 | 9 | #import "TWMessageTableViewCellBubbleView.h" 10 | #import "UIImage+TWToolkitAdditions.h" 11 | 12 | #define kFont [UIFont systemFontOfSize:15.0] 13 | static UILineBreakMode kLineBreakMode = UILineBreakModeWordWrap; 14 | static CGFloat kMaxWidth = 223.0; 15 | static CGFloat kPaddingTop = 6.0; 16 | static CGFloat kPaddingBottom = 8.0; 17 | static CGFloat kMarginTop = 2.0; 18 | static CGFloat kMarginBottom = 2.0; 19 | 20 | @implementation TWMessageTableViewCellBubbleView 21 | 22 | @synthesize messageText; 23 | @synthesize messageStyle; 24 | 25 | #pragma mark Class Methods 26 | 27 | + (UIImage *)bubbleImageForMessageStyle:(TWMessageTableViewCellMessageStyle)aMessageStyle { 28 | UIImage *image; 29 | if (aMessageStyle == TWMessageTableViewCellMessageStyleGreen) { 30 | image = [[UIImage imageNamed:@"images/TWMessageTableViewCellBackgroundGreen.png" bundle:@"TWToolkit.bundle"] stretchableImageWithLeftCapWidth:17 topCapHeight:14]; 31 | } else { 32 | image = [[UIImage imageNamed:@"images/TWMessageTableViewCellBackgroundGray.png" bundle:@"TWToolkit.bundle"] stretchableImageWithLeftCapWidth:24 topCapHeight:14]; 33 | } 34 | return image; 35 | } 36 | 37 | 38 | + (CGSize)textSizeForText:(NSString *)text { 39 | CGSize maxSize = CGSizeMake(kMaxWidth - 38.0, 1000.0); 40 | return [text sizeWithFont:kFont constrainedToSize:maxSize lineBreakMode:kLineBreakMode]; 41 | } 42 | 43 | 44 | + (CGSize)bubbleSizeForText:(NSString *)text { 45 | CGSize textSize = [self textSizeForText:text]; 46 | return CGSizeMake(textSize.width + 38.0, textSize.height + kPaddingTop + kPaddingBottom); 47 | } 48 | 49 | 50 | + (CGFloat)cellHeightForText:(NSString *)text { 51 | return [self bubbleSizeForText:text].height + kMarginTop + kMarginBottom; 52 | } 53 | 54 | #pragma mark UIView 55 | 56 | - (id)initWithFrame:(CGRect)frame { 57 | if (self = [super initWithFrame:frame]) { 58 | self.backgroundColor = [UIColor colorWithRed:0.859 green:0.886 blue:0.929 alpha:1.0]; 59 | } 60 | return self; 61 | } 62 | 63 | 64 | - (void)drawRect:(CGRect)frame { 65 | UIImage *bubbleImage = [[self class] bubbleImageForMessageStyle:messageStyle]; 66 | CGSize bubbleSize = [[self class] bubbleSizeForText:messageText]; 67 | CGRect bubbleFrame = CGRectMake((messageStyle == TWMessageTableViewCellMessageStyleGreen ? self.frame.size.width - bubbleSize.width : 0.0), kMarginTop, bubbleSize.width, bubbleSize.height); 68 | [bubbleImage drawInRect:bubbleFrame]; 69 | 70 | CGSize textSize = [[self class] textSizeForText:messageText]; 71 | CGRect textFrame = CGRectMake(((messageStyle == TWMessageTableViewCellMessageStyleGreen) ? (13.0 + bubbleFrame.origin.x) : 23.0), kPaddingTop + kMarginTop, textSize.width, textSize.height); 72 | [messageText drawInRect:textFrame withFont:kFont lineBreakMode:kLineBreakMode alignment:(messageStyle == TWMessageTableViewCellMessageStyleGreen) ? UITextAlignmentRight : UITextAlignmentLeft]; 73 | } 74 | 75 | @end 76 | -------------------------------------------------------------------------------- /TWToolkit/NSDate+TWToolkitAdditions.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSDate+TWToolkitAdditions.m 3 | // TWToolkit 4 | // 5 | // Created by Sam Soffes on 5/26/10. 6 | // Copyright 2010 Tasteful Works, Inc. All rights reserved. 7 | // 8 | 9 | #import "NSDate+TWToolkitAdditions.h" 10 | 11 | @implementation NSDate (TWToolkitAdditions) 12 | 13 | + (NSDate *)dateFromISO8601String:(NSString *)string { 14 | NSDateFormatter* dateFormatter = [[[NSDateFormatter alloc] init] autorelease]; 15 | [dateFormatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss'Z'"]; 16 | return [dateFormatter dateFromString:string]; 17 | } 18 | 19 | 20 | - (NSString *)ISO8601String { 21 | NSDateFormatter* dateFormatter = [[[NSDateFormatter alloc] init] autorelease]; 22 | [dateFormatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss'Z'"]; 23 | return [dateFormatter stringFromDate:self]; 24 | } 25 | 26 | 27 | - (NSString *)timeAgoInWords { 28 | return [self timeAgoInWordsIncludingSeconds:YES]; 29 | } 30 | 31 | 32 | - (NSString *)timeAgoInWordsIncludingSeconds:(BOOL)includeSeconds { 33 | NSTimeInterval intervalInSeconds = fabs([self timeIntervalSinceNow]); 34 | double intervalInMinutes = round(intervalInSeconds / 60.0); 35 | 36 | if (intervalInMinutes >= 0 && intervalInMinutes <= 1) { 37 | if (!includeSeconds) { 38 | return intervalInMinutes <= 0 ? @"less than a minute" : @"1 minute"; 39 | } 40 | if (intervalInSeconds >= 0 && intervalInSeconds < 5) { 41 | return [NSString stringWithFormat:@"less than %d seconds", 5]; 42 | } else if (intervalInSeconds >= 5 && intervalInSeconds < 10) { 43 | return [NSString stringWithFormat:@"less than %d seconds", 10]; 44 | } else if (intervalInSeconds >= 10 && intervalInSeconds < 20) { 45 | return [NSString stringWithFormat:@"less than %d seconds", 20]; 46 | } else if (intervalInSeconds >= 20 && intervalInSeconds < 40) { 47 | return @"half a minute"; 48 | } else if (intervalInSeconds >= 40 && intervalInSeconds < 60) { 49 | return @"less than a minute"; 50 | } else { 51 | return @"1 minute"; 52 | } 53 | } else if (intervalInMinutes >= 2 && intervalInMinutes <= 44) { 54 | return [NSString stringWithFormat:@"%.0f minutes", intervalInMinutes]; 55 | } else if (intervalInMinutes >= 45 && intervalInMinutes <= 89) { 56 | return @"about 1 hour"; 57 | } else if (intervalInMinutes >= 90 && intervalInMinutes <= 1439) { 58 | return [NSString stringWithFormat:@"about %.0f hours", round(intervalInMinutes/60.0)]; 59 | } else if (intervalInMinutes >= 1440 && intervalInMinutes <= 2879) { 60 | return @"1 day"; 61 | } else if (intervalInMinutes >= 2880 && intervalInMinutes <= 43199) { 62 | return [NSString stringWithFormat:@"%.0f days", round(intervalInMinutes/1440.0)]; 63 | } else if (intervalInMinutes >= 43200 && intervalInMinutes <= 86399) { 64 | return @"about 1 month"; 65 | } else if (intervalInMinutes >= 86400 && intervalInMinutes <= 525599) { 66 | return [NSString stringWithFormat:@"%.0f months", round(intervalInMinutes/43200.0)]; 67 | } else if (intervalInMinutes >= 525600 && intervalInMinutes <= 1051199) { 68 | return @"about 1 year"; 69 | } else { 70 | return [NSString stringWithFormat:@"over %.0f years", round(intervalInMinutes/525600.0)]; 71 | } 72 | return nil; 73 | } 74 | 75 | @end 76 | -------------------------------------------------------------------------------- /TWToolkit/TWWebView.h: -------------------------------------------------------------------------------- 1 | // 2 | // TWWebView.h 3 | // TWToolkit 4 | // 5 | // Created by Sam Soffes on 4/26/10. 6 | // Copyright 2010 Tasteful Works, Inc. All rights reserved. 7 | // 8 | // This class is a wrapper for UIWebView that makes many common 9 | // and usually difficult tasks very simple. Note that this class 10 | // doesn't actually inherit from UIWebView, but instead forwards 11 | // all of UIWebView's public methods to an internal instance. 12 | // It has been designed to be a drop in replacement for UIWebView. 13 | // 14 | // Things of interest are the TWWebView properties and the extra 15 | // delegate methods. 16 | // 17 | 18 | @protocol TWWebViewDelegate; 19 | 20 | @interface TWWebView : UIView { 21 | 22 | id _delegate; 23 | 24 | UIWebView *_webView; 25 | NSURLRequest *_lastRequest; 26 | BOOL _testedDOM; 27 | BOOL _DOMloaded; 28 | BOOL _scrollEnabled; 29 | BOOL _bounces; 30 | BOOL _shadowsHidden; 31 | BOOL _consoleEnabled; 32 | NSString *_persistedCSS; 33 | } 34 | 35 | // TWWebView Properties 36 | @property (nonatomic, assign) id delegate; 37 | @property (nonatomic, readonly, getter=isLoading) BOOL loading; 38 | @property (nonatomic, assign) BOOL scrollEnabled; 39 | @property (nonatomic, assign) BOOL bounces; 40 | @property (nonatomic, assign) BOOL shadowsHidden; 41 | @property (nonatomic, assign) BOOL consoleEnabled; 42 | @property (nonatomic, retain, readonly) NSURLRequest *lastRequest; 43 | 44 | // UIWebView Properties 45 | @property (nonatomic, readonly) BOOL canGoBack; 46 | @property (nonatomic, readonly) BOOL canGoForward; 47 | @property (nonatomic) UIDataDetectorTypes dataDetectorTypes; 48 | @property (nonatomic, readonly, getter=isLoadingRequest) BOOL loadingRequest; 49 | @property (nonatomic, readonly, retain) NSURLRequest *request; 50 | @property (nonatomic) BOOL scalesPageToFit; 51 | 52 | // TWWebViewMethods 53 | - (void)dismissKeyboard; 54 | - (void)injectCSS:(NSString *)string; 55 | - (void)injectCSS:(NSString *)string persist:(BOOL)persist; 56 | 57 | // Convenience Methods 58 | - (void)loadHTMLString:(NSString *)string; 59 | - (void)loadURL:(NSURL *)aURL; 60 | - (void)loadURLString:(NSString *)string; 61 | 62 | // UIWebView Methods 63 | - (void)goBack; 64 | - (void)goForward; 65 | - (void)loadData:(NSData *)data MIMEType:(NSString *)MIMEType textEncodingName:(NSString *)encodingName baseURL:(NSURL *)baseURL; 66 | - (void)loadHTMLString:(NSString *)string baseURL:(NSURL *)baseURL; 67 | - (void)loadRequest:(NSURLRequest *)aRequest; 68 | - (void)reload; 69 | - (void)stopLoading; 70 | - (NSString *)stringByEvaluatingJavaScriptFromString:(NSString *)script; 71 | 72 | @end 73 | 74 | 75 | @protocol TWWebViewDelegate 76 | 77 | @optional 78 | 79 | // TWWebViewDelegate 80 | - (void)webViewDidStartLoading:(TWWebView *)aWebView; 81 | - (void)webViewDidLoadDOM:(TWWebView *)aWebView; 82 | - (void)webViewDidFinishLoading:(TWWebView *)aWebView; 83 | 84 | // UIWebViewDelegate 85 | - (void)webView:(TWWebView *)aWebView didFailLoadWithError:(NSError *)error; 86 | - (BOOL)webView:(TWWebView *)aWebView shouldStartLoadWithRequest:(NSURLRequest *)aRequest navigationType:(UIWebViewNavigationType)navigationType; 87 | - (void)webViewDidFinishLoad:(TWWebView *)aWebView; 88 | - (void)webViewDidStartLoad:(TWWebView *)aWebView; 89 | 90 | @end 91 | -------------------------------------------------------------------------------- /TWCatalog/Classes/TCRootViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // TCRootViewController.m 3 | // TWCatalog 4 | // 5 | // Created by Sam Soffes on 10/9/09. 6 | // Copyright 2009 Tasteful Works, Inc. All rights reserved. 7 | // 8 | 9 | #import "TCRootViewController.h" 10 | #import "TCPickerDemoViewController.h" 11 | #import "TCGradientViewDemoViewController.h" 12 | 13 | #define kTitleKey @"title" 14 | #define kClassesKey @"classes" 15 | 16 | @interface UIViewController (TCRootViewControllerAdditions) 17 | + (id)setup; 18 | @end 19 | 20 | @implementation TCRootViewController 21 | 22 | #pragma mark - 23 | #pragma mark NSObject 24 | #pragma mark - 25 | 26 | - (void)dealloc { 27 | [data release]; 28 | [super dealloc]; 29 | } 30 | 31 | 32 | #pragma mark - 33 | #pragma mark UIViewController 34 | #pragma mark - 35 | 36 | - (void)viewDidLoad { 37 | [super viewDidLoad]; 38 | 39 | self.title = @"TWCatalog"; 40 | 41 | data = [[NSArray alloc] initWithObjects: 42 | [NSDictionary dictionaryWithObjectsAndKeys: 43 | [NSArray arrayWithObjects: 44 | @"TCGradientViewDemoViewController", 45 | @"TCHUDViewDemoViewController", 46 | @"TCLineViewDemoViewController", 47 | @"TCPieProgressViewDemoViewController", 48 | nil], 49 | kClassesKey, 50 | @"Views", 51 | kTitleKey, 52 | nil], 53 | [NSDictionary dictionaryWithObjectsAndKeys: 54 | [NSArray arrayWithObjects: 55 | @"TCPickerDemoViewController", 56 | @"TCMessagesDemoViewController", 57 | nil], 58 | kClassesKey, 59 | @"View Controllers", 60 | kTitleKey, 61 | nil], 62 | nil]; 63 | } 64 | 65 | 66 | #pragma mark - 67 | #pragma mark UITableViewDataSource 68 | #pragma mark - 69 | 70 | - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { 71 | return [data count]; 72 | } 73 | 74 | 75 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 76 | return [[[data objectAtIndex:section] objectForKey:kClassesKey] count]; 77 | } 78 | 79 | 80 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 81 | 82 | static NSString *cellIdentifier = @"cell"; 83 | 84 | UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier]; 85 | if (cell == nil) { 86 | cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier] autorelease]; 87 | } 88 | 89 | Class klass = [[NSBundle mainBundle] classNamed:[[[data objectAtIndex:indexPath.section] objectForKey:kClassesKey] objectAtIndex:indexPath.row]]; 90 | 91 | cell.textLabel.text = [klass title]; 92 | // cell.detailTextLabel.text = [row objectForKey:kDescriptionKey]; 93 | cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; 94 | 95 | return cell; 96 | } 97 | 98 | 99 | - (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section { 100 | return [[data objectAtIndex:section] objectForKey:kTitleKey]; 101 | } 102 | 103 | 104 | #pragma mark - 105 | #pragma mark UITableViewDelegate 106 | #pragma mark - 107 | 108 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 109 | [self.tableView deselectRowAtIndexPath:indexPath animated:YES]; 110 | 111 | Class klass = [[NSBundle mainBundle] classNamed:[[[data objectAtIndex:indexPath.section] objectForKey:kClassesKey] objectAtIndex:indexPath.row]]; 112 | UIViewController *viewController = [[klass alloc] init]; 113 | [self.navigationController pushViewController:viewController animated:YES]; 114 | [viewController release]; 115 | } 116 | 117 | @end 118 | -------------------------------------------------------------------------------- /TWToolkit/TWPieProgressView.m: -------------------------------------------------------------------------------- 1 | // 2 | // TWPieProgressView.m 3 | // TWToolkit 4 | // 5 | // Created by Sam Soffes on 4/22/10. 6 | // Copyright 2010 Tasteful Works, Inc. All rights reserved. 7 | // 8 | 9 | #import "TWPieProgressView.h" 10 | #import "TWDrawingMacros.h" 11 | 12 | #define kAngleOffset -90.0 13 | 14 | @implementation TWPieProgressView 15 | 16 | @synthesize progress = _progress; 17 | @synthesize pieBorderWidth = _pieBorderWidth; 18 | @synthesize pieBorderColor = _pieBorderColor; 19 | @synthesize pieFillColor = _pieFillColor; 20 | @synthesize pieBackgroundColor = _pieBackgroundColor; 21 | 22 | #pragma mark NSObject 23 | 24 | - (void)dealloc { 25 | self.pieBorderColor = nil; 26 | self.pieFillColor = nil; 27 | self.pieBackgroundColor = nil; 28 | [super dealloc]; 29 | } 30 | 31 | #pragma mark UIView 32 | 33 | - (id)initWithFrame:(CGRect)aFrame { 34 | if ((self = [super initWithFrame:aFrame])) { 35 | self.backgroundColor = [UIColor clearColor]; 36 | 37 | self.progress = 0.0; 38 | self.pieBorderWidth = 4.0; 39 | self.pieBorderColor = [UIColor colorWithRed:0.612 green:0.710 blue:0.839 alpha:1.0]; 40 | self.pieFillColor = [UIColor colorWithRed:0.612 green:0.710 blue:0.839 alpha:1.0]; 41 | self.pieBackgroundColor = [UIColor whiteColor]; 42 | } 43 | return self; 44 | } 45 | 46 | 47 | - (void)drawRect:(CGRect)rect { 48 | if (!_hasDrawn) { 49 | [self addObserver:self forKeyPath:@"pieBorderWidth" options:NSKeyValueObservingOptionNew context:nil]; 50 | [self addObserver:self forKeyPath:@"pieBorderColor" options:NSKeyValueObservingOptionNew context:nil]; 51 | [self addObserver:self forKeyPath:@"pieFillColor" options:NSKeyValueObservingOptionNew context:nil]; 52 | [self addObserver:self forKeyPath:@"pieBackgroundColor" options:NSKeyValueObservingOptionNew context:nil]; 53 | _hasDrawn = YES; 54 | } 55 | 56 | CGContextRef context = UIGraphicsGetCurrentContext(); 57 | CGContextClipToRect(context, rect); 58 | 59 | // Background 60 | [_pieBackgroundColor set]; 61 | CGContextFillEllipseInRect(context, rect); 62 | 63 | // Fill 64 | [_pieFillColor set]; 65 | if (_progress > 0.0) { 66 | CGPoint center = CGPointMake(CGRectGetMidX(rect), CGRectGetMidY(rect)); 67 | CGFloat radius = center.y; 68 | CGFloat angle = DEGREES_TO_RADIANS((360.0 * _progress) + kAngleOffset); 69 | CGPoint points[3] = { 70 | CGPointMake(center.x, 0.0), 71 | center, 72 | CGPointMake(center.x + radius * cos(angle), center.y + radius * sin(angle)) 73 | }; 74 | CGContextAddLines(context, points, sizeof(points) / sizeof(points[0])); 75 | CGContextAddArc(context, center.x, center.y, radius, DEGREES_TO_RADIANS(kAngleOffset), angle, false); 76 | CGContextDrawPath(context, kCGPathEOFill); 77 | } 78 | 79 | // Border 80 | [_pieBorderColor set]; 81 | CGContextSetLineWidth(context, _pieBorderWidth); 82 | CGRect pieInnerRect = CGRectMake(_pieBorderWidth / 2.0, _pieBorderWidth / 2.0, rect.size.width - _pieBorderWidth, rect.size.height - _pieBorderWidth); 83 | CGContextStrokeEllipseInRect(context, pieInnerRect); 84 | } 85 | 86 | #pragma mark Setters 87 | 88 | - (void)setProgress:(CGFloat)newProgress { 89 | _progress = fmax(0.0, fmin(1.0, newProgress)); 90 | [self setNeedsDisplay]; 91 | } 92 | 93 | #pragma mark Observer 94 | 95 | - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { 96 | // Redraw if attributes changed 97 | if ([keyPath isEqualToString:@"pieBorderWidth"] || [keyPath isEqualToString:@"pieBorderColor"] || [keyPath isEqualToString:@"pieFillColor"] || [keyPath isEqualToString:@"pieBackgroundColor"]) { 98 | [self setNeedsDisplay]; 99 | return; 100 | } 101 | 102 | [super observeValueForKeyPath:keyPath ofObject:object change:change context:context]; 103 | } 104 | 105 | @end 106 | -------------------------------------------------------------------------------- /TWToolkit/TWKeychain.m: -------------------------------------------------------------------------------- 1 | // 2 | // TWKeychain.m 3 | // TWToolkit 4 | // 5 | // Created by Sam Soffes on 5/19/10. 6 | // Copyright 2009 Tasteful Works, Inc. All rights reserved. 7 | // 8 | 9 | #import "TWKeychain.h" 10 | #import 11 | 12 | NSString *TWKeychainErrorDomain = @"com.tastefulworks.twkeychain"; 13 | static TWKeychain *kDefaultKeychain = nil; 14 | 15 | @interface TWKeychain (PrivateMethods) 16 | + (NSMutableDictionary *)keychainQueryForService:(NSString *)service account:(NSString *)account; 17 | @end 18 | 19 | @implementation TWKeychain 20 | 21 | #pragma mark Class Methods 22 | 23 | + (TWKeychain *)defaultKeychain { 24 | if (kDefaultKeychain == nil) { 25 | kDefaultKeychain = [[self alloc] init]; 26 | } 27 | return kDefaultKeychain; 28 | } 29 | 30 | 31 | + (NSMutableDictionary *)keychainQueryForService:(NSString *)service account:(NSString *)account { 32 | return [NSMutableDictionary dictionaryWithObjectsAndKeys:(id)kSecClassGenericPassword, 33 | (id)kSecClass, account, (id)kSecAttrAccount, 34 | service, (id)kSecAttrService, 35 | nil]; 36 | } 37 | 38 | 39 | + (NSString *)passwordForService:(NSString *)service account:(NSString *)account { 40 | return [self passwordForService:service account:account error:nil]; 41 | } 42 | 43 | 44 | + (NSString *)passwordForService:(NSString *)service account:(NSString *)account error:(NSError **)error { 45 | OSStatus status = TWKeychainErrorBadArguments; 46 | NSString *result = nil; 47 | 48 | if (0 < [service length] && 0 < [account length]) { 49 | CFDataRef passwordData = NULL; 50 | NSMutableDictionary *keychainQuery = [self keychainQueryForService:service account:account]; 51 | [keychainQuery setObject:(id)kCFBooleanTrue forKey:(id)kSecReturnData]; 52 | [keychainQuery setObject:(id)kSecMatchLimitOne forKey:(id)kSecMatchLimit]; 53 | 54 | OSStatus status = SecItemCopyMatching((CFDictionaryRef)keychainQuery, 55 | (CFTypeRef *)&passwordData); 56 | if (status == noErr && 0 < [(NSData *)passwordData length]) { 57 | result = [[[NSString alloc] initWithData:(NSData *)passwordData 58 | encoding:NSUTF8StringEncoding] autorelease]; 59 | } 60 | 61 | if (passwordData != NULL) { 62 | CFRelease(passwordData); 63 | } 64 | } 65 | 66 | if (status != noErr && error != NULL) { 67 | *error = [NSError errorWithDomain:TWKeychainErrorDomain code:status userInfo:nil]; 68 | } 69 | 70 | return result; 71 | } 72 | 73 | 74 | + (BOOL)deletePasswordForService:(NSString *)service account:(NSString *)account { 75 | return [self deletePasswordForService:service account:account error:nil]; 76 | } 77 | 78 | 79 | + (BOOL)deletePasswordForService:(NSString *)service account:(NSString *)account error:(NSError **)error { 80 | OSStatus status = TWKeychainErrorBadArguments; 81 | if (0 < [service length] && 0 < [account length]) { 82 | NSMutableDictionary *keychainQuery = [self keychainQueryForService:service account:account]; 83 | status = SecItemDelete((CFDictionaryRef)keychainQuery); 84 | } 85 | 86 | if (status != noErr && error != NULL) { 87 | *error = [NSError errorWithDomain:TWKeychainErrorDomain code:status userInfo:nil]; 88 | } 89 | 90 | return status == noErr; 91 | } 92 | 93 | 94 | + (BOOL)setPassword:(NSString *)password forService:(NSString *)service account:(NSString *)account { 95 | return [self setPassword:password forService:service account:account error:nil]; 96 | } 97 | 98 | 99 | + (BOOL)setPassword:(NSString *)password forService:(NSString *)service account:(NSString *)account error:(NSError **)error { 100 | OSStatus status = TWKeychainErrorBadArguments; 101 | if (0 < [service length] && 0 < [account length]) { 102 | [self deletePasswordForService:service account:account]; 103 | if (0 < [password length]) { 104 | NSMutableDictionary *keychainQuery = [self keychainQueryForService:service account:account]; 105 | NSData *passwordData = [password dataUsingEncoding:NSUTF8StringEncoding]; 106 | [keychainQuery setObject:passwordData forKey:(id)kSecValueData]; 107 | status = SecItemAdd((CFDictionaryRef)keychainQuery, NULL); 108 | } 109 | } 110 | 111 | if (status != noErr && error != NULL) { 112 | *error = [NSError errorWithDomain:TWKeychainErrorDomain code:status userInfo:nil]; 113 | } 114 | 115 | return status == noErr; 116 | } 117 | 118 | @end 119 | -------------------------------------------------------------------------------- /TWToolkit/TWLoadingView.m: -------------------------------------------------------------------------------- 1 | // 2 | // SSLoadingView.m 3 | // TWToolkit 4 | // 5 | // Created by Sam Soffes on 7/8/09. 6 | // Copyright 2009 Tasteful Works, Inc. All rights reserved. 7 | // 8 | 9 | #import "TWLoadingView.h" 10 | 11 | static CGFloat interiorPadding = 20.0; 12 | static CGFloat indicatorSize = 20.0; 13 | static CGFloat indicatorRightMargin = 8.0; 14 | 15 | @implementation TWLoadingView 16 | 17 | @synthesize activityIndicator = _activityIndicator; 18 | @synthesize text = _text; 19 | @synthesize font = _font; 20 | @synthesize textColor = _textColor; 21 | @synthesize shadowColor = _shadowColor; 22 | 23 | #pragma mark NSObject 24 | 25 | - (void)dealloc { 26 | [self removeObserver:self forKeyPath:@"text"]; 27 | [self removeObserver:self forKeyPath:@"font"]; 28 | [self removeObserver:self forKeyPath:@"textColor"]; 29 | [self removeObserver:self forKeyPath:@"shadowColor"]; 30 | self.font = nil; 31 | self.text = nil; 32 | self.textColor = nil; 33 | self.shadowColor = nil; 34 | [_activityIndicator release]; 35 | [super dealloc]; 36 | } 37 | 38 | #pragma mark UIView 39 | 40 | - (id)initWithFrame:(CGRect)frame { 41 | if (self = [super initWithFrame:frame]) { 42 | 43 | // View defaults 44 | self.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; 45 | self.backgroundColor = [UIColor whiteColor]; 46 | self.opaque = YES; 47 | 48 | // Setup the indicator 49 | _activityIndicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray]; 50 | _activityIndicator.hidesWhenStopped = NO; 51 | [_activityIndicator startAnimating]; 52 | [self addSubview:_activityIndicator]; 53 | 54 | // Defaults 55 | self.text = @"Loading..."; 56 | self.font = [UIFont systemFontOfSize:16.0]; 57 | UIColor *aColor = [[UIColor alloc] initWithHue:0.613 saturation:0.3 brightness:0.42 alpha:1.0]; 58 | self.textColor = aColor; 59 | [aColor release]; 60 | self.shadowColor = [UIColor whiteColor]; 61 | 62 | // Add observers 63 | [self addObserver:self forKeyPath:@"text" options:NSKeyValueObservingOptionNew context:nil]; 64 | [self addObserver:self forKeyPath:@"font" options:NSKeyValueObservingOptionNew context:nil]; 65 | [self addObserver:self forKeyPath:@"textColor" options:NSKeyValueObservingOptionNew context:nil]; 66 | [self addObserver:self forKeyPath:@"shadowColor" options:NSKeyValueObservingOptionNew context:nil]; 67 | } 68 | return self; 69 | } 70 | 71 | 72 | - (void)drawRect:(CGRect)rect { 73 | 74 | CGRect frame = self.frame; 75 | 76 | // Calculate sizes 77 | CGSize maxSize = CGSizeMake(frame.size.width - (interiorPadding * 2.0) - indicatorSize - indicatorRightMargin, indicatorSize); 78 | CGSize textSize = [_text sizeWithFont:_font constrainedToSize:maxSize lineBreakMode:UILineBreakModeWordWrap]; 79 | 80 | // Calculate position 81 | CGFloat totalWidth = textSize.width + indicatorSize + indicatorRightMargin; 82 | NSInteger y = (NSInteger)((frame.size.height / 2.0) - (indicatorSize / 2.0)); 83 | 84 | // Position the indicator 85 | _activityIndicator.frame = CGRectMake((NSInteger)((frame.size.width - totalWidth) / 2.0), y, indicatorSize, indicatorSize); 86 | 87 | // Calculate text position 88 | CGRect textRect = CGRectMake(_activityIndicator.frame.origin.x + indicatorSize + indicatorRightMargin, y, textSize.width, textSize.height); 89 | 90 | // Draw shadow. The offset is (0, 1) 91 | [_shadowColor set]; 92 | CGRect shadowRect = CGRectMake(textRect.origin.x, textRect.origin.y + 1.0, textRect.size.width, textRect.size.height); 93 | [_text drawInRect:shadowRect withFont:_font lineBreakMode:UILineBreakModeTailTruncation alignment:UITextAlignmentLeft]; 94 | 95 | // Draw text 96 | [_textColor set]; 97 | [_text drawInRect:textRect withFont:_font lineBreakMode:UILineBreakModeTailTruncation alignment:UITextAlignmentLeft]; 98 | } 99 | 100 | #pragma mark Observer 101 | 102 | - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { 103 | 104 | // Redraw if colors or borders changed 105 | if ([keyPath isEqualToString:@"text"] || [keyPath isEqualToString:@"font"] || 106 | [keyPath isEqualToString:@"textColor"] || [keyPath isEqualToString:@"shadowColor"]) { 107 | [self setNeedsDisplay]; 108 | return; 109 | } 110 | 111 | [super observeValueForKeyPath:keyPath ofObject:object change:change context:context]; 112 | } 113 | 114 | @end 115 | -------------------------------------------------------------------------------- /Readme.markdown: -------------------------------------------------------------------------------- 1 | **IMPORTANT:** TWToolkit has been renamed and is now being maintained at [SSToolkit](http://github.com/samsoffes/sstoolkit). 2 | 3 | # TWToolkit 4 | 5 | TWToolkit makes life easier. It is made up of various view controllers, views, and categories that we use at [Tasteful Works][] for our apps. Feel free to fork the repo and help us make it better. 6 | 7 | ## Classes 8 | 9 | ### View Controllers 10 | 11 | * [TWViewController][] - custom modal craziness 12 | * [TWPickerViewController][] - easily create picker view controllers like the Settings app 13 | * [TWMessagesViewController][] - simple message UI like the built-in SMS app 14 | 15 | ### Views 16 | 17 | * [TWGradientView][] - easily create gradients with optional borders and insets 18 | * [TWHUDView][] - simple heads-up display 19 | * [TWLabel][] - ever wanted to align your text to the top or the bottom 20 | * [TWLineView][] - easily create lines with an inset 21 | * [TWLoadingView][] - flexible loading view 22 | * [TWPieProgressView][] - pie chart style progress bar similar to the one in Xcode's status bar 23 | * [TWTextField][] - simply add edge insets 24 | * [TWWebView][] - handy delegate additions and control over shadows and scroll (still betay) 25 | 26 | ### Categories 27 | 28 | [Several categories](http://github.com/tastefulworks/twtoolkit/blob/master/TWToolkit/TWCategories.h) are included and used throughout TWToolkit. 29 | 30 | ## Adding TWToolkit to your project 31 | 32 | 1. Run the following command to add the submodule. Be sure you have been added to the project on GitHub. 33 | 34 | git submodule add git://github.com/tastefulworks/twtoolkit.git Frameworks/TWToolkit 35 | 36 | 2. In Finder, navigate to the `Frameworks/TWToolkit` folder and drag the `xcodeproj` file into the `Frameworks` folder in your Xcode project. 37 | 38 | 3. In Finder, drag `TWToolkit.bundle` located in `Frameworks/TWToolkit/Resources` into the `Resources` folder in your Xcode project. 39 | 40 | 4. Select the TWToolkit Xcode project from the sidebar in Xcode. In the file browser on the right in Xcode, click the checkbox next to `libTWToolkit.a`. (If you don't see the file browser, hit Command-Shift-E to toggle it on.) 41 | 42 | 5. Select your target from the sidebar and open Get Info (Command-I). 43 | 44 | 6. Choose the *General* tab from the top. 45 | 46 | 7. Under the *Direct Dependencies* area, click the plus button, select *TWToolkit* from the menu, and choose *Add Target*. 47 | 48 | 8. Choose the build tab from the top of the window. Make sure the configuration dropdown at the top is set to *All Configurations*. 49 | 50 | 9. Add `Frameworks/TWToolkit` to *Header Search Path* (do not click the *Recursive* checkbox). 51 | 52 | 10. Add `-all_load -ObjC` to *Other Linker Flags*. 53 | 54 | ## Usage 55 | 56 | To use TWToolkit, simply add the following line to your source file. 57 | 58 | #import 59 | 60 | You can also import individual files instead of the whole framework (for faster compile times) by doing something like: 61 | 62 | #import 63 | 64 | ## Demo 65 | 66 | [TWCatalog][] is include with TWToolkit. This is a sample iPhone application to demonstrate the various features of TWToolkit. 67 | 68 | ## Links 69 | 70 | * [Known bugs](http://github.com/tastefulworks/twtoolkit/issues/labels/Bug) 71 | * [Future features](http://github.com/tastefulworks/twtoolkit/issues/labels/Enhancement) 72 | 73 | [Tasteful Works]: http://tastefulworks.com/ 74 | [TWViewController]: http://github.com/tastefulworks/twtoolkit/blob/master/TWToolkit/TWViewController.h 75 | [TWPickerViewController]: http://github.com/tastefulworks/twtoolkit/blob/master/TWToolkit/TWPickerViewController.h 76 | [TWMessagesViewController]: http://github.com/tastefulworks/twtoolkit/blob/master/TWToolkit/TWMessagesViewController.h 77 | [TWHUDView]: http://github.com/tastefulworks/twtoolkit/blob/master/TWToolkit/TWHUDView.h 78 | [TWGradientView]: http://github.com/tastefulworks/twtoolkit/blob/master/TWToolkit/TWGradientView.h 79 | [TWLabel]: http://github.com/tastefulworks/twtoolkit/blob/master/TWToolkit/TWLabel.h 80 | [TWLineView]: http://github.com/tastefulworks/twtoolkit/blob/master/TWToolkit/TWLineView.h 81 | [TWLoadingView]: http://github.com/tastefulworks/twtoolkit/blob/master/TWToolkit/TWLoadingView.h 82 | [TWPieProgressView]: http://github.com/tastefulworks/twtoolkit/blob/master/TWToolkit/TWPieProgressView.h 83 | [TWTextField]: http://github.com/tastefulworks/twtoolkit/blob/master/TWToolkit/TWTextField.h 84 | [TWWebView]: http://github.com/tastefulworks/twtoolkit/blob/master/TWToolkit/TWWebView.h 85 | [TWCatalog]: https://github.com/tastefulworks/twtoolkit/tree/master/TWCatalog/ 86 | -------------------------------------------------------------------------------- /TWToolkit/TWHUDView.m: -------------------------------------------------------------------------------- 1 | // 2 | // TWHUDView.h 3 | // TWToolkit 4 | // 5 | // Created by Sam Soffes on 9/29/09. 6 | // Copyright 2009 Tasteful Works, Inc. All rights reserved. 7 | // 8 | 9 | #import "TWHUDView.h" 10 | #import "UIImage+TWToolkitAdditions.h" 11 | #import 12 | 13 | static CGFloat kHUDSize = 172.0; 14 | static CGFloat kIndicatorSize = 40.0; 15 | 16 | @implementation TWHUDView 17 | 18 | @synthesize textLabel = _textLabel; 19 | @synthesize activityIndicator = _activityIndicator; 20 | @synthesize loading = _loading; 21 | @synthesize successful = _successful; 22 | 23 | #pragma mark NSObject 24 | 25 | - (id)init { 26 | return [self initWithTitle:nil loading:YES]; 27 | } 28 | 29 | 30 | - (void)dealloc { 31 | [_activityIndicator release]; 32 | [_textLabel release]; 33 | [super dealloc]; 34 | } 35 | 36 | 37 | #pragma mark UIView 38 | 39 | - (id)initWithFrame:(CGRect)frame { 40 | return [self initWithTitle:nil loading:YES]; 41 | } 42 | 43 | 44 | - (void)drawRect:(CGRect)rect { 45 | CGContextRef context = UIGraphicsGetCurrentContext(); 46 | 47 | // Draw rounded rectangle 48 | CGContextSetRGBFillColor(context, 0.0, 0.0, 0.0, 0.5); 49 | CGRect rrect = CGRectMake(0.0, 0.0, kHUDSize, kHUDSize); 50 | CGFloat radius = 14.0; 51 | CGFloat minx = CGRectGetMinX(rrect); 52 | CGFloat midx = CGRectGetMidX(rrect); 53 | CGFloat maxx = CGRectGetMaxX(rrect); 54 | CGFloat miny = CGRectGetMinY(rrect); 55 | CGFloat midy = CGRectGetMidY(rrect); 56 | CGFloat maxy = CGRectGetMaxY(rrect); 57 | CGContextMoveToPoint(context, minx, midy); 58 | CGContextAddArcToPoint(context, minx, miny, midx, miny, radius); 59 | CGContextAddArcToPoint(context, maxx, miny, maxx, midy, radius); 60 | CGContextAddArcToPoint(context, maxx, maxy, midx, maxy, radius); 61 | CGContextAddArcToPoint(context, minx, maxy, minx, midy, radius); 62 | CGContextClosePath(context); 63 | CGContextFillPath(context); 64 | 65 | // Image 66 | if (_loading == NO) { 67 | [[UIColor whiteColor] set]; 68 | NSString *dingbat = _successful ? @"✔" : @"✘"; 69 | CGFloat margin = roundf((kHUDSize - 40.0) / 2.0); 70 | CGRect dingbatRect = CGRectMake(margin, margin - 20.0, 40.0, 40.0); 71 | [dingbat drawInRect:dingbatRect withFont:[UIFont systemFontOfSize:60.0] lineBreakMode:UILineBreakModeClip alignment:UITextAlignmentCenter]; 72 | } 73 | } 74 | 75 | 76 | - (void)layoutSubviews { 77 | _activityIndicator.frame = CGRectMake(round((kHUDSize - kIndicatorSize) / 2.0), round((kHUDSize - kIndicatorSize) / 2.0), kIndicatorSize, kIndicatorSize); 78 | _textLabel.frame = CGRectMake(0.0, round(kHUDSize - 30.0), kHUDSize, 20.0); 79 | } 80 | 81 | 82 | #pragma mark UIAlertView 83 | 84 | - (void)show { 85 | [super show]; 86 | 87 | // Set the frame to 20px larger than it should be because UIAlertView 88 | // will automatically resize it down after the animation 89 | CGFloat biggerSize = kHUDSize + 20.0; 90 | CGSize screenSize = [[UIScreen mainScreen] bounds].size; 91 | self.frame = CGRectMake(round((screenSize.width - biggerSize) / 2.0), 92 | round((screenSize.height - biggerSize) / 2.0) + 10.0, 93 | biggerSize, biggerSize); 94 | } 95 | 96 | 97 | // Deprecated. Overridding UIAlertView's setTitle. 98 | - (void)setTitle:(NSString *)aTitle { 99 | _textLabel.text = aTitle; 100 | } 101 | 102 | 103 | #pragma mark HUD 104 | 105 | - (id)initWithTitle:(NSString *)aTitle { 106 | return [self initWithTitle:aTitle loading:YES]; 107 | } 108 | 109 | 110 | - (id)initWithTitle:(NSString *)aTitle loading:(BOOL)isLoading { 111 | if (self = [super initWithFrame:CGRectZero]) { 112 | 113 | // Indicator 114 | _activityIndicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge]; 115 | _activityIndicator.alpha = 0.0; 116 | [_activityIndicator startAnimating]; 117 | [self addSubview:_activityIndicator]; 118 | 119 | // Text Label 120 | _textLabel = [[UILabel alloc] initWithFrame:CGRectZero]; 121 | _textLabel.font = [UIFont boldSystemFontOfSize:14]; 122 | _textLabel.backgroundColor = [UIColor clearColor]; 123 | _textLabel.textColor = [UIColor whiteColor]; 124 | _textLabel.shadowColor = [UIColor blackColor]; 125 | _textLabel.shadowOffset = CGSizeMake(0.0, 1.0); 126 | _textLabel.textAlignment = UITextAlignmentCenter; 127 | _textLabel.lineBreakMode = UILineBreakModeTailTruncation; 128 | _textLabel.text = aTitle ? aTitle : @"Loading"; 129 | [self addSubview:_textLabel]; 130 | 131 | // Loading 132 | self.loading = isLoading; 133 | } 134 | return self; 135 | } 136 | 137 | 138 | - (void)completeWithTitle:(NSString *)aTitle { 139 | self.successful = YES; 140 | self.loading = NO; 141 | _textLabel.text = aTitle; 142 | } 143 | 144 | 145 | - (void)completeAndDismissWithTitle:(NSString *)aTitle { 146 | [self completeWithTitle:aTitle]; 147 | [self performSelector:@selector(dismiss) withObject:nil afterDelay:1.0]; 148 | } 149 | 150 | 151 | - (void)failWithTitle:(NSString *)aTitle { 152 | self.successful = NO; 153 | self.loading = NO; 154 | _textLabel.text = aTitle; 155 | } 156 | 157 | 158 | - (void)failAndDismissWithTitle:(NSString *)aTitle { 159 | [self failWithTitle:aTitle]; 160 | [self performSelector:@selector(dismiss) withObject:nil afterDelay:1.0]; 161 | } 162 | 163 | 164 | - (void)dismiss { 165 | [self dismissAnimated:YES]; 166 | } 167 | 168 | 169 | - (void)dismissAnimated:(BOOL)animated { 170 | [super dismissWithClickedButtonIndex:0 animated:animated]; 171 | } 172 | 173 | 174 | #pragma mark Setters 175 | 176 | - (void)setLoading:(BOOL)isLoading { 177 | _loading = isLoading; 178 | _activityIndicator.alpha = _loading ? 1.0 : 0.0; 179 | [self setNeedsDisplay]; 180 | } 181 | 182 | @end 183 | -------------------------------------------------------------------------------- /TWToolkit/TWMessagesViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // TWMessagesViewController.m 3 | // Messages 4 | // 5 | // Created by Sam Soffes on 3/10/10. 6 | // Copyright 2010 Tasteful Works. All rights reserved. 7 | // 8 | 9 | #import "TWMessagesViewController.h" 10 | #import "TWMessageTableViewCell.h" 11 | #import "TWMessageTableViewCellBubbleView.h" 12 | #import "TWGradientView.h" 13 | #import "TWTextField.h" 14 | #import "UIImage+TWToolkitAdditions.h" 15 | 16 | CGFloat kInputHeight = 40.0; 17 | 18 | @implementation TWMessagesViewController 19 | 20 | @synthesize tableView = _tableView; 21 | 22 | #pragma mark NSObject 23 | 24 | - (id)init { 25 | return [self initWithNibName:nil bundle:nil]; 26 | } 27 | 28 | 29 | - (void)dealloc { 30 | [_tableView release]; 31 | [_inputView release]; 32 | [_sendButton release]; 33 | [super dealloc]; 34 | } 35 | 36 | #pragma mark UITableViewController 37 | 38 | - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { 39 | if (self = [super initWithNibName:nil bundle:nil]) { 40 | self.view.backgroundColor = [UIColor colorWithRed:0.859 green:0.886 blue:0.929 alpha:1.0]; 41 | 42 | // Table view 43 | _tableView = [[UITableView alloc] initWithFrame:CGRectMake(0.0, 0.0, self.view.frame.size.width, self.view.frame.size.height - kInputHeight) style:UITableViewStylePlain]; 44 | _tableView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; 45 | _tableView.backgroundColor = self.view.backgroundColor; 46 | _tableView.dataSource = self; 47 | _tableView.delegate = self; 48 | _tableView.separatorColor = self.view.backgroundColor; 49 | [self.view addSubview:_tableView]; 50 | 51 | // Input 52 | _inputView = [[TWGradientView alloc] initWithFrame:CGRectMake(0.0, self.view.frame.size.height - 44.0 - kInputHeight, self.view.frame.size.width, kInputHeight)]; 53 | _inputView.autoresizingMask = UIViewAutoresizingFlexibleWidth; 54 | _inputView.hasBottomBorder = NO; 55 | _inputView.topBorderColor = [UIColor colorWithRed:0.733 green:0.741 blue:0.745 alpha:1.0]; 56 | _inputView.topColor = [UIColor colorWithRed:0.914 green:0.922 blue:0.929 alpha:1.0]; 57 | _inputView.bottomColor = [UIColor colorWithRed:0.765 green:0.773 blue:0.788 alpha:1.0]; 58 | [self.view addSubview:_inputView]; 59 | 60 | // Text field 61 | TWTextField *textField = [[TWTextField alloc] initWithFrame:CGRectMake(6.0, 8.0, self.view.frame.size.width - 75.0, 27.0)]; 62 | textField.background = [[UIImage imageNamed:@"images/TWMessagesViewControllerTextFieldBackground.png" bundle:@"TWToolkit.bundle"] stretchableImageWithLeftCapWidth:12 topCapHeight:0]; 63 | textField.delegate = self; 64 | textField.font = [UIFont systemFontOfSize:15.0]; 65 | textField.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter; 66 | textField.textInsets = UIEdgeInsetsMake(0.0, 12.0, 0.0, 12.0); 67 | [_inputView addSubview:textField]; 68 | [textField release]; 69 | 70 | // Send button 71 | _sendButton = [[UIButton buttonWithType:UIButtonTypeCustom] retain]; 72 | _sendButton.frame = CGRectMake(self.view.frame.size.width - 65.0, 8.0, 59.0, 27.0); 73 | _sendButton.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin; 74 | _sendButton.titleLabel.font = [UIFont boldSystemFontOfSize:16.0]; 75 | _sendButton.titleLabel.shadowOffset = CGSizeMake(0.0, -1.0); 76 | [_sendButton setBackgroundImage:[[UIImage imageNamed:@"images/TWMessagesViewControllerSendButtonBackground.png" bundle:@"TWToolkit.bundle"] stretchableImageWithLeftCapWidth:12 topCapHeight:0] forState:UIControlStateNormal]; 77 | [_sendButton setTitle:@"Send" forState:UIControlStateNormal]; 78 | [_sendButton setTitleColor:[UIColor colorWithWhite:1.0 alpha:0.4] forState:UIControlStateNormal]; 79 | [_sendButton setTitleShadowColor:[UIColor colorWithRed:0.325 green:0.463 blue:0.675 alpha:1.0] forState:UIControlStateNormal]; 80 | [_inputView addSubview:_sendButton]; 81 | } 82 | return self; 83 | } 84 | 85 | #pragma mark TWMessagesViewController 86 | 87 | // This method is intended to be overridden by subclasses 88 | - (TWMessageTableViewCellMessageStyle)messageStyleForRowAtIndexPath:(NSIndexPath *)indexPath { 89 | return TWMessageTableViewCellMessageStyleGray; 90 | } 91 | 92 | 93 | // This method is intended to be overridden by subclasses 94 | - (NSString *)textForRowAtIndexPath:(NSIndexPath *)indexPath { 95 | return nil; 96 | } 97 | 98 | #pragma mark UITableViewDataSource 99 | 100 | - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { 101 | return 1; 102 | } 103 | 104 | 105 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 106 | return 0; 107 | } 108 | 109 | 110 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 111 | 112 | static NSString *cellIdentifier = @"cellIdentifier"; 113 | 114 | TWMessageTableViewCell *cell = (TWMessageTableViewCell *)[tableView dequeueReusableCellWithIdentifier:cellIdentifier]; 115 | if (cell == nil) { 116 | cell = [[[TWMessageTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier] autorelease]; 117 | } 118 | 119 | cell.messageStyle = [self messageStyleForRowAtIndexPath:indexPath]; 120 | cell.messageText = [self textForRowAtIndexPath:indexPath]; 121 | 122 | return cell; 123 | } 124 | 125 | #pragma mark UITableViewDelegate 126 | 127 | - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { 128 | return [TWMessageTableViewCellBubbleView cellHeightForText:[self textForRowAtIndexPath:indexPath]]; 129 | } 130 | 131 | #pragma mark UITextFieldDelegate 132 | 133 | - (void)textFieldDidBeginEditing:(UITextField *)textField { 134 | [UIView beginAnimations:@"beginEditing" context:_inputView]; 135 | [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut]; 136 | [UIView setAnimationDuration:0.3]; 137 | _tableView.contentInset = UIEdgeInsetsMake(0.0, 0.0, 216.0, 0.0); 138 | _tableView.scrollIndicatorInsets = _tableView.contentInset; 139 | _inputView.frame = CGRectMake(0.0, 160.0, self.view.frame.size.width, kInputHeight); 140 | [_sendButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; 141 | [UIView commitAnimations]; 142 | } 143 | 144 | 145 | - (void)textFieldDidEndEditing:(UITextField *)textField { 146 | [UIView beginAnimations:@"endEditing" context:_inputView]; 147 | [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut]; 148 | [UIView setAnimationDuration:0.3]; 149 | _tableView.contentInset = UIEdgeInsetsZero; 150 | _tableView.scrollIndicatorInsets = UIEdgeInsetsZero; 151 | _inputView.frame = CGRectMake(0.0, _tableView.frame.size.height, self.view.frame.size.width, kInputHeight); 152 | [_sendButton setTitleColor:[UIColor colorWithWhite:1.0 alpha:0.4] forState:UIControlStateNormal]; 153 | [UIView commitAnimations]; 154 | } 155 | 156 | @end 157 | -------------------------------------------------------------------------------- /TWToolkit/TWGradientView.m: -------------------------------------------------------------------------------- 1 | // 2 | // TWGradientView.m 3 | // TWToolkit 4 | // 5 | // Created by Sam Soffes on 10/27/09. 6 | // Copyright 2009 Tasteful Works, Inc. All rights reserved. 7 | // 8 | 9 | #import "TWGradientView.h" 10 | 11 | @interface TWGradientView (PrivateMethods) 12 | 13 | - (void)_refreshGradient; 14 | 15 | @end 16 | 17 | 18 | @implementation TWGradientView 19 | 20 | @synthesize topColor = _topColor; 21 | @synthesize bottomColor = _bottomColor; 22 | @synthesize topBorderColor = _topBorderColor; 23 | @synthesize bottomBorderColor = _bottomBorderColor; 24 | @synthesize topInsetAlpha = _topInsetAlpha; 25 | @synthesize bottomInsetAlpha = _bottomInsetAlpha; 26 | @synthesize hasTopBorder = _hasTopBorder; 27 | @synthesize hasBottomBorder = _hasBottomBorder; 28 | @synthesize showsInsets = _showsInsets; 29 | 30 | #pragma mark Class Methods 31 | 32 | + (UIColor *)defaultTopColor { 33 | return [UIColor colorWithRed:0.676 green:0.722 blue:0.765 alpha:1.0]; 34 | } 35 | 36 | 37 | + (UIColor *)defaultBottomColor { 38 | return [UIColor colorWithRed:0.514 green:0.568 blue:0.617 alpha:1.0]; 39 | } 40 | 41 | 42 | + (UIColor *)defaultTopBorderColor { 43 | return [UIColor colorWithRed:0.558 green:0.599 blue:0.643 alpha:1.0]; 44 | } 45 | 46 | 47 | + (UIColor *)defaultBottomBorderColor { 48 | return [UIColor colorWithRed:0.428 green:0.479 blue:0.520 alpha:1.0]; 49 | } 50 | 51 | 52 | + (CGFloat)defaultTopInsetAlpha { 53 | return 0.3; 54 | } 55 | 56 | 57 | + (CGFloat)defaultBottomInsetAlpha { 58 | return 0.0; 59 | } 60 | 61 | #pragma mark NSObject 62 | 63 | - (void)dealloc { 64 | if (_hasDrawn) { 65 | [self removeObserver:self forKeyPath:@"topColor"]; 66 | [self removeObserver:self forKeyPath:@"bottomColor"]; 67 | [self removeObserver:self forKeyPath:@"topBorderColor"]; 68 | [self removeObserver:self forKeyPath:@"bottomBorderColor"]; 69 | [self removeObserver:self forKeyPath:@"topInsetAlpha"]; 70 | [self removeObserver:self forKeyPath:@"bottomInsetAlpha"]; 71 | [self removeObserver:self forKeyPath:@"hasTopBorder"]; 72 | [self removeObserver:self forKeyPath:@"hasBottomBorder"]; 73 | [self removeObserver:self forKeyPath:@"showsInsets"]; 74 | CGGradientRelease(_gradient); 75 | } 76 | self.topColor = nil; 77 | self.bottomColor = nil; 78 | self.topBorderColor = nil; 79 | self.bottomBorderColor = nil; 80 | [super dealloc]; 81 | } 82 | 83 | #pragma mark UIView 84 | 85 | - (id)initWithFrame:(CGRect)frame { 86 | if (self = [super initWithFrame:frame]) { 87 | self.opaque = YES; 88 | 89 | // Defaults 90 | self.topColor = [TWGradientView defaultTopColor]; 91 | self.bottomColor = [TWGradientView defaultBottomColor]; 92 | self.topBorderColor = [TWGradientView defaultTopBorderColor]; 93 | self.bottomBorderColor = [TWGradientView defaultBottomBorderColor]; 94 | self.topInsetAlpha = [TWGradientView defaultTopInsetAlpha]; 95 | self.bottomInsetAlpha = [TWGradientView defaultBottomInsetAlpha]; 96 | self.hasTopBorder = YES; 97 | self.hasBottomBorder = YES; 98 | self.showsInsets = YES; 99 | 100 | _hasDrawn = NO; 101 | _gradient = nil; 102 | } 103 | return self; 104 | } 105 | 106 | 107 | - (void)drawRect:(CGRect)rect { 108 | if (!_hasDrawn) { 109 | // Add observers 110 | [self addObserver:self forKeyPath:@"topColor" options:NSKeyValueObservingOptionNew context:nil]; 111 | [self addObserver:self forKeyPath:@"bottomColor" options:NSKeyValueObservingOptionNew context:nil]; 112 | [self addObserver:self forKeyPath:@"topBorderColor" options:NSKeyValueObservingOptionNew context:nil]; 113 | [self addObserver:self forKeyPath:@"bottomBorderColor" options:NSKeyValueObservingOptionNew context:nil]; 114 | [self addObserver:self forKeyPath:@"topInsetAlpha" options:NSKeyValueObservingOptionNew context:nil]; 115 | [self addObserver:self forKeyPath:@"bottomInsetAlpha" options:NSKeyValueObservingOptionNew context:nil]; 116 | [self addObserver:self forKeyPath:@"hasTopBorder" options:NSKeyValueObservingOptionNew context:nil]; 117 | [self addObserver:self forKeyPath:@"hasBottomBorder" options:NSKeyValueObservingOptionNew context:nil]; 118 | [self addObserver:self forKeyPath:@"showsInsets" options:NSKeyValueObservingOptionNew context:nil]; 119 | 120 | // Draw gradient 121 | [self _refreshGradient]; 122 | 123 | _hasDrawn = YES; 124 | } 125 | 126 | CGContextRef context = UIGraphicsGetCurrentContext(); 127 | CGContextClipToRect(context, rect); 128 | 129 | // Gradient 130 | CGPoint start = CGPointMake(0.0, 0.0); 131 | CGPoint end = CGPointMake(0.0, rect.size.height); 132 | CGContextDrawLinearGradient(context, _gradient, start, end, 0); 133 | 134 | CGContextSetLineWidth(context, 2.0); 135 | 136 | if (_hasTopBorder) { 137 | // Top inset 138 | if (_showsInsets && _topInsetAlpha > 0.0) { 139 | CGContextSetStrokeColorWithColor(context, [UIColor colorWithWhite:1.0 alpha:_topInsetAlpha].CGColor); 140 | CGContextMoveToPoint(context, 0.0, 1.0); 141 | CGContextAddLineToPoint(context, rect.size.width, 1.0); 142 | CGContextStrokePath(context); 143 | } 144 | 145 | // Top border 146 | CGContextSetStrokeColorWithColor(context, _topBorderColor.CGColor); 147 | CGContextMoveToPoint(context, 0.0, 0.0); 148 | CGContextAddLineToPoint(context, rect.size.width, 0.0); 149 | CGContextStrokePath(context); 150 | } 151 | 152 | if (_hasBottomBorder) { 153 | // Bottom inset 154 | if (_showsInsets && _bottomInsetAlpha > 0.0) { 155 | CGContextSetStrokeColorWithColor(context, [UIColor colorWithWhite:1.0 alpha:_bottomInsetAlpha].CGColor); 156 | CGContextMoveToPoint(context, 0.0, rect.size.height - 1.0); 157 | CGContextAddLineToPoint(context, rect.size.width, rect.size.height - 1.0); 158 | CGContextStrokePath(context); 159 | } 160 | 161 | // Bottom border 162 | CGContextSetStrokeColorWithColor(context, _bottomBorderColor.CGColor); 163 | CGContextMoveToPoint(context, 0.0, rect.size.height); 164 | CGContextAddLineToPoint(context, rect.size.width, rect.size.height); 165 | CGContextStrokePath(context); 166 | } 167 | } 168 | 169 | #pragma mark Gradient Methods 170 | 171 | - (void)_refreshGradient { 172 | // TODO: Automatically convert colors into the same colorspace 173 | CGColorSpaceRef colorSpace = CGColorGetColorSpace(_topColor.CGColor); 174 | NSArray *colors = [NSArray arrayWithObjects:(id)_topColor.CGColor, (id)_bottomColor.CGColor, nil]; 175 | CGGradientRelease(_gradient); 176 | _gradient = CGGradientCreateWithColors(colorSpace, (CFArrayRef)colors, NULL); 177 | [self setNeedsDisplay]; 178 | } 179 | 180 | #pragma mark Observer 181 | 182 | - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { 183 | // Update the gradient and redraw if gradient colors changed 184 | if ([keyPath isEqualToString:@"topColor"] || [keyPath isEqualToString:@"bottomColor"]) { 185 | [self _refreshGradient]; 186 | return; 187 | } 188 | 189 | // Redraw if colors or borders changed 190 | if ([keyPath isEqualToString:@"topBorderColor"] || [keyPath isEqualToString:@"bottomBorderColor"] || 191 | [keyPath isEqualToString:@"topInsetAlpha"] || [keyPath isEqualToString:@"bottomInsetAlpha"] || 192 | [keyPath isEqualToString:@"hasTopBorder"] || [keyPath isEqualToString:@"hasBottomBorder"] || 193 | [keyPath isEqualToString:@"showsInsets"]) { 194 | [self setNeedsDisplay]; 195 | return; 196 | } 197 | 198 | [super observeValueForKeyPath:keyPath ofObject:object change:change context:context]; 199 | } 200 | 201 | @end 202 | -------------------------------------------------------------------------------- /TWToolkit/TWViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // TWViewController.m 3 | // TWToolkit 4 | // 5 | // Created by Sam Soffes on 7/14/10. 6 | // Copyright 2010 Tasteful Works. All rights reserved. 7 | // 8 | 9 | #import "TWViewController.h" 10 | #import "UIImage+TWToolkitAdditions.h" 11 | #import "UIView+TWToolkitAdditions.h" 12 | #import 13 | 14 | @interface TWViewController (PrivateMethods) 15 | - (void)_cleanUpModal; 16 | - (void)_presentModalAnimationDidStop:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context; 17 | - (void)_dismissModalAnimationDidStop:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context; 18 | - (void)_dismissVignetteAnimationDidStop:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context; 19 | @end 20 | 21 | 22 | @implementation TWViewController 23 | 24 | @synthesize modalParentViewController = _modalParentViewController; 25 | @synthesize customModalViewController = _customModalViewController; 26 | 27 | #pragma mark NSObject 28 | 29 | - (void)dealloc { 30 | [self _cleanUpModal]; 31 | [super dealloc]; 32 | } 33 | 34 | #pragma mark UIViewController 35 | 36 | - (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration { 37 | [UIView beginAnimations:@"rotate" context:self]; 38 | [UIView setAnimationDuration:duration]; 39 | [self layoutViewsWithOrientation:toInterfaceOrientation]; 40 | [UIView commitAnimations]; 41 | } 42 | 43 | 44 | - (void)viewWillAppear:(BOOL)animated { 45 | [self layoutViews]; 46 | } 47 | 48 | #pragma mark Layout 49 | 50 | - (void)layoutViews { 51 | [self layoutViewsWithOrientation:self.interfaceOrientation]; 52 | } 53 | 54 | 55 | - (void)layoutViewsWithOrientation:(UIInterfaceOrientation)orientation { 56 | CGSize size; 57 | 58 | // Landscape 59 | if (orientation == UIInterfaceOrientationLandscapeLeft || orientation == UIInterfaceOrientationLandscapeRight) { 60 | size = CGSizeMake(1024.0, 768.0); 61 | _vignetteView.frame = CGRectMake(0.0, -128.0, 1024.0, 1024.0); 62 | } 63 | 64 | // Portrait 65 | else { 66 | size = CGSizeMake(768.0, 1024.0); 67 | _vignetteView.frame = CGRectMake(-128.0, 0.0, 1024.0, 1024.0); 68 | } 69 | 70 | _modalContainerBackgroundView.frame = CGRectMake(roundf(size.width - 554.0) / 2.0, (roundf(size.height - 634.0) / 2.0), 554.0, 634.0); 71 | } 72 | 73 | #pragma mark Modal 74 | 75 | - (void)presentCustomModalViewController:(id)viewController { 76 | _customModalViewController = [viewController retain]; 77 | 78 | if (_customModalViewController == nil) { 79 | return; 80 | } 81 | 82 | _customModalViewController.modalParentViewController = self; 83 | 84 | if (_vignetteView == nil) { 85 | _vignetteView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"images/TWViewControllerModalVignetteiPad.png" bundle:@"TWToolkit.bundle"]]; 86 | _vignetteView.alpha = 0.0; 87 | _vignetteView.userInteractionEnabled = YES; 88 | } 89 | 90 | [self.view addSubview:_vignetteView]; 91 | [_vignetteView fadeIn]; 92 | 93 | if (_modalContainerBackgroundView == nil) { 94 | UIImage *modalBackgroundImage = [[UIImage imageNamed:@"images/TWViewControllerFormBackground.png" bundle:@"TWToolkit.bundle"] stretchableImageWithLeftCapWidth:43.0 topCapHeight:45.0]; 95 | _modalContainerBackgroundView = [[UIImageView alloc] initWithImage:modalBackgroundImage]; 96 | _modalContainerBackgroundView.autoresizesSubviews = NO; 97 | _modalContainerBackgroundView.userInteractionEnabled = YES; 98 | } 99 | 100 | [self.view addSubview:_modalContainerBackgroundView]; 101 | 102 | if (_modalContainerView == nil) { 103 | _modalContainerView = [[UIView alloc] initWithFrame:CGRectMake(7.0, 7.0, 540.0, 620.0)]; 104 | _modalContainerView.layer.cornerRadius = 5.0; 105 | _modalContainerView.clipsToBounds = YES; 106 | [_modalContainerBackgroundView addSubview:_modalContainerView]; 107 | } 108 | 109 | UIView *modalView = _customModalViewController.view; 110 | [_modalContainerView addSubview:modalView]; 111 | modalView.frame = CGRectMake(0.0, 0.0, 540.0, 620.0); 112 | 113 | CGSize size; 114 | if (self.interfaceOrientation == UIInterfaceOrientationLandscapeLeft || self.interfaceOrientation == UIInterfaceOrientationLandscapeRight) { 115 | size = CGSizeMake(1024.0, 768.0); 116 | } else { 117 | size = CGSizeMake(768.0, 1024.0); 118 | } 119 | 120 | _modalContainerBackgroundView.frame = CGRectMake(roundf(size.width - 554.0) / 2.0, (roundf(size.height - 634.0) / 2.0) + size.height, 554.0, 634.0); 121 | 122 | if ([_customModalViewController respondsToSelector:@selector(viewWillAppear:)]) { 123 | [_customModalViewController viewWillAppear:YES]; 124 | } 125 | [UIView beginAnimations:@"com.tastefulworks.twviewcontroller.present-modal" context:self]; 126 | [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut]; 127 | [UIView setAnimationDuration:0.5]; 128 | [UIView setAnimationDelegate:self]; 129 | [UIView setAnimationDidStopSelector:@selector(_presentModalAnimationDidStop:finished:context:)]; 130 | [self layoutViewsWithOrientation:self.interfaceOrientation]; 131 | [UIView commitAnimations]; 132 | } 133 | 134 | 135 | - (void)dismissCustomModalViewController { 136 | CGSize size; 137 | if (self.interfaceOrientation == UIInterfaceOrientationLandscapeLeft || self.interfaceOrientation == UIInterfaceOrientationLandscapeRight) { 138 | size = CGSizeMake(1024.0, 768.0); 139 | } else { 140 | size = CGSizeMake(768.0, 1024.0); 141 | } 142 | 143 | [UIView beginAnimations:@"com.tastefulworks.twviewcontroller.dismiss-modal" context:self]; 144 | [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut]; 145 | [UIView setAnimationDuration:0.4]; 146 | [UIView setAnimationDelegate:self]; 147 | [UIView setAnimationDidStopSelector:@selector(_dismissModalAnimationDidStop:finished:context:)]; 148 | _modalContainerBackgroundView.frame = CGRectMake(roundf(size.width - 554.0) / 2.0, (roundf(size.height - 634.0) / 2.0) + size.height, 554.0, 634.0); 149 | [UIView commitAnimations]; 150 | 151 | [UIView beginAnimations:@"com.tastefulworks.twviewcontroller.remove-vignette" context:self]; 152 | [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut]; 153 | [UIView setAnimationDelay:0.2]; 154 | [UIView setAnimationDelegate:self]; 155 | [UIView setAnimationDidStopSelector:@selector(_dismissVignetteAnimationDidStop:finished:context:)]; 156 | _vignetteView.alpha = 0.0; 157 | [UIView commitAnimations]; 158 | } 159 | 160 | #pragma mark Private Methods 161 | 162 | - (void)_cleanUpModal { 163 | [_modalContainerBackgroundView removeFromSuperview]; 164 | [_modalContainerBackgroundView release]; 165 | _modalContainerBackgroundView = nil; 166 | 167 | [_vignetteView removeFromSuperview]; 168 | [_vignetteView release]; 169 | _vignetteView = nil; 170 | 171 | [_customModalViewController release]; 172 | _customModalViewController = nil; 173 | 174 | [_modalContainerView release]; 175 | _modalContainerView = nil; 176 | } 177 | 178 | 179 | - (void)_presentModalAnimationDidStop:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context { 180 | if ([_customModalViewController respondsToSelector:@selector(viewDidAppear:)]) { 181 | [_customModalViewController viewDidAppear:YES]; 182 | } 183 | } 184 | 185 | 186 | - (void)_dismissModalAnimationDidStop:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context { 187 | if ([_customModalViewController respondsToSelector:@selector(viewDidDisappear:)]) { 188 | [_customModalViewController viewDidDisappear:YES]; 189 | } 190 | } 191 | 192 | 193 | - (void)_dismissVignetteAnimationDidStop:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context { 194 | [self _cleanUpModal]; 195 | } 196 | 197 | @end 198 | -------------------------------------------------------------------------------- /TWToolkit/NSString+TWToolkitAdditions.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSString+TWToolkitAdditions.m 3 | // TWToolkit 4 | // 5 | // Created by Sam Soffes on 6/22/09. 6 | // Copyright 2009 Tasteful Works, Inc. All rights reserved. 7 | // 8 | 9 | #import "NSString+TWToolkitAdditions.h" 10 | #include 11 | 12 | static const char encodingTable[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; 13 | 14 | @implementation NSString (TWToolkitAdditions) 15 | 16 | - (BOOL)containsString:(NSString *)string { 17 | return !NSEqualRanges([self rangeOfString:string], NSMakeRange(NSNotFound, 0)); 18 | } 19 | 20 | - (NSString *)MD5Sum { 21 | unsigned char digest[CC_MD5_DIGEST_LENGTH], i; 22 | CC_MD5([self UTF8String], [self lengthOfBytesUsingEncoding:NSUTF8StringEncoding], digest); 23 | NSMutableString *ms = [NSMutableString string]; 24 | for (i = 0; i < CC_MD5_DIGEST_LENGTH; i++) { 25 | [ms appendFormat: @"%02x", (int)(digest[i])]; 26 | } 27 | return [[ms copy] autorelease]; 28 | } 29 | 30 | 31 | // Adapted from http://snipplr.com/view/2771/compare-two-version-strings 32 | - (NSComparisonResult)compareToVersionString:(NSString *)version { 33 | NSInteger i; 34 | 35 | // Break version into fields (separated by '.') 36 | NSMutableArray *leftFields = [[NSMutableArray alloc] initWithArray:[self componentsSeparatedByString:@"."]]; 37 | NSMutableArray *rightFields = [[NSMutableArray alloc] initWithArray:[version componentsSeparatedByString:@"."]]; 38 | 39 | // Implict ".0" in case version doesn't have the same number of '.' 40 | if ([leftFields count] < [rightFields count]) { 41 | while ([leftFields count] != [rightFields count]) { 42 | [leftFields addObject:@"0"]; 43 | } 44 | } else if ([leftFields count] > [rightFields count]) { 45 | while ([leftFields count] != [rightFields count]) { 46 | [rightFields addObject:@"0"]; 47 | } 48 | } 49 | 50 | // Do a numeric comparison on each field 51 | for (i = 0; i < [leftFields count]; i++) { 52 | NSComparisonResult result = [[leftFields objectAtIndex:i] compare:[rightFields objectAtIndex:i] options:NSNumericSearch]; 53 | if (result != NSOrderedSame) { 54 | [leftFields release]; 55 | [rightFields release]; 56 | return result; 57 | } 58 | } 59 | 60 | [leftFields release]; 61 | [rightFields release]; 62 | return NSOrderedSame; 63 | } 64 | 65 | #pragma mark Localization Methods 66 | 67 | + (NSString *)localizedString:(NSString *)key { 68 | return [[[NSBundle mainBundle] localizedInfoDictionary] objectForKey:key]; 69 | } 70 | 71 | 72 | #pragma mark HTML Methods 73 | 74 | - (NSString *)escapeHTML { 75 | NSMutableString *s = [NSMutableString string]; 76 | 77 | int start = 0; 78 | int len = [self length]; 79 | NSCharacterSet *chs = [NSCharacterSet characterSetWithCharactersInString:@"<>&\""]; 80 | 81 | while (start < len) { 82 | NSRange r = [self rangeOfCharacterFromSet:chs options:0 range:NSMakeRange(start, len-start)]; 83 | if (r.location == NSNotFound) { 84 | [s appendString:[self substringFromIndex:start]]; 85 | break; 86 | } 87 | 88 | if (start < r.location) { 89 | [s appendString:[self substringWithRange:NSMakeRange(start, r.location-start)]]; 90 | } 91 | 92 | switch ([self characterAtIndex:r.location]) { 93 | case '<': 94 | [s appendString:@"<"]; 95 | break; 96 | case '>': 97 | [s appendString:@">"]; 98 | break; 99 | case '"': 100 | [s appendString:@"""]; 101 | break; 102 | // case '…': 103 | // [s appendString:@"…"]; 104 | // break; 105 | case '&': 106 | [s appendString:@"&"]; 107 | break; 108 | } 109 | 110 | start = r.location + 1; 111 | } 112 | 113 | return s; 114 | } 115 | 116 | 117 | - (NSString *)unescapeHTML { 118 | NSMutableString *s = [NSMutableString string]; 119 | NSMutableString *target = [[self mutableCopy] autorelease]; 120 | NSCharacterSet *chs = [NSCharacterSet characterSetWithCharactersInString:@"&"]; 121 | 122 | while ([target length] > 0) { 123 | NSRange r = [target rangeOfCharacterFromSet:chs]; 124 | if (r.location == NSNotFound) { 125 | [s appendString:target]; 126 | break; 127 | } 128 | 129 | if (r.location > 0) { 130 | [s appendString:[target substringToIndex:r.location]]; 131 | [target deleteCharactersInRange:NSMakeRange(0, r.location)]; 132 | } 133 | 134 | if ([target hasPrefix:@"<"]) { 135 | [s appendString:@"<"]; 136 | [target deleteCharactersInRange:NSMakeRange(0, 4)]; 137 | } else if ([target hasPrefix:@">"]) { 138 | [s appendString:@">"]; 139 | [target deleteCharactersInRange:NSMakeRange(0, 4)]; 140 | } else if ([target hasPrefix:@"""]) { 141 | [s appendString:@"\""]; 142 | [target deleteCharactersInRange:NSMakeRange(0, 6)]; 143 | } else if ([target hasPrefix:@"'"]) { 144 | [s appendString:@"'"]; 145 | [target deleteCharactersInRange:NSMakeRange(0, 5)]; 146 | } else if ([target hasPrefix:@"&"]) { 147 | [s appendString:@"&"]; 148 | [target deleteCharactersInRange:NSMakeRange(0, 5)]; 149 | } else if ([target hasPrefix:@"…"]) { 150 | [s appendString:@"…"]; 151 | [target deleteCharactersInRange:NSMakeRange(0, 8)]; 152 | } else { 153 | [s appendString:@"&"]; 154 | [target deleteCharactersInRange:NSMakeRange(0, 1)]; 155 | } 156 | } 157 | 158 | return s; 159 | } 160 | 161 | 162 | #pragma mark URL Methods 163 | 164 | - (NSString *)URLEncodedString { 165 | return [(NSString *)CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, 166 | (CFStringRef)self, 167 | NULL, 168 | CFSTR("!*'();:@&=+$,/?%#[]"), 169 | kCFStringEncodingUTF8) autorelease]; 170 | } 171 | 172 | 173 | - (NSString *)URLEncodedParameterString { 174 | NSString *result = (NSString *)CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, 175 | (CFStringRef)self, 176 | NULL, 177 | CFSTR(":/=,!$&'()*+;[]@#?"), 178 | kCFStringEncodingUTF8); 179 | return [result autorelease]; 180 | } 181 | 182 | 183 | - (NSString*)URLDecodedString { 184 | return [(NSString *)CFURLCreateStringByReplacingPercentEscapesUsingEncoding(kCFAllocatorDefault, 185 | (CFStringRef)self, 186 | CFSTR(""), 187 | kCFStringEncodingUTF8) autorelease]; 188 | } 189 | 190 | 191 | - (NSString *)removeQuotes { 192 | NSUInteger length = [self length]; 193 | NSString *ret = self; 194 | if ([self characterAtIndex:0] == '"') { 195 | ret = [ret substringFromIndex:1]; 196 | } 197 | if ([self characterAtIndex:length - 1] == '"') { 198 | ret = [ret substringToIndex:length - 2]; 199 | } 200 | 201 | return ret; 202 | } 203 | 204 | 205 | #pragma mark Base64 Methods 206 | 207 | - (NSString *)base64EncodedString { 208 | if ([self length] == 0) { 209 | return @""; 210 | } 211 | 212 | const char *source = [self UTF8String]; 213 | int strlength = strlen(source); 214 | 215 | char *characters = malloc(((strlength + 2) / 3) * 4); 216 | if (characters == NULL) { 217 | return nil; 218 | } 219 | 220 | NSUInteger length = 0; 221 | NSUInteger i = 0; 222 | 223 | while (i < strlength) { 224 | char buffer[3] = {0,0,0}; 225 | short bufferLength = 0; 226 | while (bufferLength < 3 && i < strlength) { 227 | buffer[bufferLength++] = source[i++]; 228 | } 229 | characters[length++] = encodingTable[(buffer[0] & 0xFC) >> 2]; 230 | characters[length++] = encodingTable[((buffer[0] & 0x03) << 4) | ((buffer[1] & 0xF0) >> 4)]; 231 | if (bufferLength > 1) { 232 | characters[length++] = encodingTable[((buffer[1] & 0x0F) << 2) | ((buffer[2] & 0xC0) >> 6)]; 233 | } else { 234 | characters[length++] = '='; 235 | } 236 | if (bufferLength > 2) { 237 | characters[length++] = encodingTable[buffer[2] & 0x3F]; 238 | } else { 239 | characters[length++] = '='; 240 | } 241 | } 242 | 243 | return [[[NSString alloc] initWithBytesNoCopy:characters length:length encoding:NSASCIIStringEncoding freeWhenDone:YES] autorelease]; 244 | } 245 | 246 | @end 247 | -------------------------------------------------------------------------------- /TWToolkit/TWWebView.m: -------------------------------------------------------------------------------- 1 | // 2 | // TWWebView.m 3 | // TWToolkit 4 | // 5 | // Created by Sam Soffes on 4/26/10. 6 | // Copyright 2010 Tasteful Works, Inc. All rights reserved. 7 | // 8 | 9 | #import "TWWebView.h" 10 | #import "NSString+TWToolkitAdditions.h" 11 | 12 | static NSTimeInterval kTWWebViewLoadDelay = 0.3; 13 | static BOOL TWWebViewIsBackedByScroller; 14 | static BOOL TWWebViewIsBackedByScrollerCached = NO; 15 | 16 | @interface TWWebView (PrivateMethods) 17 | 18 | + (BOOL)_isBackedByScroller; 19 | - (void)_loadingStatusChanged; 20 | - (void)_finishedLoading; 21 | - (void)_DOMLoaded; 22 | - (void)_injectCSS:(NSString *)css; 23 | 24 | @end 25 | 26 | 27 | @implementation TWWebView 28 | 29 | @synthesize delegate = _delegate; 30 | @synthesize scrollEnabled = _scrollEnabled; 31 | @synthesize bounces = _bounces; 32 | @synthesize shadowsHidden = _shadowsHidden; 33 | @synthesize consoleEnabled = _consoleEnabled; 34 | @synthesize lastRequest = _lastRequest; 35 | 36 | #pragma mark NSObject 37 | 38 | - (void)dealloc { 39 | // TODO: If you dealloc when the page is almost loaded, 40 | // _loadingStatusChanged still gets called sometimes causing a crash 41 | [[self class] cancelPreviousPerformRequestsWithTarget:self selector:@selector(_loadingStatusChanged) object:nil]; 42 | _delegate = nil; 43 | _webView.delegate = nil; 44 | [_webView stopLoading]; 45 | [_webView release]; 46 | [_persistedCSS release]; 47 | [_lastRequest release]; 48 | [super dealloc]; 49 | } 50 | 51 | #pragma mark UIView 52 | 53 | - (id)initWithFrame:(CGRect)frame { 54 | if (self = [super initWithFrame:frame]) { 55 | _webView = [[UIWebView alloc] initWithFrame:CGRectZero]; 56 | _webView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; 57 | _webView.delegate = self; 58 | [self addSubview:_webView]; 59 | 60 | _scrollEnabled = YES; 61 | _bounces = YES; 62 | _shadowsHidden = NO; 63 | _consoleEnabled = NO; 64 | } 65 | return self; 66 | } 67 | 68 | 69 | - (void)layoutSubviews { 70 | _webView.frame = CGRectMake(0.0, 0.0, self.frame.size.width, self.frame.size.height); 71 | } 72 | 73 | #pragma mark TWWebView Methods 74 | 75 | - (void)dismissKeyboard { 76 | [_webView stringByEvaluatingJavaScriptFromString:@"document.activeElement.blur()"]; 77 | } 78 | 79 | 80 | - (void)injectCSS:(NSString *)css { 81 | [self injectCSS:css persist:NO]; 82 | } 83 | 84 | 85 | - (void)injectCSS:(NSString *)css persist:(BOOL)persist { 86 | [self _injectCSS:css]; 87 | 88 | if (persist) { 89 | [_persistedCSS release]; 90 | _persistedCSS = [css retain]; 91 | } 92 | } 93 | 94 | #pragma mark Convenience Methods 95 | 96 | - (void)loadHTMLString:(NSString *)string { 97 | [self loadHTMLString:string baseURL:nil]; 98 | } 99 | 100 | 101 | - (void)loadURL:(NSURL *)aURL { 102 | [self loadRequest:[NSURLRequest requestWithURL:aURL]]; 103 | } 104 | 105 | 106 | - (void)loadURLString:(NSString *)string { 107 | if ([string hasPrefix:@"http://"] == NO && [string hasPrefix:@"https://"] == NO) { 108 | string = [NSString stringWithFormat:@"http://%@", string]; 109 | } 110 | [self loadURL:[NSURL URLWithString:string]]; 111 | } 112 | 113 | #pragma mark Private Methods 114 | 115 | + (BOOL)_isBackedByScroller { 116 | if (TWWebViewIsBackedByScrollerCached == NO) { 117 | TWWebViewIsBackedByScroller = [[[UIDevice currentDevice] systemVersion] compareToVersionString:@"3.2"] == NSOrderedDescending; 118 | TWWebViewIsBackedByScrollerCached = YES; 119 | } 120 | return TWWebViewIsBackedByScroller; 121 | } 122 | 123 | 124 | - (void)_loadingStatusChanged { 125 | if (self.loadingRequest == NO) { 126 | [self _finishedLoading]; 127 | } 128 | } 129 | 130 | 131 | - (void)_finishedLoading { 132 | if ([_delegate respondsToSelector:@selector(webViewDidFinishLoading:)]) { 133 | [_delegate webViewDidFinishLoading:self]; 134 | } 135 | } 136 | 137 | 138 | - (void)_DOMLoaded { 139 | // Reinject persisted CSS 140 | if (_persistedCSS) { 141 | [self _injectCSS:_persistedCSS]; 142 | } 143 | 144 | if ([_delegate respondsToSelector:@selector(webViewDidLoadDOM:)]) { 145 | [_delegate webViewDidLoadDOM:self]; 146 | } 147 | } 148 | 149 | 150 | - (void)_injectCSS:(NSString *)css { 151 | static NSString *injectCSSFormat = @"var styleTag=document.createElement('style');styleTag.setAttribute('type','text/css');styleTag.innerHTML='%@';document.getElementsByTagName('head')[0].appendChild(styleTag);"; 152 | [self stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:injectCSSFormat, css]]; 153 | } 154 | 155 | #pragma mark Getters 156 | 157 | - (BOOL)shadowsHidden { 158 | for (UIView *view in [_webView subviews]) { 159 | if ([view isKindOfClass:[UIScrollView class]]) { 160 | for (UIView *innerView in [view subviews]) { 161 | if ([innerView isKindOfClass:[UIImageView class]]) { 162 | return [innerView isHidden]; 163 | } 164 | } 165 | } 166 | } 167 | return NO; 168 | } 169 | 170 | #pragma mark Setters 171 | 172 | - (void)setOpaque:(BOOL)o { 173 | [super setOpaque:o]; 174 | _webView.opaque = o; 175 | } 176 | 177 | 178 | - (void)setBackgroundColor:(UIColor *)color { 179 | [super setBackgroundColor:color]; 180 | _webView.backgroundColor = color; 181 | } 182 | 183 | 184 | - (void)setScrollEnabled:(BOOL)enabled { 185 | if (_scrollEnabled == enabled) { 186 | return; 187 | } 188 | 189 | _scrollEnabled = enabled; 190 | 191 | // UIScroller in < 3.2 192 | if ([[self class] _isBackedByScroller]) { 193 | id scroller = [self.subviews objectAtIndex:0]; 194 | 195 | // This prevents the solution from be rejected 196 | NSString *selectorString = @""; 197 | selectorString = [selectorString stringByAppendingFormat:@"s"]; 198 | selectorString = [selectorString stringByAppendingFormat:@"e"]; 199 | selectorString = [selectorString stringByAppendingFormat:@"t"]; 200 | selectorString = [selectorString stringByAppendingFormat:@"S"]; 201 | selectorString = [selectorString stringByAppendingFormat:@"c"]; 202 | selectorString = [selectorString stringByAppendingFormat:@"r"]; 203 | selectorString = [selectorString stringByAppendingFormat:@"o"]; 204 | selectorString = [selectorString stringByAppendingFormat:@"l"]; 205 | selectorString = [selectorString stringByAppendingFormat:@"l"]; 206 | selectorString = [selectorString stringByAppendingFormat:@"i"]; 207 | selectorString = [selectorString stringByAppendingFormat:@"n"]; 208 | selectorString = [selectorString stringByAppendingFormat:@"g"]; 209 | selectorString = [selectorString stringByAppendingFormat:@"E"]; 210 | selectorString = [selectorString stringByAppendingFormat:@"n"]; 211 | selectorString = [selectorString stringByAppendingFormat:@"a"]; 212 | selectorString = [selectorString stringByAppendingFormat:@"b"]; 213 | selectorString = [selectorString stringByAppendingFormat:@"l"]; 214 | selectorString = [selectorString stringByAppendingFormat:@"e"]; 215 | selectorString = [selectorString stringByAppendingFormat:@"d"]; 216 | selectorString = [selectorString stringByAppendingFormat:@":"]; 217 | 218 | SEL selector = NSSelectorFromString(selectorString); 219 | 220 | if ([scroller respondsToSelector:selector]) { 221 | // Yay invocation magic 222 | NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[[scroller class] instanceMethodSignatureForSelector:selector]]; 223 | [invocation setSelector:selector]; 224 | [invocation setArgument:&_bounces atIndex:2]; 225 | [invocation invokeWithTarget:scroller]; 226 | } 227 | } 228 | 229 | // UIScrollView >= 3.2 230 | else { 231 | UIScrollView *scrollView = [_webView.subviews objectAtIndex:0]; 232 | scrollView.scrollEnabled = _scrollEnabled; 233 | } 234 | } 235 | 236 | 237 | - (void)setBounces:(BOOL)allow { 238 | if (_bounces == allow) { 239 | return; 240 | } 241 | 242 | _bounces = allow; 243 | 244 | // UIScroller in < 3.2 245 | if ([[self class] _isBackedByScroller]) { 246 | id scroller = [self.subviews objectAtIndex:0]; 247 | 248 | // Thanks @jakemarsh for this hacky workaround 249 | // This prevents the solution from be rejected 250 | NSString *selectorString = @""; 251 | selectorString = [selectorString stringByAppendingFormat:@"s"]; 252 | selectorString = [selectorString stringByAppendingFormat:@"e"]; 253 | selectorString = [selectorString stringByAppendingFormat:@"t"]; 254 | selectorString = [selectorString stringByAppendingFormat:@"A"]; 255 | selectorString = [selectorString stringByAppendingFormat:@"l"]; 256 | selectorString = [selectorString stringByAppendingFormat:@"l"]; 257 | selectorString = [selectorString stringByAppendingFormat:@"o"]; 258 | selectorString = [selectorString stringByAppendingFormat:@"w"]; 259 | selectorString = [selectorString stringByAppendingFormat:@"s"]; 260 | selectorString = [selectorString stringByAppendingFormat:@"R"]; 261 | selectorString = [selectorString stringByAppendingFormat:@"u"]; 262 | selectorString = [selectorString stringByAppendingFormat:@"b"]; 263 | selectorString = [selectorString stringByAppendingFormat:@"b"]; 264 | selectorString = [selectorString stringByAppendingFormat:@"e"]; 265 | selectorString = [selectorString stringByAppendingFormat:@"r"]; 266 | selectorString = [selectorString stringByAppendingFormat:@"B"]; 267 | selectorString = [selectorString stringByAppendingFormat:@"a"]; 268 | selectorString = [selectorString stringByAppendingFormat:@"n"]; 269 | selectorString = [selectorString stringByAppendingFormat:@"d"]; 270 | selectorString = [selectorString stringByAppendingFormat:@"i"]; 271 | selectorString = [selectorString stringByAppendingFormat:@"n"]; 272 | selectorString = [selectorString stringByAppendingFormat:@"g"]; 273 | selectorString = [selectorString stringByAppendingFormat:@":"]; 274 | 275 | SEL selector = NSSelectorFromString(selectorString); 276 | 277 | if ([scroller respondsToSelector:selector]) { 278 | // Yay invocation magic 279 | NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[[scroller class] instanceMethodSignatureForSelector:selector]]; 280 | [invocation setSelector:selector]; 281 | [invocation setArgument:&_bounces atIndex:2]; 282 | [invocation invokeWithTarget:scroller]; 283 | } 284 | } 285 | 286 | // UIScrollView >= 3.2 287 | else { 288 | UIScrollView *scrollView = [_webView.subviews objectAtIndex:0]; 289 | scrollView.bounces = _bounces; 290 | } 291 | } 292 | 293 | 294 | - (void)setShadowsHidden:(BOOL)hide { 295 | if (_shadowsHidden == hide) { 296 | return; 297 | } 298 | 299 | _shadowsHidden = hide; 300 | 301 | // Thanks @flyosity http://twitter.com/flyosity/status/17951035384 302 | for (UIView *view in [_webView subviews]) { 303 | if ([view isKindOfClass:[UIScrollView class]]) { 304 | for (UIView *innerView in [view subviews]) { 305 | if ([innerView isKindOfClass:[UIImageView class]]) { 306 | innerView.hidden = _shadowsHidden; 307 | } 308 | } 309 | } 310 | } 311 | } 312 | 313 | #pragma mark UIWebView Methods 314 | 315 | - (BOOL)canGoBack { 316 | return [_webView canGoBack]; 317 | } 318 | 319 | 320 | - (BOOL)canGoForward { 321 | return [_webView canGoForward]; 322 | } 323 | 324 | - (void)setDataDetectorTypes:(UIDataDetectorTypes)types { 325 | [_webView setDataDetectorTypes:types]; 326 | } 327 | 328 | 329 | - (UIDataDetectorTypes)dataDetectorTypes { 330 | return [_webView dataDetectorTypes]; 331 | } 332 | 333 | 334 | - (BOOL)isLoadingRequest { 335 | return [_webView isLoading]; 336 | } 337 | 338 | 339 | - (NSURLRequest *)request { 340 | return [_webView request]; 341 | } 342 | 343 | 344 | - (BOOL)scalesPageToFit { 345 | return [_webView scalesPageToFit]; 346 | } 347 | 348 | 349 | - (void)setScalesPageToFit:(BOOL)scales { 350 | [_webView setScalesPageToFit:scales]; 351 | } 352 | 353 | 354 | - (void)goBack { 355 | [_webView goBack]; 356 | } 357 | 358 | 359 | - (void)goForward { 360 | [_webView goForward]; 361 | } 362 | 363 | 364 | - (void)loadData:(NSData *)data MIMEType:(NSString *)MIMEType textEncodingName:(NSString *)encodingName baseURL:(NSURL *)baseURL { 365 | [_webView loadData:data MIMEType:MIMEType textEncodingName:encodingName baseURL:baseURL]; 366 | } 367 | 368 | 369 | - (void)loadHTMLString:(NSString *)string baseURL:(NSURL *)baseURL { 370 | if (!baseURL) { 371 | baseURL = [NSURL URLWithString:@"http://localhost"]; 372 | } 373 | [_webView loadHTMLString:string baseURL:baseURL]; 374 | } 375 | 376 | 377 | - (void)loadRequest:(NSURLRequest *)aRequest { 378 | [_webView loadRequest:aRequest]; 379 | } 380 | 381 | 382 | - (void)reload { 383 | [_lastRequest release]; 384 | _lastRequest = nil; 385 | [_webView reload]; 386 | } 387 | 388 | 389 | - (void)stopLoading { 390 | [_webView stopLoading]; 391 | } 392 | 393 | 394 | - (NSString *)stringByEvaluatingJavaScriptFromString:(NSString *)script { 395 | return [_webView stringByEvaluatingJavaScriptFromString:script]; 396 | } 397 | 398 | #pragma mark UIWebViewDelegate 399 | 400 | - (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error { 401 | // Reset load timer 402 | [[self class] cancelPreviousPerformRequestsWithTarget:self selector:@selector(_loadingStatusChanged) object:nil]; 403 | [self performSelector:@selector(_loadingStatusChanged) withObject:nil afterDelay:kTWWebViewLoadDelay]; 404 | 405 | // Forward delegate message 406 | if ([_delegate respondsToSelector:@selector(webView:didFailLoadWithError:)]) { 407 | [_delegate webView:self didFailLoadWithError:error]; 408 | } 409 | } 410 | 411 | 412 | - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)aRequest navigationType:(UIWebViewNavigationType)navigationType { 413 | BOOL should = YES; 414 | NSURL *url = [aRequest URL]; 415 | NSString *scheme = [url scheme]; 416 | 417 | // Check for DOM load message 418 | if ([scheme isEqual:@"x-twwebview"]) { 419 | NSString *host = [url host]; 420 | if ([host isEqual:@"dom-loaded"]) { 421 | [self _DOMLoaded]; 422 | } else if ([host isEqual:@"log"] && _consoleEnabled) { 423 | NSLog(@"[TWWebView Console] %@", [[url query] URLDecodedString]); 424 | } 425 | return NO; 426 | } 427 | 428 | // Forward delegate message 429 | if ([_delegate respondsToSelector:@selector(webView:shouldStartLoadWithRequest:navigationType:)]) { 430 | should = [_delegate webView:self shouldStartLoadWithRequest:aRequest navigationType:navigationType]; 431 | } 432 | 433 | // Only load http or http requests if delegate doesn't care 434 | else { 435 | should = [scheme isEqualToString:@"http"] || [scheme isEqualToString:@"https"] || [scheme isEqualToString:@"file"]; 436 | } 437 | 438 | // Stop if we shouldn't load it 439 | if (should == NO) { 440 | return NO; 441 | } 442 | 443 | // Starting a new request 444 | if ([[aRequest mainDocumentURL] isEqual:[_lastRequest mainDocumentURL]] == NO) { 445 | [_lastRequest release]; 446 | _lastRequest = [aRequest retain]; 447 | _testedDOM = NO; 448 | 449 | if ([_delegate respondsToSelector:@selector(webViewDidStartLoading:)]) { 450 | [_delegate webViewDidStartLoading:self]; 451 | } 452 | } 453 | 454 | // Child request for same page 455 | else { 456 | // Reset load timer 457 | [[self class] cancelPreviousPerformRequestsWithTarget:self selector:@selector(_loadingStatusChanged) object:nil]; 458 | } 459 | 460 | return should; 461 | } 462 | 463 | 464 | - (void)webViewDidFinishLoad:(UIWebView *)webView { 465 | // Reset load timer 466 | [[self class] cancelPreviousPerformRequestsWithTarget:self selector:@selector(_loadingStatusChanged) object:nil]; 467 | [self performSelector:@selector(_loadingStatusChanged) withObject:nil afterDelay:kTWWebViewLoadDelay]; 468 | 469 | // Check DOM 470 | if (_testedDOM == NO) { 471 | _testedDOM = YES; 472 | 473 | // The internal delegate will intercept this load and forward the event to the real delegate 474 | // Crazy javascript from http://dean.edwards.name/weblog/2006/06/again 475 | static NSString *testDOM = @"var _TWWebViewDOMLoadTimer=setInterval(function(){if(/loaded|complete/.test(document.readyState)){clearInterval(_TWWebViewDOMLoadTimer);location.href='x-twwebview://dom-loaded'}},10);"; 476 | [self stringByEvaluatingJavaScriptFromString:testDOM]; 477 | 478 | // Override console to pass messages to NSLog 479 | if (_consoleEnabled) { 480 | [self stringByEvaluatingJavaScriptFromString:@"console.log=function(msg){location.href='x-twwebview://log/?'+escape(msg.toString())}"]; 481 | } 482 | } 483 | 484 | // Forward delegate message 485 | if ([_delegate respondsToSelector:@selector(webViewDidFinishLoad:)]) { 486 | [_delegate webViewDidFinishLoad:self]; 487 | } 488 | } 489 | 490 | 491 | - (void)webViewDidStartLoad:(UIWebView *)webView { 492 | // Forward delegate message 493 | if ([_delegate respondsToSelector:@selector(webViewDidStartLoad:)]) { 494 | [_delegate webViewDidStartLoad:self]; 495 | } 496 | } 497 | 498 | @end 499 | -------------------------------------------------------------------------------- /TWCatalog/TWCatalog.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 45; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 1D3623260D0F684500981E51 /* TCAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D3623250D0F684500981E51 /* TCAppDelegate.m */; }; 11 | 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; 12 | 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; 13 | 288765FD0DF74451002DB57D /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 288765FC0DF74451002DB57D /* CoreGraphics.framework */; }; 14 | B21B85B41067D4A600E5C076 /* libTWToolkit.a in Frameworks */ = {isa = PBXBuildFile; fileRef = B21B85B31067D4A300E5C076 /* libTWToolkit.a */; }; 15 | B21B85B81067D4B500E5C076 /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B21B85B71067D4B500E5C076 /* SystemConfiguration.framework */; }; 16 | B21B85BE1067D4F300E5C076 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = B21B85BC1067D4F300E5C076 /* main.m */; }; 17 | B21B86441067D7EA00E5C076 /* libsqlite3.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = B21B86431067D7EA00E5C076 /* libsqlite3.dylib */; }; 18 | B22A28E410B4762200EA6CD9 /* TCHUDViewDemoViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B22A28E310B4762200EA6CD9 /* TCHUDViewDemoViewController.m */; }; 19 | B22A2A8C10B4916500EA6CD9 /* TWToolkit.bundle in Resources */ = {isa = PBXBuildFile; fileRef = B22A2A8B10B4916500EA6CD9 /* TWToolkit.bundle */; }; 20 | B23A3461117C92F20085E48A /* TCLineViewDemoViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B23A3460117C92F20085E48A /* TCLineViewDemoViewController.m */; }; 21 | B24521CD1211AF2800E80F78 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B24521CC1211AF2800E80F78 /* Security.framework */; }; 22 | B2503BCC10A90E34009B0E7B /* TCGradientViewDemoViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B2503BCB10A90E34009B0E7B /* TCGradientViewDemoViewController.m */; }; 23 | B27C60EC107FFD1D00F7FBD7 /* TCRootViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B27C60EB107FFD1D00F7FBD7 /* TCRootViewController.m */; }; 24 | B27C61271080003700F7FBD7 /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = B27C61261080003700F7FBD7 /* Default.png */; }; 25 | B27C613D108000FC00F7FBD7 /* TCPickerDemoViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B27C613C108000FC00F7FBD7 /* TCPickerDemoViewController.m */; }; 26 | B27C61841080037D00F7FBD7 /* TCPickerDetailViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B27C61831080037D00F7FBD7 /* TCPickerDetailViewController.m */; }; 27 | B27C6196108006C900F7FBD7 /* placeholder.png in Resources */ = {isa = PBXBuildFile; fileRef = B27C6195108006C900F7FBD7 /* placeholder.png */; }; 28 | B27FDDBF10A49B660076DC56 /* Icon.png in Resources */ = {isa = PBXBuildFile; fileRef = B27FDDBE10A49B660076DC56 /* Icon.png */; }; 29 | B27FDDC910A49C350076DC56 /* iTunesArtwork in Resources */ = {isa = PBXBuildFile; fileRef = B27FDDC810A49C350076DC56 /* iTunesArtwork */; }; 30 | B2C682A61149552D006EDD71 /* TCMessagesDemoViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B2C682A51149552D006EDD71 /* TCMessagesDemoViewController.m */; }; 31 | B2ED13551181434200FAAA13 /* TCPieProgressViewDemoViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B2ED13541181434200FAAA13 /* TCPieProgressViewDemoViewController.m */; }; 32 | /* End PBXBuildFile section */ 33 | 34 | /* Begin PBXContainerItemProxy section */ 35 | B21B85B21067D4A300E5C076 /* PBXContainerItemProxy */ = { 36 | isa = PBXContainerItemProxy; 37 | containerPortal = B21B85AB1067D4A300E5C076 /* TWToolkit.xcodeproj */; 38 | proxyType = 2; 39 | remoteGlobalIDString = D2AAC07E0554694100DB518D; 40 | remoteInfo = TWToolkit; 41 | }; 42 | B21B85B51067D4AD00E5C076 /* PBXContainerItemProxy */ = { 43 | isa = PBXContainerItemProxy; 44 | containerPortal = B21B85AB1067D4A300E5C076 /* TWToolkit.xcodeproj */; 45 | proxyType = 1; 46 | remoteGlobalIDString = D2AAC07D0554694100DB518D; 47 | remoteInfo = TWToolkit; 48 | }; 49 | /* End PBXContainerItemProxy section */ 50 | 51 | /* Begin PBXFileReference section */ 52 | 1D30AB110D05D00D00671497 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 53 | 1D3623240D0F684500981E51 /* TCAppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TCAppDelegate.h; sourceTree = ""; }; 54 | 1D3623250D0F684500981E51 /* TCAppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TCAppDelegate.m; sourceTree = ""; }; 55 | 1D6058910D05DD3D006BFB54 /* TWCatalog.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = TWCatalog.app; sourceTree = BUILT_PRODUCTS_DIR; }; 56 | 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 57 | 288765FC0DF74451002DB57D /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; 58 | B21B85AB1067D4A300E5C076 /* TWToolkit.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = TWToolkit.xcodeproj; path = ../TWToolkit.xcodeproj; sourceTree = SOURCE_ROOT; }; 59 | B21B85B71067D4B500E5C076 /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; }; 60 | B21B85BC1067D4F300E5C076 /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 61 | B21B85BD1067D4F300E5C076 /* TWCatalog_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TWCatalog_Prefix.pch; sourceTree = ""; }; 62 | B21B85C01067D4FD00E5C076 /* TWCatalog-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "TWCatalog-Info.plist"; sourceTree = ""; }; 63 | B21B86431067D7EA00E5C076 /* libsqlite3.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libsqlite3.dylib; path = usr/lib/libsqlite3.dylib; sourceTree = SDKROOT; }; 64 | B22A28E210B4762200EA6CD9 /* TCHUDViewDemoViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TCHUDViewDemoViewController.h; sourceTree = ""; }; 65 | B22A28E310B4762200EA6CD9 /* TCHUDViewDemoViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TCHUDViewDemoViewController.m; sourceTree = ""; }; 66 | B22A2A8B10B4916500EA6CD9 /* TWToolkit.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; name = TWToolkit.bundle; path = ../Resources/TWToolkit.bundle; sourceTree = SOURCE_ROOT; }; 67 | B23A345F117C92F20085E48A /* TCLineViewDemoViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TCLineViewDemoViewController.h; sourceTree = ""; }; 68 | B23A3460117C92F20085E48A /* TCLineViewDemoViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TCLineViewDemoViewController.m; sourceTree = ""; }; 69 | B24521CC1211AF2800E80F78 /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = iphoneos3.0/System/Library/Frameworks/Security.framework; sourceTree = ""; }; 70 | B2503BCA10A90E34009B0E7B /* TCGradientViewDemoViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TCGradientViewDemoViewController.h; sourceTree = ""; }; 71 | B2503BCB10A90E34009B0E7B /* TCGradientViewDemoViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TCGradientViewDemoViewController.m; sourceTree = ""; }; 72 | B27C60EA107FFD1D00F7FBD7 /* TCRootViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TCRootViewController.h; sourceTree = ""; }; 73 | B27C60EB107FFD1D00F7FBD7 /* TCRootViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TCRootViewController.m; sourceTree = ""; }; 74 | B27C61261080003700F7FBD7 /* Default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Default.png; sourceTree = ""; }; 75 | B27C613B108000FC00F7FBD7 /* TCPickerDemoViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TCPickerDemoViewController.h; sourceTree = ""; }; 76 | B27C613C108000FC00F7FBD7 /* TCPickerDemoViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TCPickerDemoViewController.m; sourceTree = ""; }; 77 | B27C61821080037D00F7FBD7 /* TCPickerDetailViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TCPickerDetailViewController.h; sourceTree = ""; }; 78 | B27C61831080037D00F7FBD7 /* TCPickerDetailViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TCPickerDetailViewController.m; sourceTree = ""; }; 79 | B27C6195108006C900F7FBD7 /* placeholder.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = placeholder.png; sourceTree = ""; }; 80 | B27FDDBE10A49B660076DC56 /* Icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Icon.png; sourceTree = ""; }; 81 | B27FDDC810A49C350076DC56 /* iTunesArtwork */ = {isa = PBXFileReference; lastKnownFileType = file; path = iTunesArtwork; sourceTree = ""; }; 82 | B2C682A41149552D006EDD71 /* TCMessagesDemoViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TCMessagesDemoViewController.h; sourceTree = ""; }; 83 | B2C682A51149552D006EDD71 /* TCMessagesDemoViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TCMessagesDemoViewController.m; sourceTree = ""; }; 84 | B2ED13531181434200FAAA13 /* TCPieProgressViewDemoViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TCPieProgressViewDemoViewController.h; sourceTree = ""; }; 85 | B2ED13541181434200FAAA13 /* TCPieProgressViewDemoViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TCPieProgressViewDemoViewController.m; sourceTree = ""; }; 86 | /* End PBXFileReference section */ 87 | 88 | /* Begin PBXFrameworksBuildPhase section */ 89 | 1D60588F0D05DD3D006BFB54 /* Frameworks */ = { 90 | isa = PBXFrameworksBuildPhase; 91 | buildActionMask = 2147483647; 92 | files = ( 93 | 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */, 94 | 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */, 95 | 288765FD0DF74451002DB57D /* CoreGraphics.framework in Frameworks */, 96 | B21B85B41067D4A600E5C076 /* libTWToolkit.a in Frameworks */, 97 | B21B85B81067D4B500E5C076 /* SystemConfiguration.framework in Frameworks */, 98 | B21B86441067D7EA00E5C076 /* libsqlite3.dylib in Frameworks */, 99 | B24521CD1211AF2800E80F78 /* Security.framework in Frameworks */, 100 | ); 101 | runOnlyForDeploymentPostprocessing = 0; 102 | }; 103 | /* End PBXFrameworksBuildPhase section */ 104 | 105 | /* Begin PBXGroup section */ 106 | 080E96DDFE201D6D7F000001 /* Classes */ = { 107 | isa = PBXGroup; 108 | children = ( 109 | B2C6828811495412006EDD71 /* Demo */, 110 | B2ED1351118142ED00FAAA13 /* Views */, 111 | B2ED1352118142F100FAAA13 /* View Controllers */, 112 | ); 113 | path = Classes; 114 | sourceTree = ""; 115 | }; 116 | 19C28FACFE9D520D11CA2CBB /* Products */ = { 117 | isa = PBXGroup; 118 | children = ( 119 | 1D6058910D05DD3D006BFB54 /* TWCatalog.app */, 120 | ); 121 | name = Products; 122 | sourceTree = ""; 123 | }; 124 | 29B97314FDCFA39411CA2CEA /* CustomTemplate */ = { 125 | isa = PBXGroup; 126 | children = ( 127 | 080E96DDFE201D6D7F000001 /* Classes */, 128 | B21B85BB1067D4F300E5C076 /* Other Sources */, 129 | B21B85BF1067D4FD00E5C076 /* Resources */, 130 | 29B97323FDCFA39411CA2CEA /* Frameworks */, 131 | 19C28FACFE9D520D11CA2CBB /* Products */, 132 | ); 133 | name = CustomTemplate; 134 | sourceTree = ""; 135 | }; 136 | 29B97323FDCFA39411CA2CEA /* Frameworks */ = { 137 | isa = PBXGroup; 138 | children = ( 139 | B21B85AB1067D4A300E5C076 /* TWToolkit.xcodeproj */, 140 | B21B86431067D7EA00E5C076 /* libsqlite3.dylib */, 141 | B21B85B71067D4B500E5C076 /* SystemConfiguration.framework */, 142 | 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */, 143 | 1D30AB110D05D00D00671497 /* Foundation.framework */, 144 | 288765FC0DF74451002DB57D /* CoreGraphics.framework */, 145 | B24521CC1211AF2800E80F78 /* Security.framework */, 146 | ); 147 | name = Frameworks; 148 | sourceTree = ""; 149 | }; 150 | B21B85AC1067D4A300E5C076 /* Products */ = { 151 | isa = PBXGroup; 152 | children = ( 153 | B21B85B31067D4A300E5C076 /* libTWToolkit.a */, 154 | ); 155 | name = Products; 156 | sourceTree = ""; 157 | }; 158 | B21B85BB1067D4F300E5C076 /* Other Sources */ = { 159 | isa = PBXGroup; 160 | children = ( 161 | B21B85BC1067D4F300E5C076 /* main.m */, 162 | B21B85BD1067D4F300E5C076 /* TWCatalog_Prefix.pch */, 163 | ); 164 | path = "Other Sources"; 165 | sourceTree = ""; 166 | }; 167 | B21B85BF1067D4FD00E5C076 /* Resources */ = { 168 | isa = PBXGroup; 169 | children = ( 170 | B22A2A8B10B4916500EA6CD9 /* TWToolkit.bundle */, 171 | B27FDDC810A49C350076DC56 /* iTunesArtwork */, 172 | B27FDDBE10A49B660076DC56 /* Icon.png */, 173 | B27C6195108006C900F7FBD7 /* placeholder.png */, 174 | B27C61261080003700F7FBD7 /* Default.png */, 175 | B21B85C01067D4FD00E5C076 /* TWCatalog-Info.plist */, 176 | ); 177 | path = Resources; 178 | sourceTree = ""; 179 | }; 180 | B22A28E110B4761800EA6CD9 /* HUD View */ = { 181 | isa = PBXGroup; 182 | children = ( 183 | B22A28E210B4762200EA6CD9 /* TCHUDViewDemoViewController.h */, 184 | B22A28E310B4762200EA6CD9 /* TCHUDViewDemoViewController.m */, 185 | ); 186 | name = "HUD View"; 187 | sourceTree = ""; 188 | }; 189 | B23A345E117C92E90085E48A /* Line View */ = { 190 | isa = PBXGroup; 191 | children = ( 192 | B23A345F117C92F20085E48A /* TCLineViewDemoViewController.h */, 193 | B23A3460117C92F20085E48A /* TCLineViewDemoViewController.m */, 194 | ); 195 | name = "Line View"; 196 | sourceTree = ""; 197 | }; 198 | B2503BC910A90E28009B0E7B /* Gradient View */ = { 199 | isa = PBXGroup; 200 | children = ( 201 | B2503BCA10A90E34009B0E7B /* TCGradientViewDemoViewController.h */, 202 | B2503BCB10A90E34009B0E7B /* TCGradientViewDemoViewController.m */, 203 | ); 204 | name = "Gradient View"; 205 | sourceTree = ""; 206 | }; 207 | B2A67B3010A8838100E266F5 /* Settings Picker */ = { 208 | isa = PBXGroup; 209 | children = ( 210 | B27C613B108000FC00F7FBD7 /* TCPickerDemoViewController.h */, 211 | B27C613C108000FC00F7FBD7 /* TCPickerDemoViewController.m */, 212 | B27C61821080037D00F7FBD7 /* TCPickerDetailViewController.h */, 213 | B27C61831080037D00F7FBD7 /* TCPickerDetailViewController.m */, 214 | ); 215 | name = "Settings Picker"; 216 | sourceTree = ""; 217 | }; 218 | B2C6828811495412006EDD71 /* Demo */ = { 219 | isa = PBXGroup; 220 | children = ( 221 | 1D3623240D0F684500981E51 /* TCAppDelegate.h */, 222 | 1D3623250D0F684500981E51 /* TCAppDelegate.m */, 223 | B27C60EA107FFD1D00F7FBD7 /* TCRootViewController.h */, 224 | B27C60EB107FFD1D00F7FBD7 /* TCRootViewController.m */, 225 | ); 226 | name = Demo; 227 | sourceTree = ""; 228 | }; 229 | B2C682A311495524006EDD71 /* Messages */ = { 230 | isa = PBXGroup; 231 | children = ( 232 | B2C682A41149552D006EDD71 /* TCMessagesDemoViewController.h */, 233 | B2C682A51149552D006EDD71 /* TCMessagesDemoViewController.m */, 234 | ); 235 | name = Messages; 236 | sourceTree = ""; 237 | }; 238 | B2ED133D118142A100FAAA13 /* Pie Progress View */ = { 239 | isa = PBXGroup; 240 | children = ( 241 | B2ED13531181434200FAAA13 /* TCPieProgressViewDemoViewController.h */, 242 | B2ED13541181434200FAAA13 /* TCPieProgressViewDemoViewController.m */, 243 | ); 244 | name = "Pie Progress View"; 245 | sourceTree = ""; 246 | }; 247 | B2ED1351118142ED00FAAA13 /* Views */ = { 248 | isa = PBXGroup; 249 | children = ( 250 | B2503BC910A90E28009B0E7B /* Gradient View */, 251 | B22A28E110B4761800EA6CD9 /* HUD View */, 252 | B23A345E117C92E90085E48A /* Line View */, 253 | B2ED133D118142A100FAAA13 /* Pie Progress View */, 254 | ); 255 | name = Views; 256 | sourceTree = ""; 257 | }; 258 | B2ED1352118142F100FAAA13 /* View Controllers */ = { 259 | isa = PBXGroup; 260 | children = ( 261 | B2A67B3010A8838100E266F5 /* Settings Picker */, 262 | B2C682A311495524006EDD71 /* Messages */, 263 | ); 264 | name = "View Controllers"; 265 | sourceTree = ""; 266 | }; 267 | /* End PBXGroup section */ 268 | 269 | /* Begin PBXNativeTarget section */ 270 | 1D6058900D05DD3D006BFB54 /* TWCatalog */ = { 271 | isa = PBXNativeTarget; 272 | buildConfigurationList = 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "TWCatalog" */; 273 | buildPhases = ( 274 | 1D60588D0D05DD3D006BFB54 /* Resources */, 275 | 1D60588E0D05DD3D006BFB54 /* Sources */, 276 | 1D60588F0D05DD3D006BFB54 /* Frameworks */, 277 | ); 278 | buildRules = ( 279 | ); 280 | dependencies = ( 281 | B21B85B61067D4AD00E5C076 /* PBXTargetDependency */, 282 | ); 283 | name = TWCatalog; 284 | productName = TWCatalog; 285 | productReference = 1D6058910D05DD3D006BFB54 /* TWCatalog.app */; 286 | productType = "com.apple.product-type.application"; 287 | }; 288 | /* End PBXNativeTarget section */ 289 | 290 | /* Begin PBXProject section */ 291 | 29B97313FDCFA39411CA2CEA /* Project object */ = { 292 | isa = PBXProject; 293 | attributes = { 294 | ORGANIZATIONNAME = "Tasteful Works, Inc"; 295 | }; 296 | buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "TWCatalog" */; 297 | compatibilityVersion = "Xcode 3.1"; 298 | hasScannedForEncodings = 1; 299 | mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */; 300 | projectDirPath = ""; 301 | projectReferences = ( 302 | { 303 | ProductGroup = B21B85AC1067D4A300E5C076 /* Products */; 304 | ProjectRef = B21B85AB1067D4A300E5C076 /* TWToolkit.xcodeproj */; 305 | }, 306 | ); 307 | projectRoot = ""; 308 | targets = ( 309 | 1D6058900D05DD3D006BFB54 /* TWCatalog */, 310 | ); 311 | }; 312 | /* End PBXProject section */ 313 | 314 | /* Begin PBXReferenceProxy section */ 315 | B21B85B31067D4A300E5C076 /* libTWToolkit.a */ = { 316 | isa = PBXReferenceProxy; 317 | fileType = archive.ar; 318 | path = libTWToolkit.a; 319 | remoteRef = B21B85B21067D4A300E5C076 /* PBXContainerItemProxy */; 320 | sourceTree = BUILT_PRODUCTS_DIR; 321 | }; 322 | /* End PBXReferenceProxy section */ 323 | 324 | /* Begin PBXResourcesBuildPhase section */ 325 | 1D60588D0D05DD3D006BFB54 /* Resources */ = { 326 | isa = PBXResourcesBuildPhase; 327 | buildActionMask = 2147483647; 328 | files = ( 329 | B27C61271080003700F7FBD7 /* Default.png in Resources */, 330 | B27C6196108006C900F7FBD7 /* placeholder.png in Resources */, 331 | B27FDDBF10A49B660076DC56 /* Icon.png in Resources */, 332 | B27FDDC910A49C350076DC56 /* iTunesArtwork in Resources */, 333 | B22A2A8C10B4916500EA6CD9 /* TWToolkit.bundle in Resources */, 334 | ); 335 | runOnlyForDeploymentPostprocessing = 0; 336 | }; 337 | /* End PBXResourcesBuildPhase section */ 338 | 339 | /* Begin PBXSourcesBuildPhase section */ 340 | 1D60588E0D05DD3D006BFB54 /* Sources */ = { 341 | isa = PBXSourcesBuildPhase; 342 | buildActionMask = 2147483647; 343 | files = ( 344 | 1D3623260D0F684500981E51 /* TCAppDelegate.m in Sources */, 345 | B21B85BE1067D4F300E5C076 /* main.m in Sources */, 346 | B27C60EC107FFD1D00F7FBD7 /* TCRootViewController.m in Sources */, 347 | B27C613D108000FC00F7FBD7 /* TCPickerDemoViewController.m in Sources */, 348 | B27C61841080037D00F7FBD7 /* TCPickerDetailViewController.m in Sources */, 349 | B2503BCC10A90E34009B0E7B /* TCGradientViewDemoViewController.m in Sources */, 350 | B22A28E410B4762200EA6CD9 /* TCHUDViewDemoViewController.m in Sources */, 351 | B2C682A61149552D006EDD71 /* TCMessagesDemoViewController.m in Sources */, 352 | B23A3461117C92F20085E48A /* TCLineViewDemoViewController.m in Sources */, 353 | B2ED13551181434200FAAA13 /* TCPieProgressViewDemoViewController.m in Sources */, 354 | ); 355 | runOnlyForDeploymentPostprocessing = 0; 356 | }; 357 | /* End PBXSourcesBuildPhase section */ 358 | 359 | /* Begin PBXTargetDependency section */ 360 | B21B85B61067D4AD00E5C076 /* PBXTargetDependency */ = { 361 | isa = PBXTargetDependency; 362 | name = TWToolkit; 363 | targetProxy = B21B85B51067D4AD00E5C076 /* PBXContainerItemProxy */; 364 | }; 365 | /* End PBXTargetDependency section */ 366 | 367 | /* Begin XCBuildConfiguration section */ 368 | 1D6058940D05DD3E006BFB54 /* Debug */ = { 369 | isa = XCBuildConfiguration; 370 | buildSettings = { 371 | ALWAYS_SEARCH_USER_PATHS = NO; 372 | COPY_PHASE_STRIP = NO; 373 | GCC_DYNAMIC_NO_PIC = NO; 374 | GCC_OPTIMIZATION_LEVEL = 0; 375 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 376 | GCC_PREFIX_HEADER = "Other Sources/TWCatalog_Prefix.pch"; 377 | HEADER_SEARCH_PATHS = ../; 378 | INFOPLIST_FILE = "Resources/TWCatalog-Info.plist"; 379 | OTHER_LDFLAGS = ( 380 | "-ObjC", 381 | "-all_load", 382 | ); 383 | PRODUCT_NAME = TWCatalog; 384 | SDKROOT = iphoneos4.0; 385 | }; 386 | name = Debug; 387 | }; 388 | 1D6058950D05DD3E006BFB54 /* Release */ = { 389 | isa = XCBuildConfiguration; 390 | buildSettings = { 391 | ALWAYS_SEARCH_USER_PATHS = NO; 392 | COPY_PHASE_STRIP = YES; 393 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 394 | GCC_PREFIX_HEADER = "Other Sources/TWCatalog_Prefix.pch"; 395 | HEADER_SEARCH_PATHS = ../; 396 | INFOPLIST_FILE = "TWCatalog-Info.plist"; 397 | PRODUCT_NAME = TWCatalog; 398 | }; 399 | name = Release; 400 | }; 401 | C01FCF4F08A954540054247B /* Debug */ = { 402 | isa = XCBuildConfiguration; 403 | buildSettings = { 404 | ARCHS = "$(ARCHS_STANDARD_32_BIT)"; 405 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 406 | GCC_C_LANGUAGE_STANDARD = c99; 407 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 408 | GCC_WARN_UNUSED_VARIABLE = YES; 409 | PREBINDING = NO; 410 | SDKROOT = iphoneos3.0; 411 | }; 412 | name = Debug; 413 | }; 414 | C01FCF5008A954540054247B /* Release */ = { 415 | isa = XCBuildConfiguration; 416 | buildSettings = { 417 | ARCHS = "$(ARCHS_STANDARD_32_BIT)"; 418 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 419 | GCC_C_LANGUAGE_STANDARD = c99; 420 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 421 | GCC_WARN_UNUSED_VARIABLE = YES; 422 | PREBINDING = NO; 423 | SDKROOT = iphoneos3.0; 424 | }; 425 | name = Release; 426 | }; 427 | /* End XCBuildConfiguration section */ 428 | 429 | /* Begin XCConfigurationList section */ 430 | 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "TWCatalog" */ = { 431 | isa = XCConfigurationList; 432 | buildConfigurations = ( 433 | 1D6058940D05DD3E006BFB54 /* Debug */, 434 | 1D6058950D05DD3E006BFB54 /* Release */, 435 | ); 436 | defaultConfigurationIsVisible = 0; 437 | defaultConfigurationName = Release; 438 | }; 439 | C01FCF4E08A954540054247B /* Build configuration list for PBXProject "TWCatalog" */ = { 440 | isa = XCConfigurationList; 441 | buildConfigurations = ( 442 | C01FCF4F08A954540054247B /* Debug */, 443 | C01FCF5008A954540054247B /* Release */, 444 | ); 445 | defaultConfigurationIsVisible = 0; 446 | defaultConfigurationName = Release; 447 | }; 448 | /* End XCConfigurationList section */ 449 | }; 450 | rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; 451 | } 452 | -------------------------------------------------------------------------------- /TWToolkit.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 45; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | AACBBE4A0F95108600F1A2B1 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AACBBE490F95108600F1A2B1 /* Foundation.framework */; }; 11 | B213D07C11AE1D1D00BACA8D /* NSDate+TWToolkitAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = B213D07A11AE1D1D00BACA8D /* NSDate+TWToolkitAdditions.h */; }; 12 | B213D07D11AE1D1D00BACA8D /* NSDate+TWToolkitAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = B213D07B11AE1D1D00BACA8D /* NSDate+TWToolkitAdditions.m */; }; 13 | B215045F10583A7300409ED4 /* TWToolkit_Prefix.pch in Headers */ = {isa = PBXBuildFile; fileRef = B215045E10583A7300409ED4 /* TWToolkit_Prefix.pch */; }; 14 | B21504CA10583B4000409ED4 /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B21504C910583B4000409ED4 /* SystemConfiguration.framework */; }; 15 | B215051210583BBB00409ED4 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B215051110583BBB00409ED4 /* UIKit.framework */; }; 16 | B215ACCC117363D9002562A4 /* UIScrollView+TWToolkitAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = B215ACCA117363D9002562A4 /* UIScrollView+TWToolkitAdditions.h */; }; 17 | B215ACCD117363D9002562A4 /* UIScrollView+TWToolkitAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = B215ACCB117363D9002562A4 /* UIScrollView+TWToolkitAdditions.m */; }; 18 | B215ADAE1173770F002562A4 /* TWLineView.h in Headers */ = {isa = PBXBuildFile; fileRef = B215ADAC1173770F002562A4 /* TWLineView.h */; }; 19 | B215ADAF1173770F002562A4 /* TWLineView.m in Sources */ = {isa = PBXBuildFile; fileRef = B215ADAD1173770F002562A4 /* TWLineView.m */; }; 20 | B21D2EF61185ED25009F7206 /* TWWebView.h in Headers */ = {isa = PBXBuildFile; fileRef = B21D2EF41185ED25009F7206 /* TWWebView.h */; }; 21 | B21D2EF71185ED25009F7206 /* TWWebView.m in Sources */ = {isa = PBXBuildFile; fileRef = B21D2EF51185ED25009F7206 /* TWWebView.m */; }; 22 | B24244E611498A480061E255 /* TWTextField.h in Headers */ = {isa = PBXBuildFile; fileRef = B24244E411498A480061E255 /* TWTextField.h */; }; 23 | B24244E711498A480061E255 /* TWTextField.m in Sources */ = {isa = PBXBuildFile; fileRef = B24244E511498A480061E255 /* TWTextField.m */; }; 24 | B24B551810B36F6B0014994C /* UIImage+TWToolkitAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = B24B551610B36F6B0014994C /* UIImage+TWToolkitAdditions.h */; }; 25 | B24B551910B36F6B0014994C /* UIImage+TWToolkitAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = B24B551710B36F6B0014994C /* UIImage+TWToolkitAdditions.m */; }; 26 | B2503B9510A90DA6009B0E7B /* TWGradientView.h in Headers */ = {isa = PBXBuildFile; fileRef = B2503B9310A90DA6009B0E7B /* TWGradientView.h */; }; 27 | B2503B9610A90DA6009B0E7B /* TWGradientView.m in Sources */ = {isa = PBXBuildFile; fileRef = B2503B9410A90DA6009B0E7B /* TWGradientView.m */; }; 28 | B253C1FA10728DC500E0CE10 /* TWHUDView.h in Headers */ = {isa = PBXBuildFile; fileRef = B253C1F810728DC500E0CE10 /* TWHUDView.h */; }; 29 | B253C1FB10728DC500E0CE10 /* TWHUDView.m in Sources */ = {isa = PBXBuildFile; fileRef = B253C1F910728DC500E0CE10 /* TWHUDView.m */; }; 30 | B25E614011CFBA34001DA5CD /* UIViewController+TWToolkitAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = B25E613E11CFBA34001DA5CD /* UIViewController+TWToolkitAdditions.h */; }; 31 | B25E614111CFBA34001DA5CD /* UIViewController+TWToolkitAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = B25E613F11CFBA34001DA5CD /* UIViewController+TWToolkitAdditions.m */; }; 32 | B26184C7121C6C51009AB3B4 /* TWTextView.h in Headers */ = {isa = PBXBuildFile; fileRef = B26184C5121C6C51009AB3B4 /* TWTextView.h */; }; 33 | B26184C8121C6C51009AB3B4 /* TWTextView.m in Sources */ = {isa = PBXBuildFile; fileRef = B26184C6121C6C51009AB3B4 /* TWTextView.m */; }; 34 | B270B5EE117C9EDC00944B8A /* UIColor+TWToolkitAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = B270B5EC117C9EDC00944B8A /* UIColor+TWToolkitAdditions.h */; }; 35 | B270B5EF117C9EDC00944B8A /* UIColor+TWToolkitAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = B270B5ED117C9EDC00944B8A /* UIColor+TWToolkitAdditions.m */; }; 36 | B2752E02120B4A1E003B0087 /* TWConcurrentOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = B2752E00120B4A1E003B0087 /* TWConcurrentOperation.h */; }; 37 | B2752E03120B4A1E003B0087 /* TWConcurrentOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = B2752E01120B4A1E003B0087 /* TWConcurrentOperation.m */; }; 38 | B27E357D11815C7F006A3499 /* TWCategories.h in Headers */ = {isa = PBXBuildFile; fileRef = B27E357A11815C7F006A3499 /* TWCategories.h */; }; 39 | B27E357E11815C7F006A3499 /* TWDrawingMacros.h in Headers */ = {isa = PBXBuildFile; fileRef = B27E357B11815C7F006A3499 /* TWDrawingMacros.h */; }; 40 | B27E357F11815C7F006A3499 /* TWToolkit.h in Headers */ = {isa = PBXBuildFile; fileRef = B27E357C11815C7F006A3499 /* TWToolkit.h */; }; 41 | B28517DA1063E43E008D42E7 /* TWPickerViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = B28517D81063E43E008D42E7 /* TWPickerViewController.h */; }; 42 | B28517DB1063E43E008D42E7 /* TWPickerViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B28517D91063E43E008D42E7 /* TWPickerViewController.m */; }; 43 | B28517E01063E442008D42E7 /* TWLoadingView.h in Headers */ = {isa = PBXBuildFile; fileRef = B28517DC1063E442008D42E7 /* TWLoadingView.h */; }; 44 | B28517E11063E442008D42E7 /* TWLoadingView.m in Sources */ = {isa = PBXBuildFile; fileRef = B28517DD1063E442008D42E7 /* TWLoadingView.m */; }; 45 | B28D8E3F1173D6DA00B37266 /* UIView+TWToolkitAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = B28D8E3B1173D6DA00B37266 /* UIView+TWToolkitAdditions.h */; }; 46 | B28D8E401173D6DA00B37266 /* UIView+TWToolkitAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = B28D8E3C1173D6DA00B37266 /* UIView+TWToolkitAdditions.m */; }; 47 | B28E46F4117CBB5B0089E536 /* UIControl+TWToolkitAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = B28E46F2117CBB5B0089E536 /* UIControl+TWToolkitAdditions.h */; }; 48 | B28E46F5117CBB5B0089E536 /* UIControl+TWToolkitAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = B28E46F3117CBB5B0089E536 /* UIControl+TWToolkitAdditions.m */; }; 49 | B2974D72106299CB00C9F4A6 /* UIDevice+TWToolkitAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = B2974D61106299CB00C9F4A6 /* UIDevice+TWToolkitAdditions.h */; }; 50 | B2974D73106299CB00C9F4A6 /* UIDevice+TWToolkitAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = B2974D62106299CB00C9F4A6 /* UIDevice+TWToolkitAdditions.m */; }; 51 | B2A1127F12073D1D0049990A /* TWModalViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = B2A1127C12073D1D0049990A /* TWModalViewController.h */; }; 52 | B2A1128012073D1D0049990A /* TWViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = B2A1127D12073D1D0049990A /* TWViewController.h */; }; 53 | B2A1128112073D1D0049990A /* TWViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B2A1127E12073D1D0049990A /* TWViewController.m */; }; 54 | B2A1128612073D240049990A /* TWIndicatorLabel.h in Headers */ = {isa = PBXBuildFile; fileRef = B2A1128212073D240049990A /* TWIndicatorLabel.h */; }; 55 | B2A1128712073D240049990A /* TWIndicatorLabel.m in Sources */ = {isa = PBXBuildFile; fileRef = B2A1128312073D240049990A /* TWIndicatorLabel.m */; }; 56 | B2A1128812073D240049990A /* TWLabel.h in Headers */ = {isa = PBXBuildFile; fileRef = B2A1128412073D240049990A /* TWLabel.h */; }; 57 | B2A1128912073D240049990A /* TWLabel.m in Sources */ = {isa = PBXBuildFile; fileRef = B2A1128512073D240049990A /* TWLabel.m */; }; 58 | B2C20770106296FB00AE1B56 /* NSArray+TWToolkitAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = B2C20766106296FB00AE1B56 /* NSArray+TWToolkitAdditions.h */; }; 59 | B2C20771106296FB00AE1B56 /* NSArray+TWToolkitAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = B2C20767106296FB00AE1B56 /* NSArray+TWToolkitAdditions.m */; }; 60 | B2C20772106296FB00AE1B56 /* NSData+TWToolkitAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = B2C20768106296FB00AE1B56 /* NSData+TWToolkitAdditions.h */; }; 61 | B2C20773106296FB00AE1B56 /* NSData+TWToolkitAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = B2C20769106296FB00AE1B56 /* NSData+TWToolkitAdditions.m */; }; 62 | B2C20774106296FB00AE1B56 /* NSString+TWToolkitAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = B2C2076A106296FB00AE1B56 /* NSString+TWToolkitAdditions.h */; }; 63 | B2C20775106296FB00AE1B56 /* NSString+TWToolkitAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = B2C2076B106296FB00AE1B56 /* NSString+TWToolkitAdditions.m */; }; 64 | B2C68299114954D3006EDD71 /* TWMessageTableViewCellBubbleView.h in Headers */ = {isa = PBXBuildFile; fileRef = B2C68297114954D3006EDD71 /* TWMessageTableViewCellBubbleView.h */; }; 65 | B2C6829A114954D3006EDD71 /* TWMessageTableViewCellBubbleView.m in Sources */ = {isa = PBXBuildFile; fileRef = B2C68298114954D3006EDD71 /* TWMessageTableViewCellBubbleView.m */; }; 66 | B2C6829D114954DB006EDD71 /* TWMessageTableViewCell.h in Headers */ = {isa = PBXBuildFile; fileRef = B2C6829B114954DB006EDD71 /* TWMessageTableViewCell.h */; }; 67 | B2C6829E114954DB006EDD71 /* TWMessageTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = B2C6829C114954DB006EDD71 /* TWMessageTableViewCell.m */; }; 68 | B2C682A1114954DF006EDD71 /* TWMessagesViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = B2C6829F114954DF006EDD71 /* TWMessagesViewController.h */; }; 69 | B2C682A2114954DF006EDD71 /* TWMessagesViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B2C682A0114954DF006EDD71 /* TWMessagesViewController.m */; }; 70 | B2D3527111A46A4900B1886F /* TWKeychain.h in Headers */ = {isa = PBXBuildFile; fileRef = B2D3526F11A46A4900B1886F /* TWKeychain.h */; }; 71 | B2D3527211A46A4900B1886F /* TWKeychain.m in Sources */ = {isa = PBXBuildFile; fileRef = B2D3527011A46A4900B1886F /* TWKeychain.m */; }; 72 | B2ED132811813E6600FAAA13 /* TWPieProgressView.h in Headers */ = {isa = PBXBuildFile; fileRef = B2ED132611813E6600FAAA13 /* TWPieProgressView.h */; }; 73 | B2ED132911813E6600FAAA13 /* TWPieProgressView.m in Sources */ = {isa = PBXBuildFile; fileRef = B2ED132711813E6600FAAA13 /* TWPieProgressView.m */; }; 74 | B2FD73E51187828F007281D3 /* NSURL+TWToolkitAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = B2FD73E31187828F007281D3 /* NSURL+TWToolkitAdditions.h */; }; 75 | B2FD73E61187828F007281D3 /* NSURL+TWToolkitAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = B2FD73E41187828F007281D3 /* NSURL+TWToolkitAdditions.m */; }; 76 | /* End PBXBuildFile section */ 77 | 78 | /* Begin PBXFileReference section */ 79 | AACBBE490F95108600F1A2B1 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 80 | B213D07A11AE1D1D00BACA8D /* NSDate+TWToolkitAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSDate+TWToolkitAdditions.h"; sourceTree = ""; }; 81 | B213D07B11AE1D1D00BACA8D /* NSDate+TWToolkitAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSDate+TWToolkitAdditions.m"; sourceTree = ""; }; 82 | B215045E10583A7300409ED4 /* TWToolkit_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TWToolkit_Prefix.pch; sourceTree = ""; }; 83 | B21504C910583B4000409ED4 /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; }; 84 | B215051110583BBB00409ED4 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 85 | B215ACCA117363D9002562A4 /* UIScrollView+TWToolkitAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIScrollView+TWToolkitAdditions.h"; sourceTree = ""; }; 86 | B215ACCB117363D9002562A4 /* UIScrollView+TWToolkitAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIScrollView+TWToolkitAdditions.m"; sourceTree = ""; }; 87 | B215ADAC1173770F002562A4 /* TWLineView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TWLineView.h; sourceTree = ""; }; 88 | B215ADAD1173770F002562A4 /* TWLineView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TWLineView.m; sourceTree = ""; }; 89 | B21D2EF41185ED25009F7206 /* TWWebView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TWWebView.h; sourceTree = ""; }; 90 | B21D2EF51185ED25009F7206 /* TWWebView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TWWebView.m; sourceTree = ""; }; 91 | B22A2A8010B4908D00EA6CD9 /* TWToolkit.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = TWToolkit.bundle; sourceTree = ""; }; 92 | B24244E411498A480061E255 /* TWTextField.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TWTextField.h; sourceTree = ""; }; 93 | B24244E511498A480061E255 /* TWTextField.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TWTextField.m; sourceTree = ""; }; 94 | B24B551610B36F6B0014994C /* UIImage+TWToolkitAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIImage+TWToolkitAdditions.h"; sourceTree = ""; }; 95 | B24B551710B36F6B0014994C /* UIImage+TWToolkitAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIImage+TWToolkitAdditions.m"; sourceTree = ""; }; 96 | B2503B9310A90DA6009B0E7B /* TWGradientView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TWGradientView.h; sourceTree = ""; }; 97 | B2503B9410A90DA6009B0E7B /* TWGradientView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TWGradientView.m; sourceTree = ""; }; 98 | B253C1F810728DC500E0CE10 /* TWHUDView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TWHUDView.h; sourceTree = ""; }; 99 | B253C1F910728DC500E0CE10 /* TWHUDView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TWHUDView.m; sourceTree = ""; }; 100 | B25E613E11CFBA34001DA5CD /* UIViewController+TWToolkitAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIViewController+TWToolkitAdditions.h"; sourceTree = ""; }; 101 | B25E613F11CFBA34001DA5CD /* UIViewController+TWToolkitAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIViewController+TWToolkitAdditions.m"; sourceTree = ""; }; 102 | B26184C5121C6C51009AB3B4 /* TWTextView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TWTextView.h; sourceTree = ""; }; 103 | B26184C6121C6C51009AB3B4 /* TWTextView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TWTextView.m; sourceTree = ""; }; 104 | B270B5EC117C9EDC00944B8A /* UIColor+TWToolkitAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIColor+TWToolkitAdditions.h"; sourceTree = ""; }; 105 | B270B5ED117C9EDC00944B8A /* UIColor+TWToolkitAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIColor+TWToolkitAdditions.m"; sourceTree = ""; }; 106 | B2752E00120B4A1E003B0087 /* TWConcurrentOperation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TWConcurrentOperation.h; sourceTree = ""; }; 107 | B2752E01120B4A1E003B0087 /* TWConcurrentOperation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TWConcurrentOperation.m; sourceTree = ""; }; 108 | B27E357A11815C7F006A3499 /* TWCategories.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TWCategories.h; sourceTree = ""; }; 109 | B27E357B11815C7F006A3499 /* TWDrawingMacros.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TWDrawingMacros.h; sourceTree = ""; }; 110 | B27E357C11815C7F006A3499 /* TWToolkit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TWToolkit.h; sourceTree = ""; }; 111 | B28517D81063E43E008D42E7 /* TWPickerViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TWPickerViewController.h; sourceTree = ""; }; 112 | B28517D91063E43E008D42E7 /* TWPickerViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TWPickerViewController.m; sourceTree = ""; }; 113 | B28517DC1063E442008D42E7 /* TWLoadingView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TWLoadingView.h; sourceTree = ""; }; 114 | B28517DD1063E442008D42E7 /* TWLoadingView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TWLoadingView.m; sourceTree = ""; }; 115 | B28D8E3B1173D6DA00B37266 /* UIView+TWToolkitAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIView+TWToolkitAdditions.h"; sourceTree = ""; }; 116 | B28D8E3C1173D6DA00B37266 /* UIView+TWToolkitAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIView+TWToolkitAdditions.m"; sourceTree = ""; }; 117 | B28E46F2117CBB5B0089E536 /* UIControl+TWToolkitAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIControl+TWToolkitAdditions.h"; sourceTree = ""; }; 118 | B28E46F3117CBB5B0089E536 /* UIControl+TWToolkitAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIControl+TWToolkitAdditions.m"; sourceTree = ""; }; 119 | B2974D61106299CB00C9F4A6 /* UIDevice+TWToolkitAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIDevice+TWToolkitAdditions.h"; sourceTree = ""; }; 120 | B2974D62106299CB00C9F4A6 /* UIDevice+TWToolkitAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIDevice+TWToolkitAdditions.m"; sourceTree = ""; }; 121 | B2A1127C12073D1D0049990A /* TWModalViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TWModalViewController.h; sourceTree = ""; }; 122 | B2A1127D12073D1D0049990A /* TWViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TWViewController.h; sourceTree = ""; }; 123 | B2A1127E12073D1D0049990A /* TWViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TWViewController.m; sourceTree = ""; }; 124 | B2A1128212073D240049990A /* TWIndicatorLabel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TWIndicatorLabel.h; sourceTree = ""; }; 125 | B2A1128312073D240049990A /* TWIndicatorLabel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TWIndicatorLabel.m; sourceTree = ""; }; 126 | B2A1128412073D240049990A /* TWLabel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TWLabel.h; sourceTree = ""; }; 127 | B2A1128512073D240049990A /* TWLabel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TWLabel.m; sourceTree = ""; }; 128 | B2C20766106296FB00AE1B56 /* NSArray+TWToolkitAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSArray+TWToolkitAdditions.h"; sourceTree = ""; }; 129 | B2C20767106296FB00AE1B56 /* NSArray+TWToolkitAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSArray+TWToolkitAdditions.m"; sourceTree = ""; }; 130 | B2C20768106296FB00AE1B56 /* NSData+TWToolkitAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSData+TWToolkitAdditions.h"; sourceTree = ""; }; 131 | B2C20769106296FB00AE1B56 /* NSData+TWToolkitAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSData+TWToolkitAdditions.m"; sourceTree = ""; }; 132 | B2C2076A106296FB00AE1B56 /* NSString+TWToolkitAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSString+TWToolkitAdditions.h"; sourceTree = ""; }; 133 | B2C2076B106296FB00AE1B56 /* NSString+TWToolkitAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSString+TWToolkitAdditions.m"; sourceTree = ""; }; 134 | B2C68297114954D3006EDD71 /* TWMessageTableViewCellBubbleView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TWMessageTableViewCellBubbleView.h; sourceTree = ""; }; 135 | B2C68298114954D3006EDD71 /* TWMessageTableViewCellBubbleView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TWMessageTableViewCellBubbleView.m; sourceTree = ""; }; 136 | B2C6829B114954DB006EDD71 /* TWMessageTableViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TWMessageTableViewCell.h; sourceTree = ""; }; 137 | B2C6829C114954DB006EDD71 /* TWMessageTableViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TWMessageTableViewCell.m; sourceTree = ""; }; 138 | B2C6829F114954DF006EDD71 /* TWMessagesViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TWMessagesViewController.h; sourceTree = ""; }; 139 | B2C682A0114954DF006EDD71 /* TWMessagesViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TWMessagesViewController.m; sourceTree = ""; }; 140 | B2D3526F11A46A4900B1886F /* TWKeychain.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TWKeychain.h; sourceTree = ""; }; 141 | B2D3527011A46A4900B1886F /* TWKeychain.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TWKeychain.m; sourceTree = ""; }; 142 | B2ED132611813E6600FAAA13 /* TWPieProgressView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TWPieProgressView.h; sourceTree = ""; }; 143 | B2ED132711813E6600FAAA13 /* TWPieProgressView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TWPieProgressView.m; sourceTree = ""; }; 144 | B2FD73E31187828F007281D3 /* NSURL+TWToolkitAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSURL+TWToolkitAdditions.h"; sourceTree = ""; }; 145 | B2FD73E41187828F007281D3 /* NSURL+TWToolkitAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSURL+TWToolkitAdditions.m"; sourceTree = ""; }; 146 | D2AAC07E0554694100DB518D /* libTWToolkit.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libTWToolkit.a; sourceTree = BUILT_PRODUCTS_DIR; }; 147 | /* End PBXFileReference section */ 148 | 149 | /* Begin PBXFrameworksBuildPhase section */ 150 | D2AAC07C0554694100DB518D /* Frameworks */ = { 151 | isa = PBXFrameworksBuildPhase; 152 | buildActionMask = 2147483647; 153 | files = ( 154 | AACBBE4A0F95108600F1A2B1 /* Foundation.framework in Frameworks */, 155 | B21504CA10583B4000409ED4 /* SystemConfiguration.framework in Frameworks */, 156 | B215051210583BBB00409ED4 /* UIKit.framework in Frameworks */, 157 | ); 158 | runOnlyForDeploymentPostprocessing = 0; 159 | }; 160 | /* End PBXFrameworksBuildPhase section */ 161 | 162 | /* Begin PBXGroup section */ 163 | 034768DFFF38A50411DB9C8B /* Products */ = { 164 | isa = PBXGroup; 165 | children = ( 166 | D2AAC07E0554694100DB518D /* libTWToolkit.a */, 167 | ); 168 | name = Products; 169 | sourceTree = ""; 170 | }; 171 | 0867D691FE84028FC02AAC07 /* TWToolkit */ = { 172 | isa = PBXGroup; 173 | children = ( 174 | B2FA61431059616200499856 /* TWToolkit */, 175 | B215045D10583A7300409ED4 /* Other Sources */, 176 | B22A2A7F10B4908D00EA6CD9 /* Resources */, 177 | 0867D69AFE84028FC02AAC07 /* Frameworks */, 178 | 034768DFFF38A50411DB9C8B /* Products */, 179 | ); 180 | name = TWToolkit; 181 | sourceTree = ""; 182 | }; 183 | 0867D69AFE84028FC02AAC07 /* Frameworks */ = { 184 | isa = PBXGroup; 185 | children = ( 186 | AACBBE490F95108600F1A2B1 /* Foundation.framework */, 187 | B21504C910583B4000409ED4 /* SystemConfiguration.framework */, 188 | B215051110583BBB00409ED4 /* UIKit.framework */, 189 | ); 190 | name = Frameworks; 191 | sourceTree = ""; 192 | }; 193 | B215045D10583A7300409ED4 /* Other Sources */ = { 194 | isa = PBXGroup; 195 | children = ( 196 | B215045E10583A7300409ED4 /* TWToolkit_Prefix.pch */, 197 | ); 198 | path = "Other Sources"; 199 | sourceTree = ""; 200 | }; 201 | B22A2A7F10B4908D00EA6CD9 /* Resources */ = { 202 | isa = PBXGroup; 203 | children = ( 204 | B22A2A8010B4908D00EA6CD9 /* TWToolkit.bundle */, 205 | ); 206 | path = Resources; 207 | sourceTree = ""; 208 | }; 209 | B23A34B3117C954B0085E48A /* Private */ = { 210 | isa = PBXGroup; 211 | children = ( 212 | B23A34B4117C95540085E48A /* Views */, 213 | B23A34B5117C95580085E48A /* Cells */, 214 | ); 215 | name = Private; 216 | sourceTree = ""; 217 | }; 218 | B23A34B4117C95540085E48A /* Views */ = { 219 | isa = PBXGroup; 220 | children = ( 221 | B2C68297114954D3006EDD71 /* TWMessageTableViewCellBubbleView.h */, 222 | B2C68298114954D3006EDD71 /* TWMessageTableViewCellBubbleView.m */, 223 | ); 224 | name = Views; 225 | sourceTree = ""; 226 | }; 227 | B23A34B5117C95580085E48A /* Cells */ = { 228 | isa = PBXGroup; 229 | children = ( 230 | B2C6829B114954DB006EDD71 /* TWMessageTableViewCell.h */, 231 | B2C6829C114954DB006EDD71 /* TWMessageTableViewCell.m */, 232 | ); 233 | name = Cells; 234 | sourceTree = ""; 235 | }; 236 | B28517D51063E42A008D42E7 /* View Controllers */ = { 237 | isa = PBXGroup; 238 | children = ( 239 | B2A1127C12073D1D0049990A /* TWModalViewController.h */, 240 | B2A1127D12073D1D0049990A /* TWViewController.h */, 241 | B2A1127E12073D1D0049990A /* TWViewController.m */, 242 | B28517D81063E43E008D42E7 /* TWPickerViewController.h */, 243 | B28517D91063E43E008D42E7 /* TWPickerViewController.m */, 244 | B2C6829F114954DF006EDD71 /* TWMessagesViewController.h */, 245 | B2C682A0114954DF006EDD71 /* TWMessagesViewController.m */, 246 | ); 247 | name = "View Controllers"; 248 | sourceTree = ""; 249 | }; 250 | B28517D71063E433008D42E7 /* Views */ = { 251 | isa = PBXGroup; 252 | children = ( 253 | B2503B9310A90DA6009B0E7B /* TWGradientView.h */, 254 | B2503B9410A90DA6009B0E7B /* TWGradientView.m */, 255 | B253C1F810728DC500E0CE10 /* TWHUDView.h */, 256 | B253C1F910728DC500E0CE10 /* TWHUDView.m */, 257 | B2A1128212073D240049990A /* TWIndicatorLabel.h */, 258 | B2A1128312073D240049990A /* TWIndicatorLabel.m */, 259 | B2A1128412073D240049990A /* TWLabel.h */, 260 | B2A1128512073D240049990A /* TWLabel.m */, 261 | B215ADAC1173770F002562A4 /* TWLineView.h */, 262 | B215ADAD1173770F002562A4 /* TWLineView.m */, 263 | B28517DC1063E442008D42E7 /* TWLoadingView.h */, 264 | B28517DD1063E442008D42E7 /* TWLoadingView.m */, 265 | B2ED132611813E6600FAAA13 /* TWPieProgressView.h */, 266 | B2ED132711813E6600FAAA13 /* TWPieProgressView.m */, 267 | B24244E411498A480061E255 /* TWTextField.h */, 268 | B24244E511498A480061E255 /* TWTextField.m */, 269 | B26184C5121C6C51009AB3B4 /* TWTextView.h */, 270 | B26184C6121C6C51009AB3B4 /* TWTextView.m */, 271 | B21D2EF41185ED25009F7206 /* TWWebView.h */, 272 | B21D2EF51185ED25009F7206 /* TWWebView.m */, 273 | ); 274 | name = Views; 275 | sourceTree = ""; 276 | }; 277 | B2B9EC0A10826D670025F5AC /* Foundation */ = { 278 | isa = PBXGroup; 279 | children = ( 280 | B2C20766106296FB00AE1B56 /* NSArray+TWToolkitAdditions.h */, 281 | B2C20767106296FB00AE1B56 /* NSArray+TWToolkitAdditions.m */, 282 | B2C20768106296FB00AE1B56 /* NSData+TWToolkitAdditions.h */, 283 | B2C20769106296FB00AE1B56 /* NSData+TWToolkitAdditions.m */, 284 | B213D07A11AE1D1D00BACA8D /* NSDate+TWToolkitAdditions.h */, 285 | B213D07B11AE1D1D00BACA8D /* NSDate+TWToolkitAdditions.m */, 286 | B2C2076A106296FB00AE1B56 /* NSString+TWToolkitAdditions.h */, 287 | B2C2076B106296FB00AE1B56 /* NSString+TWToolkitAdditions.m */, 288 | B2FD73E31187828F007281D3 /* NSURL+TWToolkitAdditions.h */, 289 | B2FD73E41187828F007281D3 /* NSURL+TWToolkitAdditions.m */, 290 | ); 291 | name = Foundation; 292 | sourceTree = ""; 293 | }; 294 | B2B9EC0B10826D710025F5AC /* UIKit */ = { 295 | isa = PBXGroup; 296 | children = ( 297 | B270B5EC117C9EDC00944B8A /* UIColor+TWToolkitAdditions.h */, 298 | B270B5ED117C9EDC00944B8A /* UIColor+TWToolkitAdditions.m */, 299 | B28E46F2117CBB5B0089E536 /* UIControl+TWToolkitAdditions.h */, 300 | B28E46F3117CBB5B0089E536 /* UIControl+TWToolkitAdditions.m */, 301 | B2974D61106299CB00C9F4A6 /* UIDevice+TWToolkitAdditions.h */, 302 | B2974D62106299CB00C9F4A6 /* UIDevice+TWToolkitAdditions.m */, 303 | B24B551610B36F6B0014994C /* UIImage+TWToolkitAdditions.h */, 304 | B24B551710B36F6B0014994C /* UIImage+TWToolkitAdditions.m */, 305 | B215ACCA117363D9002562A4 /* UIScrollView+TWToolkitAdditions.h */, 306 | B215ACCB117363D9002562A4 /* UIScrollView+TWToolkitAdditions.m */, 307 | B28D8E3B1173D6DA00B37266 /* UIView+TWToolkitAdditions.h */, 308 | B28D8E3C1173D6DA00B37266 /* UIView+TWToolkitAdditions.m */, 309 | B25E613E11CFBA34001DA5CD /* UIViewController+TWToolkitAdditions.h */, 310 | B25E613F11CFBA34001DA5CD /* UIViewController+TWToolkitAdditions.m */, 311 | ); 312 | name = UIKit; 313 | sourceTree = ""; 314 | }; 315 | B2C20765106296F200AE1B56 /* Categories */ = { 316 | isa = PBXGroup; 317 | children = ( 318 | B2B9EC0A10826D670025F5AC /* Foundation */, 319 | B2B9EC0B10826D710025F5AC /* UIKit */, 320 | ); 321 | name = Categories; 322 | sourceTree = ""; 323 | }; 324 | B2D3526E11A46A4000B1886F /* Misc */ = { 325 | isa = PBXGroup; 326 | children = ( 327 | B2752E00120B4A1E003B0087 /* TWConcurrentOperation.h */, 328 | B2752E01120B4A1E003B0087 /* TWConcurrentOperation.m */, 329 | B2D3526F11A46A4900B1886F /* TWKeychain.h */, 330 | B2D3527011A46A4900B1886F /* TWKeychain.m */, 331 | ); 332 | name = Misc; 333 | sourceTree = ""; 334 | }; 335 | B2FA61431059616200499856 /* TWToolkit */ = { 336 | isa = PBXGroup; 337 | children = ( 338 | B27E357C11815C7F006A3499 /* TWToolkit.h */, 339 | B27E357A11815C7F006A3499 /* TWCategories.h */, 340 | B27E357B11815C7F006A3499 /* TWDrawingMacros.h */, 341 | B28517D51063E42A008D42E7 /* View Controllers */, 342 | B28517D71063E433008D42E7 /* Views */, 343 | B2D3526E11A46A4000B1886F /* Misc */, 344 | B2C20765106296F200AE1B56 /* Categories */, 345 | B23A34B3117C954B0085E48A /* Private */, 346 | ); 347 | path = TWToolkit; 348 | sourceTree = ""; 349 | }; 350 | /* End PBXGroup section */ 351 | 352 | /* Begin PBXHeadersBuildPhase section */ 353 | D2AAC07A0554694100DB518D /* Headers */ = { 354 | isa = PBXHeadersBuildPhase; 355 | buildActionMask = 2147483647; 356 | files = ( 357 | B215045F10583A7300409ED4 /* TWToolkit_Prefix.pch in Headers */, 358 | B2C20770106296FB00AE1B56 /* NSArray+TWToolkitAdditions.h in Headers */, 359 | B2C20772106296FB00AE1B56 /* NSData+TWToolkitAdditions.h in Headers */, 360 | B2C20774106296FB00AE1B56 /* NSString+TWToolkitAdditions.h in Headers */, 361 | B2974D72106299CB00C9F4A6 /* UIDevice+TWToolkitAdditions.h in Headers */, 362 | B28517DA1063E43E008D42E7 /* TWPickerViewController.h in Headers */, 363 | B28517E01063E442008D42E7 /* TWLoadingView.h in Headers */, 364 | B253C1FA10728DC500E0CE10 /* TWHUDView.h in Headers */, 365 | B2503B9510A90DA6009B0E7B /* TWGradientView.h in Headers */, 366 | B24B551810B36F6B0014994C /* UIImage+TWToolkitAdditions.h in Headers */, 367 | B2C68299114954D3006EDD71 /* TWMessageTableViewCellBubbleView.h in Headers */, 368 | B2C6829D114954DB006EDD71 /* TWMessageTableViewCell.h in Headers */, 369 | B2C682A1114954DF006EDD71 /* TWMessagesViewController.h in Headers */, 370 | B24244E611498A480061E255 /* TWTextField.h in Headers */, 371 | B215ACCC117363D9002562A4 /* UIScrollView+TWToolkitAdditions.h in Headers */, 372 | B215ADAE1173770F002562A4 /* TWLineView.h in Headers */, 373 | B28D8E3F1173D6DA00B37266 /* UIView+TWToolkitAdditions.h in Headers */, 374 | B270B5EE117C9EDC00944B8A /* UIColor+TWToolkitAdditions.h in Headers */, 375 | B28E46F4117CBB5B0089E536 /* UIControl+TWToolkitAdditions.h in Headers */, 376 | B2ED132811813E6600FAAA13 /* TWPieProgressView.h in Headers */, 377 | B27E357D11815C7F006A3499 /* TWCategories.h in Headers */, 378 | B27E357E11815C7F006A3499 /* TWDrawingMacros.h in Headers */, 379 | B27E357F11815C7F006A3499 /* TWToolkit.h in Headers */, 380 | B21D2EF61185ED25009F7206 /* TWWebView.h in Headers */, 381 | B2FD73E51187828F007281D3 /* NSURL+TWToolkitAdditions.h in Headers */, 382 | B2D3527111A46A4900B1886F /* TWKeychain.h in Headers */, 383 | B213D07C11AE1D1D00BACA8D /* NSDate+TWToolkitAdditions.h in Headers */, 384 | B25E614011CFBA34001DA5CD /* UIViewController+TWToolkitAdditions.h in Headers */, 385 | B2A1127F12073D1D0049990A /* TWModalViewController.h in Headers */, 386 | B2A1128012073D1D0049990A /* TWViewController.h in Headers */, 387 | B2A1128612073D240049990A /* TWIndicatorLabel.h in Headers */, 388 | B2A1128812073D240049990A /* TWLabel.h in Headers */, 389 | B2752E02120B4A1E003B0087 /* TWConcurrentOperation.h in Headers */, 390 | B26184C7121C6C51009AB3B4 /* TWTextView.h in Headers */, 391 | ); 392 | runOnlyForDeploymentPostprocessing = 0; 393 | }; 394 | /* End PBXHeadersBuildPhase section */ 395 | 396 | /* Begin PBXNativeTarget section */ 397 | D2AAC07D0554694100DB518D /* TWToolkit */ = { 398 | isa = PBXNativeTarget; 399 | buildConfigurationList = 1DEB921E08733DC00010E9CD /* Build configuration list for PBXNativeTarget "TWToolkit" */; 400 | buildPhases = ( 401 | D2AAC07A0554694100DB518D /* Headers */, 402 | D2AAC07B0554694100DB518D /* Sources */, 403 | D2AAC07C0554694100DB518D /* Frameworks */, 404 | ); 405 | buildRules = ( 406 | ); 407 | dependencies = ( 408 | ); 409 | name = TWToolkit; 410 | productName = TWToolkit; 411 | productReference = D2AAC07E0554694100DB518D /* libTWToolkit.a */; 412 | productType = "com.apple.product-type.library.static"; 413 | }; 414 | /* End PBXNativeTarget section */ 415 | 416 | /* Begin PBXProject section */ 417 | 0867D690FE84028FC02AAC07 /* Project object */ = { 418 | isa = PBXProject; 419 | attributes = { 420 | ORGANIZATIONNAME = "Tasteful Works, Inc"; 421 | }; 422 | buildConfigurationList = 1DEB922208733DC00010E9CD /* Build configuration list for PBXProject "TWToolkit" */; 423 | compatibilityVersion = "Xcode 3.1"; 424 | hasScannedForEncodings = 1; 425 | mainGroup = 0867D691FE84028FC02AAC07 /* TWToolkit */; 426 | productRefGroup = 034768DFFF38A50411DB9C8B /* Products */; 427 | projectDirPath = ""; 428 | projectRoot = ""; 429 | targets = ( 430 | D2AAC07D0554694100DB518D /* TWToolkit */, 431 | ); 432 | }; 433 | /* End PBXProject section */ 434 | 435 | /* Begin PBXSourcesBuildPhase section */ 436 | D2AAC07B0554694100DB518D /* Sources */ = { 437 | isa = PBXSourcesBuildPhase; 438 | buildActionMask = 2147483647; 439 | files = ( 440 | B2C20771106296FB00AE1B56 /* NSArray+TWToolkitAdditions.m in Sources */, 441 | B2C20773106296FB00AE1B56 /* NSData+TWToolkitAdditions.m in Sources */, 442 | B2C20775106296FB00AE1B56 /* NSString+TWToolkitAdditions.m in Sources */, 443 | B2974D73106299CB00C9F4A6 /* UIDevice+TWToolkitAdditions.m in Sources */, 444 | B28517DB1063E43E008D42E7 /* TWPickerViewController.m in Sources */, 445 | B28517E11063E442008D42E7 /* TWLoadingView.m in Sources */, 446 | B253C1FB10728DC500E0CE10 /* TWHUDView.m in Sources */, 447 | B2503B9610A90DA6009B0E7B /* TWGradientView.m in Sources */, 448 | B24B551910B36F6B0014994C /* UIImage+TWToolkitAdditions.m in Sources */, 449 | B2C6829A114954D3006EDD71 /* TWMessageTableViewCellBubbleView.m in Sources */, 450 | B2C6829E114954DB006EDD71 /* TWMessageTableViewCell.m in Sources */, 451 | B2C682A2114954DF006EDD71 /* TWMessagesViewController.m in Sources */, 452 | B24244E711498A480061E255 /* TWTextField.m in Sources */, 453 | B215ACCD117363D9002562A4 /* UIScrollView+TWToolkitAdditions.m in Sources */, 454 | B215ADAF1173770F002562A4 /* TWLineView.m in Sources */, 455 | B28D8E401173D6DA00B37266 /* UIView+TWToolkitAdditions.m in Sources */, 456 | B270B5EF117C9EDC00944B8A /* UIColor+TWToolkitAdditions.m in Sources */, 457 | B28E46F5117CBB5B0089E536 /* UIControl+TWToolkitAdditions.m in Sources */, 458 | B2ED132911813E6600FAAA13 /* TWPieProgressView.m in Sources */, 459 | B21D2EF71185ED25009F7206 /* TWWebView.m in Sources */, 460 | B2FD73E61187828F007281D3 /* NSURL+TWToolkitAdditions.m in Sources */, 461 | B2D3527211A46A4900B1886F /* TWKeychain.m in Sources */, 462 | B213D07D11AE1D1D00BACA8D /* NSDate+TWToolkitAdditions.m in Sources */, 463 | B25E614111CFBA34001DA5CD /* UIViewController+TWToolkitAdditions.m in Sources */, 464 | B2A1128112073D1D0049990A /* TWViewController.m in Sources */, 465 | B2A1128712073D240049990A /* TWIndicatorLabel.m in Sources */, 466 | B2A1128912073D240049990A /* TWLabel.m in Sources */, 467 | B2752E03120B4A1E003B0087 /* TWConcurrentOperation.m in Sources */, 468 | B26184C8121C6C51009AB3B4 /* TWTextView.m in Sources */, 469 | ); 470 | runOnlyForDeploymentPostprocessing = 0; 471 | }; 472 | /* End PBXSourcesBuildPhase section */ 473 | 474 | /* Begin XCBuildConfiguration section */ 475 | 1DEB921F08733DC00010E9CD /* Debug */ = { 476 | isa = XCBuildConfiguration; 477 | buildSettings = { 478 | ALWAYS_SEARCH_USER_PATHS = NO; 479 | ARCHS = "$(ARCHS_STANDARD_32_BIT)"; 480 | COPY_PHASE_STRIP = NO; 481 | DSTROOT = /tmp/TWToolkit.dst; 482 | GCC_DYNAMIC_NO_PIC = NO; 483 | GCC_ENABLE_FIX_AND_CONTINUE = YES; 484 | GCC_MODEL_TUNING = G5; 485 | GCC_OPTIMIZATION_LEVEL = 0; 486 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 487 | GCC_PREFIX_HEADER = "Other Sources/TWToolkit_Prefix.pch"; 488 | HEADER_SEARCH_PATHS = /usr/include/libxml2; 489 | INSTALL_PATH = /usr/local/lib; 490 | LD_OPENMP_FLAGS = "-fopenmp -lxml2"; 491 | PRODUCT_NAME = TWToolkit; 492 | SDKROOT = iphoneos3.2; 493 | }; 494 | name = Debug; 495 | }; 496 | 1DEB922008733DC00010E9CD /* Release */ = { 497 | isa = XCBuildConfiguration; 498 | buildSettings = { 499 | ALWAYS_SEARCH_USER_PATHS = NO; 500 | ARCHS = "$(ARCHS_STANDARD_32_BIT)"; 501 | DSTROOT = /tmp/TWToolkit.dst; 502 | GCC_MODEL_TUNING = G5; 503 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 504 | GCC_PREFIX_HEADER = "Other Sources/TWToolkit_Prefix.pch"; 505 | HEADER_SEARCH_PATHS = /usr/include/libxml2; 506 | INSTALL_PATH = /usr/local/lib; 507 | LD_OPENMP_FLAGS = "-fopenmp -lxml2"; 508 | PRODUCT_NAME = TWToolkit; 509 | SDKROOT = iphoneos3.2; 510 | }; 511 | name = Release; 512 | }; 513 | 1DEB922308733DC00010E9CD /* Debug */ = { 514 | isa = XCBuildConfiguration; 515 | buildSettings = { 516 | ARCHS = "$(ARCHS_STANDARD_32_BIT)"; 517 | GCC_C_LANGUAGE_STANDARD = c99; 518 | GCC_OPTIMIZATION_LEVEL = 0; 519 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 520 | GCC_WARN_UNUSED_VARIABLE = YES; 521 | OTHER_LDFLAGS = "-ObjC"; 522 | PREBINDING = NO; 523 | SDKROOT = iphoneos3.0; 524 | }; 525 | name = Debug; 526 | }; 527 | 1DEB922408733DC00010E9CD /* Release */ = { 528 | isa = XCBuildConfiguration; 529 | buildSettings = { 530 | ARCHS = "$(ARCHS_STANDARD_32_BIT)"; 531 | GCC_C_LANGUAGE_STANDARD = c99; 532 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 533 | GCC_WARN_UNUSED_VARIABLE = YES; 534 | OTHER_LDFLAGS = "-ObjC"; 535 | PREBINDING = NO; 536 | SDKROOT = iphoneos3.0; 537 | }; 538 | name = Release; 539 | }; 540 | /* End XCBuildConfiguration section */ 541 | 542 | /* Begin XCConfigurationList section */ 543 | 1DEB921E08733DC00010E9CD /* Build configuration list for PBXNativeTarget "TWToolkit" */ = { 544 | isa = XCConfigurationList; 545 | buildConfigurations = ( 546 | 1DEB921F08733DC00010E9CD /* Debug */, 547 | 1DEB922008733DC00010E9CD /* Release */, 548 | ); 549 | defaultConfigurationIsVisible = 0; 550 | defaultConfigurationName = Release; 551 | }; 552 | 1DEB922208733DC00010E9CD /* Build configuration list for PBXProject "TWToolkit" */ = { 553 | isa = XCConfigurationList; 554 | buildConfigurations = ( 555 | 1DEB922308733DC00010E9CD /* Debug */, 556 | 1DEB922408733DC00010E9CD /* Release */, 557 | ); 558 | defaultConfigurationIsVisible = 0; 559 | defaultConfigurationName = Release; 560 | }; 561 | /* End XCConfigurationList section */ 562 | }; 563 | rootObject = 0867D690FE84028FC02AAC07 /* Project object */; 564 | } 565 | --------------------------------------------------------------------------------