├── README.md ├── ScreenShot ├── BlueRoundCircle.gif ├── Ipad.gif ├── RoundCircle.gif ├── magic.gif ├── manual.gif ├── mix.gif └── ori.gif ├── WCPullRefreshControlExample.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ ├── xcshareddata │ │ └── WCPullRefreshControlExample.xccheckout │ └── xcuserdata │ │ └── huangwenchen.xcuserdatad │ │ └── UserInterfaceState.xcuserstate └── xcuserdata │ └── huangwenchen.xcuserdatad │ ├── xcdebugger │ └── Breakpoints_v2.xcbkptlist │ └── xcschemes │ ├── WCPullRefreshControlExample.xcscheme │ └── xcschememanagement.plist ├── WCPullRefreshControlExample ├── AppDelegate.h ├── AppDelegate.m ├── Base.lproj │ ├── LaunchScreen.xib │ └── Main.storyboard ├── DemoTableview.h ├── DemoTableview.m ├── Images.xcassets │ └── AppIcon.appiconset │ │ └── Contents.json ├── Info.plist ├── WCGraintCircleLayer.h ├── WCGraintCircleLayer.m ├── WebviewViewController.h ├── WebviewViewController.m ├── classes │ ├── CAShapeLayer+WCPullRefresh.h │ ├── CAShapeLayer+WCPullRefresh.m │ ├── NSDate+WCPullRefresh.h │ ├── NSDate+WCPullRefresh.m │ ├── WCMagicSquareView.h │ ├── WCMagicSquareView.m │ ├── WCProgressItem.h │ ├── WCProgressItem.m │ ├── WCPullRefreshControl.h │ ├── WCPullRefreshControl.m │ ├── WCRefreshingItem.h │ └── WCRefreshingItem.m └── main.m └── WCPullRefreshControlExampleTests ├── Info.plist └── WCPullRefreshControlExampleTests.m /README.md: -------------------------------------------------------------------------------- 1 | ##Not update anymore. 2 | My new github address https://github.com/LeoMobileDeveloper 3 | 4 | # WCPullRefreshControl 5 | 6 | WCPullRefreshControl is a "Pull refresh" library. It is quite easy to add "Pull refresh" to your project with just several lines of code. 7 | 8 | =========== 9 | ##What is it looks like 10 | 11 | 12 | 13 | 14 | 15 | =========== 16 | ##Manual Start refreshing 17 | Is some case,when view is load,you should start refreshing.You can manual start it like this. 18 | 19 | 20 | ====== 21 | ##Features 22 | 23 | * Support different kinds of scrollview,such as UIScrollview,tableview,webview. 24 | * Support different kinds of device size(Iphone,ipad) 25 | * Support Device orientation 26 | 27 | 28 | =========== 29 | ##Requirements 30 | 31 | * ARC 32 | 33 | =========== 34 | ## Version 35 | 36 | * 1.0.2 37 | 38 | =========== 39 | 40 | ## Installation 41 | 42 | 1. Download the latest code version. 43 | 2. Open your project in Xcode, then drag and drop **classes folder** into your project. Make sure to select Copy items when asked if you extracted the code archive outside of your project. 44 | 45 | =========== 46 | 47 | ##Getting Started 48 | 49 | * Import `WCSimplePullRefreshControl.h` 50 | 51 | * Keep a property of **WCPullRefreshControl**,let your class conforms to **UIScrollveiwDelegate** 52 | 53 | ```objective-c 54 | @property (strong,nonatomic)WCSimplePullRefreshControl * pullRefresh; 55 | ```` 56 | 57 | * Initialise it property if you want to use block to handle refreshing action,just write code in action block 58 | 59 | ```objective-c 60 | self.pullRefresh = [[WCSimplePullRefreshControl alloc] initWithScrollview:self.tableView Action:^{ 61 | [self performSelector:@selector(reset) withObject:nil afterDelay:2.0]; 62 | }]; 63 | ```` 64 | 65 | * Call these two methods in `UIScrollviewDelegate` method 66 | ```objective-c 67 | -(void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate{ 68 | [self.pullRefresh updateWhenScrollDidEndDraging]; 69 | } 70 | -(void)scrollViewDidScroll:(UIScrollView *)scrollView{ 71 | [self.pullRefresh updateWhenScrollviewScroll]; 72 | } 73 | ```` 74 | 75 | * When refreshing action finished call `finishRefreshingSuccessully:`,you pass in a Bool to tell refresh control whether refreshing finish successfully or not. 76 | 77 | 78 | =========== 79 | ## Delegate 80 | You can set delegate of `WCSimpleRefreshControl` to the class that use it. Note you have to comforms to `WCPullRefreshControlDelegate` first. 81 | 82 | Then in delegate method, you can handle refreshing action. 83 | ```objective-c 84 | -(void)DidStartRefreshingWithScrollview:(UIScrollView *)scrollview{ 85 | //Handle refreshing action 86 | } 87 | ```` 88 | 89 | =========== 90 | ## Method 91 | ```objective-c 92 | -(instancetype)initWithScrollview:(UIScrollView *)scrollview 93 | Action:(WCRefreshAction)action 94 | progressItem:(WCProgressItemType)progressType 95 | refreshingItem:(WCRefreshingItemType)refreshingType 96 | lastUpdate:(NSDate *)date 97 | showLastUpdate:(BOOL)isShowLastUpdate 98 | textColor:(UIColor *)textcolor 99 | itemColor:(UIColor *)itemColor 100 | pullHeight:(CGFloat)pullHeight 101 | ```` 102 | * scrollveiw - the scrollview that you want this view to be attached. 103 | * Action - refreshing action.For example, do some internet fetching 104 | * progressType - define the progress type(3 kinds) 105 | * refreshingType - define the refreshing type(4 kinds) 106 | * date - last update date 107 | * isShowLastUpdate - whether label shows last update date 108 | * textcolor - text color of label 109 | * itemColor - Stroke color of refreshing item and progress item 110 | * pullHeight - length to pull before start to refreshing 111 | 112 | =========== 113 | 114 | ## License 115 | 116 | This code is distributed under the terms and conditions of the [MIT license](LICENSE). 117 | 118 | =========== 119 | 120 | ## Bug 121 | If you find bug,please send email to njuhwc@163.com 122 | 123 | 124 | -------------------------------------------------------------------------------- /ScreenShot/BlueRoundCircle.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wenchenhuang/WCPullRefreshControl/e68f031a7bff17985d13073a1ea81e4537d7f810/ScreenShot/BlueRoundCircle.gif -------------------------------------------------------------------------------- /ScreenShot/Ipad.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wenchenhuang/WCPullRefreshControl/e68f031a7bff17985d13073a1ea81e4537d7f810/ScreenShot/Ipad.gif -------------------------------------------------------------------------------- /ScreenShot/RoundCircle.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wenchenhuang/WCPullRefreshControl/e68f031a7bff17985d13073a1ea81e4537d7f810/ScreenShot/RoundCircle.gif -------------------------------------------------------------------------------- /ScreenShot/magic.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wenchenhuang/WCPullRefreshControl/e68f031a7bff17985d13073a1ea81e4537d7f810/ScreenShot/magic.gif -------------------------------------------------------------------------------- /ScreenShot/manual.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wenchenhuang/WCPullRefreshControl/e68f031a7bff17985d13073a1ea81e4537d7f810/ScreenShot/manual.gif -------------------------------------------------------------------------------- /ScreenShot/mix.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wenchenhuang/WCPullRefreshControl/e68f031a7bff17985d13073a1ea81e4537d7f810/ScreenShot/mix.gif -------------------------------------------------------------------------------- /ScreenShot/ori.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wenchenhuang/WCPullRefreshControl/e68f031a7bff17985d13073a1ea81e4537d7f810/ScreenShot/ori.gif -------------------------------------------------------------------------------- /WCPullRefreshControlExample.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 52458F781ADCE8250074C990 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 52458F771ADCE8250074C990 /* main.m */; }; 11 | 52458F7B1ADCE8250074C990 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 52458F7A1ADCE8250074C990 /* AppDelegate.m */; }; 12 | 52458F811ADCE8250074C990 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 52458F7F1ADCE8250074C990 /* Main.storyboard */; }; 13 | 52458F831ADCE8250074C990 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 52458F821ADCE8250074C990 /* Images.xcassets */; }; 14 | 52458F861ADCE8250074C990 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 52458F841ADCE8250074C990 /* LaunchScreen.xib */; }; 15 | 52458F921ADCE8260074C990 /* WCPullRefreshControlExampleTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 52458F911ADCE8260074C990 /* WCPullRefreshControlExampleTests.m */; }; 16 | 52458FC61ADCEAF20074C990 /* CAShapeLayer+WCPullRefresh.m in Sources */ = {isa = PBXBuildFile; fileRef = 52458FB91ADCEAF20074C990 /* CAShapeLayer+WCPullRefresh.m */; }; 17 | 52458FC71ADCEAF20074C990 /* NSDate+WCPullRefresh.m in Sources */ = {isa = PBXBuildFile; fileRef = 52458FBB1ADCEAF20074C990 /* NSDate+WCPullRefresh.m */; }; 18 | 52458FC81ADCEAF20074C990 /* WCMagicSquareView.m in Sources */ = {isa = PBXBuildFile; fileRef = 52458FBD1ADCEAF20074C990 /* WCMagicSquareView.m */; }; 19 | 52458FC91ADCEAF20074C990 /* WCProgressItem.m in Sources */ = {isa = PBXBuildFile; fileRef = 52458FBF1ADCEAF20074C990 /* WCProgressItem.m */; }; 20 | 52458FCA1ADCEAF20074C990 /* WCPullRefreshControl.m in Sources */ = {isa = PBXBuildFile; fileRef = 52458FC11ADCEAF20074C990 /* WCPullRefreshControl.m */; }; 21 | 52458FCB1ADCEAF20074C990 /* WCRefreshingItem.m in Sources */ = {isa = PBXBuildFile; fileRef = 52458FC31ADCEAF20074C990 /* WCRefreshingItem.m */; }; 22 | 525B26351ADD0ABC009B523F /* DemoTableview.m in Sources */ = {isa = PBXBuildFile; fileRef = 525B26341ADD0ABC009B523F /* DemoTableview.m */; }; 23 | 52918AA91AEA36B50023CD96 /* WCGraintCircleLayer.m in Sources */ = {isa = PBXBuildFile; fileRef = 52918AA81AEA36B50023CD96 /* WCGraintCircleLayer.m */; }; 24 | 529DAA031AE928A100D3322D /* WebviewViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 529DAA021AE928A100D3322D /* WebviewViewController.m */; }; 25 | /* End PBXBuildFile section */ 26 | 27 | /* Begin PBXContainerItemProxy section */ 28 | 52458F8C1ADCE8260074C990 /* PBXContainerItemProxy */ = { 29 | isa = PBXContainerItemProxy; 30 | containerPortal = 52458F6A1ADCE8250074C990 /* Project object */; 31 | proxyType = 1; 32 | remoteGlobalIDString = 52458F711ADCE8250074C990; 33 | remoteInfo = WCPullRefreshControlExample; 34 | }; 35 | /* End PBXContainerItemProxy section */ 36 | 37 | /* Begin PBXFileReference section */ 38 | 52458F721ADCE8250074C990 /* WCPullRefreshControlExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = WCPullRefreshControlExample.app; sourceTree = BUILT_PRODUCTS_DIR; }; 39 | 52458F761ADCE8250074C990 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 40 | 52458F771ADCE8250074C990 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 41 | 52458F791ADCE8250074C990 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 42 | 52458F7A1ADCE8250074C990 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 43 | 52458F801ADCE8250074C990 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 44 | 52458F821ADCE8250074C990 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 45 | 52458F851ADCE8250074C990 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; 46 | 52458F8B1ADCE8260074C990 /* WCPullRefreshControlExampleTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = WCPullRefreshControlExampleTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 47 | 52458F901ADCE8260074C990 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 48 | 52458F911ADCE8260074C990 /* WCPullRefreshControlExampleTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = WCPullRefreshControlExampleTests.m; sourceTree = ""; }; 49 | 52458FB81ADCEAF20074C990 /* CAShapeLayer+WCPullRefresh.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "CAShapeLayer+WCPullRefresh.h"; path = "classes/CAShapeLayer+WCPullRefresh.h"; sourceTree = ""; }; 50 | 52458FB91ADCEAF20074C990 /* CAShapeLayer+WCPullRefresh.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "CAShapeLayer+WCPullRefresh.m"; path = "classes/CAShapeLayer+WCPullRefresh.m"; sourceTree = ""; }; 51 | 52458FBA1ADCEAF20074C990 /* NSDate+WCPullRefresh.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "NSDate+WCPullRefresh.h"; path = "classes/NSDate+WCPullRefresh.h"; sourceTree = ""; }; 52 | 52458FBB1ADCEAF20074C990 /* NSDate+WCPullRefresh.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "NSDate+WCPullRefresh.m"; path = "classes/NSDate+WCPullRefresh.m"; sourceTree = ""; }; 53 | 52458FBC1ADCEAF20074C990 /* WCMagicSquareView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WCMagicSquareView.h; path = classes/WCMagicSquareView.h; sourceTree = ""; }; 54 | 52458FBD1ADCEAF20074C990 /* WCMagicSquareView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = WCMagicSquareView.m; path = classes/WCMagicSquareView.m; sourceTree = ""; }; 55 | 52458FBE1ADCEAF20074C990 /* WCProgressItem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WCProgressItem.h; path = classes/WCProgressItem.h; sourceTree = ""; }; 56 | 52458FBF1ADCEAF20074C990 /* WCProgressItem.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = WCProgressItem.m; path = classes/WCProgressItem.m; sourceTree = ""; }; 57 | 52458FC01ADCEAF20074C990 /* WCPullRefreshControl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WCPullRefreshControl.h; path = classes/WCPullRefreshControl.h; sourceTree = ""; }; 58 | 52458FC11ADCEAF20074C990 /* WCPullRefreshControl.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = WCPullRefreshControl.m; path = classes/WCPullRefreshControl.m; sourceTree = ""; }; 59 | 52458FC21ADCEAF20074C990 /* WCRefreshingItem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WCRefreshingItem.h; path = classes/WCRefreshingItem.h; sourceTree = ""; }; 60 | 52458FC31ADCEAF20074C990 /* WCRefreshingItem.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = WCRefreshingItem.m; path = classes/WCRefreshingItem.m; sourceTree = ""; }; 61 | 525B26331ADD0ABC009B523F /* DemoTableview.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DemoTableview.h; sourceTree = ""; }; 62 | 525B26341ADD0ABC009B523F /* DemoTableview.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DemoTableview.m; sourceTree = ""; }; 63 | 52918AA71AEA36B50023CD96 /* WCGraintCircleLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WCGraintCircleLayer.h; sourceTree = ""; }; 64 | 52918AA81AEA36B50023CD96 /* WCGraintCircleLayer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WCGraintCircleLayer.m; sourceTree = ""; }; 65 | 529DAA011AE928A100D3322D /* WebviewViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebviewViewController.h; sourceTree = ""; }; 66 | 529DAA021AE928A100D3322D /* WebviewViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WebviewViewController.m; sourceTree = ""; }; 67 | /* End PBXFileReference section */ 68 | 69 | /* Begin PBXFrameworksBuildPhase section */ 70 | 52458F6F1ADCE8250074C990 /* Frameworks */ = { 71 | isa = PBXFrameworksBuildPhase; 72 | buildActionMask = 2147483647; 73 | files = ( 74 | ); 75 | runOnlyForDeploymentPostprocessing = 0; 76 | }; 77 | 52458F881ADCE8260074C990 /* Frameworks */ = { 78 | isa = PBXFrameworksBuildPhase; 79 | buildActionMask = 2147483647; 80 | files = ( 81 | ); 82 | runOnlyForDeploymentPostprocessing = 0; 83 | }; 84 | /* End PBXFrameworksBuildPhase section */ 85 | 86 | /* Begin PBXGroup section */ 87 | 52458F691ADCE8250074C990 = { 88 | isa = PBXGroup; 89 | children = ( 90 | 52458F741ADCE8250074C990 /* WCPullRefreshControlExample */, 91 | 52458F8E1ADCE8260074C990 /* WCPullRefreshControlExampleTests */, 92 | 52458F731ADCE8250074C990 /* Products */, 93 | ); 94 | sourceTree = ""; 95 | }; 96 | 52458F731ADCE8250074C990 /* Products */ = { 97 | isa = PBXGroup; 98 | children = ( 99 | 52458F721ADCE8250074C990 /* WCPullRefreshControlExample.app */, 100 | 52458F8B1ADCE8260074C990 /* WCPullRefreshControlExampleTests.xctest */, 101 | ); 102 | name = Products; 103 | sourceTree = ""; 104 | }; 105 | 52458F741ADCE8250074C990 /* WCPullRefreshControlExample */ = { 106 | isa = PBXGroup; 107 | children = ( 108 | 52458FCD1ADCEAFE0074C990 /* Classes */, 109 | 52458F791ADCE8250074C990 /* AppDelegate.h */, 110 | 52458F7A1ADCE8250074C990 /* AppDelegate.m */, 111 | 52458F7F1ADCE8250074C990 /* Main.storyboard */, 112 | 529DAA011AE928A100D3322D /* WebviewViewController.h */, 113 | 529DAA021AE928A100D3322D /* WebviewViewController.m */, 114 | 525B26331ADD0ABC009B523F /* DemoTableview.h */, 115 | 525B26341ADD0ABC009B523F /* DemoTableview.m */, 116 | 52458F821ADCE8250074C990 /* Images.xcassets */, 117 | 52458F841ADCE8250074C990 /* LaunchScreen.xib */, 118 | 52458F751ADCE8250074C990 /* Supporting Files */, 119 | ); 120 | path = WCPullRefreshControlExample; 121 | sourceTree = ""; 122 | }; 123 | 52458F751ADCE8250074C990 /* Supporting Files */ = { 124 | isa = PBXGroup; 125 | children = ( 126 | 52458F761ADCE8250074C990 /* Info.plist */, 127 | 52458F771ADCE8250074C990 /* main.m */, 128 | ); 129 | name = "Supporting Files"; 130 | sourceTree = ""; 131 | }; 132 | 52458F8E1ADCE8260074C990 /* WCPullRefreshControlExampleTests */ = { 133 | isa = PBXGroup; 134 | children = ( 135 | 52458F911ADCE8260074C990 /* WCPullRefreshControlExampleTests.m */, 136 | 52458F8F1ADCE8260074C990 /* Supporting Files */, 137 | ); 138 | path = WCPullRefreshControlExampleTests; 139 | sourceTree = ""; 140 | }; 141 | 52458F8F1ADCE8260074C990 /* Supporting Files */ = { 142 | isa = PBXGroup; 143 | children = ( 144 | 52458F901ADCE8260074C990 /* Info.plist */, 145 | ); 146 | name = "Supporting Files"; 147 | sourceTree = ""; 148 | }; 149 | 52458FCD1ADCEAFE0074C990 /* Classes */ = { 150 | isa = PBXGroup; 151 | children = ( 152 | 52918AA71AEA36B50023CD96 /* WCGraintCircleLayer.h */, 153 | 52918AA81AEA36B50023CD96 /* WCGraintCircleLayer.m */, 154 | 52458FB81ADCEAF20074C990 /* CAShapeLayer+WCPullRefresh.h */, 155 | 52458FB91ADCEAF20074C990 /* CAShapeLayer+WCPullRefresh.m */, 156 | 52458FBA1ADCEAF20074C990 /* NSDate+WCPullRefresh.h */, 157 | 52458FBB1ADCEAF20074C990 /* NSDate+WCPullRefresh.m */, 158 | 52458FBC1ADCEAF20074C990 /* WCMagicSquareView.h */, 159 | 52458FBD1ADCEAF20074C990 /* WCMagicSquareView.m */, 160 | 52458FBE1ADCEAF20074C990 /* WCProgressItem.h */, 161 | 52458FBF1ADCEAF20074C990 /* WCProgressItem.m */, 162 | 52458FC01ADCEAF20074C990 /* WCPullRefreshControl.h */, 163 | 52458FC11ADCEAF20074C990 /* WCPullRefreshControl.m */, 164 | 52458FC21ADCEAF20074C990 /* WCRefreshingItem.h */, 165 | 52458FC31ADCEAF20074C990 /* WCRefreshingItem.m */, 166 | ); 167 | name = Classes; 168 | sourceTree = ""; 169 | }; 170 | /* End PBXGroup section */ 171 | 172 | /* Begin PBXNativeTarget section */ 173 | 52458F711ADCE8250074C990 /* WCPullRefreshControlExample */ = { 174 | isa = PBXNativeTarget; 175 | buildConfigurationList = 52458F951ADCE8260074C990 /* Build configuration list for PBXNativeTarget "WCPullRefreshControlExample" */; 176 | buildPhases = ( 177 | 52458F6E1ADCE8250074C990 /* Sources */, 178 | 52458F6F1ADCE8250074C990 /* Frameworks */, 179 | 52458F701ADCE8250074C990 /* Resources */, 180 | ); 181 | buildRules = ( 182 | ); 183 | dependencies = ( 184 | ); 185 | name = WCPullRefreshControlExample; 186 | productName = WCPullRefreshControlExample; 187 | productReference = 52458F721ADCE8250074C990 /* WCPullRefreshControlExample.app */; 188 | productType = "com.apple.product-type.application"; 189 | }; 190 | 52458F8A1ADCE8260074C990 /* WCPullRefreshControlExampleTests */ = { 191 | isa = PBXNativeTarget; 192 | buildConfigurationList = 52458F981ADCE8260074C990 /* Build configuration list for PBXNativeTarget "WCPullRefreshControlExampleTests" */; 193 | buildPhases = ( 194 | 52458F871ADCE8260074C990 /* Sources */, 195 | 52458F881ADCE8260074C990 /* Frameworks */, 196 | 52458F891ADCE8260074C990 /* Resources */, 197 | ); 198 | buildRules = ( 199 | ); 200 | dependencies = ( 201 | 52458F8D1ADCE8260074C990 /* PBXTargetDependency */, 202 | ); 203 | name = WCPullRefreshControlExampleTests; 204 | productName = WCPullRefreshControlExampleTests; 205 | productReference = 52458F8B1ADCE8260074C990 /* WCPullRefreshControlExampleTests.xctest */; 206 | productType = "com.apple.product-type.bundle.unit-test"; 207 | }; 208 | /* End PBXNativeTarget section */ 209 | 210 | /* Begin PBXProject section */ 211 | 52458F6A1ADCE8250074C990 /* Project object */ = { 212 | isa = PBXProject; 213 | attributes = { 214 | LastUpgradeCheck = 0630; 215 | ORGANIZATIONNAME = huangwenchen; 216 | TargetAttributes = { 217 | 52458F711ADCE8250074C990 = { 218 | CreatedOnToolsVersion = 6.3; 219 | }; 220 | 52458F8A1ADCE8260074C990 = { 221 | CreatedOnToolsVersion = 6.3; 222 | TestTargetID = 52458F711ADCE8250074C990; 223 | }; 224 | }; 225 | }; 226 | buildConfigurationList = 52458F6D1ADCE8250074C990 /* Build configuration list for PBXProject "WCPullRefreshControlExample" */; 227 | compatibilityVersion = "Xcode 3.2"; 228 | developmentRegion = English; 229 | hasScannedForEncodings = 0; 230 | knownRegions = ( 231 | en, 232 | Base, 233 | ); 234 | mainGroup = 52458F691ADCE8250074C990; 235 | productRefGroup = 52458F731ADCE8250074C990 /* Products */; 236 | projectDirPath = ""; 237 | projectRoot = ""; 238 | targets = ( 239 | 52458F711ADCE8250074C990 /* WCPullRefreshControlExample */, 240 | 52458F8A1ADCE8260074C990 /* WCPullRefreshControlExampleTests */, 241 | ); 242 | }; 243 | /* End PBXProject section */ 244 | 245 | /* Begin PBXResourcesBuildPhase section */ 246 | 52458F701ADCE8250074C990 /* Resources */ = { 247 | isa = PBXResourcesBuildPhase; 248 | buildActionMask = 2147483647; 249 | files = ( 250 | 52458F811ADCE8250074C990 /* Main.storyboard in Resources */, 251 | 52458F861ADCE8250074C990 /* LaunchScreen.xib in Resources */, 252 | 52458F831ADCE8250074C990 /* Images.xcassets in Resources */, 253 | ); 254 | runOnlyForDeploymentPostprocessing = 0; 255 | }; 256 | 52458F891ADCE8260074C990 /* Resources */ = { 257 | isa = PBXResourcesBuildPhase; 258 | buildActionMask = 2147483647; 259 | files = ( 260 | ); 261 | runOnlyForDeploymentPostprocessing = 0; 262 | }; 263 | /* End PBXResourcesBuildPhase section */ 264 | 265 | /* Begin PBXSourcesBuildPhase section */ 266 | 52458F6E1ADCE8250074C990 /* Sources */ = { 267 | isa = PBXSourcesBuildPhase; 268 | buildActionMask = 2147483647; 269 | files = ( 270 | 52458FCA1ADCEAF20074C990 /* WCPullRefreshControl.m in Sources */, 271 | 52458FC81ADCEAF20074C990 /* WCMagicSquareView.m in Sources */, 272 | 52458FC91ADCEAF20074C990 /* WCProgressItem.m in Sources */, 273 | 529DAA031AE928A100D3322D /* WebviewViewController.m in Sources */, 274 | 52458F7B1ADCE8250074C990 /* AppDelegate.m in Sources */, 275 | 52918AA91AEA36B50023CD96 /* WCGraintCircleLayer.m in Sources */, 276 | 52458FC71ADCEAF20074C990 /* NSDate+WCPullRefresh.m in Sources */, 277 | 52458FC61ADCEAF20074C990 /* CAShapeLayer+WCPullRefresh.m in Sources */, 278 | 52458F781ADCE8250074C990 /* main.m in Sources */, 279 | 525B26351ADD0ABC009B523F /* DemoTableview.m in Sources */, 280 | 52458FCB1ADCEAF20074C990 /* WCRefreshingItem.m in Sources */, 281 | ); 282 | runOnlyForDeploymentPostprocessing = 0; 283 | }; 284 | 52458F871ADCE8260074C990 /* Sources */ = { 285 | isa = PBXSourcesBuildPhase; 286 | buildActionMask = 2147483647; 287 | files = ( 288 | 52458F921ADCE8260074C990 /* WCPullRefreshControlExampleTests.m in Sources */, 289 | ); 290 | runOnlyForDeploymentPostprocessing = 0; 291 | }; 292 | /* End PBXSourcesBuildPhase section */ 293 | 294 | /* Begin PBXTargetDependency section */ 295 | 52458F8D1ADCE8260074C990 /* PBXTargetDependency */ = { 296 | isa = PBXTargetDependency; 297 | target = 52458F711ADCE8250074C990 /* WCPullRefreshControlExample */; 298 | targetProxy = 52458F8C1ADCE8260074C990 /* PBXContainerItemProxy */; 299 | }; 300 | /* End PBXTargetDependency section */ 301 | 302 | /* Begin PBXVariantGroup section */ 303 | 52458F7F1ADCE8250074C990 /* Main.storyboard */ = { 304 | isa = PBXVariantGroup; 305 | children = ( 306 | 52458F801ADCE8250074C990 /* Base */, 307 | ); 308 | name = Main.storyboard; 309 | sourceTree = ""; 310 | }; 311 | 52458F841ADCE8250074C990 /* LaunchScreen.xib */ = { 312 | isa = PBXVariantGroup; 313 | children = ( 314 | 52458F851ADCE8250074C990 /* Base */, 315 | ); 316 | name = LaunchScreen.xib; 317 | sourceTree = ""; 318 | }; 319 | /* End PBXVariantGroup section */ 320 | 321 | /* Begin XCBuildConfiguration section */ 322 | 52458F931ADCE8260074C990 /* Debug */ = { 323 | isa = XCBuildConfiguration; 324 | buildSettings = { 325 | ALWAYS_SEARCH_USER_PATHS = NO; 326 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 327 | CLANG_CXX_LIBRARY = "libc++"; 328 | CLANG_ENABLE_MODULES = YES; 329 | CLANG_ENABLE_OBJC_ARC = YES; 330 | CLANG_WARN_BOOL_CONVERSION = YES; 331 | CLANG_WARN_CONSTANT_CONVERSION = YES; 332 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 333 | CLANG_WARN_EMPTY_BODY = YES; 334 | CLANG_WARN_ENUM_CONVERSION = YES; 335 | CLANG_WARN_INT_CONVERSION = YES; 336 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 337 | CLANG_WARN_UNREACHABLE_CODE = YES; 338 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 339 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 340 | COPY_PHASE_STRIP = NO; 341 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 342 | ENABLE_STRICT_OBJC_MSGSEND = YES; 343 | GCC_C_LANGUAGE_STANDARD = gnu99; 344 | GCC_DYNAMIC_NO_PIC = NO; 345 | GCC_NO_COMMON_BLOCKS = YES; 346 | GCC_OPTIMIZATION_LEVEL = 0; 347 | GCC_PREPROCESSOR_DEFINITIONS = ( 348 | "DEBUG=1", 349 | "$(inherited)", 350 | ); 351 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 352 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 353 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 354 | GCC_WARN_UNDECLARED_SELECTOR = YES; 355 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 356 | GCC_WARN_UNUSED_FUNCTION = YES; 357 | GCC_WARN_UNUSED_VARIABLE = YES; 358 | IPHONEOS_DEPLOYMENT_TARGET = 8.3; 359 | MTL_ENABLE_DEBUG_INFO = YES; 360 | ONLY_ACTIVE_ARCH = YES; 361 | SDKROOT = iphoneos; 362 | TARGETED_DEVICE_FAMILY = "1,2"; 363 | }; 364 | name = Debug; 365 | }; 366 | 52458F941ADCE8260074C990 /* Release */ = { 367 | isa = XCBuildConfiguration; 368 | buildSettings = { 369 | ALWAYS_SEARCH_USER_PATHS = NO; 370 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 371 | CLANG_CXX_LIBRARY = "libc++"; 372 | CLANG_ENABLE_MODULES = YES; 373 | CLANG_ENABLE_OBJC_ARC = YES; 374 | CLANG_WARN_BOOL_CONVERSION = YES; 375 | CLANG_WARN_CONSTANT_CONVERSION = YES; 376 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 377 | CLANG_WARN_EMPTY_BODY = YES; 378 | CLANG_WARN_ENUM_CONVERSION = YES; 379 | CLANG_WARN_INT_CONVERSION = YES; 380 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 381 | CLANG_WARN_UNREACHABLE_CODE = YES; 382 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 383 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 384 | COPY_PHASE_STRIP = NO; 385 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 386 | ENABLE_NS_ASSERTIONS = NO; 387 | ENABLE_STRICT_OBJC_MSGSEND = YES; 388 | GCC_C_LANGUAGE_STANDARD = gnu99; 389 | GCC_NO_COMMON_BLOCKS = YES; 390 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 391 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 392 | GCC_WARN_UNDECLARED_SELECTOR = YES; 393 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 394 | GCC_WARN_UNUSED_FUNCTION = YES; 395 | GCC_WARN_UNUSED_VARIABLE = YES; 396 | IPHONEOS_DEPLOYMENT_TARGET = 8.3; 397 | MTL_ENABLE_DEBUG_INFO = NO; 398 | SDKROOT = iphoneos; 399 | TARGETED_DEVICE_FAMILY = "1,2"; 400 | VALIDATE_PRODUCT = YES; 401 | }; 402 | name = Release; 403 | }; 404 | 52458F961ADCE8260074C990 /* Debug */ = { 405 | isa = XCBuildConfiguration; 406 | buildSettings = { 407 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 408 | INFOPLIST_FILE = WCPullRefreshControlExample/Info.plist; 409 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 410 | PRODUCT_NAME = "$(TARGET_NAME)"; 411 | }; 412 | name = Debug; 413 | }; 414 | 52458F971ADCE8260074C990 /* Release */ = { 415 | isa = XCBuildConfiguration; 416 | buildSettings = { 417 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 418 | INFOPLIST_FILE = WCPullRefreshControlExample/Info.plist; 419 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 420 | PRODUCT_NAME = "$(TARGET_NAME)"; 421 | }; 422 | name = Release; 423 | }; 424 | 52458F991ADCE8260074C990 /* Debug */ = { 425 | isa = XCBuildConfiguration; 426 | buildSettings = { 427 | BUNDLE_LOADER = "$(TEST_HOST)"; 428 | FRAMEWORK_SEARCH_PATHS = ( 429 | "$(SDKROOT)/Developer/Library/Frameworks", 430 | "$(inherited)", 431 | ); 432 | GCC_PREPROCESSOR_DEFINITIONS = ( 433 | "DEBUG=1", 434 | "$(inherited)", 435 | ); 436 | INFOPLIST_FILE = WCPullRefreshControlExampleTests/Info.plist; 437 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 438 | PRODUCT_NAME = "$(TARGET_NAME)"; 439 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/WCPullRefreshControlExample.app/WCPullRefreshControlExample"; 440 | }; 441 | name = Debug; 442 | }; 443 | 52458F9A1ADCE8260074C990 /* Release */ = { 444 | isa = XCBuildConfiguration; 445 | buildSettings = { 446 | BUNDLE_LOADER = "$(TEST_HOST)"; 447 | FRAMEWORK_SEARCH_PATHS = ( 448 | "$(SDKROOT)/Developer/Library/Frameworks", 449 | "$(inherited)", 450 | ); 451 | INFOPLIST_FILE = WCPullRefreshControlExampleTests/Info.plist; 452 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 453 | PRODUCT_NAME = "$(TARGET_NAME)"; 454 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/WCPullRefreshControlExample.app/WCPullRefreshControlExample"; 455 | }; 456 | name = Release; 457 | }; 458 | /* End XCBuildConfiguration section */ 459 | 460 | /* Begin XCConfigurationList section */ 461 | 52458F6D1ADCE8250074C990 /* Build configuration list for PBXProject "WCPullRefreshControlExample" */ = { 462 | isa = XCConfigurationList; 463 | buildConfigurations = ( 464 | 52458F931ADCE8260074C990 /* Debug */, 465 | 52458F941ADCE8260074C990 /* Release */, 466 | ); 467 | defaultConfigurationIsVisible = 0; 468 | defaultConfigurationName = Release; 469 | }; 470 | 52458F951ADCE8260074C990 /* Build configuration list for PBXNativeTarget "WCPullRefreshControlExample" */ = { 471 | isa = XCConfigurationList; 472 | buildConfigurations = ( 473 | 52458F961ADCE8260074C990 /* Debug */, 474 | 52458F971ADCE8260074C990 /* Release */, 475 | ); 476 | defaultConfigurationIsVisible = 0; 477 | defaultConfigurationName = Release; 478 | }; 479 | 52458F981ADCE8260074C990 /* Build configuration list for PBXNativeTarget "WCPullRefreshControlExampleTests" */ = { 480 | isa = XCConfigurationList; 481 | buildConfigurations = ( 482 | 52458F991ADCE8260074C990 /* Debug */, 483 | 52458F9A1ADCE8260074C990 /* Release */, 484 | ); 485 | defaultConfigurationIsVisible = 0; 486 | defaultConfigurationName = Release; 487 | }; 488 | /* End XCConfigurationList section */ 489 | }; 490 | rootObject = 52458F6A1ADCE8250074C990 /* Project object */; 491 | } 492 | -------------------------------------------------------------------------------- /WCPullRefreshControlExample.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /WCPullRefreshControlExample.xcodeproj/project.xcworkspace/xcshareddata/WCPullRefreshControlExample.xccheckout: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDESourceControlProjectFavoriteDictionaryKey 6 | 7 | IDESourceControlProjectIdentifier 8 | 47B36A5F-E16F-45BD-8A73-A350CA572D20 9 | IDESourceControlProjectName 10 | WCPullRefreshControlExample 11 | IDESourceControlProjectOriginsDictionary 12 | 13 | 0D5677A72058771A1A44EF3EEC0661B6A058C1D4 14 | https://github.com/wenchenhuang/WCPullRefreshControl.git 15 | 16 | IDESourceControlProjectPath 17 | WCPullRefreshControlExample.xcodeproj 18 | IDESourceControlProjectRelativeInstallPathDictionary 19 | 20 | 0D5677A72058771A1A44EF3EEC0661B6A058C1D4 21 | ../.. 22 | 23 | IDESourceControlProjectURL 24 | https://github.com/wenchenhuang/WCPullRefreshControl.git 25 | IDESourceControlProjectVersion 26 | 111 27 | IDESourceControlProjectWCCIdentifier 28 | 0D5677A72058771A1A44EF3EEC0661B6A058C1D4 29 | IDESourceControlProjectWCConfigurations 30 | 31 | 32 | IDESourceControlRepositoryExtensionIdentifierKey 33 | public.vcs.git 34 | IDESourceControlWCCIdentifierKey 35 | 0D5677A72058771A1A44EF3EEC0661B6A058C1D4 36 | IDESourceControlWCCName 37 | WCPullRefreshControl 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /WCPullRefreshControlExample.xcodeproj/project.xcworkspace/xcuserdata/huangwenchen.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wenchenhuang/WCPullRefreshControl/e68f031a7bff17985d13073a1ea81e4537d7f810/WCPullRefreshControlExample.xcodeproj/project.xcworkspace/xcuserdata/huangwenchen.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /WCPullRefreshControlExample.xcodeproj/xcuserdata/huangwenchen.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | -------------------------------------------------------------------------------- /WCPullRefreshControlExample.xcodeproj/xcuserdata/huangwenchen.xcuserdatad/xcschemes/WCPullRefreshControlExample.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 29 | 35 | 36 | 37 | 38 | 39 | 44 | 45 | 47 | 53 | 54 | 55 | 56 | 57 | 63 | 64 | 65 | 66 | 75 | 77 | 83 | 84 | 85 | 86 | 87 | 88 | 94 | 96 | 102 | 103 | 104 | 105 | 107 | 108 | 111 | 112 | 113 | -------------------------------------------------------------------------------- /WCPullRefreshControlExample.xcodeproj/xcuserdata/huangwenchen.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | WCPullRefreshControlExample.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | 52458F711ADCE8250074C990 16 | 17 | primary 18 | 19 | 20 | 52458F8A1ADCE8260074C990 21 | 22 | primary 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /WCPullRefreshControlExample/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // WCPullRefreshControlExample 4 | // 5 | // Created by huangwenchen on 15/4/14. 6 | // Copyright (c) 2015年 huangwenchen. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | 16 | @end 17 | 18 | -------------------------------------------------------------------------------- /WCPullRefreshControlExample/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // WCPullRefreshControlExample 4 | // 5 | // Created by huangwenchen on 15/4/14. 6 | // Copyright (c) 2015年 huangwenchen. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | 11 | @interface AppDelegate () 12 | 13 | @end 14 | 15 | @implementation AppDelegate 16 | 17 | 18 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 19 | // Override point for customization after application launch. 20 | return YES; 21 | } 22 | 23 | - (void)applicationWillResignActive:(UIApplication *)application { 24 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 25 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 26 | } 27 | 28 | - (void)applicationDidEnterBackground:(UIApplication *)application { 29 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 30 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 31 | } 32 | 33 | - (void)applicationWillEnterForeground:(UIApplication *)application { 34 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. 35 | } 36 | 37 | - (void)applicationDidBecomeActive:(UIApplication *)application { 38 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 39 | } 40 | 41 | - (void)applicationWillTerminate:(UIApplication *)application { 42 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 43 | } 44 | 45 | @end 46 | -------------------------------------------------------------------------------- /WCPullRefreshControlExample/Base.lproj/LaunchScreen.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 20 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /WCPullRefreshControlExample/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 30 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 50 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 70 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | -------------------------------------------------------------------------------- /WCPullRefreshControlExample/DemoTableview.h: -------------------------------------------------------------------------------- 1 | // 2 | // DemoTableview.h 3 | // WCPullRefreshControlExample 4 | // 5 | // Created by huangwenchen on 15/4/14. 6 | // Copyright (c) 2015年 huangwenchen. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | 12 | @interface DemoTableview : UITableViewController 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /WCPullRefreshControlExample/DemoTableview.m: -------------------------------------------------------------------------------- 1 | // 2 | // DemoTableview.m 3 | // WCPullRefreshControlExample 4 | // 5 | // Created by huangwenchen on 15/4/14. 6 | // Copyright (c) 2015年 huangwenchen. All rights reserved. 7 | // 8 | 9 | #import "DemoTableview.h" 10 | #import "WCPullRefreshControl.h" 11 | 12 | @interface DemoTableview() 13 | @property (strong,nonatomic)WCPullRefreshControl * pullRefresh; 14 | 15 | @end 16 | 17 | @implementation DemoTableview 18 | -(void)viewDidLoad{ 19 | self.pullRefresh = [[WCPullRefreshControl alloc] initWithScrollview:self.tableView 20 | Action:NULL 21 | progressItem:WCProgressItemTypeRoundCricle 22 | refreshingItem:WCRefreshingItemTypeRoundCircle 23 | lastUpdate:nil 24 | showLastUpdate:NO 25 | textColor:[UIColor blueColor] 26 | itemColor:[UIColor blueColor] 27 | pullHeight:64]; 28 | self.pullRefresh.delegate = self; 29 | } 30 | -(void)reset{ 31 | [self.pullRefresh finishRefreshingSuccessully:YES]; 32 | } 33 | 34 | -(void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate{ 35 | [self.pullRefresh updateWhenScrollDidEndDraging]; 36 | } 37 | -(void)scrollViewDidScroll:(UIScrollView *)scrollView{ 38 | [self.pullRefresh updateWhenScrollviewScroll]; 39 | } 40 | -(void)DidStartRefreshingWithScrollview:(UIScrollView *)scrollview{ 41 | [self performSelector:@selector(reset) withObject:nil afterDelay:2.0]; 42 | } 43 | 44 | @end 45 | -------------------------------------------------------------------------------- /WCPullRefreshControlExample/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "29x29", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "40x40", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "40x40", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "60x60", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "60x60", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "ipad", 35 | "size" : "29x29", 36 | "scale" : "1x" 37 | }, 38 | { 39 | "idiom" : "ipad", 40 | "size" : "29x29", 41 | "scale" : "2x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "40x40", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "40x40", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "76x76", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "76x76", 61 | "scale" : "2x" 62 | } 63 | ], 64 | "info" : { 65 | "version" : 1, 66 | "author" : "xcode" 67 | } 68 | } -------------------------------------------------------------------------------- /WCPullRefreshControlExample/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | huangwenchen.$(PRODUCT_NAME:rfc1034identifier) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UIStatusBarHidden 34 | 35 | UIStatusBarStyle 36 | UIStatusBarStyleLightContent 37 | UISupportedInterfaceOrientations 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationLandscapeLeft 41 | UIInterfaceOrientationLandscapeRight 42 | 43 | UIViewControllerBasedStatusBarAppearance 44 | 45 | UISupportedInterfaceOrientations~ipad 46 | 47 | UIInterfaceOrientationPortrait 48 | UIInterfaceOrientationPortraitUpsideDown 49 | UIInterfaceOrientationLandscapeLeft 50 | UIInterfaceOrientationLandscapeRight 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /WCPullRefreshControlExample/WCGraintCircleLayer.h: -------------------------------------------------------------------------------- 1 | // 2 | // WCGraintCircleLayer.h 3 | // WCGraintCircleView 4 | // 5 | // Created by huangwenchen on 15/4/24. 6 | // Copyright (c) 2015年 huangwenchen. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface WCGraintCircleLayer : CALayer 12 | -(instancetype)initGraintCircleWithBounds:(CGRect)bounds Position:(CGPoint)position FromColor:(UIColor *)fromColor ToColor:(UIColor *)toColor LineWidth:(CGFloat) linewidth; 13 | @property (nonatomic)CGFloat progress; 14 | @end 15 | -------------------------------------------------------------------------------- /WCPullRefreshControlExample/WCGraintCircleLayer.m: -------------------------------------------------------------------------------- 1 | // 2 | // WCGraintCircleLayer.m 3 | // WCGraintCircleView 4 | // 5 | // Created by huangwenchen on 15/4/24. 6 | // Copyright (c) 2015年 huangwenchen. All rights reserved. 7 | // 8 | 9 | #import "WCGraintCircleLayer.h" 10 | @interface WCGraintCircleLayer() 11 | @property (strong,nonatomic)CAShapeLayer * maskShapeLayer; 12 | @end 13 | 14 | @implementation WCGraintCircleLayer 15 | -(void)setProgress:(CGFloat)progress{ 16 | _progress = progress; 17 | self.maskShapeLayer.strokeEnd = progress; 18 | self.maskShapeLayer.strokeEnd = 0.015 + (0.985-0.015)*progress; 19 | } 20 | -(instancetype)initGraintCircleWithBounds:(CGRect)bounds Position:(CGPoint)position FromColor:(UIColor *)fromColor ToColor:(UIColor *)toColor LineWidth:(CGFloat) linewidth{ 21 | if (self = [super init]) { 22 | self.bounds = bounds; 23 | self.position = position; 24 | NSArray * colors = [self graintFromColor:fromColor ToColor:toColor Count:4.0]; 25 | for (int i = 0; i < colors.count -1; i++) { 26 | CAGradientLayer * graint = [CAGradientLayer layer]; 27 | graint.bounds = CGRectMake(0,0,CGRectGetWidth(bounds)/2,CGRectGetHeight(bounds)/2); 28 | NSValue * valuePoint = [[self positionArrayWithMainBounds:self.bounds] objectAtIndex:i]; 29 | graint.position = valuePoint.CGPointValue; 30 | UIColor * fromColor = colors[i]; 31 | UIColor * toColor = colors[i+1]; 32 | NSArray *colors = [NSArray arrayWithObjects:(id)fromColor.CGColor, toColor.CGColor, nil]; 33 | NSNumber *stopOne = [NSNumber numberWithFloat:0.0]; 34 | NSNumber *stopTwo = [NSNumber numberWithFloat:1.0]; 35 | NSArray *locations = [NSArray arrayWithObjects:stopOne, stopTwo, nil]; 36 | graint.colors = colors; 37 | graint.locations = locations; 38 | graint.startPoint = ((NSValue *)[[self startPoints] objectAtIndex:i]).CGPointValue; 39 | graint.endPoint = ((NSValue *)[[self endPoints] objectAtIndex:i]).CGPointValue; 40 | [self addSublayer:graint]; 41 | //Set mask 42 | self.maskShapeLayer = [CAShapeLayer layer]; 43 | CGRect rect = CGRectMake(0,0,CGRectGetWidth(self.bounds) - 2 * linewidth, CGRectGetHeight(self.bounds) - 2 * linewidth); 44 | self.maskShapeLayer.bounds = rect; 45 | self.maskShapeLayer.position = CGPointMake(CGRectGetWidth(self.bounds)/2, CGRectGetHeight(self.bounds)/2); 46 | self.maskShapeLayer.strokeColor = [UIColor blueColor].CGColor; 47 | self.maskShapeLayer.fillColor = [UIColor clearColor].CGColor; 48 | self.maskShapeLayer.path = [UIBezierPath bezierPathWithRoundedRect:rect cornerRadius:CGRectGetWidth(rect)/2].CGPath; 49 | self.maskShapeLayer.lineWidth = linewidth; 50 | self.maskShapeLayer.lineCap = kCALineCapRound; 51 | self.maskShapeLayer.strokeStart = 0.015; 52 | self.maskShapeLayer.strokeEnd = 0.985; 53 | [self setMask:self.maskShapeLayer]; 54 | } 55 | } 56 | return self; 57 | } 58 | -(NSArray *)positionArrayWithMainBounds:(CGRect)bounds{ 59 | CGPoint first = CGPointMake(CGRectGetWidth(bounds)/4 *3, CGRectGetHeight(bounds)/4 *1); 60 | CGPoint second = CGPointMake(CGRectGetWidth(bounds)/4 *3, CGRectGetHeight(bounds)/4 *3); 61 | CGPoint thrid = CGPointMake(CGRectGetWidth(bounds)/4 *1, CGRectGetHeight(bounds)/4 *3); 62 | CGPoint fourth = CGPointMake(CGRectGetWidth(bounds)/4 *1, CGRectGetHeight(bounds)/4 *1); 63 | return @[[NSValue valueWithCGPoint:first], 64 | [NSValue valueWithCGPoint:second], 65 | [NSValue valueWithCGPoint:thrid], 66 | [NSValue valueWithCGPoint:fourth]]; 67 | } 68 | -(NSArray *)startPoints{ 69 | return @[[NSValue valueWithCGPoint:CGPointMake(0,0)], 70 | [NSValue valueWithCGPoint:CGPointMake(1,0)], 71 | [NSValue valueWithCGPoint:CGPointMake(1,1)], 72 | [NSValue valueWithCGPoint:CGPointMake(0,1)]]; 73 | } 74 | -(NSArray *)endPoints{ 75 | return @[[NSValue valueWithCGPoint:CGPointMake(1,1)], 76 | [NSValue valueWithCGPoint:CGPointMake(0,1)], 77 | [NSValue valueWithCGPoint:CGPointMake(0,0)], 78 | [NSValue valueWithCGPoint:CGPointMake(1,0)]]; 79 | } 80 | -(NSArray *)graintFromColor:(UIColor *)fromColor ToColor:(UIColor *)toColor Count:(NSInteger)count{ 81 | CGFloat fromR = 0.0,fromG = 0.0,fromB = 0.0,fromAlpha = 0.0; 82 | [fromColor getRed:&fromR green:&fromG blue:&fromB alpha:&fromAlpha]; 83 | CGFloat toR = 0.0,toG = 0.0,toB = 0.0,toAlpha = 0.0; 84 | [toColor getRed:&toR green:&toG blue:&toB alpha:&toAlpha]; 85 | NSMutableArray * result = [[NSMutableArray alloc] init]; 86 | for (int i = 0; i <= count; i++) { 87 | CGFloat oneR = fromR + (toR - fromR)/count * i; 88 | CGFloat oneG = fromG + (toG - fromG)/count * i; 89 | CGFloat oneB = fromB + (toB - fromB)/count * i; 90 | CGFloat oneAlpha = fromAlpha + (toAlpha - fromAlpha)/count * i; 91 | UIColor * onecolor = [UIColor colorWithRed:oneR green:oneG blue:oneB alpha:oneAlpha]; 92 | [result addObject:onecolor]; 93 | } 94 | // [result addObject:[self midColorWithFromColor:fromColor ToColor:toColor Progress:0.0]]; 95 | // [result addObject:[self midColorWithFromColor:fromColor ToColor:toColor Progress:0.2]]; 96 | // [result addObject:[self midColorWithFromColor:fromColor ToColor:toColor Progress:0.4]]; 97 | // [result addObject:[self midColorWithFromColor:fromColor ToColor:toColor Progress:0.6]]; 98 | // [result addObject:[self midColorWithFromColor:fromColor ToColor:toColor Progress:1.0]]; 99 | 100 | return result; 101 | } 102 | -(UIColor *)midColorWithFromColor:(UIColor *)fromColor ToColor:(UIColor*)toColor Progress:(CGFloat)progress{ 103 | CGFloat fromR = 0.0,fromG = 0.0,fromB = 0.0,fromAlpha = 0.0; 104 | [fromColor getRed:&fromR green:&fromG blue:&fromB alpha:&fromAlpha]; 105 | CGFloat toR = 0.0,toG = 0.0,toB = 0.0,toAlpha = 0.0; 106 | [toColor getRed:&toR green:&toG blue:&toB alpha:&toAlpha]; 107 | CGFloat oneR = fromR + (toR - fromR) * progress; 108 | CGFloat oneG = fromG + (toG - fromG) * progress; 109 | CGFloat oneB = fromB + (toB - fromB) * progress; 110 | CGFloat oneAlpha = fromAlpha + (toAlpha - fromAlpha) * progress; 111 | UIColor * onecolor = [UIColor colorWithRed:oneR green:oneG blue:oneB alpha:oneAlpha]; 112 | return onecolor; 113 | } 114 | 115 | @end 116 | -------------------------------------------------------------------------------- /WCPullRefreshControlExample/WebviewViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // WebviewViewController.h 3 | // WCPullRefreshControlExample 4 | // 5 | // Created by huangwenchen on 15/4/23. 6 | // Copyright (c) 2015年 huangwenchen. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface WebviewViewController : UIViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /WCPullRefreshControlExample/WebviewViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // WebviewViewController.m 3 | // WCPullRefreshControlExample 4 | // 5 | // Created by huangwenchen on 15/4/23. 6 | // Copyright (c) 2015年 huangwenchen. All rights reserved. 7 | // 8 | 9 | #import "WebviewViewController.h" 10 | #import "WCPullRefreshControl.h" 11 | @interface WebviewViewController () 12 | @property (strong,nonatomic) WCPullRefreshControl * pullRefresh; 13 | 14 | @property (weak, nonatomic) IBOutlet UIWebView *webview; 15 | @property (strong,nonatomic) NSURLRequest * request; 16 | @end 17 | 18 | @implementation WebviewViewController 19 | 20 | - (void)viewDidLoad { 21 | [super viewDidLoad]; 22 | self.request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.google.com"]]; 23 | self.webview.scrollView.delegate = self; 24 | self.webview.delegate = self; 25 | self.pullRefresh = [[WCPullRefreshControl alloc] initWithScrollview:self.webview.scrollView 26 | Action:^{ 27 | if (self.webview.isLoading) { 28 | [self.webview stopLoading]; 29 | } 30 | [self.webview loadRequest:self.request]; 31 | } 32 | progressItem:WCProgressItemTypeMagicSquare 33 | refreshingItem:WCRefreshingItemTypeMagicSquare 34 | lastUpdate:[NSDate date] 35 | showLastUpdate:YES 36 | textColor:[UIColor blueColor] 37 | itemColor:[UIColor lightGrayColor] 38 | pullHeight:64]; 39 | } 40 | -(void)viewDidAppear:(BOOL)animated{ 41 | [self.pullRefresh manualStartRefreshingWithAction]; 42 | } 43 | -(void)webViewDidFinishLoad:(UIWebView *)webView{ 44 | [self.pullRefresh finishRefreshingSuccessully:true]; 45 | } 46 | -(void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error{ 47 | [self.pullRefresh finishRefreshingSuccessully:false]; 48 | } 49 | 50 | -(void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate{ 51 | [self.pullRefresh updateWhenScrollDidEndDraging]; 52 | } 53 | -(void)scrollViewDidScroll:(UIScrollView *)scrollView{ 54 | [self.pullRefresh updateWhenScrollviewScroll]; 55 | } 56 | 57 | @end 58 | -------------------------------------------------------------------------------- /WCPullRefreshControlExample/classes/CAShapeLayer+WCPullRefresh.h: -------------------------------------------------------------------------------- 1 | // 2 | // CAShapeLayer+WCPullRefresh.h 3 | // WCPullRefreshControl 4 | // 5 | // Created by huangwenchen on 15/4/13. 6 | // Copyright (c) 2015年 huangwenchen. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | @interface CAShapeLayer (WCPullRefresh) 12 | +(CAShapeLayer *)createCircleWithBounds:(CGRect)bounds 13 | Position:(CGPoint)position 14 | StrokeColor:(UIColor*)color 15 | LineWidth:(CGFloat)lineWidth; 16 | 17 | +(CAShapeLayer *)createArrowLayerWithBound:(CGRect)bounds 18 | Position:(CGPoint)position 19 | StrokeColor:(UIColor *)color 20 | LineWidth:(CGFloat)lineWidth 21 | offSet:(CGFloat)offset 22 | arrowSize:(CGFloat)arrowSize; 23 | +(CAShapeLayer *)create25_25StarLayerWithStrokeColor:(UIColor*)color 24 | LineWidth:(CGFloat)lineWidth; 25 | @end 26 | -------------------------------------------------------------------------------- /WCPullRefreshControlExample/classes/CAShapeLayer+WCPullRefresh.m: -------------------------------------------------------------------------------- 1 | // 2 | // CAShapeLayer+WCPullRefresh.m 3 | // WCPullRefreshControl 4 | // 5 | // Created by huangwenchen on 15/4/13. 6 | // Copyright (c) 2015年 huangwenchen. All rights reserved. 7 | // 8 | 9 | #import "CAShapeLayer+WCPullRefresh.h" 10 | 11 | @implementation CAShapeLayer (WCPullRefresh) 12 | +(CAShapeLayer *)createCircleWithBounds:(CGRect)bounds 13 | Position:(CGPoint)position 14 | StrokeColor:(UIColor*)color 15 | LineWidth:(CGFloat)lineWidth 16 | { 17 | CAShapeLayer* shapelayer = [CAShapeLayer layer]; 18 | shapelayer.strokeColor = color.CGColor; 19 | shapelayer.fillColor = [UIColor clearColor].CGColor; 20 | shapelayer.path = [UIBezierPath bezierPathWithRoundedRect:bounds cornerRadius:CGRectGetWidth(bounds)/2].CGPath; 21 | shapelayer.bounds = bounds; 22 | shapelayer.position = position; 23 | shapelayer.lineCap = kCALineCapRound; 24 | shapelayer.lineWidth = 2.0; 25 | return shapelayer; 26 | } 27 | +(CAShapeLayer *)createArrowLayerWithBound:(CGRect)bounds 28 | Position:(CGPoint)position 29 | StrokeColor:(UIColor *)color 30 | LineWidth:(CGFloat)lineWidth 31 | offSet:(CGFloat)offset 32 | arrowSize:(CGFloat)arrowSize 33 | { 34 | CAShapeLayer * arrowLayer = [CAShapeLayer layer]; 35 | arrowLayer.strokeColor = color.CGColor; 36 | arrowLayer.lineCap = kCALineCapSquare; 37 | arrowLayer.bounds = bounds; 38 | arrowLayer.position = position; 39 | arrowLayer.lineWidth = 1.0; 40 | arrowLayer.fillColor = [UIColor clearColor].CGColor; 41 | CGMutablePathRef arrowpath = CGPathCreateMutable(); 42 | CGPathMoveToPoint(arrowpath,nil,CGRectGetMidX(bounds) ,CGRectGetMaxY(bounds)-offset); 43 | CGPathAddLineToPoint(arrowpath,nil,CGRectGetMidX(bounds),offset); 44 | CGPathMoveToPoint(arrowpath,nil,CGRectGetMidX(bounds) ,CGRectGetMaxY(bounds) -offset); 45 | CGPathAddLineToPoint(arrowpath,nil,CGRectGetMidX(bounds) + arrowSize,CGRectGetMaxY(bounds) - offset - arrowSize); 46 | CGPathMoveToPoint(arrowpath,nil,CGRectGetMidX(bounds) ,CGRectGetMaxY(bounds) -offset); 47 | CGPathAddLineToPoint(arrowpath,nil,CGRectGetMidX(bounds) - arrowSize,CGRectGetMaxY(bounds) - offset - arrowSize); 48 | arrowLayer.path = arrowpath; 49 | return arrowLayer; 50 | } 51 | +(CAShapeLayer *)create25_25StarLayerWithStrokeColor:(UIColor*)color 52 | LineWidth:(CGFloat)lineWidth 53 | { 54 | 55 | CAShapeLayer * starLayer = [CAShapeLayer layer]; 56 | UIBezierPath* starPath = UIBezierPath.bezierPath; 57 | [starPath moveToPoint: CGPointMake(12.5, 0)]; 58 | [starPath addLineToPoint: CGPointMake(16.91, 6.43)]; 59 | [starPath addLineToPoint: CGPointMake(24.39, 8.64)]; 60 | [starPath addLineToPoint: CGPointMake(19.63, 14.82)]; 61 | [starPath addLineToPoint: CGPointMake(19.85, 22.61)]; 62 | [starPath addLineToPoint: CGPointMake(12.5, 20)]; 63 | [starPath addLineToPoint: CGPointMake(5.15, 22.61)]; 64 | [starPath addLineToPoint: CGPointMake(5.37, 14.82)]; 65 | [starPath addLineToPoint: CGPointMake(0.61, 8.64)]; 66 | [starPath addLineToPoint: CGPointMake(8.09, 6.43)]; 67 | [starPath closePath]; 68 | starLayer.path = starPath.CGPath; 69 | starLayer.strokeColor = color.CGColor; 70 | starLayer.fillColor = [UIColor clearColor].CGColor; 71 | starLayer.lineJoin = kCALineJoinMiter; 72 | starLayer.lineWidth = lineWidth; 73 | starLayer.bounds = CGRectMake(0,0,25.0,25.0); 74 | starLayer.position = CGPointMake(12.5,12.5); 75 | return starLayer; 76 | } 77 | @end 78 | -------------------------------------------------------------------------------- /WCPullRefreshControlExample/classes/NSDate+WCPullRefresh.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSDate+WCPullRefresh.h 3 | // WCPullRefreshControl 4 | // 5 | // Created by huangwenchen on 15/4/13. 6 | // Copyright (c) 2015年 huangwenchen. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NSDate (WCPullRefresh) 12 | +(NSString *)stringFromLastdate:(NSDate *) lastDate; 13 | @end 14 | -------------------------------------------------------------------------------- /WCPullRefreshControlExample/classes/NSDate+WCPullRefresh.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSDate+WCPullRefresh.m 3 | // WCPullRefreshControl 4 | // 5 | // Created by huangwenchen on 15/4/13. 6 | // Copyright (c) 2015年 huangwenchen. All rights reserved. 7 | // 8 | 9 | #import "NSDate+WCPullRefresh.h" 10 | 11 | @implementation NSDate (WCPullRefresh) 12 | +(NSString *)stringFromLastdate:(NSDate *) lastDate 13 | { 14 | if (lastDate == nil) { 15 | return @"This is first update"; 16 | }else{ 17 | NSDateFormatter * formatter = [[NSDateFormatter alloc] init]; 18 | [formatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"]; 19 | NSString *datestr = [formatter stringFromDate:lastDate]; 20 | return [NSString stringWithFormat:@"Last update: %@",datestr]; 21 | } 22 | } 23 | @end 24 | -------------------------------------------------------------------------------- /WCPullRefreshControlExample/classes/WCMagicSquareView.h: -------------------------------------------------------------------------------- 1 | // 2 | // WCMagicSquareView.h 3 | // WCPullRefreshControl 4 | // 5 | // Created by huangwenchen on 15/4/13. 6 | // Copyright (c) 2015年 huangwenchen. All rights reserved. 7 | // 8 | 9 | #import "WCPullRefreshControl.h" 10 | 11 | @interface WCMagicSquareView : WCPullRefreshControl 12 | -(instancetype)initWithProgress:(CGFloat)progress Color:(UIColor*)color MaxWidth:(CGFloat)maxwidth; 13 | -(void)startAnimating; 14 | -(void)stopAnimating; 15 | @property (nonatomic)CGFloat progress; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /WCPullRefreshControlExample/classes/WCMagicSquareView.m: -------------------------------------------------------------------------------- 1 | // 2 | // WCMagicSquareView.m 3 | // WCPullRefreshControl 4 | // 5 | // Created by huangwenchen on 15/4/13. 6 | // Copyright (c) 2015年 huangwenchen. All rights reserved. 7 | // 8 | #import "WCMagicSquareView.h" 9 | @interface WCMagicSquareView() 10 | @property (strong,nonatomic)UIView * view1; 11 | @property (strong,nonatomic)UIView * view2; 12 | @property (strong,nonatomic)UIView * view3; 13 | @property (strong,nonatomic)UIView * view4; 14 | @property (nonatomic) CGFloat maxwidth; 15 | @end 16 | static const CGFloat space = 5.0; 17 | static const CGFloat squareLength = 15.0; 18 | static const CGFloat speedfast = 1.5; 19 | static const CGFloat speedslow = 1.0; 20 | @implementation WCMagicSquareView 21 | -(void)startAnimating{ 22 | [self addAnimationToView:self.view1 WithDuration:0.45 Delay:0.0]; 23 | [self addAnimationToView:self.view2 WithDuration:0.45 Delay:0.15]; 24 | [self addAnimationToView:self.view3 WithDuration:0.45 Delay:0.30]; 25 | [self addAnimationToView:self.view4 WithDuration:0.45 Delay:0.45]; 26 | 27 | } 28 | 29 | -(void)stopAnimating{ 30 | [self deleteAnimationWith:self.view1]; 31 | [self deleteAnimationWith:self.view2]; 32 | [self deleteAnimationWith:self.view3]; 33 | [self deleteAnimationWith:self.view4]; 34 | 35 | } 36 | -(NSArray *)keysArray{ 37 | return @[@"view1",@"view2",@"view3",@"view4"]; 38 | } 39 | -(NSArray *)centerArray{ 40 | return @[[NSValue valueWithCGPoint:[self centerOfView1]], 41 | [NSValue valueWithCGPoint:[self centerOfView2]], 42 | [NSValue valueWithCGPoint:[self centerOfView3]], 43 | [NSValue valueWithCGPoint:[self centerOfView4]]]; 44 | } 45 | -(instancetype)initWithProgress:(CGFloat)progress Color:(UIColor *)color MaxWidth:(CGFloat)maxwidth{ 46 | if (self = [super initWithFrame:CGRectMake(0,0,maxwidth,squareLength)]) { 47 | self.progress = progress; 48 | self.maxwidth = maxwidth; 49 | //Set up view 50 | for (int index = 0;index < [self centerArray].count;index ++) { 51 | NSValue * nsCenter = [[self centerArray] objectAtIndex:index]; 52 | NSString * key = [[self keysArray] objectAtIndex:index]; 53 | UIView * oneview = [[UIView alloc] initWithFrame:CGRectMake(0,0,squareLength, squareLength)]; 54 | oneview.layer.cornerRadius = 4.0; 55 | oneview.backgroundColor = color; 56 | oneview.center = nsCenter.CGPointValue; 57 | oneview.alpha = 1.0; 58 | [self setValue:oneview forKey:key]; 59 | [self addSubview:oneview]; 60 | } 61 | [self updateAlpha]; 62 | } 63 | return self; 64 | } 65 | -(void)setProgress:(CGFloat)progress{ 66 | _progress = progress; 67 | [self updateSubviews]; 68 | } 69 | -(void)updateAlpha{ 70 | self.view2.alpha = MIN(1.0,speedslow * self.progress); 71 | self.view3.alpha = MIN(1.0,speedfast * self.progress); 72 | self.view1.alpha = MIN(1.0,speedfast * self.progress); 73 | self.view4.alpha = MIN(1.0,speedslow * self.progress); 74 | 75 | } 76 | -(void)addAnimationToView:(UIView *)view WithDuration:(CGFloat)duration Delay:(CGFloat)delay 77 | { 78 | [UIView beginAnimations:nil context:NULL]; 79 | [UIView setAnimationDelay:delay]; 80 | [UIView setAnimationDuration:duration]; 81 | [UIView setAnimationBeginsFromCurrentState:YES]; 82 | [UIView setAnimationCurve:UIViewAnimationCurveLinear]; 83 | [UIView setAnimationDuration:duration]; 84 | [UIView setAnimationRepeatCount:99999]; 85 | [UIView setAnimationRepeatAutoreverses:YES]; 86 | view.transform = CGAffineTransformMakeScale(1.0,1.4); 87 | view.alpha = 0.5; 88 | [UIView commitAnimations]; 89 | } 90 | -(void)deleteAnimationWith:(UIView *)view{ 91 | [UIView beginAnimations:nil context:NULL]; 92 | [UIView setAnimationDuration:0.1]; 93 | [UIView setAnimationBeginsFromCurrentState:YES]; 94 | view.transform = CGAffineTransformMakeScale(1.0,1.0); 95 | view.alpha = 1.0; 96 | [UIView commitAnimations]; 97 | } 98 | -(CGPoint)centerOfView1{ 99 | CGFloat minX = squareLength /2; 100 | CGFloat maxX = self.maxwidth / 2 - space/2 - squareLength / 2; 101 | CGFloat x = (maxX- minX)*self.progress*speedfast + minX; 102 | CGFloat y = 10; 103 | x = MIN(maxX,x); 104 | return CGPointMake(x,y); 105 | } 106 | -(CGPoint)centerOfView2{ 107 | CGFloat minX = squareLength /2; 108 | CGFloat maxX = self.maxwidth / 2 - space/2 * 3 - squareLength / 2*3; 109 | CGFloat x = (maxX - minX)*self.progress*speedslow + squareLength /2; 110 | CGFloat y = 10; 111 | x = MIN(maxX,x); 112 | return CGPointMake(x,y); 113 | } 114 | -(CGPoint)centerOfView3{ 115 | CGFloat maxX = self.maxwidth - squareLength /2; 116 | CGFloat minx = self.maxwidth/2 + space/2 + squareLength / 2; 117 | CGFloat x = maxX - (maxX - minx)*self.progress*speedfast; 118 | CGFloat y = 10; 119 | x = MAX(minx,x); 120 | return CGPointMake(x,y); 121 | 122 | } 123 | -(CGPoint)centerOfView4{ 124 | CGFloat maxX = self.maxwidth - squareLength /2; 125 | CGFloat minx = self.maxwidth/2 + space/2 * 3 + squareLength/2 * 3; 126 | CGFloat x = maxX - (maxX - minx)*self.progress*speedslow; 127 | CGFloat y = 10; 128 | x = MAX(minx,x); 129 | return CGPointMake(x,y); 130 | 131 | } 132 | -(void)updateSubviews{ 133 | self.view1.center = [self centerOfView1]; 134 | self.view2.center = [self centerOfView2]; 135 | self.view3.center = [self centerOfView3]; 136 | self.view4.center = [self centerOfView4]; 137 | [self updateAlpha]; 138 | } 139 | @end 140 | -------------------------------------------------------------------------------- /WCPullRefreshControlExample/classes/WCProgressItem.h: -------------------------------------------------------------------------------- 1 | // 2 | // WCProgressItem.h 3 | // WCPullRefreshControl 4 | // 5 | // Created by huangwenchen on 15/4/11. 6 | // Copyright (c) 2015年 huangwenchen. All rights reserved. 7 | // 8 | 9 | #import 10 | typedef NS_ENUM(NSUInteger, WCProgressItemType) { 11 | WCProgressItemTypeRoundCricle = 0, 12 | WCProgressItemTypeStar = 1, 13 | WCProgressItemTypeMagicSquare = 2, 14 | WCProgressItemTypeGradientCircle = 3, 15 | }; 16 | @interface WCProgressItem : UIView 17 | -(instancetype)initWithFrame:(CGRect)frame Type:(WCProgressItemType)type Color:(UIColor *)color; 18 | @property(nonatomic)CGFloat progress; 19 | @end 20 | -------------------------------------------------------------------------------- /WCPullRefreshControlExample/classes/WCProgressItem.m: -------------------------------------------------------------------------------- 1 | // 2 | // WCProgressItem.m 3 | // WCPullRefreshControl 4 | // 5 | // Created by huangwenchen on 15/4/11. 6 | // Copyright (c) 2015年 huangwenchen. All rights reserved. 7 | // 8 | 9 | #import "WCProgressItem.h" 10 | #import "CAShapeLayer+WCPullRefresh.h" 11 | #import "WCMagicSquareView.h" 12 | #import "WCGraintCircleLayer.h" 13 | static const CGFloat offset = 4.0; 14 | static const CGFloat arrowOffset = 2.0; 15 | @interface WCProgressItem() 16 | @property (strong,nonatomic)CAShapeLayer * shapelayer; 17 | @property (strong,nonatomic)CAShapeLayer * arrowLayer; 18 | @property (nonatomic)WCProgressItemType type; 19 | @property (strong,nonatomic) WCMagicSquareView * squareview; 20 | @property (strong,nonatomic) WCGraintCircleLayer * graintlayer; 21 | 22 | @end 23 | 24 | @implementation WCProgressItem 25 | -(instancetype)initWithFrame:(CGRect)frame Type:(WCProgressItemType)type Color:(UIColor *)color{ 26 | if (self = [super initWithFrame:frame]) { 27 | switch (type) { 28 | case WCProgressItemTypeRoundCricle: 29 | self.shapelayer = [CAShapeLayer createCircleWithBounds: CGRectMake(0,0,frame.size.width,frame.size.height) 30 | Position:CGPointMake(frame.size.width/2,frame.size.height/2) 31 | StrokeColor:color 32 | LineWidth:2.0]; 33 | self.arrowLayer = [CAShapeLayer createArrowLayerWithBound:CGRectMake(0,0,frame.size.width,frame.size.height) 34 | Position:CGPointMake(frame.size.width/2,frame.size.height/2) 35 | StrokeColor:color 36 | LineWidth:1.0 37 | offSet:offset 38 | arrowSize:arrowOffset]; 39 | [self.layer addSublayer:self.arrowLayer]; 40 | [self.layer addSublayer:self.shapelayer]; 41 | break; 42 | case WCProgressItemTypeStar: 43 | self.shapelayer = [CAShapeLayer create25_25StarLayerWithStrokeColor:[UIColor blueColor] LineWidth:2.0]; 44 | [self.layer addSublayer:self.shapelayer]; 45 | break; 46 | case WCProgressItemTypeMagicSquare: 47 | self.frame = CGRectMake(0,0,320,20); 48 | self.squareview = [[WCMagicSquareView alloc] initWithProgress:0.0 Color:color MaxWidth:320]; 49 | [self addSubview:self.squareview]; 50 | break; 51 | case WCProgressItemTypeGradientCircle: 52 | self.graintlayer = [[WCGraintCircleLayer alloc] initGraintCircleWithBounds:CGRectMake(0, 0, frame.size.width, frame.size.height) 53 | Position:CGPointMake(CGRectGetWidth(frame)/2, CGRectGetHeight(frame)/2) 54 | FromColor:[UIColor clearColor] 55 | ToColor:color 56 | LineWidth:3.0]; 57 | [self.layer addSublayer:self.graintlayer]; 58 | break; 59 | default: 60 | break; 61 | } 62 | self.shapelayer.strokeStart = 0.0; 63 | self.shapelayer.strokeEnd = 0.0; 64 | self.type = type; 65 | } 66 | return self; 67 | } 68 | -(void)LogFrame:(CGRect)rect{ 69 | NSLog(@"%f %f %f %f",rect.origin.x,rect.origin.y,rect.size.width,rect.size.height); 70 | } 71 | -(void)setProgress:(CGFloat)progress{ 72 | _progress = progress; 73 | switch (self.type) { 74 | case WCProgressItemTypeRoundCricle: 75 | _progress = progress*0.95; 76 | self.shapelayer.strokeStart = 0.05; 77 | self.shapelayer.strokeEnd = _progress; 78 | break; 79 | case WCProgressItemTypeStar: 80 | self.shapelayer.strokeEnd = _progress; 81 | break; 82 | case WCProgressItemTypeMagicSquare: 83 | self.squareview.progress = _progress; 84 | break; 85 | case WCProgressItemTypeGradientCircle: 86 | self.graintlayer.progress = _progress; 87 | break; 88 | default: 89 | break; 90 | } 91 | } 92 | @end 93 | -------------------------------------------------------------------------------- /WCPullRefreshControlExample/classes/WCPullRefreshControl.h: -------------------------------------------------------------------------------- 1 | // 2 | // WCPullRefreshControl.h 3 | // WCPullRefreshControl 4 | // 5 | // Created by huangwenchen on 15/4/13. 6 | // Copyright (c) 2015年 huangwenchen. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "NSDate+WCPullRefresh.h" 11 | #import "WCProgressItem.h" 12 | #import "WCRefreshingItem.h" 13 | static const CGFloat defaultPullHeight = 64.0; 14 | 15 | typedef enum { 16 | WCPullRefreshControlStateIdle = 0, 17 | WCPullRefreshControlStateRefreshing = 1, 18 | WCPullRefreshControlStateDisappearing = 2 19 | } WCPullRefreshControlState; 20 | 21 | typedef void(^WCRefreshAction)(void); 22 | @protocol WCPullRefreshControlDelegate 23 | -(void)DidStartRefreshingWithScrollview:(UIScrollView *)scrollview; 24 | @end 25 | 26 | 27 | @interface WCPullRefreshControl : UIView 28 | @property (weak,nonatomic)iddelegate; 29 | @property (strong,nonatomic)NSDate * lastUpdateDate; 30 | @property (strong,nonatomic)UIScrollView * attachedScrollView; 31 | @property (nonatomic)CGFloat pullHeight; 32 | -(void)updateWhenScrollviewScroll; 33 | -(void)updateWhenScrollDidEndDraging; 34 | -(void)finishRefreshingSuccessully:(BOOL)success; 35 | //-(void)manualStartRefreshingWithAction:(WCRefreshAction)action; 36 | -(void)manualStartRefreshingWithAction; 37 | /*! 38 | * @discussion Main init mtehod, you can custom the refreshcontrol as you like 39 | * @param scrollview The scrollview that you attached to.Such as tableview,webview,collectview 40 | * @param action The action that excute during refreshing.Such as fetching something from internet 41 | * @param progressType Type of progresssview 42 | * @param refreshingType Type of refreshingview 43 | * @param date Last update.If you want the refreshcontrol to show lastupdate.This can not be nil. 44 | * @param isShowLastUpdate Whether to show last update date 45 | * @param textcolor Color of textlabel 46 | * @param progressColor Color of progress and refreshing item 47 | * @param pullHeight Max length to trigger refreshing action 48 | * @return UIView * 49 | */ 50 | -(instancetype)initWithScrollview:(UIScrollView *)scrollview 51 | Action:(WCRefreshAction) action 52 | progressItem:(WCProgressItemType)progressType 53 | refreshingItem:(WCRefreshingItemType)refreshingType 54 | lastUpdate:(NSDate *)date 55 | showLastUpdate:(BOOL)isShowLastUpdate 56 | textColor:(UIColor *)textcolor 57 | itemColor:(UIColor *)progressColor 58 | pullHeight:(CGFloat)pullHeight; 59 | -(instancetype)initWithScrollview:(UIScrollView *)scrollview 60 | Action:(WCRefreshAction) action; 61 | 62 | -(instancetype)initWithScrollview:(UIScrollView *)scrollview 63 | Action:(WCRefreshAction) action 64 | lastUpdate:(NSDate *)date 65 | showLastUpdate:(BOOL)isShowLastUpdate; 66 | @end 67 | -------------------------------------------------------------------------------- /WCPullRefreshControlExample/classes/WCPullRefreshControl.m: -------------------------------------------------------------------------------- 1 | #import "WCPullRefreshControl.h" 2 | static const CGFloat itemlength = 25.0; 3 | @interface WCPullRefreshControl() 4 | 5 | @property (strong,nonatomic)WCProgressItem * progressItem; 6 | @property (strong,nonatomic)WCRefreshingItem * refreshingItem; 7 | @property (copy,nonatomic)WCRefreshAction refreshAction; 8 | @property (strong,nonatomic)UILabel * lastUpdateLabel; 9 | @property (nonatomic,readwrite) WCPullRefreshControlState state; 10 | @property (nonatomic) BOOL showLastUpdate; 11 | //@property (nonatomic) CGFloat originalInset; 12 | @property (nonatomic) CGFloat originalOffset; 13 | @end 14 | 15 | @implementation WCPullRefreshControl 16 | 17 | -(instancetype)initWithScrollview:(UIScrollView *)scrollview Action:(WCRefreshAction)action{ 18 | return [self initWithScrollview:scrollview Action:action lastUpdate:nil showLastUpdate:NO]; 19 | } 20 | -(instancetype)initWithScrollview:(UIScrollView *)scrollview Action:(WCRefreshAction)action lastUpdate:(NSDate *)date showLastUpdate:(BOOL)isShowLastUpdate{ 21 | return [self initWithScrollview:scrollview 22 | Action:action 23 | progressItem:WCProgressItemTypeRoundCricle 24 | refreshingItem:WCRefreshingItemTypeRoundCircle 25 | lastUpdate:date 26 | showLastUpdate:isShowLastUpdate 27 | textColor:[UIColor blueColor] 28 | itemColor:[UIColor blueColor] 29 | pullHeight:64.0 30 | ]; 31 | } 32 | 33 | -(instancetype)initWithScrollview:(UIScrollView *)scrollview 34 | Action:(WCRefreshAction)action 35 | progressItem:(WCProgressItemType)progressType 36 | refreshingItem:(WCRefreshingItemType)refreshingType 37 | lastUpdate:(NSDate *)date 38 | showLastUpdate:(BOOL)isShowLastUpdate 39 | textColor:(UIColor *)textcolor 40 | itemColor:(UIColor *)itemColor 41 | pullHeight:(CGFloat)pullHeight 42 | { 43 | if (self = [super init]) { 44 | CGRect frame = CGRectMake(0,0,[UIScreen mainScreen].bounds.size.width,defaultPullHeight); 45 | self.pullHeight = pullHeight; 46 | self.frame = frame; 47 | self.center =CGPointMake([UIScreen mainScreen].bounds.size.width/2, -1 * defaultPullHeight/2); 48 | self.attachedScrollView = scrollview; 49 | self.refreshAction = action; 50 | self.showLastUpdate = isShowLastUpdate; 51 | [scrollview addSubview:self]; 52 | //Set up items 53 | CGRect itemFrame; 54 | itemFrame.origin = CGPointZero; 55 | itemFrame.size = CGSizeMake(itemlength,itemlength); 56 | if (progressType == WCProgressItemTypeMagicSquare) { 57 | self.progressItem = [[WCProgressItem alloc] initWithFrame:CGRectMake(0,0,scrollview.contentSize.width,15) Type:progressType Color:itemColor]; 58 | }else{ 59 | self.progressItem = [[WCProgressItem alloc] initWithFrame:itemFrame Type:progressType Color:itemColor]; 60 | } 61 | self.progressItem.hidden = NO; 62 | self.progressItem.center = CGPointMake([UIScreen mainScreen].bounds.size.width/2,defaultPullHeight/8 *4); 63 | 64 | [self addSubview:self.progressItem]; 65 | if (refreshingType == WCRefreshingItemTypeMagicSquare) { 66 | self.refreshingItem = [[WCRefreshingItem alloc] initWithFrame:CGRectMake(0,0,scrollview.contentSize.width,15) Type:refreshingType Color:itemColor]; 67 | }else{ 68 | self.refreshingItem = [[WCRefreshingItem alloc] initWithFrame:itemFrame Type:refreshingType Color:itemColor]; 69 | } 70 | self.refreshingItem.center = self.progressItem.center; 71 | self.refreshingItem.hidden = YES; 72 | [self addSubview:self.refreshingItem]; 73 | //Set up label 74 | 75 | CGRect labelFrame; 76 | labelFrame.origin = CGPointMake(0.0,defaultPullHeight/4 * 3); 77 | labelFrame.size =CGSizeMake([UIScreen mainScreen].bounds.size.width,defaultPullHeight/4); 78 | self.lastUpdateLabel = [[UILabel alloc] init]; 79 | self.lastUpdateLabel.frame = labelFrame; 80 | self.lastUpdateLabel.textAlignment = NSTextAlignmentCenter; 81 | self.lastUpdateLabel.textColor = textcolor; 82 | self.lastUpdateLabel.font = [UIFont systemFontOfSize:10]; 83 | self.lastUpdateLabel.alpha = 0.0; 84 | [self addSubview:self.lastUpdateLabel]; 85 | [self setTranslatesAutoresizingMaskIntoConstraints:NO]; 86 | NSLayoutConstraint * consstraint1 = [NSLayoutConstraint constraintWithItem:self 87 | attribute:NSLayoutAttributeCenterX 88 | relatedBy:NSLayoutRelationEqual 89 | toItem:scrollview 90 | attribute:NSLayoutAttributeCenterX 91 | multiplier:1.0 92 | constant:0.0]; 93 | NSLayoutConstraint * consstraint2 = [NSLayoutConstraint constraintWithItem:self 94 | attribute:NSLayoutAttributeBottom 95 | relatedBy:NSLayoutRelationEqual 96 | toItem:scrollview 97 | attribute:NSLayoutAttributeTop 98 | multiplier:1.0 99 | constant:-1 * scrollview.contentInset.top]; 100 | NSLayoutConstraint * consstraint3 = [NSLayoutConstraint constraintWithItem:self 101 | attribute:NSLayoutAttributeWidth 102 | relatedBy:NSLayoutRelationEqual 103 | toItem:nil 104 | attribute:NSLayoutAttributeWidth 105 | multiplier:1.0 106 | constant:[UIScreen mainScreen].bounds.size.width]; 107 | NSLayoutConstraint * consstraint4 = [NSLayoutConstraint constraintWithItem:self 108 | attribute:NSLayoutAttributeHeight 109 | relatedBy:NSLayoutRelationEqual 110 | toItem:nil 111 | attribute:NSLayoutAttributeHeight 112 | multiplier:1.0 113 | constant:defaultPullHeight]; 114 | [scrollview addConstraints:@[consstraint1,consstraint2,consstraint3,consstraint4]]; 115 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(orientationDidChanged:) 116 | name:UIDeviceOrientationDidChangeNotification 117 | object:nil]; 118 | } 119 | return self; 120 | } 121 | -(void)orientationDidChanged:(NSNotification *)notification 122 | { 123 | if (self.state== WCPullRefreshControlStateIdle) { 124 | self.originalOffset = 0; 125 | }if(self.state == WCPullRefreshControlStateRefreshing){ 126 | self.originalOffset = self.attachedScrollView.contentInset.top - defaultPullHeight; 127 | } 128 | } 129 | 130 | -(void)updateWhenScrollDidEndDraging{ 131 | if ([self currentProgress] >=1 && self.state == WCPullRefreshControlStateIdle) { 132 | self.state = WCPullRefreshControlStateRefreshing; 133 | self.refreshingItem.hidden = NO; 134 | self.progressItem.hidden = YES; 135 | [self.refreshingItem startAnimating]; 136 | CGPoint currentOffset = self.attachedScrollView.contentOffset; 137 | self.attachedScrollView.contentInset = UIEdgeInsetsMake(defaultPullHeight+self.originalOffset,0,0,0); 138 | self.attachedScrollView.contentOffset = currentOffset; 139 | self.lastUpdateLabel.text = @"Updating..."; 140 | if (self.refreshAction) { 141 | self.refreshAction(); 142 | } 143 | if ([self.delegate respondsToSelector:@selector(DidStartRefreshingWithScrollview:)]) { 144 | [self.delegate DidStartRefreshingWithScrollview:self.attachedScrollView]; 145 | } 146 | } 147 | } 148 | -(void)updateWhenScrollviewScroll{ 149 | if (self.state == WCPullRefreshControlStateIdle) { 150 | if (self.originalOffset == 0) { 151 | self.originalOffset = self.attachedScrollView.contentInset.top; 152 | } 153 | self.progressItem.progress = [self currentProgress]; 154 | self.lastUpdateLabel.alpha = [self currentProgress]; 155 | self.progressItem.alpha = [self currentProgress]; 156 | if (self.showLastUpdate) { 157 | self.lastUpdateLabel.text = [NSDate stringFromLastdate:self.lastUpdateDate]; 158 | }else{ 159 | if ([self currentProgress] < 1.0) { 160 | self.lastUpdateLabel.text = @"Pull to update..."; 161 | }else{ 162 | self.lastUpdateLabel.text = @"Release to update..."; 163 | } 164 | } 165 | } 166 | } 167 | -(void)manualStartRefreshingWithAction{ 168 | [UIView animateWithDuration:0.8 169 | animations:^{ 170 | self.attachedScrollView.contentOffset = CGPointMake(0,-1 * self.attachedScrollView.contentInset.top - self.pullHeight); 171 | 172 | } completion:^(BOOL finished) { 173 | [self updateWhenScrollDidEndDraging]; 174 | // action(); 175 | }]; 176 | } 177 | -(void)finishRefreshingSuccessully:(BOOL)success{ 178 | [self.refreshingItem stopAnimating]; 179 | self.state = WCPullRefreshControlStateDisappearing; 180 | if (success) { 181 | self.lastUpdateDate = [NSDate date]; 182 | self.lastUpdateLabel.text = @"Succeed to update"; 183 | }else{ 184 | self.lastUpdateLabel.text = @"Fail to update"; 185 | } 186 | [UIView animateWithDuration:0.8 animations:^{ 187 | self.attachedScrollView.contentInset = UIEdgeInsetsMake(self.originalOffset,0,0,0); 188 | } completion:^(BOOL finished) { 189 | self.refreshingItem.hidden = YES; 190 | self.progressItem.hidden = NO; 191 | self.state = WCPullRefreshControlStateIdle; 192 | self.originalOffset = 0.0; 193 | }]; 194 | } 195 | -(CGFloat)currentProgress{ 196 | return MIN(1.0,MAX(0,-1*(self.attachedScrollView.contentOffset.y + self.originalOffset)/self.pullHeight)); 197 | } 198 | -(void)dealloc{ 199 | [[NSNotificationCenter defaultCenter] removeObserver:self forKeyPath:UIDeviceOrientationDidChangeNotification]; 200 | [self removeFromSuperview]; 201 | } 202 | @end 203 | -------------------------------------------------------------------------------- /WCPullRefreshControlExample/classes/WCRefreshingItem.h: -------------------------------------------------------------------------------- 1 | // 2 | // WCRefreshingItem.h 3 | // WCPullRefreshControl 4 | // 5 | // Created by huangwenchen on 15/4/11. 6 | // Copyright (c) 2015年 huangwenchen. All rights reserved. 7 | // 8 | 9 | #import 10 | typedef NS_ENUM(NSUInteger, WCRefreshingItemType) { 11 | WCRefreshingItemTypeSystemIndicator, 12 | WCRefreshingItemTypeRoundCircle, 13 | WCRefreshingItemTypeStar, 14 | WCRefreshingItemTypeMagicSquare, 15 | WCRefreshingItemTypeGradientCircle, 16 | 17 | }; 18 | @interface WCRefreshingItem : UIView 19 | -(instancetype)initWithFrame:(CGRect)frame Type:(WCRefreshingItemType)type Color:(UIColor *)color; 20 | -(void)startAnimating; 21 | -(void)stopAnimating; 22 | @end 23 | -------------------------------------------------------------------------------- /WCPullRefreshControlExample/classes/WCRefreshingItem.m: -------------------------------------------------------------------------------- 1 | // 2 | // WCRefreshingItem.m 3 | // WCPullRefreshControl 4 | // 5 | // Created by huangwenchen on 15/4/11. 6 | // Copyright (c) 2015年 huangwenchen. All rights reserved. 7 | // 8 | 9 | #import "WCRefreshingItem.h" 10 | #import "CAShapeLayer+WCPullRefresh.h" 11 | #import "WCMagicSquareView.h" 12 | #import "WCGraintCircleLayer.h" 13 | @interface WCRefreshingItem() 14 | 15 | @property (strong,nonatomic)UIActivityIndicatorView * spinner; 16 | @property (strong,nonatomic)CAShapeLayer * shapelayer; 17 | @property (nonatomic)WCRefreshingItemType type; 18 | @property (strong,nonatomic) WCMagicSquareView * squareview; 19 | @property (strong,nonatomic) WCGraintCircleLayer * graintlayer; 20 | @end 21 | 22 | @implementation WCRefreshingItem 23 | 24 | -(instancetype)initWithFrame:(CGRect)frame Type:(WCRefreshingItemType)type Color:(UIColor *)color{ 25 | if (self = [super initWithFrame:frame]) { 26 | self.type = type; 27 | switch (type) { 28 | case WCRefreshingItemTypeSystemIndicator: 29 | self.spinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray]; 30 | [self.spinner setColor:color]; 31 | self.spinner.frame =self.bounds; 32 | self.spinner.hidesWhenStopped = NO; 33 | [self addSubview:self.spinner]; 34 | break; 35 | case WCRefreshingItemTypeRoundCircle: 36 | self.shapelayer = [CAShapeLayer createCircleWithBounds: CGRectMake(0,0,frame.size.width,frame.size.height) 37 | Position: CGPointMake(frame.size.width/2,frame.size.height/2) 38 | StrokeColor: color 39 | LineWidth:2.0]; 40 | self.shapelayer.strokeStart = 0.0; 41 | self.shapelayer.strokeEnd = 0.9; 42 | [self.layer addSublayer:self.shapelayer]; 43 | break; 44 | case WCRefreshingItemTypeStar: 45 | self.shapelayer = [CAShapeLayer create25_25StarLayerWithStrokeColor:color LineWidth:2.0]; 46 | [self.layer addSublayer:self.shapelayer]; 47 | break; 48 | case WCRefreshingItemTypeMagicSquare: 49 | self.squareview = [[WCMagicSquareView alloc] initWithProgress:1.0 Color:color MaxWidth:320]; 50 | self.frame = CGRectMake(0,0,320,20); 51 | [self addSubview:self.squareview]; 52 | break; 53 | case WCRefreshingItemTypeGradientCircle: 54 | self.graintlayer = [[WCGraintCircleLayer alloc] initGraintCircleWithBounds:CGRectMake(0, 0, frame.size.width, frame.size.height) 55 | Position:CGPointMake(CGRectGetWidth(frame)/2, CGRectGetHeight(frame)/2) 56 | FromColor:[UIColor clearColor] 57 | ToColor:color 58 | LineWidth:3.0]; 59 | [self.layer addSublayer:self.graintlayer]; 60 | break; 61 | default: 62 | break; 63 | } 64 | 65 | } 66 | return self; 67 | } 68 | -(void)startAnimating{ 69 | CAKeyframeAnimation * animation = [CAKeyframeAnimation animation]; 70 | animation.keyPath = @"transform"; 71 | animation.values = @[[self transformWithRotation:M_PI* 0.0], 72 | [self transformWithRotation:M_PI* 0.5], 73 | [self transformWithRotation:M_PI], 74 | [self transformWithRotation:M_PI * 1.5], 75 | [self transformWithRotation:2*M_PI]]; 76 | animation.duration = 1.0; 77 | animation.repeatCount = INFINITY; 78 | animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]; 79 | 80 | switch (self.type) { 81 | case WCRefreshingItemTypeSystemIndicator: 82 | [self.spinner startAnimating]; 83 | break; 84 | case WCRefreshingItemTypeMagicSquare: 85 | [self.squareview startAnimating]; 86 | break; 87 | case WCRefreshingItemTypeGradientCircle: 88 | [self.graintlayer addAnimation:animation forKey:@"rotate"]; 89 | break; 90 | case WCRefreshingItemTypeRoundCircle: 91 | case WCRefreshingItemTypeStar: 92 | [self.shapelayer addAnimation:animation forKey:@"rotate"]; 93 | 94 | break; 95 | default: 96 | break; 97 | } 98 | } 99 | -(NSValue *)transformWithRotation:(CGFloat)rotate{ 100 | return [NSValue valueWithCATransform3D:CATransform3DMakeRotation(rotate,0,0,1)]; 101 | } 102 | -(void)stopAnimating{ 103 | switch (self.type) { 104 | case WCRefreshingItemTypeSystemIndicator: 105 | [self.spinner stopAnimating]; 106 | break; 107 | case WCRefreshingItemTypeMagicSquare: 108 | [self.squareview stopAnimating]; 109 | break; 110 | case WCRefreshingItemTypeGradientCircle: 111 | case WCRefreshingItemTypeRoundCircle: 112 | case WCRefreshingItemTypeStar: 113 | [self.shapelayer removeAnimationForKey:@"rotate"]; 114 | 115 | break; 116 | default: 117 | break; 118 | } 119 | } 120 | @end 121 | -------------------------------------------------------------------------------- /WCPullRefreshControlExample/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // WCPullRefreshControlExample 4 | // 5 | // Created by huangwenchen on 15/4/14. 6 | // Copyright (c) 2015年 huangwenchen. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "AppDelegate.h" 11 | 12 | int main(int argc, char * argv[]) { 13 | @autoreleasepool { 14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /WCPullRefreshControlExampleTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | huangwenchen.$(PRODUCT_NAME:rfc1034identifier) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /WCPullRefreshControlExampleTests/WCPullRefreshControlExampleTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // WCPullRefreshControlExampleTests.m 3 | // WCPullRefreshControlExampleTests 4 | // 5 | // Created by huangwenchen on 15/4/14. 6 | // Copyright (c) 2015年 huangwenchen. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @interface WCPullRefreshControlExampleTests : XCTestCase 13 | 14 | @end 15 | 16 | @implementation WCPullRefreshControlExampleTests 17 | 18 | - (void)setUp { 19 | [super setUp]; 20 | // Put setup code here. This method is called before the invocation of each test method in the class. 21 | } 22 | 23 | - (void)tearDown { 24 | // Put teardown code here. This method is called after the invocation of each test method in the class. 25 | [super tearDown]; 26 | } 27 | 28 | - (void)testExample { 29 | // This is an example of a functional test case. 30 | XCTAssert(YES, @"Pass"); 31 | } 32 | 33 | - (void)testPerformanceExample { 34 | // This is an example of a performance test case. 35 | [self measureBlock:^{ 36 | // Put the code you want to measure the time of here. 37 | }]; 38 | } 39 | 40 | @end 41 | --------------------------------------------------------------------------------