├── PullToRefreshDemo ├── en.lproj │ ├── InfoPlist.strings │ └── ViewController.xib ├── big_arrow.png ├── loading-1.png ├── loading-2.png ├── loading-3.png ├── loading-4.png ├── loading-5.png ├── loading-6.png ├── loading-7.png ├── loading-8.png ├── loading-9.png ├── big_arrow@2x.png ├── loading-10.png ├── loading-11.png ├── loading-12.png ├── loading-13.png ├── loading-14.png ├── loading-15.png ├── loading-16.png ├── loading-17.png ├── loading-18.png ├── loading-19.png ├── loading-1@2x.png ├── loading-2@2x.png ├── loading-3@2x.png ├── loading-4@2x.png ├── loading-5@2x.png ├── loading-6@2x.png ├── loading-7@2x.png ├── loading-8@2x.png ├── loading-9@2x.png ├── loading-10@2x.png ├── loading-11@2x.png ├── loading-12@2x.png ├── loading-13@2x.png ├── loading-14@2x.png ├── loading-15@2x.png ├── loading-16@2x.png ├── loading-17@2x.png ├── loading-18@2x.png ├── loading-19@2x.png ├── MyTableView.h ├── main.m ├── PullToRefreshDemo-Prefix.pch ├── AppDelegate.h ├── ViewController.h ├── CustomPullToRefresh.h ├── MyTableView.m ├── PullToRefreshDemo-Info.plist ├── AppDelegate.m ├── ViewController.m ├── MSPullToRefreshController.h ├── CustomPullToRefresh.m └── MSPullToRefreshController.m ├── .gitignore ├── MSPullToRefreshController.podspec ├── LICENSE ├── README.md └── PullToRefreshDemo.xcodeproj └── project.pbxproj /PullToRefreshDemo/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | PullToRefreshDemo.xcodeproj/project.xcworkspace* 2 | PullToRefreshDemo.xcodeproj/xcuserdata* 3 | .DS_Store* 4 | -------------------------------------------------------------------------------- /PullToRefreshDemo/big_arrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bogardon/MSPullToRefreshController/HEAD/PullToRefreshDemo/big_arrow.png -------------------------------------------------------------------------------- /PullToRefreshDemo/loading-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bogardon/MSPullToRefreshController/HEAD/PullToRefreshDemo/loading-1.png -------------------------------------------------------------------------------- /PullToRefreshDemo/loading-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bogardon/MSPullToRefreshController/HEAD/PullToRefreshDemo/loading-2.png -------------------------------------------------------------------------------- /PullToRefreshDemo/loading-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bogardon/MSPullToRefreshController/HEAD/PullToRefreshDemo/loading-3.png -------------------------------------------------------------------------------- /PullToRefreshDemo/loading-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bogardon/MSPullToRefreshController/HEAD/PullToRefreshDemo/loading-4.png -------------------------------------------------------------------------------- /PullToRefreshDemo/loading-5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bogardon/MSPullToRefreshController/HEAD/PullToRefreshDemo/loading-5.png -------------------------------------------------------------------------------- /PullToRefreshDemo/loading-6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bogardon/MSPullToRefreshController/HEAD/PullToRefreshDemo/loading-6.png -------------------------------------------------------------------------------- /PullToRefreshDemo/loading-7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bogardon/MSPullToRefreshController/HEAD/PullToRefreshDemo/loading-7.png -------------------------------------------------------------------------------- /PullToRefreshDemo/loading-8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bogardon/MSPullToRefreshController/HEAD/PullToRefreshDemo/loading-8.png -------------------------------------------------------------------------------- /PullToRefreshDemo/loading-9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bogardon/MSPullToRefreshController/HEAD/PullToRefreshDemo/loading-9.png -------------------------------------------------------------------------------- /PullToRefreshDemo/big_arrow@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bogardon/MSPullToRefreshController/HEAD/PullToRefreshDemo/big_arrow@2x.png -------------------------------------------------------------------------------- /PullToRefreshDemo/loading-10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bogardon/MSPullToRefreshController/HEAD/PullToRefreshDemo/loading-10.png -------------------------------------------------------------------------------- /PullToRefreshDemo/loading-11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bogardon/MSPullToRefreshController/HEAD/PullToRefreshDemo/loading-11.png -------------------------------------------------------------------------------- /PullToRefreshDemo/loading-12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bogardon/MSPullToRefreshController/HEAD/PullToRefreshDemo/loading-12.png -------------------------------------------------------------------------------- /PullToRefreshDemo/loading-13.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bogardon/MSPullToRefreshController/HEAD/PullToRefreshDemo/loading-13.png -------------------------------------------------------------------------------- /PullToRefreshDemo/loading-14.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bogardon/MSPullToRefreshController/HEAD/PullToRefreshDemo/loading-14.png -------------------------------------------------------------------------------- /PullToRefreshDemo/loading-15.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bogardon/MSPullToRefreshController/HEAD/PullToRefreshDemo/loading-15.png -------------------------------------------------------------------------------- /PullToRefreshDemo/loading-16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bogardon/MSPullToRefreshController/HEAD/PullToRefreshDemo/loading-16.png -------------------------------------------------------------------------------- /PullToRefreshDemo/loading-17.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bogardon/MSPullToRefreshController/HEAD/PullToRefreshDemo/loading-17.png -------------------------------------------------------------------------------- /PullToRefreshDemo/loading-18.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bogardon/MSPullToRefreshController/HEAD/PullToRefreshDemo/loading-18.png -------------------------------------------------------------------------------- /PullToRefreshDemo/loading-19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bogardon/MSPullToRefreshController/HEAD/PullToRefreshDemo/loading-19.png -------------------------------------------------------------------------------- /PullToRefreshDemo/loading-1@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bogardon/MSPullToRefreshController/HEAD/PullToRefreshDemo/loading-1@2x.png -------------------------------------------------------------------------------- /PullToRefreshDemo/loading-2@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bogardon/MSPullToRefreshController/HEAD/PullToRefreshDemo/loading-2@2x.png -------------------------------------------------------------------------------- /PullToRefreshDemo/loading-3@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bogardon/MSPullToRefreshController/HEAD/PullToRefreshDemo/loading-3@2x.png -------------------------------------------------------------------------------- /PullToRefreshDemo/loading-4@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bogardon/MSPullToRefreshController/HEAD/PullToRefreshDemo/loading-4@2x.png -------------------------------------------------------------------------------- /PullToRefreshDemo/loading-5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bogardon/MSPullToRefreshController/HEAD/PullToRefreshDemo/loading-5@2x.png -------------------------------------------------------------------------------- /PullToRefreshDemo/loading-6@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bogardon/MSPullToRefreshController/HEAD/PullToRefreshDemo/loading-6@2x.png -------------------------------------------------------------------------------- /PullToRefreshDemo/loading-7@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bogardon/MSPullToRefreshController/HEAD/PullToRefreshDemo/loading-7@2x.png -------------------------------------------------------------------------------- /PullToRefreshDemo/loading-8@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bogardon/MSPullToRefreshController/HEAD/PullToRefreshDemo/loading-8@2x.png -------------------------------------------------------------------------------- /PullToRefreshDemo/loading-9@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bogardon/MSPullToRefreshController/HEAD/PullToRefreshDemo/loading-9@2x.png -------------------------------------------------------------------------------- /PullToRefreshDemo/loading-10@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bogardon/MSPullToRefreshController/HEAD/PullToRefreshDemo/loading-10@2x.png -------------------------------------------------------------------------------- /PullToRefreshDemo/loading-11@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bogardon/MSPullToRefreshController/HEAD/PullToRefreshDemo/loading-11@2x.png -------------------------------------------------------------------------------- /PullToRefreshDemo/loading-12@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bogardon/MSPullToRefreshController/HEAD/PullToRefreshDemo/loading-12@2x.png -------------------------------------------------------------------------------- /PullToRefreshDemo/loading-13@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bogardon/MSPullToRefreshController/HEAD/PullToRefreshDemo/loading-13@2x.png -------------------------------------------------------------------------------- /PullToRefreshDemo/loading-14@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bogardon/MSPullToRefreshController/HEAD/PullToRefreshDemo/loading-14@2x.png -------------------------------------------------------------------------------- /PullToRefreshDemo/loading-15@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bogardon/MSPullToRefreshController/HEAD/PullToRefreshDemo/loading-15@2x.png -------------------------------------------------------------------------------- /PullToRefreshDemo/loading-16@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bogardon/MSPullToRefreshController/HEAD/PullToRefreshDemo/loading-16@2x.png -------------------------------------------------------------------------------- /PullToRefreshDemo/loading-17@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bogardon/MSPullToRefreshController/HEAD/PullToRefreshDemo/loading-17@2x.png -------------------------------------------------------------------------------- /PullToRefreshDemo/loading-18@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bogardon/MSPullToRefreshController/HEAD/PullToRefreshDemo/loading-18@2x.png -------------------------------------------------------------------------------- /PullToRefreshDemo/loading-19@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bogardon/MSPullToRefreshController/HEAD/PullToRefreshDemo/loading-19@2x.png -------------------------------------------------------------------------------- /PullToRefreshDemo/MyTableView.h: -------------------------------------------------------------------------------- 1 | // 2 | // MyTableView.h 3 | // PullToRefreshDemo 4 | // 5 | // Created by John Z Wu on 9/23/12. 6 | // Copyright (c) 2012 TFM. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface MyTableView : UITableView 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /PullToRefreshDemo/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // PullToRefreshDemo 4 | // 5 | // Created by John Wu on 3/22/12. 6 | // Copyright (c) 2012 TFM. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "AppDelegate.h" 12 | 13 | int main(int argc, char *argv[]) 14 | { 15 | @autoreleasepool { 16 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /PullToRefreshDemo/PullToRefreshDemo-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'PullToRefreshDemo' target in the 'PullToRefreshDemo' project 3 | // 4 | 5 | #import 6 | 7 | #ifndef __IPHONE_4_0 8 | #warning "This project uses features only available in iOS SDK 4.0 and later." 9 | #endif 10 | 11 | #ifdef __OBJC__ 12 | #import 13 | #import 14 | #endif 15 | -------------------------------------------------------------------------------- /PullToRefreshDemo/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // PullToRefreshDemo 4 | // 5 | // Created by John Wu on 3/22/12. 6 | // Copyright (c) 2012 TFM. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class ViewController; 12 | 13 | @interface AppDelegate : UIResponder 14 | 15 | @property (strong, nonatomic) UIWindow *window; 16 | 17 | @property (strong, nonatomic) ViewController *viewController; 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /MSPullToRefreshController.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.platform = :ios 3 | s.name = "MSPullToRefreshController" 4 | s.version = "1.1.0" 5 | s.summary = "The most flexible pull to refresh component EVER." 6 | s.license = 'MIT' 7 | s.homepage = 'https://github.com/bONchON/MSPullToRefreshController' 8 | s.author = { 9 | 'John Z Wu' => 'bogardon@gmail.com' 10 | } 11 | s.source = { 12 | :git => 'https://github.com/bONchON/MSPullToRefreshController.git', 13 | :tag => 'v1.1.0' 14 | } 15 | s.source_files = 'PullToRefreshDemo/MSPullToRefreshController.{h,m}' 16 | s.requires_arc = false 17 | end 18 | -------------------------------------------------------------------------------- /PullToRefreshDemo/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // PullToRefreshDemo 4 | // 5 | // Created by John Wu on 3/22/12. 6 | // Copyright (c) 2012 TFM. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "CustomPullToRefresh.h" 11 | 12 | @interface ViewController : UIViewController { 13 | UITableView *_table; 14 | NSMutableArray *_primes; 15 | CustomPullToRefresh *_ptr; 16 | } 17 | 18 | - (BOOL) isPrime:(unsigned long long)input; 19 | - (void) findNextPrime; 20 | - (void) endSearch; 21 | 22 | @property (nonatomic, retain) IBOutlet UITableView *table; 23 | 24 | 25 | @end 26 | -------------------------------------------------------------------------------- /PullToRefreshDemo/CustomPullToRefresh.h: -------------------------------------------------------------------------------- 1 | // 2 | // CustomPullToRefresh.h 3 | // PullToRefreshDemo 4 | // 5 | // Created by John Wu on 3/22/12. 6 | // Copyright (c) 2012 TFM. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "MSPullToRefreshController.h" 11 | 12 | @protocol CustomPullToRefreshDelegate; 13 | 14 | @interface CustomPullToRefresh : NSObject { 15 | UIImageView *_rainbowTop; 16 | UIImageView *_arrowTop; 17 | UIImageView *_rainbowBot; 18 | UIImageView *_arrowBot; 19 | MSPullToRefreshController *_ptrc; 20 | UIScrollView *_scrollView; 21 | 22 | id _delegate; 23 | } 24 | 25 | - (id) initWithScrollView:(UIScrollView *)scrollView delegate:(id )delegate; 26 | - (void) endRefresh; 27 | - (void) startRefresh; 28 | 29 | @end 30 | 31 | @protocol CustomPullToRefreshDelegate 32 | 33 | - (void) customPullToRefreshShouldRefresh:(CustomPullToRefresh *)ptr; 34 | 35 | @end -------------------------------------------------------------------------------- /PullToRefreshDemo/MyTableView.m: -------------------------------------------------------------------------------- 1 | // 2 | // MyTableView.m 3 | // PullToRefreshDemo 4 | // 5 | // Created by John Z Wu on 9/23/12. 6 | // Copyright (c) 2012 TFM. All rights reserved. 7 | // 8 | 9 | #import "MyTableView.h" 10 | 11 | @implementation MyTableView 12 | 13 | - (id)initWithFrame:(CGRect)frame 14 | { 15 | self = [super initWithFrame:frame]; 16 | if (self) { 17 | // Initialization code 18 | } 19 | return self; 20 | } 21 | 22 | - (void) setContentSize:(CGSize)contentSize { 23 | CGFloat contentSizeArea = contentSize.width*contentSize.height; 24 | CGFloat frameArea = self.frame.size.width*self.frame.size.height; 25 | CGSize adjustedContentSize = contentSizeArea < frameArea ? self.frame.size : contentSize; 26 | [super setContentSize:adjustedContentSize]; 27 | } 28 | 29 | /* 30 | // Only override drawRect: if you perform custom drawing. 31 | // An empty implementation adversely affects performance during animation. 32 | - (void)drawRect:(CGRect)rect 33 | { 34 | // Drawing code 35 | } 36 | */ 37 | 38 | @end 39 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012 GoMiso (http://gomiso.com/) 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /PullToRefreshDemo/PullToRefreshDemo-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | ${PRODUCT_NAME} 9 | CFBundleExecutable 10 | ${EXECUTABLE_NAME} 11 | CFBundleIdentifier 12 | com.bazaarlabs.${PRODUCT_NAME:rfc1034identifier} 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | ${PRODUCT_NAME} 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1.0 25 | LSRequiresIPhoneOS 26 | 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /PullToRefreshDemo/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // PullToRefreshDemo 4 | // 5 | // Created by John Wu on 3/22/12. 6 | // Copyright (c) 2012 TFM. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | 11 | #import "ViewController.h" 12 | 13 | @implementation AppDelegate 14 | 15 | @synthesize window = _window; 16 | @synthesize viewController = _viewController; 17 | 18 | - (void)dealloc 19 | { 20 | [_window release]; 21 | [_viewController release]; 22 | [super dealloc]; 23 | } 24 | 25 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 26 | { 27 | self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease]; 28 | // Override point for customization after application launch. 29 | self.viewController = [[[ViewController alloc] initWithNibName:@"ViewController" bundle:nil] autorelease]; 30 | self.window.rootViewController = self.viewController; 31 | [self.window makeKeyAndVisible]; 32 | return YES; 33 | } 34 | 35 | - (void)applicationWillResignActive:(UIApplication *)application 36 | { 37 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 38 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 39 | } 40 | 41 | - (void)applicationDidEnterBackground:(UIApplication *)application 42 | { 43 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 44 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 45 | } 46 | 47 | - (void)applicationWillEnterForeground:(UIApplication *)application 48 | { 49 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. 50 | } 51 | 52 | - (void)applicationDidBecomeActive:(UIApplication *)application 53 | { 54 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 55 | } 56 | 57 | - (void)applicationWillTerminate:(UIApplication *)application 58 | { 59 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 60 | } 61 | 62 | @end 63 | -------------------------------------------------------------------------------- /PullToRefreshDemo/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // PullToRefreshDemo 4 | // 5 | // Created by John Wu on 3/22/12. 6 | // Copyright (c) 2012 TFM. All rights reserved. 7 | // 8 | 9 | #import "ViewController.h" 10 | #import "MSPullToRefreshController.h" 11 | 12 | @interface ViewController () 13 | 14 | @end 15 | 16 | @implementation ViewController 17 | @synthesize table = _table; 18 | 19 | - (id) initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { 20 | self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; 21 | if (self) { 22 | _primes = [[NSMutableArray alloc] initWithObjects:[NSNumber numberWithUnsignedLongLong:2], nil]; 23 | } 24 | return self; 25 | } 26 | 27 | - (void) dealloc { 28 | [_table release]; 29 | [_primes release]; 30 | [_ptr release]; 31 | [super dealloc]; 32 | } 33 | 34 | - (void)viewDidLoad 35 | { 36 | [super viewDidLoad]; 37 | // Do any additional setup after loading the view, typically from a nib. 38 | 39 | _ptr = [[CustomPullToRefresh alloc] initWithScrollView:self.table delegate:self]; 40 | } 41 | 42 | - (void)viewDidUnload 43 | { 44 | [super viewDidUnload]; 45 | [_ptr release], _ptr = nil; 46 | // Release any retained subviews of the main view. 47 | } 48 | 49 | - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation 50 | { 51 | return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown); 52 | } 53 | 54 | - (BOOL) isPrime:(unsigned long long)input { 55 | for (unsigned long long i = 2; i < input/2+1; i++) { 56 | if (input % i == 0) 57 | return NO; 58 | } 59 | return YES; 60 | } 61 | 62 | - (void) findNextPrime { 63 | NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 64 | 65 | unsigned long long lastPrime = [[_primes lastObject] unsignedLongLongValue]; 66 | unsigned long long potentialPrime = lastPrime + 1; 67 | while ( [self isPrime:potentialPrime] == NO ) 68 | potentialPrime++; 69 | 70 | [_primes addObject:[NSNumber numberWithUnsignedLongLong:potentialPrime]]; 71 | 72 | [NSThread sleepForTimeInterval:1]; 73 | [pool release]; 74 | [self performSelectorOnMainThread:@selector(endSearch) withObject:nil waitUntilDone:NO]; 75 | } 76 | 77 | - (void) endSearch { 78 | [_ptr endRefresh]; 79 | [self.table reloadData]; 80 | } 81 | 82 | #pragma mark - UITableView Delegate Methods 83 | 84 | - (int) numberOfSectionsInTableView:(UITableView *)tableView { 85 | return 1; 86 | } 87 | 88 | - (int) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 89 | return _primes.count; 90 | } 91 | 92 | - (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 93 | static NSString *CellIdentifer = @"CellIdentifier"; 94 | UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifer]; 95 | if (cell == nil) { 96 | cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifer] autorelease]; 97 | } 98 | 99 | cell.textLabel.text = [[_primes objectAtIndex:indexPath.row] stringValue]; 100 | 101 | return cell; 102 | } 103 | 104 | #pragma mark - CustomPullToRefresh Delegate Methods 105 | 106 | - (void) customPullToRefreshShouldRefresh:(CustomPullToRefresh *)ptr { 107 | [self performSelectorInBackground:@selector(findNextPrime) withObject:nil]; 108 | } 109 | 110 | 111 | 112 | @end 113 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # [Miso's](http://gomiso.com) Pull To Refresh Library ([blog post here](http://blog.gomiso.com/2012/03/22/yet-another-pull-to-refresh-library/)) 2 | 3 | #### Authors 4 | Me and [Tim Lee](https://github.com/timothy1ee) 5 | 6 | #### Pull To Refresh Demo 7 | I've put together a simple sample project that recreates our familiar rainbow loading in the [Miso App](http://itunes.apple.com/us/app/miso-social-tv/id352823603?mt=8). 8 | The sample artificially creates async work by finding the next largest prime and putting the results into a regular uitableview. 9 | 10 | #### Features 11 | * does not steal your scrollview's delegate (intrusive), but merely observes the scrollview's contentOffset property (non-intrusive) 12 | * allows refreshing in all 4 directions (pull down to refresh, pull up to load more?) 13 | 14 | #### How To Use 15 | Note that this library merely abstracts away the refresh cycle logic. It is up to the developer to use this class combined with custom views to create a complete, visually satisfactory solution. 16 | 17 | There's only one constructor: 18 | 19 | MSPullToRefreshController *ptrc = [[MSPullToRefreshController alloc] initWithScrollView:scrollView delegate:self]; 20 | 21 | As the Delegate, you must implement these methods to inform the library of your specific refresh requirements: 22 | 23 | /* 24 | * asks the delegate which refresh directions it would like enabled 25 | */ 26 | - (BOOL) pullToRefreshController:(MSPullToRefreshController *) controller canRefreshInDirection:(MSRefreshDirection)direction; 27 | 28 | /* 29 | * inset threshold to engage refresh 30 | */ 31 | - (CGFloat) pullToRefreshController:(MSPullToRefreshController *) controller refreshableInsetForDirection:(MSRefreshDirection) direction; 32 | 33 | /* 34 | * inset that the direction retracts back to after refresh started 35 | */ 36 | - (CGFloat) pullToRefreshController:(MSPullToRefreshController *)controller refreshingInsetForDirection:(MSRefreshDirection)direction; 37 | 38 | You may (it is in your best interest to) to implement these methods in order to transform your custom views based on where you are in the refresh cycle: 39 | 40 | /* 41 | * informs the delegate that lifting your finger will trigger a refresh 42 | * in that direction. This is only called when you cross the refreshable 43 | * offset defined in the respective MSInflectionOffsets. 44 | */ 45 | - (void) pullToRefreshController:(MSPullToRefreshController *) controller canEngageRefreshDirection:(MSRefreshDirection) direction; 46 | 47 | /* 48 | * informs the delegate that lifting your finger will NOT trigger a refresh 49 | * in that direction. This is only called when you cross the refreshable 50 | * offset defined in the respective MSInflectionOffsets. 51 | */ 52 | - (void) pullToRefreshController:(MSPullToRefreshController *) controller didDisengageRefreshDirection:(MSRefreshDirection) direction; 53 | 54 | /* 55 | * informs the delegate that refresh sequence has been started by the user 56 | * in the specified direction. A good place to start any async work. 57 | */ 58 | - (void) pullToRefreshController:(MSPullToRefreshController *) controller didEngageRefreshDirection:(MSRefreshDirection) direction; 59 | 60 | Note that you must manually end a refresh cycle in any direction: 61 | 62 | [ptrc finishRefreshingDirection:MSRefreshDirectionTop animated:NO]; 63 | 64 | You can also programatically start a refresh cycle in any direction: 65 | 66 | [ptrc startRefreshingDirection:MSRefreshDirectionTop animated:YES]; 67 | 68 | #### Caution 69 | 70 | This library will break down if the area of the scrollView's contentSize is smaller (strict) than the area of the scrollView's frame. It is up to the developer to ensure the converse. 71 | 72 | #### License 73 | 74 | MSPullToRefreshController is available under the MIT license. See the LICENSE file for more info. 75 | -------------------------------------------------------------------------------- /PullToRefreshDemo/MSPullToRefreshController.h: -------------------------------------------------------------------------------- 1 | // 2 | // MSPullToRefreshController.h 3 | // 4 | // Created by John Wu on 3/5/12. 5 | // Copyright (c) 2012 TFM. All rights reserved. 6 | // 7 | 8 | /**************************||||-ABSTRACT-||||********************************** 9 | * 10 | * This is the a generic pull-to-refresh library. 11 | * 12 | * This library attempts to abstract away the core pull- 13 | * to-refresh logic, and allow the users to implement custom 14 | * views on top and update them at key points in the refresh cycle. 15 | * 16 | * Hence, this class is NOT meant to be used directly. You 17 | * are meant to write a wrapper which uses this class to implement 18 | * your own pull-to-refresh solutions. 19 | * 20 | * Instead of overriding the delegate like most PTF libraries, 21 | * we merely observe the contentOffset property of the scrollview 22 | * using KVO. 23 | * 24 | * This library allows refreshing in any direction and/or any combination 25 | * of directions. 26 | * 27 | * It is up to the user to inform the library when to end a refresh sequence 28 | * for each direction. 29 | * 30 | * Do NOT use a scrollview with a contentSize that is smaller than the frame. 31 | * 32 | * 33 | ******************************************************************************/ 34 | 35 | #import 36 | 37 | /** 38 | * flags that determine the directions that can be engaged. 39 | */ 40 | typedef enum { 41 | MSRefreshableDirectionNone = 0, 42 | MSRefreshableDirectionTop = 1 << 0, 43 | MSRefreshableDirectionLeft = 1 << 1, 44 | MSRefreshableDirectionBottom = 1 << 2, 45 | MSRefreshableDirectionRight = 1 << 3 46 | } MSRefreshableDirections; 47 | 48 | /** 49 | * flags that determine the directions that are currently refreshing. 50 | */ 51 | typedef enum { 52 | MSRefreshingDirectionNone = 0, 53 | MSRefreshingDirectionTop = 1 << 0, 54 | MSRefreshingDirectionLeft = 1 << 1, 55 | MSRefreshingDirectionBottom = 1 << 2, 56 | MSRefreshingDirectionRight = 1 << 3 57 | } MSRefreshingDirections; 58 | 59 | /** 60 | * simple enum that specifies the direction related to delegate callbacks. 61 | */ 62 | typedef enum { 63 | MSRefreshDirectionTop = 0, 64 | MSRefreshDirectionLeft, 65 | MSRefreshDirectionBottom, 66 | MSRefreshDirectionRight 67 | } MSRefreshDirection; 68 | 69 | @protocol MSPullToRefreshDelegate; 70 | 71 | @interface MSPullToRefreshController : NSObject { 72 | 73 | // the main object 74 | UIScrollView *_scrollView; 75 | 76 | // flags to indicate where we are in the refresh sequence 77 | MSRefreshableDirections _refreshableDirections; 78 | MSRefreshingDirections _refreshingDirections; 79 | 80 | // delegate to receive callbacks on different stages of the refresh cycle 81 | id _delegate; 82 | 83 | // used internally to capture the did end dragging state 84 | BOOL _wasDragging; 85 | 86 | // scroll view's original content inset before refresh sequence 87 | UIEdgeInsets _originalScrollViewContentInset; 88 | } 89 | 90 | /* 91 | * the only constructor you should use. 92 | * pass in the scrollview to be observed and 93 | * the delegate to receive call backs 94 | */ 95 | - (id) initWithScrollView:(UIScrollView *)scrollView delegate:(id )delegate; 96 | 97 | /* 98 | * Call this function with a direction to end the refresh sequence 99 | * in that direction. With or without animation. 100 | */ 101 | - (void) finishRefreshingDirection:(MSRefreshDirection)direction animated:(BOOL)animated; 102 | 103 | /* 104 | * calls the above with animated = NO 105 | */ 106 | - (void) finishRefreshingDirection:(MSRefreshDirection)direction; 107 | 108 | /* 109 | * Programmatically start a refresh in the given direction, animated or not. 110 | */ 111 | - (void) startRefreshingDirection:(MSRefreshDirection)direction animated:(BOOL)animated; 112 | 113 | /* 114 | * calls the above with animated = NO 115 | */ 116 | - (void) startRefreshingDirection:(MSRefreshDirection)direction; 117 | 118 | @end 119 | 120 | @protocol MSPullToRefreshDelegate 121 | 122 | @required 123 | 124 | /* 125 | * asks the delegate which refresh directions it would like enabled 126 | */ 127 | - (BOOL) pullToRefreshController:(MSPullToRefreshController *) controller canRefreshInDirection:(MSRefreshDirection)direction; 128 | 129 | /* 130 | * inset threshold to engage refresh 131 | */ 132 | - (CGFloat) pullToRefreshController:(MSPullToRefreshController *) controller refreshableInsetForDirection:(MSRefreshDirection) direction; 133 | 134 | /* 135 | * inset that the direction retracts back to after refresh started 136 | */ 137 | - (CGFloat) pullToRefreshController:(MSPullToRefreshController *)controller refreshingInsetForDirection:(MSRefreshDirection)direction; 138 | 139 | @optional 140 | 141 | /* 142 | * informs the delegate that lifting your finger will trigger a refresh 143 | * in that direction. This is only called when you cross the refreshable 144 | * offset defined in the respective MSInflectionOffsets. 145 | */ 146 | - (void) pullToRefreshController:(MSPullToRefreshController *) controller canEngageRefreshDirection:(MSRefreshDirection) direction; 147 | 148 | /* 149 | * informs the delegate that lifting your finger will NOT trigger a refresh 150 | * in that direction. This is only called when you cross the refreshable 151 | * offset defined in the respective MSInflectionOffsets. 152 | */ 153 | - (void) pullToRefreshController:(MSPullToRefreshController *) controller didDisengageRefreshDirection:(MSRefreshDirection) direction; 154 | 155 | /* 156 | * informs the delegate that refresh sequence has been started by the user 157 | * in the specified direction. A good place to start any async work. 158 | */ 159 | - (void) pullToRefreshController:(MSPullToRefreshController *) controller didEngageRefreshDirection:(MSRefreshDirection) direction; 160 | 161 | 162 | @end 163 | -------------------------------------------------------------------------------- /PullToRefreshDemo/CustomPullToRefresh.m: -------------------------------------------------------------------------------- 1 | // 2 | // CustomPullToRefresh.m 3 | // PullToRefreshDemo 4 | // 5 | // Created by John Wu on 3/22/12. 6 | // Copyright (c) 2012 TFM. All rights reserved. 7 | // 8 | 9 | #import "CustomPullToRefresh.h" 10 | 11 | @implementation CustomPullToRefresh 12 | 13 | - (id) initWithScrollView:(UIScrollView *)scrollView delegate:(id)delegate { 14 | self = [super init]; 15 | if (self) { 16 | _delegate = delegate; 17 | _scrollView = [scrollView retain]; 18 | [_scrollView addObserver:self forKeyPath:@"contentSize" options:0 context:NULL]; 19 | 20 | _ptrc = [[MSPullToRefreshController alloc] initWithScrollView:_scrollView delegate:self]; 21 | 22 | NSMutableArray *animationImages = [NSMutableArray arrayWithCapacity:19]; 23 | for (int i=1; i<20; i++) 24 | [animationImages addObject:[UIImage imageNamed:[NSString stringWithFormat:@"loading-%d.png",i]]]; 25 | 26 | _rainbowTop = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"loading-1.png"]]; 27 | _rainbowTop.frame = CGRectMake(0, -_scrollView.frame.size.height, _scrollView.frame.size.width, scrollView.frame.size.height); 28 | _rainbowTop.animationImages = animationImages; 29 | _rainbowTop.animationDuration = 2; 30 | [scrollView addSubview:_rainbowTop]; 31 | 32 | _rainbowBot = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"loading-1.png"]]; 33 | _rainbowBot.autoresizingMask = UIViewAutoresizingFlexibleTopMargin; 34 | _rainbowBot.frame = CGRectMake(0, _scrollView.frame.size.height, _scrollView.frame.size.width, scrollView.frame.size.height); 35 | _rainbowBot.animationImages = animationImages; 36 | _rainbowBot.animationDuration = 2; 37 | [scrollView addSubview:_rainbowBot]; 38 | 39 | 40 | 41 | _arrowTop = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"big_arrow.png"]]; 42 | _arrowTop.frame = CGRectMake(floorf((_rainbowTop.frame.size.width-_arrowTop.frame.size.width)/2), _rainbowTop.frame.size.height - _arrowTop.frame.size.height - 10 , _arrowTop.frame.size.width, _arrowTop.frame.size.height); 43 | [_rainbowTop addSubview:_arrowTop]; 44 | 45 | _arrowBot = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"big_arrow.png"]]; 46 | _arrowBot.frame = CGRectMake(floorf((_rainbowBot.frame.size.width-_arrowBot.frame.size.width)/2), 10 , _arrowBot.frame.size.width, _arrowBot.frame.size.height); 47 | _arrowBot.transform = CGAffineTransformMakeRotation(M_PI); 48 | [_rainbowBot addSubview:_arrowBot]; 49 | 50 | } 51 | return self; 52 | } 53 | 54 | - (void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { 55 | NSLog(@"%@",NSStringFromCGSize(_scrollView.contentSize)); 56 | CGFloat contentSizeArea = _scrollView.contentSize.width*_scrollView.contentSize.height; 57 | CGFloat frameArea = _scrollView.frame.size.width*_scrollView.frame.size.height; 58 | CGSize adjustedContentSize = contentSizeArea < frameArea ? _scrollView.frame.size : _scrollView.contentSize; 59 | _rainbowBot.frame = CGRectMake(0, adjustedContentSize.height, _scrollView.frame.size.width, _scrollView.frame.size.height); 60 | } 61 | 62 | - (void) dealloc { 63 | [_scrollView removeObserver:self forKeyPath:@"contentSize"]; 64 | [_scrollView release]; 65 | [_ptrc release]; 66 | [_arrowTop release]; 67 | [_rainbowTop release]; 68 | [_rainbowBot release]; 69 | [_arrowBot release]; 70 | [super dealloc]; 71 | } 72 | 73 | - (void) endRefresh { 74 | [_ptrc finishRefreshingDirection:MSRefreshDirectionTop animated:YES]; 75 | [_ptrc finishRefreshingDirection:MSRefreshDirectionBottom animated:YES]; 76 | [_rainbowTop stopAnimating]; 77 | [_rainbowBot stopAnimating]; 78 | _arrowBot.hidden = NO; 79 | _arrowBot.transform = CGAffineTransformMakeRotation(M_PI); 80 | _arrowTop.hidden = NO; 81 | _arrowTop.transform = CGAffineTransformIdentity; 82 | } 83 | 84 | - (void) startRefresh { 85 | [_ptrc startRefreshingDirection:MSRefreshDirectionTop]; 86 | } 87 | 88 | #pragma mark - MSPullToRefreshDelegate Methods 89 | 90 | - (BOOL) pullToRefreshController:(MSPullToRefreshController *)controller canRefreshInDirection:(MSRefreshDirection)direction { 91 | return direction == MSRefreshDirectionTop || direction == MSRefreshDirectionBottom; 92 | } 93 | 94 | - (CGFloat) pullToRefreshController:(MSPullToRefreshController *)controller refreshingInsetForDirection:(MSRefreshDirection)direction { 95 | return 30; 96 | } 97 | 98 | - (CGFloat) pullToRefreshController:(MSPullToRefreshController *)controller refreshableInsetForDirection:(MSRefreshDirection)direction { 99 | return 30; 100 | } 101 | 102 | - (void) pullToRefreshController:(MSPullToRefreshController *)controller canEngageRefreshDirection:(MSRefreshDirection)direction { 103 | [UIView beginAnimations:nil context:NULL]; 104 | [UIView setAnimationDuration:0.2]; 105 | _arrowTop.transform = CGAffineTransformMakeRotation(M_PI); 106 | _arrowBot.transform = CGAffineTransformIdentity; 107 | [UIView commitAnimations]; 108 | } 109 | 110 | - (void) pullToRefreshController:(MSPullToRefreshController *)controller didDisengageRefreshDirection:(MSRefreshDirection)direction { 111 | [UIView beginAnimations:nil context:NULL]; 112 | [UIView setAnimationDuration:0.2]; 113 | _arrowTop.transform = CGAffineTransformIdentity; 114 | _arrowBot.transform = CGAffineTransformMakeRotation(M_PI); 115 | [UIView commitAnimations]; 116 | } 117 | 118 | - (void) pullToRefreshController:(MSPullToRefreshController *)controller didEngageRefreshDirection:(MSRefreshDirection)direction { 119 | _arrowTop.hidden = YES; 120 | _arrowBot.hidden = YES; 121 | [_rainbowTop startAnimating]; 122 | [_rainbowBot startAnimating]; 123 | [_delegate customPullToRefreshShouldRefresh:self]; 124 | } 125 | 126 | @end 127 | -------------------------------------------------------------------------------- /PullToRefreshDemo/en.lproj/ViewController.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 1536 5 | 12C54 6 | 2840 7 | 1187.34 8 | 625.00 9 | 10 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 11 | 1926 12 | 13 | 14 | IBProxyObject 15 | IBUITableView 16 | IBUIView 17 | 18 | 19 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 20 | 21 | 22 | PluginDependencyRecalculationVersion 23 | 24 | 25 | 26 | 27 | IBFilesOwner 28 | IBCocoaTouchFramework 29 | 30 | 31 | IBFirstResponder 32 | IBCocoaTouchFramework 33 | 34 | 35 | 36 | 274 37 | 38 | 39 | 40 | 274 41 | {320, 460} 42 | 43 | 44 | _NS:9 45 | 46 | 3 47 | MQA 48 | 49 | YES 50 | IBCocoaTouchFramework 51 | YES 52 | 1 53 | 0 54 | YES 55 | 44 56 | 22 57 | 22 58 | 59 | 60 | {{0, 20}, {320, 460}} 61 | 62 | 63 | 64 | 3 65 | MC43NQA 66 | 67 | 2 68 | 69 | 70 | NO 71 | 72 | IBCocoaTouchFramework 73 | 74 | 75 | 76 | 77 | 78 | 79 | view 80 | 81 | 82 | 83 | 7 84 | 85 | 86 | 87 | table 88 | 89 | 90 | 91 | 11 92 | 93 | 94 | 95 | dataSource 96 | 97 | 98 | 99 | 9 100 | 101 | 102 | 103 | delegate 104 | 105 | 106 | 107 | 10 108 | 109 | 110 | 111 | 112 | 113 | 0 114 | 115 | 116 | 117 | 118 | 119 | -1 120 | 121 | 122 | File's Owner 123 | 124 | 125 | -2 126 | 127 | 128 | 129 | 130 | 6 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 8 139 | 140 | 141 | 142 | 143 | 144 | 145 | ViewController 146 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 147 | UIResponder 148 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 149 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 150 | MyTableView 151 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 152 | 153 | 154 | 155 | 156 | 157 | 11 158 | 159 | 160 | 161 | 162 | MyTableView 163 | UITableView 164 | 165 | IBProjectSource 166 | ./Classes/MyTableView.h 167 | 168 | 169 | 170 | ViewController 171 | UIViewController 172 | 173 | table 174 | UITableView 175 | 176 | 177 | table 178 | 179 | table 180 | UITableView 181 | 182 | 183 | 184 | IBProjectSource 185 | ./Classes/ViewController.h 186 | 187 | 188 | 189 | 190 | 0 191 | IBCocoaTouchFramework 192 | 193 | com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS 194 | 195 | 196 | YES 197 | 3 198 | 1926 199 | 200 | 201 | -------------------------------------------------------------------------------- /PullToRefreshDemo/MSPullToRefreshController.m: -------------------------------------------------------------------------------- 1 | // 2 | // MSPullToRefreshController.m 3 | // 4 | // Created by John Wu on 3/5/12. 5 | // Copyright (c) 2012 TFM. All rights reserved. 6 | // 7 | 8 | #import "MSPullToRefreshController.h" 9 | 10 | @interface MSPullToRefreshController () 11 | 12 | @property (nonatomic, assign) MSRefreshingDirections refreshingDirections; 13 | @property (nonatomic, assign) MSRefreshableDirections refreshableDirections; 14 | @property (nonatomic, assign) id delegate; 15 | 16 | - (void) _checkOffsetsForDirection:(MSRefreshDirection)direction change:(NSDictionary *)change; 17 | 18 | @end 19 | 20 | @implementation MSPullToRefreshController 21 | @synthesize refreshingDirections = _refreshingDirections; 22 | @synthesize refreshableDirections = _refreshableDirections; 23 | @synthesize delegate = _delegate; 24 | 25 | #pragma mark - Object Life Cycle 26 | 27 | - (id) initWithScrollView:(UIScrollView *)scrollView delegate:(id )delegate { 28 | self = [super init]; 29 | if (self) { 30 | // set ivars 31 | _delegate = delegate; 32 | _scrollView = [scrollView retain]; 33 | 34 | // observe the contentOffset. NSKeyValueObservingOptionPrior is CRUCIAL! 35 | [_scrollView addObserver:self forKeyPath:@"contentOffset" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld | NSKeyValueObservingOptionPrior context:NULL]; 36 | 37 | } 38 | 39 | return self; 40 | } 41 | 42 | - (void) dealloc { 43 | // basic clean up 44 | [_scrollView removeObserver:self forKeyPath:@"contentOffset"]; 45 | [_scrollView release]; 46 | [super dealloc]; 47 | } 48 | 49 | #pragma mark - KVO 50 | 51 | - (void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { 52 | if ([keyPath isEqualToString:@"contentOffset"]) { 53 | // for each direction, check to see if refresh sequence needs to be updated. 54 | for (MSRefreshDirection direction = MSRefreshDirectionTop; direction <= MSRefreshDirectionRight; direction++) { 55 | BOOL canRefresh = [_delegate pullToRefreshController:self canRefreshInDirection:direction]; 56 | if (canRefresh) 57 | [self _checkOffsetsForDirection:direction change:change]; 58 | } 59 | 60 | _wasDragging = _scrollView.dragging; 61 | } 62 | } 63 | 64 | #pragma mark - Public Methods 65 | 66 | - (void) startRefreshingDirection:(MSRefreshDirection)direction { 67 | [self startRefreshingDirection:direction animated:NO]; 68 | } 69 | 70 | - (void) startRefreshingDirection:(MSRefreshDirection)direction animated:(BOOL)animated { 71 | MSRefreshingDirections refreshingDirection = MSRefreshingDirectionNone; 72 | MSRefreshableDirections refreshableDirection = MSRefreshableDirectionNone; 73 | UIEdgeInsets contentInset = _scrollView.contentInset; 74 | CGPoint contentOffset = CGPointZero; 75 | 76 | CGFloat refreshingInset = [_delegate pullToRefreshController:self refreshingInsetForDirection:direction]; 77 | 78 | CGFloat contentSizeArea = _scrollView.contentSize.width*_scrollView.contentSize.height; 79 | CGFloat frameArea = _scrollView.frame.size.width*_scrollView.frame.size.height; 80 | CGSize adjustedContentSize = contentSizeArea < frameArea ? _scrollView.frame.size : _scrollView.contentSize; 81 | 82 | switch (direction) { 83 | case MSRefreshDirectionTop: 84 | refreshableDirection = MSRefreshableDirectionTop; 85 | refreshingDirection = MSRefreshingDirectionTop; 86 | CGFloat originalContentOffsetY = -contentInset.top; 87 | contentInset = UIEdgeInsetsMake(contentInset.top + refreshingInset, contentInset.left, contentInset.bottom, contentInset.right); 88 | contentOffset = CGPointMake(0, -refreshingInset+originalContentOffsetY); 89 | break; 90 | case MSRefreshDirectionLeft: 91 | refreshableDirection = MSRefreshableDirectionLeft; 92 | refreshingDirection = MSRefreshingDirectionLeft; 93 | contentInset = UIEdgeInsetsMake(contentInset.top, refreshingInset, contentInset.bottom, contentInset.right); 94 | contentOffset = CGPointMake(-refreshingInset, 0); 95 | break; 96 | case MSRefreshDirectionBottom: 97 | refreshableDirection = MSRefreshableDirectionBottom; 98 | refreshingDirection = MSRefreshingDirectionBottom; 99 | contentInset = UIEdgeInsetsMake(contentInset.top, contentInset.left, refreshingInset, contentInset.right); 100 | contentOffset = CGPointMake(0, adjustedContentSize.height + refreshingInset); 101 | break; 102 | case MSRefreshDirectionRight: 103 | refreshableDirection = MSRefreshableDirectionRight; 104 | refreshingDirection = MSRefreshingDirectionRight; 105 | contentInset = UIEdgeInsetsMake(contentInset.top, contentInset.left, contentInset.bottom, refreshingInset); 106 | contentOffset = CGPointMake(adjustedContentSize.width + refreshingInset, 0); 107 | break; 108 | default: 109 | break; 110 | } 111 | 112 | if (animated) { 113 | [UIView beginAnimations:nil context:NULL]; 114 | [UIView setAnimationDuration:0.2]; 115 | } 116 | _originalScrollViewContentInset = _scrollView.contentInset; 117 | _scrollView.contentInset = contentInset; 118 | _scrollView.contentOffset = contentOffset; 119 | 120 | if (animated) { 121 | [UIView commitAnimations]; 122 | } 123 | 124 | self.refreshingDirections |= refreshingDirection; 125 | self.refreshableDirections &= ~refreshableDirection; 126 | if ([_delegate respondsToSelector:@selector(pullToRefreshController:didEngageRefreshDirection:)]) { 127 | [_delegate pullToRefreshController:self didEngageRefreshDirection:direction]; 128 | } 129 | } 130 | 131 | - (void) finishRefreshingDirection:(MSRefreshDirection)direction { 132 | [self finishRefreshingDirection:direction animated:NO]; 133 | } 134 | 135 | - (void) finishRefreshingDirection:(MSRefreshDirection)direction animated:(BOOL)animated { 136 | MSRefreshingDirections refreshingDirection = MSRefreshingDirectionNone; 137 | UIEdgeInsets contentInset = _scrollView.contentInset; 138 | switch (direction) { 139 | case MSRefreshDirectionTop: 140 | refreshingDirection = MSRefreshingDirectionTop; 141 | contentInset = UIEdgeInsetsMake(_originalScrollViewContentInset.top, contentInset.left, contentInset.bottom, contentInset.right); 142 | break; 143 | case MSRefreshDirectionLeft: 144 | refreshingDirection = MSRefreshingDirectionLeft; 145 | contentInset = UIEdgeInsetsMake(contentInset.top, 0, contentInset.bottom, contentInset.right); 146 | break; 147 | case MSRefreshDirectionBottom: 148 | refreshingDirection = MSRefreshingDirectionBottom; 149 | contentInset = UIEdgeInsetsMake(contentInset.top, contentInset.left, 0, contentInset.right); 150 | break; 151 | case MSRefreshDirectionRight: 152 | refreshingDirection = MSRefreshingDirectionRight; 153 | contentInset = UIEdgeInsetsMake(contentInset.top, contentInset.left, contentInset.bottom, 0); 154 | break; 155 | default: 156 | break; 157 | } 158 | if (animated) { 159 | [UIView beginAnimations:nil context:NULL]; 160 | [UIView setAnimationDuration:0.2]; 161 | } 162 | _scrollView.contentInset = contentInset; 163 | 164 | if (animated) { 165 | [UIView commitAnimations]; 166 | } 167 | 168 | self.refreshingDirections &= ~refreshingDirection; 169 | } 170 | 171 | #pragma mark - Private Methods 172 | 173 | - (void) _checkOffsetsForDirection:(MSRefreshDirection)direction change:(NSDictionary *)change { 174 | 175 | // define some local ivars that disambiguates according to direction 176 | CGPoint oldOffset = [[change objectForKey:NSKeyValueChangeOldKey] CGPointValue]; 177 | 178 | MSRefreshingDirections refreshingDirection = MSRefreshingDirectionNone; 179 | MSRefreshableDirections refreshableDirection = MSRefreshableDirectionNone; 180 | BOOL canEngage = NO; 181 | UIEdgeInsets contentInset = _scrollView.contentInset; 182 | 183 | CGFloat refreshableInset = [_delegate pullToRefreshController:self refreshableInsetForDirection:direction]; 184 | CGFloat refreshingInset = [_delegate pullToRefreshController:self refreshingInsetForDirection:direction]; 185 | 186 | CGFloat contentSizeArea = _scrollView.contentSize.width*_scrollView.contentSize.height; 187 | CGFloat frameArea = _scrollView.frame.size.width*_scrollView.frame.size.height; 188 | CGSize adjustedContentSize = contentSizeArea < frameArea ? _scrollView.frame.size : _scrollView.contentSize; 189 | 190 | switch (direction) { 191 | case MSRefreshDirectionTop: 192 | refreshingDirection = MSRefreshingDirectionTop; 193 | refreshableDirection = MSRefreshableDirectionTop; 194 | canEngage = oldOffset.y < - refreshableInset - _scrollView.contentInset.top; 195 | contentInset = UIEdgeInsetsMake(contentInset.top + refreshingInset, contentInset.left, contentInset.bottom, contentInset.right); 196 | break; 197 | case MSRefreshDirectionLeft: 198 | refreshingDirection = MSRefreshingDirectionLeft; 199 | refreshableDirection = MSRefreshableDirectionLeft; 200 | canEngage = oldOffset.x < -refreshableInset; 201 | contentInset = UIEdgeInsetsMake(contentInset.top, refreshingInset, contentInset.bottom, contentInset.right); 202 | break; 203 | case MSRefreshDirectionBottom: 204 | refreshingDirection = MSRefreshingDirectionBottom; 205 | refreshableDirection = MSRefreshableDirectionBottom; 206 | canEngage = (oldOffset.y + _scrollView.frame.size.height - adjustedContentSize.height > refreshableInset); 207 | contentInset = UIEdgeInsetsMake(contentInset.top, contentInset.left, refreshingInset, contentInset.right); 208 | break; 209 | case MSRefreshDirectionRight: 210 | refreshingDirection = MSRefreshingDirectionRight; 211 | refreshableDirection = MSRefreshableDirectionRight; 212 | canEngage = oldOffset.x + _scrollView.frame.size.width - adjustedContentSize.width > refreshableInset; 213 | contentInset = UIEdgeInsetsMake(contentInset.top, contentInset.left, contentInset.bottom, refreshingInset); 214 | break; 215 | default: 216 | break; 217 | } 218 | 219 | if (!(self.refreshingDirections & refreshingDirection)) { 220 | // only go in here if the requested direction is enabled and not refreshing 221 | if (canEngage) { 222 | // only go in here if user pulled past the inflection offset 223 | if (_wasDragging != _scrollView.dragging && _scrollView.decelerating && [change objectForKey:NSKeyValueChangeNotificationIsPriorKey] && (self.refreshableDirections & refreshableDirection)) { 224 | 225 | // if you are decelerating, it means you've stopped dragging. 226 | self.refreshingDirections |= refreshingDirection; 227 | self.refreshableDirections &= ~refreshableDirection; 228 | _originalScrollViewContentInset = _scrollView.contentInset; 229 | _scrollView.contentInset = contentInset; 230 | if ([_delegate respondsToSelector:@selector(pullToRefreshController:didEngageRefreshDirection:)]) { 231 | [_delegate pullToRefreshController:self didEngageRefreshDirection:direction]; 232 | } 233 | } else if (_scrollView.dragging && !_scrollView.decelerating && !(self.refreshableDirections & refreshableDirection)) { 234 | // only go in here the first time you've dragged past releasable offset 235 | self.refreshableDirections |= refreshableDirection; 236 | if ([_delegate respondsToSelector:@selector(pullToRefreshController:canEngageRefreshDirection:)]) { 237 | [_delegate pullToRefreshController:self canEngageRefreshDirection:direction]; 238 | } 239 | } 240 | } else if ((self.refreshableDirections & refreshableDirection) ) { 241 | // if you're here it means you've crossed back from the releasable offset 242 | self.refreshableDirections &= ~refreshableDirection; 243 | if ([_delegate respondsToSelector:@selector(pullToRefreshController:didDisengageRefreshDirection:)]) { 244 | [_delegate pullToRefreshController:self didDisengageRefreshDirection:direction]; 245 | } 246 | } 247 | } 248 | 249 | } 250 | 251 | @end 252 | -------------------------------------------------------------------------------- /PullToRefreshDemo.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 721F79D7151BB5C000FA0D5E /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 721F79D6151BB5C000FA0D5E /* UIKit.framework */; }; 11 | 721F79D9151BB5C000FA0D5E /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 721F79D8151BB5C000FA0D5E /* Foundation.framework */; }; 12 | 721F79DB151BB5C000FA0D5E /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 721F79DA151BB5C000FA0D5E /* CoreGraphics.framework */; }; 13 | 721F79E1151BB5C100FA0D5E /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 721F79DF151BB5C100FA0D5E /* InfoPlist.strings */; }; 14 | 721F79E3151BB5C100FA0D5E /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 721F79E2151BB5C100FA0D5E /* main.m */; }; 15 | 721F79E7151BB5C100FA0D5E /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 721F79E6151BB5C100FA0D5E /* AppDelegate.m */; }; 16 | 721F79EA151BB5C100FA0D5E /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 721F79E9151BB5C100FA0D5E /* ViewController.m */; }; 17 | 721F79ED151BB5C100FA0D5E /* ViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 721F79EB151BB5C100FA0D5E /* ViewController.xib */; }; 18 | 721F79F8151BB91100FA0D5E /* CustomPullToRefresh.m in Sources */ = {isa = PBXBuildFile; fileRef = 721F79F7151BB91100FA0D5E /* CustomPullToRefresh.m */; }; 19 | 721F79FB151BBEA300FA0D5E /* MSPullToRefreshController.m in Sources */ = {isa = PBXBuildFile; fileRef = 721F79F4151BB5DB00FA0D5E /* MSPullToRefreshController.m */; }; 20 | 721F7A26151BD94700FA0D5E /* loading-1.png in Resources */ = {isa = PBXBuildFile; fileRef = 721F7A00151BD94400FA0D5E /* loading-1.png */; }; 21 | 721F7A27151BD94700FA0D5E /* loading-1@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 721F7A01151BD94500FA0D5E /* loading-1@2x.png */; }; 22 | 721F7A28151BD94700FA0D5E /* loading-2.png in Resources */ = {isa = PBXBuildFile; fileRef = 721F7A02151BD94500FA0D5E /* loading-2.png */; }; 23 | 721F7A29151BD94700FA0D5E /* loading-2@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 721F7A03151BD94500FA0D5E /* loading-2@2x.png */; }; 24 | 721F7A2A151BD94700FA0D5E /* loading-3.png in Resources */ = {isa = PBXBuildFile; fileRef = 721F7A04151BD94500FA0D5E /* loading-3.png */; }; 25 | 721F7A2B151BD94700FA0D5E /* loading-3@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 721F7A05151BD94500FA0D5E /* loading-3@2x.png */; }; 26 | 721F7A2C151BD94700FA0D5E /* loading-4.png in Resources */ = {isa = PBXBuildFile; fileRef = 721F7A06151BD94500FA0D5E /* loading-4.png */; }; 27 | 721F7A2D151BD94700FA0D5E /* loading-4@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 721F7A07151BD94500FA0D5E /* loading-4@2x.png */; }; 28 | 721F7A2E151BD94700FA0D5E /* loading-5.png in Resources */ = {isa = PBXBuildFile; fileRef = 721F7A08151BD94600FA0D5E /* loading-5.png */; }; 29 | 721F7A2F151BD94700FA0D5E /* loading-5@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 721F7A09151BD94600FA0D5E /* loading-5@2x.png */; }; 30 | 721F7A30151BD94700FA0D5E /* loading-6.png in Resources */ = {isa = PBXBuildFile; fileRef = 721F7A0A151BD94600FA0D5E /* loading-6.png */; }; 31 | 721F7A31151BD94700FA0D5E /* loading-6@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 721F7A0B151BD94600FA0D5E /* loading-6@2x.png */; }; 32 | 721F7A32151BD94700FA0D5E /* loading-7.png in Resources */ = {isa = PBXBuildFile; fileRef = 721F7A0C151BD94600FA0D5E /* loading-7.png */; }; 33 | 721F7A33151BD94700FA0D5E /* loading-7@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 721F7A0D151BD94600FA0D5E /* loading-7@2x.png */; }; 34 | 721F7A34151BD94700FA0D5E /* loading-8.png in Resources */ = {isa = PBXBuildFile; fileRef = 721F7A0E151BD94600FA0D5E /* loading-8.png */; }; 35 | 721F7A35151BD94700FA0D5E /* loading-8@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 721F7A0F151BD94600FA0D5E /* loading-8@2x.png */; }; 36 | 721F7A36151BD94700FA0D5E /* loading-9.png in Resources */ = {isa = PBXBuildFile; fileRef = 721F7A10151BD94600FA0D5E /* loading-9.png */; }; 37 | 721F7A37151BD94700FA0D5E /* loading-9@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 721F7A11151BD94600FA0D5E /* loading-9@2x.png */; }; 38 | 721F7A38151BD94700FA0D5E /* loading-10.png in Resources */ = {isa = PBXBuildFile; fileRef = 721F7A12151BD94600FA0D5E /* loading-10.png */; }; 39 | 721F7A39151BD94700FA0D5E /* loading-10@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 721F7A13151BD94600FA0D5E /* loading-10@2x.png */; }; 40 | 721F7A3A151BD94700FA0D5E /* loading-11.png in Resources */ = {isa = PBXBuildFile; fileRef = 721F7A14151BD94600FA0D5E /* loading-11.png */; }; 41 | 721F7A3B151BD94700FA0D5E /* loading-11@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 721F7A15151BD94600FA0D5E /* loading-11@2x.png */; }; 42 | 721F7A3C151BD94700FA0D5E /* loading-12.png in Resources */ = {isa = PBXBuildFile; fileRef = 721F7A16151BD94600FA0D5E /* loading-12.png */; }; 43 | 721F7A3D151BD94700FA0D5E /* loading-12@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 721F7A17151BD94700FA0D5E /* loading-12@2x.png */; }; 44 | 721F7A3E151BD94700FA0D5E /* loading-13.png in Resources */ = {isa = PBXBuildFile; fileRef = 721F7A18151BD94700FA0D5E /* loading-13.png */; }; 45 | 721F7A3F151BD94700FA0D5E /* loading-13@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 721F7A19151BD94700FA0D5E /* loading-13@2x.png */; }; 46 | 721F7A40151BD94700FA0D5E /* loading-14.png in Resources */ = {isa = PBXBuildFile; fileRef = 721F7A1A151BD94700FA0D5E /* loading-14.png */; }; 47 | 721F7A41151BD94700FA0D5E /* loading-14@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 721F7A1B151BD94700FA0D5E /* loading-14@2x.png */; }; 48 | 721F7A42151BD94700FA0D5E /* loading-15.png in Resources */ = {isa = PBXBuildFile; fileRef = 721F7A1C151BD94700FA0D5E /* loading-15.png */; }; 49 | 721F7A43151BD94700FA0D5E /* loading-15@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 721F7A1D151BD94700FA0D5E /* loading-15@2x.png */; }; 50 | 721F7A44151BD94700FA0D5E /* loading-16.png in Resources */ = {isa = PBXBuildFile; fileRef = 721F7A1E151BD94700FA0D5E /* loading-16.png */; }; 51 | 721F7A45151BD94700FA0D5E /* loading-16@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 721F7A1F151BD94700FA0D5E /* loading-16@2x.png */; }; 52 | 721F7A46151BD94700FA0D5E /* loading-17.png in Resources */ = {isa = PBXBuildFile; fileRef = 721F7A20151BD94700FA0D5E /* loading-17.png */; }; 53 | 721F7A47151BD94700FA0D5E /* loading-17@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 721F7A21151BD94700FA0D5E /* loading-17@2x.png */; }; 54 | 721F7A48151BD94700FA0D5E /* loading-18.png in Resources */ = {isa = PBXBuildFile; fileRef = 721F7A22151BD94700FA0D5E /* loading-18.png */; }; 55 | 721F7A49151BD94700FA0D5E /* loading-18@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 721F7A23151BD94700FA0D5E /* loading-18@2x.png */; }; 56 | 721F7A4A151BD94700FA0D5E /* loading-19.png in Resources */ = {isa = PBXBuildFile; fileRef = 721F7A24151BD94700FA0D5E /* loading-19.png */; }; 57 | 721F7A4B151BD94700FA0D5E /* loading-19@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 721F7A25151BD94700FA0D5E /* loading-19@2x.png */; }; 58 | 721F7A4F151BDAD100FA0D5E /* big_arrow.png in Resources */ = {isa = PBXBuildFile; fileRef = 721F7A4D151BDAD100FA0D5E /* big_arrow.png */; }; 59 | 721F7A50151BDAD100FA0D5E /* big_arrow@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 721F7A4E151BDAD100FA0D5E /* big_arrow@2x.png */; }; 60 | 72664AB2160F18B200B9E819 /* MyTableView.m in Sources */ = {isa = PBXBuildFile; fileRef = 72664AB1160F18B200B9E819 /* MyTableView.m */; }; 61 | /* End PBXBuildFile section */ 62 | 63 | /* Begin PBXFileReference section */ 64 | 721F79D2151BB5C000FA0D5E /* PullToRefreshDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = PullToRefreshDemo.app; sourceTree = BUILT_PRODUCTS_DIR; }; 65 | 721F79D6151BB5C000FA0D5E /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 66 | 721F79D8151BB5C000FA0D5E /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 67 | 721F79DA151BB5C000FA0D5E /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; 68 | 721F79DE151BB5C100FA0D5E /* PullToRefreshDemo-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "PullToRefreshDemo-Info.plist"; sourceTree = ""; }; 69 | 721F79E0151BB5C100FA0D5E /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 70 | 721F79E2151BB5C100FA0D5E /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 71 | 721F79E4151BB5C100FA0D5E /* PullToRefreshDemo-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "PullToRefreshDemo-Prefix.pch"; sourceTree = ""; }; 72 | 721F79E5151BB5C100FA0D5E /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 73 | 721F79E6151BB5C100FA0D5E /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 74 | 721F79E8151BB5C100FA0D5E /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; 75 | 721F79E9151BB5C100FA0D5E /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; 76 | 721F79EC151BB5C100FA0D5E /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/ViewController.xib; sourceTree = ""; }; 77 | 721F79F3151BB5DB00FA0D5E /* MSPullToRefreshController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MSPullToRefreshController.h; sourceTree = ""; }; 78 | 721F79F4151BB5DB00FA0D5E /* MSPullToRefreshController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MSPullToRefreshController.m; sourceTree = ""; }; 79 | 721F79F6151BB91100FA0D5E /* CustomPullToRefresh.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CustomPullToRefresh.h; sourceTree = ""; }; 80 | 721F79F7151BB91100FA0D5E /* CustomPullToRefresh.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CustomPullToRefresh.m; sourceTree = ""; }; 81 | 721F7A00151BD94400FA0D5E /* loading-1.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "loading-1.png"; sourceTree = ""; }; 82 | 721F7A01151BD94500FA0D5E /* loading-1@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "loading-1@2x.png"; sourceTree = ""; }; 83 | 721F7A02151BD94500FA0D5E /* loading-2.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "loading-2.png"; sourceTree = ""; }; 84 | 721F7A03151BD94500FA0D5E /* loading-2@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "loading-2@2x.png"; sourceTree = ""; }; 85 | 721F7A04151BD94500FA0D5E /* loading-3.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "loading-3.png"; sourceTree = ""; }; 86 | 721F7A05151BD94500FA0D5E /* loading-3@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "loading-3@2x.png"; sourceTree = ""; }; 87 | 721F7A06151BD94500FA0D5E /* loading-4.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "loading-4.png"; sourceTree = ""; }; 88 | 721F7A07151BD94500FA0D5E /* loading-4@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "loading-4@2x.png"; sourceTree = ""; }; 89 | 721F7A08151BD94600FA0D5E /* loading-5.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "loading-5.png"; sourceTree = ""; }; 90 | 721F7A09151BD94600FA0D5E /* loading-5@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "loading-5@2x.png"; sourceTree = ""; }; 91 | 721F7A0A151BD94600FA0D5E /* loading-6.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "loading-6.png"; sourceTree = ""; }; 92 | 721F7A0B151BD94600FA0D5E /* loading-6@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "loading-6@2x.png"; sourceTree = ""; }; 93 | 721F7A0C151BD94600FA0D5E /* loading-7.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "loading-7.png"; sourceTree = ""; }; 94 | 721F7A0D151BD94600FA0D5E /* loading-7@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "loading-7@2x.png"; sourceTree = ""; }; 95 | 721F7A0E151BD94600FA0D5E /* loading-8.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "loading-8.png"; sourceTree = ""; }; 96 | 721F7A0F151BD94600FA0D5E /* loading-8@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "loading-8@2x.png"; sourceTree = ""; }; 97 | 721F7A10151BD94600FA0D5E /* loading-9.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "loading-9.png"; sourceTree = ""; }; 98 | 721F7A11151BD94600FA0D5E /* loading-9@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "loading-9@2x.png"; sourceTree = ""; }; 99 | 721F7A12151BD94600FA0D5E /* loading-10.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "loading-10.png"; sourceTree = ""; }; 100 | 721F7A13151BD94600FA0D5E /* loading-10@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "loading-10@2x.png"; sourceTree = ""; }; 101 | 721F7A14151BD94600FA0D5E /* loading-11.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "loading-11.png"; sourceTree = ""; }; 102 | 721F7A15151BD94600FA0D5E /* loading-11@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "loading-11@2x.png"; sourceTree = ""; }; 103 | 721F7A16151BD94600FA0D5E /* loading-12.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "loading-12.png"; sourceTree = ""; }; 104 | 721F7A17151BD94700FA0D5E /* loading-12@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "loading-12@2x.png"; sourceTree = ""; }; 105 | 721F7A18151BD94700FA0D5E /* loading-13.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "loading-13.png"; sourceTree = ""; }; 106 | 721F7A19151BD94700FA0D5E /* loading-13@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "loading-13@2x.png"; sourceTree = ""; }; 107 | 721F7A1A151BD94700FA0D5E /* loading-14.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "loading-14.png"; sourceTree = ""; }; 108 | 721F7A1B151BD94700FA0D5E /* loading-14@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "loading-14@2x.png"; sourceTree = ""; }; 109 | 721F7A1C151BD94700FA0D5E /* loading-15.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "loading-15.png"; sourceTree = ""; }; 110 | 721F7A1D151BD94700FA0D5E /* loading-15@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "loading-15@2x.png"; sourceTree = ""; }; 111 | 721F7A1E151BD94700FA0D5E /* loading-16.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "loading-16.png"; sourceTree = ""; }; 112 | 721F7A1F151BD94700FA0D5E /* loading-16@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "loading-16@2x.png"; sourceTree = ""; }; 113 | 721F7A20151BD94700FA0D5E /* loading-17.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "loading-17.png"; sourceTree = ""; }; 114 | 721F7A21151BD94700FA0D5E /* loading-17@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "loading-17@2x.png"; sourceTree = ""; }; 115 | 721F7A22151BD94700FA0D5E /* loading-18.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "loading-18.png"; sourceTree = ""; }; 116 | 721F7A23151BD94700FA0D5E /* loading-18@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "loading-18@2x.png"; sourceTree = ""; }; 117 | 721F7A24151BD94700FA0D5E /* loading-19.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "loading-19.png"; sourceTree = ""; }; 118 | 721F7A25151BD94700FA0D5E /* loading-19@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "loading-19@2x.png"; sourceTree = ""; }; 119 | 721F7A4D151BDAD100FA0D5E /* big_arrow.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = big_arrow.png; sourceTree = ""; }; 120 | 721F7A4E151BDAD100FA0D5E /* big_arrow@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "big_arrow@2x.png"; sourceTree = ""; }; 121 | 72664AB0160F18B200B9E819 /* MyTableView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MyTableView.h; sourceTree = ""; }; 122 | 72664AB1160F18B200B9E819 /* MyTableView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MyTableView.m; sourceTree = ""; }; 123 | /* End PBXFileReference section */ 124 | 125 | /* Begin PBXFrameworksBuildPhase section */ 126 | 721F79CF151BB5C000FA0D5E /* Frameworks */ = { 127 | isa = PBXFrameworksBuildPhase; 128 | buildActionMask = 2147483647; 129 | files = ( 130 | 721F79D7151BB5C000FA0D5E /* UIKit.framework in Frameworks */, 131 | 721F79D9151BB5C000FA0D5E /* Foundation.framework in Frameworks */, 132 | 721F79DB151BB5C000FA0D5E /* CoreGraphics.framework in Frameworks */, 133 | ); 134 | runOnlyForDeploymentPostprocessing = 0; 135 | }; 136 | /* End PBXFrameworksBuildPhase section */ 137 | 138 | /* Begin PBXGroup section */ 139 | 721F79C7151BB5C000FA0D5E = { 140 | isa = PBXGroup; 141 | children = ( 142 | 721F79DC151BB5C000FA0D5E /* PullToRefreshDemo */, 143 | 721F79D5151BB5C000FA0D5E /* Frameworks */, 144 | 721F79D3151BB5C000FA0D5E /* Products */, 145 | ); 146 | sourceTree = ""; 147 | }; 148 | 721F79D3151BB5C000FA0D5E /* Products */ = { 149 | isa = PBXGroup; 150 | children = ( 151 | 721F79D2151BB5C000FA0D5E /* PullToRefreshDemo.app */, 152 | ); 153 | name = Products; 154 | sourceTree = ""; 155 | }; 156 | 721F79D5151BB5C000FA0D5E /* Frameworks */ = { 157 | isa = PBXGroup; 158 | children = ( 159 | 721F79D6151BB5C000FA0D5E /* UIKit.framework */, 160 | 721F79D8151BB5C000FA0D5E /* Foundation.framework */, 161 | 721F79DA151BB5C000FA0D5E /* CoreGraphics.framework */, 162 | ); 163 | name = Frameworks; 164 | sourceTree = ""; 165 | }; 166 | 721F79DC151BB5C000FA0D5E /* PullToRefreshDemo */ = { 167 | isa = PBXGroup; 168 | children = ( 169 | 721F79F5151BB5DF00FA0D5E /* MSPullToRefreshController */, 170 | 721F79E5151BB5C100FA0D5E /* AppDelegate.h */, 171 | 721F79E6151BB5C100FA0D5E /* AppDelegate.m */, 172 | 721F79F6151BB91100FA0D5E /* CustomPullToRefresh.h */, 173 | 721F79F7151BB91100FA0D5E /* CustomPullToRefresh.m */, 174 | 72664AB0160F18B200B9E819 /* MyTableView.h */, 175 | 72664AB1160F18B200B9E819 /* MyTableView.m */, 176 | 721F79E8151BB5C100FA0D5E /* ViewController.h */, 177 | 721F79E9151BB5C100FA0D5E /* ViewController.m */, 178 | 721F79EB151BB5C100FA0D5E /* ViewController.xib */, 179 | 721F7A4C151BD94F00FA0D5E /* images */, 180 | 721F79DD151BB5C100FA0D5E /* Supporting Files */, 181 | ); 182 | path = PullToRefreshDemo; 183 | sourceTree = ""; 184 | }; 185 | 721F79DD151BB5C100FA0D5E /* Supporting Files */ = { 186 | isa = PBXGroup; 187 | children = ( 188 | 721F79DE151BB5C100FA0D5E /* PullToRefreshDemo-Info.plist */, 189 | 721F79DF151BB5C100FA0D5E /* InfoPlist.strings */, 190 | 721F79E2151BB5C100FA0D5E /* main.m */, 191 | 721F79E4151BB5C100FA0D5E /* PullToRefreshDemo-Prefix.pch */, 192 | ); 193 | name = "Supporting Files"; 194 | sourceTree = ""; 195 | }; 196 | 721F79F5151BB5DF00FA0D5E /* MSPullToRefreshController */ = { 197 | isa = PBXGroup; 198 | children = ( 199 | 721F79F3151BB5DB00FA0D5E /* MSPullToRefreshController.h */, 200 | 721F79F4151BB5DB00FA0D5E /* MSPullToRefreshController.m */, 201 | ); 202 | name = MSPullToRefreshController; 203 | sourceTree = ""; 204 | }; 205 | 721F7A4C151BD94F00FA0D5E /* images */ = { 206 | isa = PBXGroup; 207 | children = ( 208 | 721F7A4D151BDAD100FA0D5E /* big_arrow.png */, 209 | 721F7A4E151BDAD100FA0D5E /* big_arrow@2x.png */, 210 | 721F7A00151BD94400FA0D5E /* loading-1.png */, 211 | 721F7A01151BD94500FA0D5E /* loading-1@2x.png */, 212 | 721F7A02151BD94500FA0D5E /* loading-2.png */, 213 | 721F7A03151BD94500FA0D5E /* loading-2@2x.png */, 214 | 721F7A04151BD94500FA0D5E /* loading-3.png */, 215 | 721F7A05151BD94500FA0D5E /* loading-3@2x.png */, 216 | 721F7A06151BD94500FA0D5E /* loading-4.png */, 217 | 721F7A07151BD94500FA0D5E /* loading-4@2x.png */, 218 | 721F7A08151BD94600FA0D5E /* loading-5.png */, 219 | 721F7A09151BD94600FA0D5E /* loading-5@2x.png */, 220 | 721F7A0A151BD94600FA0D5E /* loading-6.png */, 221 | 721F7A0B151BD94600FA0D5E /* loading-6@2x.png */, 222 | 721F7A0C151BD94600FA0D5E /* loading-7.png */, 223 | 721F7A0D151BD94600FA0D5E /* loading-7@2x.png */, 224 | 721F7A0E151BD94600FA0D5E /* loading-8.png */, 225 | 721F7A0F151BD94600FA0D5E /* loading-8@2x.png */, 226 | 721F7A10151BD94600FA0D5E /* loading-9.png */, 227 | 721F7A11151BD94600FA0D5E /* loading-9@2x.png */, 228 | 721F7A12151BD94600FA0D5E /* loading-10.png */, 229 | 721F7A13151BD94600FA0D5E /* loading-10@2x.png */, 230 | 721F7A14151BD94600FA0D5E /* loading-11.png */, 231 | 721F7A15151BD94600FA0D5E /* loading-11@2x.png */, 232 | 721F7A16151BD94600FA0D5E /* loading-12.png */, 233 | 721F7A17151BD94700FA0D5E /* loading-12@2x.png */, 234 | 721F7A18151BD94700FA0D5E /* loading-13.png */, 235 | 721F7A19151BD94700FA0D5E /* loading-13@2x.png */, 236 | 721F7A1A151BD94700FA0D5E /* loading-14.png */, 237 | 721F7A1B151BD94700FA0D5E /* loading-14@2x.png */, 238 | 721F7A1C151BD94700FA0D5E /* loading-15.png */, 239 | 721F7A1D151BD94700FA0D5E /* loading-15@2x.png */, 240 | 721F7A1E151BD94700FA0D5E /* loading-16.png */, 241 | 721F7A1F151BD94700FA0D5E /* loading-16@2x.png */, 242 | 721F7A20151BD94700FA0D5E /* loading-17.png */, 243 | 721F7A21151BD94700FA0D5E /* loading-17@2x.png */, 244 | 721F7A22151BD94700FA0D5E /* loading-18.png */, 245 | 721F7A23151BD94700FA0D5E /* loading-18@2x.png */, 246 | 721F7A24151BD94700FA0D5E /* loading-19.png */, 247 | 721F7A25151BD94700FA0D5E /* loading-19@2x.png */, 248 | ); 249 | name = images; 250 | sourceTree = ""; 251 | }; 252 | /* End PBXGroup section */ 253 | 254 | /* Begin PBXNativeTarget section */ 255 | 721F79D1151BB5C000FA0D5E /* PullToRefreshDemo */ = { 256 | isa = PBXNativeTarget; 257 | buildConfigurationList = 721F79F0151BB5C100FA0D5E /* Build configuration list for PBXNativeTarget "PullToRefreshDemo" */; 258 | buildPhases = ( 259 | 721F79CE151BB5C000FA0D5E /* Sources */, 260 | 721F79CF151BB5C000FA0D5E /* Frameworks */, 261 | 721F79D0151BB5C000FA0D5E /* Resources */, 262 | ); 263 | buildRules = ( 264 | ); 265 | dependencies = ( 266 | ); 267 | name = PullToRefreshDemo; 268 | productName = PullToRefreshDemo; 269 | productReference = 721F79D2151BB5C000FA0D5E /* PullToRefreshDemo.app */; 270 | productType = "com.apple.product-type.application"; 271 | }; 272 | /* End PBXNativeTarget section */ 273 | 274 | /* Begin PBXProject section */ 275 | 721F79C9151BB5C000FA0D5E /* Project object */ = { 276 | isa = PBXProject; 277 | attributes = { 278 | LastUpgradeCheck = 0460; 279 | ORGANIZATIONNAME = TFM; 280 | }; 281 | buildConfigurationList = 721F79CC151BB5C000FA0D5E /* Build configuration list for PBXProject "PullToRefreshDemo" */; 282 | compatibilityVersion = "Xcode 3.2"; 283 | developmentRegion = English; 284 | hasScannedForEncodings = 0; 285 | knownRegions = ( 286 | en, 287 | ); 288 | mainGroup = 721F79C7151BB5C000FA0D5E; 289 | productRefGroup = 721F79D3151BB5C000FA0D5E /* Products */; 290 | projectDirPath = ""; 291 | projectRoot = ""; 292 | targets = ( 293 | 721F79D1151BB5C000FA0D5E /* PullToRefreshDemo */, 294 | ); 295 | }; 296 | /* End PBXProject section */ 297 | 298 | /* Begin PBXResourcesBuildPhase section */ 299 | 721F79D0151BB5C000FA0D5E /* Resources */ = { 300 | isa = PBXResourcesBuildPhase; 301 | buildActionMask = 2147483647; 302 | files = ( 303 | 721F79E1151BB5C100FA0D5E /* InfoPlist.strings in Resources */, 304 | 721F79ED151BB5C100FA0D5E /* ViewController.xib in Resources */, 305 | 721F7A26151BD94700FA0D5E /* loading-1.png in Resources */, 306 | 721F7A27151BD94700FA0D5E /* loading-1@2x.png in Resources */, 307 | 721F7A28151BD94700FA0D5E /* loading-2.png in Resources */, 308 | 721F7A29151BD94700FA0D5E /* loading-2@2x.png in Resources */, 309 | 721F7A2A151BD94700FA0D5E /* loading-3.png in Resources */, 310 | 721F7A2B151BD94700FA0D5E /* loading-3@2x.png in Resources */, 311 | 721F7A2C151BD94700FA0D5E /* loading-4.png in Resources */, 312 | 721F7A2D151BD94700FA0D5E /* loading-4@2x.png in Resources */, 313 | 721F7A2E151BD94700FA0D5E /* loading-5.png in Resources */, 314 | 721F7A2F151BD94700FA0D5E /* loading-5@2x.png in Resources */, 315 | 721F7A30151BD94700FA0D5E /* loading-6.png in Resources */, 316 | 721F7A31151BD94700FA0D5E /* loading-6@2x.png in Resources */, 317 | 721F7A32151BD94700FA0D5E /* loading-7.png in Resources */, 318 | 721F7A33151BD94700FA0D5E /* loading-7@2x.png in Resources */, 319 | 721F7A34151BD94700FA0D5E /* loading-8.png in Resources */, 320 | 721F7A35151BD94700FA0D5E /* loading-8@2x.png in Resources */, 321 | 721F7A36151BD94700FA0D5E /* loading-9.png in Resources */, 322 | 721F7A37151BD94700FA0D5E /* loading-9@2x.png in Resources */, 323 | 721F7A38151BD94700FA0D5E /* loading-10.png in Resources */, 324 | 721F7A39151BD94700FA0D5E /* loading-10@2x.png in Resources */, 325 | 721F7A3A151BD94700FA0D5E /* loading-11.png in Resources */, 326 | 721F7A3B151BD94700FA0D5E /* loading-11@2x.png in Resources */, 327 | 721F7A3C151BD94700FA0D5E /* loading-12.png in Resources */, 328 | 721F7A3D151BD94700FA0D5E /* loading-12@2x.png in Resources */, 329 | 721F7A3E151BD94700FA0D5E /* loading-13.png in Resources */, 330 | 721F7A3F151BD94700FA0D5E /* loading-13@2x.png in Resources */, 331 | 721F7A40151BD94700FA0D5E /* loading-14.png in Resources */, 332 | 721F7A41151BD94700FA0D5E /* loading-14@2x.png in Resources */, 333 | 721F7A42151BD94700FA0D5E /* loading-15.png in Resources */, 334 | 721F7A43151BD94700FA0D5E /* loading-15@2x.png in Resources */, 335 | 721F7A44151BD94700FA0D5E /* loading-16.png in Resources */, 336 | 721F7A45151BD94700FA0D5E /* loading-16@2x.png in Resources */, 337 | 721F7A46151BD94700FA0D5E /* loading-17.png in Resources */, 338 | 721F7A47151BD94700FA0D5E /* loading-17@2x.png in Resources */, 339 | 721F7A48151BD94700FA0D5E /* loading-18.png in Resources */, 340 | 721F7A49151BD94700FA0D5E /* loading-18@2x.png in Resources */, 341 | 721F7A4A151BD94700FA0D5E /* loading-19.png in Resources */, 342 | 721F7A4B151BD94700FA0D5E /* loading-19@2x.png in Resources */, 343 | 721F7A4F151BDAD100FA0D5E /* big_arrow.png in Resources */, 344 | 721F7A50151BDAD100FA0D5E /* big_arrow@2x.png in Resources */, 345 | ); 346 | runOnlyForDeploymentPostprocessing = 0; 347 | }; 348 | /* End PBXResourcesBuildPhase section */ 349 | 350 | /* Begin PBXSourcesBuildPhase section */ 351 | 721F79CE151BB5C000FA0D5E /* Sources */ = { 352 | isa = PBXSourcesBuildPhase; 353 | buildActionMask = 2147483647; 354 | files = ( 355 | 721F79FB151BBEA300FA0D5E /* MSPullToRefreshController.m in Sources */, 356 | 721F79E3151BB5C100FA0D5E /* main.m in Sources */, 357 | 721F79E7151BB5C100FA0D5E /* AppDelegate.m in Sources */, 358 | 721F79EA151BB5C100FA0D5E /* ViewController.m in Sources */, 359 | 721F79F8151BB91100FA0D5E /* CustomPullToRefresh.m in Sources */, 360 | 72664AB2160F18B200B9E819 /* MyTableView.m in Sources */, 361 | ); 362 | runOnlyForDeploymentPostprocessing = 0; 363 | }; 364 | /* End PBXSourcesBuildPhase section */ 365 | 366 | /* Begin PBXVariantGroup section */ 367 | 721F79DF151BB5C100FA0D5E /* InfoPlist.strings */ = { 368 | isa = PBXVariantGroup; 369 | children = ( 370 | 721F79E0151BB5C100FA0D5E /* en */, 371 | ); 372 | name = InfoPlist.strings; 373 | sourceTree = ""; 374 | }; 375 | 721F79EB151BB5C100FA0D5E /* ViewController.xib */ = { 376 | isa = PBXVariantGroup; 377 | children = ( 378 | 721F79EC151BB5C100FA0D5E /* en */, 379 | ); 380 | name = ViewController.xib; 381 | sourceTree = ""; 382 | }; 383 | /* End PBXVariantGroup section */ 384 | 385 | /* Begin XCBuildConfiguration section */ 386 | 721F79EE151BB5C100FA0D5E /* Debug */ = { 387 | isa = XCBuildConfiguration; 388 | buildSettings = { 389 | ALWAYS_SEARCH_USER_PATHS = NO; 390 | ARCHS = "$(ARCHS_STANDARD_32_BIT)"; 391 | CLANG_WARN_CONSTANT_CONVERSION = YES; 392 | CLANG_WARN_ENUM_CONVERSION = YES; 393 | CLANG_WARN_INT_CONVERSION = YES; 394 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 395 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 396 | COPY_PHASE_STRIP = NO; 397 | GCC_C_LANGUAGE_STANDARD = gnu99; 398 | GCC_DYNAMIC_NO_PIC = NO; 399 | GCC_OPTIMIZATION_LEVEL = 0; 400 | GCC_PREPROCESSOR_DEFINITIONS = ( 401 | "DEBUG=1", 402 | "$(inherited)", 403 | ); 404 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 405 | GCC_VERSION = com.apple.compilers.llvm.clang.1_0; 406 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 407 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 408 | GCC_WARN_UNUSED_VARIABLE = YES; 409 | IPHONEOS_DEPLOYMENT_TARGET = 4.0; 410 | SDKROOT = iphoneos; 411 | }; 412 | name = Debug; 413 | }; 414 | 721F79EF151BB5C100FA0D5E /* Release */ = { 415 | isa = XCBuildConfiguration; 416 | buildSettings = { 417 | ALWAYS_SEARCH_USER_PATHS = NO; 418 | ARCHS = "$(ARCHS_STANDARD_32_BIT)"; 419 | CLANG_WARN_CONSTANT_CONVERSION = YES; 420 | CLANG_WARN_ENUM_CONVERSION = YES; 421 | CLANG_WARN_INT_CONVERSION = YES; 422 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 423 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 424 | COPY_PHASE_STRIP = YES; 425 | GCC_C_LANGUAGE_STANDARD = gnu99; 426 | GCC_VERSION = com.apple.compilers.llvm.clang.1_0; 427 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 428 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 429 | GCC_WARN_UNUSED_VARIABLE = YES; 430 | IPHONEOS_DEPLOYMENT_TARGET = 4.0; 431 | OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1"; 432 | SDKROOT = iphoneos; 433 | VALIDATE_PRODUCT = YES; 434 | }; 435 | name = Release; 436 | }; 437 | 721F79F1151BB5C100FA0D5E /* Debug */ = { 438 | isa = XCBuildConfiguration; 439 | buildSettings = { 440 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 441 | GCC_PREFIX_HEADER = "PullToRefreshDemo/PullToRefreshDemo-Prefix.pch"; 442 | INFOPLIST_FILE = "PullToRefreshDemo/PullToRefreshDemo-Info.plist"; 443 | IPHONEOS_DEPLOYMENT_TARGET = 4.0; 444 | PRODUCT_NAME = "$(TARGET_NAME)"; 445 | WRAPPER_EXTENSION = app; 446 | }; 447 | name = Debug; 448 | }; 449 | 721F79F2151BB5C100FA0D5E /* Release */ = { 450 | isa = XCBuildConfiguration; 451 | buildSettings = { 452 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 453 | GCC_PREFIX_HEADER = "PullToRefreshDemo/PullToRefreshDemo-Prefix.pch"; 454 | INFOPLIST_FILE = "PullToRefreshDemo/PullToRefreshDemo-Info.plist"; 455 | IPHONEOS_DEPLOYMENT_TARGET = 4.0; 456 | PRODUCT_NAME = "$(TARGET_NAME)"; 457 | WRAPPER_EXTENSION = app; 458 | }; 459 | name = Release; 460 | }; 461 | /* End XCBuildConfiguration section */ 462 | 463 | /* Begin XCConfigurationList section */ 464 | 721F79CC151BB5C000FA0D5E /* Build configuration list for PBXProject "PullToRefreshDemo" */ = { 465 | isa = XCConfigurationList; 466 | buildConfigurations = ( 467 | 721F79EE151BB5C100FA0D5E /* Debug */, 468 | 721F79EF151BB5C100FA0D5E /* Release */, 469 | ); 470 | defaultConfigurationIsVisible = 0; 471 | defaultConfigurationName = Release; 472 | }; 473 | 721F79F0151BB5C100FA0D5E /* Build configuration list for PBXNativeTarget "PullToRefreshDemo" */ = { 474 | isa = XCConfigurationList; 475 | buildConfigurations = ( 476 | 721F79F1151BB5C100FA0D5E /* Debug */, 477 | 721F79F2151BB5C100FA0D5E /* Release */, 478 | ); 479 | defaultConfigurationIsVisible = 0; 480 | defaultConfigurationName = Release; 481 | }; 482 | /* End XCConfigurationList section */ 483 | }; 484 | rootObject = 721F79C9151BB5C000FA0D5E /* Project object */; 485 | } 486 | --------------------------------------------------------------------------------