├── .gitignore ├── CBStoreHouseRefreshControl.podspec ├── CBStoreHouseRefreshControl.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── CBStoreHouseRefreshControl.xccheckout └── xcshareddata │ └── xcschemes │ └── CBStoreHouseRefreshControl.xcscheme ├── CBStoreHouseRefreshControl ├── AKTA.plist ├── AppDelegate.h ├── AppDelegate.m ├── Base.lproj │ └── LaunchScreen.xib ├── ContentViewController.h ├── ContentViewController.m ├── Images.xcassets │ ├── AppIcon.appiconset │ │ └── Contents.json │ ├── bg_pattern.imageset │ │ ├── Contents.json │ │ └── bg_pattern@2x.png │ └── cell.imageset │ │ ├── Contents.json │ │ └── cell@2x.png ├── Info.plist ├── main.m └── storehouse.plist ├── CBStoreHouseRefreshControlTests ├── CBStoreHouseRefreshControlTests.m └── Info.plist ├── Class ├── BarItem.h ├── BarItem.m ├── CBStoreHouseRefreshControl.h └── CBStoreHouseRefreshControl.m ├── LICENSE └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | ######################### 2 | # .gitignore file for Xcode4 / OS X Source projects 3 | # 4 | # For latest version, see: http://stackoverflow.com/questions/49478/git-ignore-file-for-xcode-projects 5 | # NB: if you are storing "built" products, this WILL NOT WORK, 6 | # and you should use a different .gitignore (or none at all) 7 | # This file is for SOURCE projects, where there are many extra 8 | # files that we want to exclude 9 | # 10 | ######################### 11 | 12 | ##### 13 | # OS X temporary files that should never be committed 14 | # 15 | # c.f. http://www.westwind.com/reference/os-x/invisibles.html 16 | # *.lock - this is used and abused by many editors for many different things, so YMMV 17 | 18 | .DS_Store 19 | .Trashes 20 | *.swp 21 | *.lock 22 | profile 23 | cocos2d-x-2.2 24 | 25 | 26 | #### 27 | # Xcode temporary files that should never be committed 28 | # 29 | # NIB/XIB files still exist even on Storyboard projects, so we want this... 30 | 31 | *~.nib 32 | 33 | 34 | #### 35 | # Xcode build files - 36 | # 37 | # NB: slash on the end, so we only remove the FOLDER, not any files that were badly named "DerivedData" or "build" 38 | 39 | */DerivedData/* 40 | */build/* 41 | 42 | 43 | ##### 44 | # Xcode private settings (window sizes, bookmarks, breakpoints, custom executables, smart groups) 45 | # 46 | # This is complicated: 47 | # 48 | # SOMETIMES you need to put this file in version control. 49 | # Apple designed it poorly - if you use "custom executables", they are saved in this file. 50 | # 51 | # 99% of projects do NOT use those, so they do NOT want to version control this file. 52 | # ..but if you're in the 1%, comment out the line "*.pbxuser" 53 | # 54 | # .pbxuser: http://lists.apple.com/archives/xcode-users/2004/Jan/msg00193.html 55 | # .mode1v3: http://lists.apple.com/archives/xcode-users/2007/Oct/msg00465.html 56 | # .mode2v3: http://lists.apple.com/archives/xcode-users/2007/Oct/msg00465.html 57 | # .perspectivev3: http://stackoverflow.com/questions/5223297/xcode-projects-what-is-a-perspectivev3-file 58 | 59 | *.pbxuser 60 | *.mode1v3 61 | *.mode2v3 62 | *.perspectivev3 63 | !default.pbxuser 64 | !default.mode1v3 65 | !default.mode2v3 66 | !default.perspectivev3 67 | 68 | 69 | #### 70 | # Xcode 4 - semi-personal settings 71 | # 72 | # 73 | # OPTION 1: --------------------------------- 74 | # throw away ALL personal settings (including custom schemes! 75 | # - unless they are "shared") 76 | # 77 | # NB: this is exclusive with OPTION 2 below 78 | 79 | xcuserdata 80 | 81 | # OPTION 2: --------------------------------- 82 | # get rid of ALL personal settings, but KEEP SOME OF THEM 83 | # - NB: you must manually uncomment the bits you want to keep 84 | # 85 | # NB: this is exclusive with OPTION 1 above 86 | # 87 | #xcuserdata/**/* 88 | 89 | # (requires option 2 above): Personal Schemes 90 | # 91 | #!xcuserdata/**/xcschemes/* 92 | 93 | 94 | #### 95 | # XCode 4 workspaces - more detailed 96 | # 97 | # Workspaces are important! They are a core feature of Xcode - don't exclude them :) 98 | # 99 | # Workspace layout is quite spammy. For reference: 100 | # 101 | # /(root)/ 102 | # /(project-name).xcodeproj/ 103 | # project.pbxproj 104 | # /project.xcworkspace/ 105 | # contents.xcworkspacedata 106 | # /xcuserdata/ 107 | # /(your name)/xcuserdatad/ 108 | # UserInterfaceState.xcuserstate 109 | # /xcsshareddata/ 110 | # /xcschemes/ 111 | # (shared scheme name).xcscheme 112 | # /xcuserdata/ 113 | # /(your name)/xcuserdatad/ 114 | # (private scheme).xcscheme 115 | # xcschememanagement.plist 116 | # 117 | # 118 | 119 | 120 | #### 121 | # Xcode 4 - Deprecated classes 122 | # 123 | # Allegedly, if you manually "deprecate" your classes, they get moved here. 124 | # 125 | # We're using source-control, so this is a "feature" that we do not want! 126 | 127 | *.moved-aside 128 | 129 | 130 | #### 131 | # Cocoapods: cocoapods.org 132 | # 133 | # Ignoring these files means that whoever uses the code will first have to run: 134 | # pod install 135 | # in the App.xcodeproj directory. 136 | # This ensures the latest dependencies are used. 137 | 138 | Pods/* 139 | Podfile.lock 140 | 141 | 142 | #### 143 | # Injection For XCode: injectionforxcode.com 144 | # 145 | # Repo: github.com/johnno1962/injectionforxcode 146 | 147 | iOSInjectionProject/* -------------------------------------------------------------------------------- /CBStoreHouseRefreshControl.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = "CBStoreHouseRefreshControl" 3 | s.version = "1.0" 4 | s.summary = "Fully customizable pull-to-refresh control inspired by Storehouse iOS app" 5 | s.description = <<-DESC 6 | A fully customizable pull-to-refresh control for iOS inspired by Storehouse iOS app. 7 | You can use any shape through a plist file. 8 | DESC 9 | s.homepage = "https://github.com/coolbeet/CBStoreHouseRefreshControl" 10 | s.screenshots = "https://s3.amazonaws.com/suyu.test/CBStoreHouseRefreshControl1.gif", "https://s3.amazonaws.com/suyu.test/CBStoreHouseRefreshControl2.gif" 11 | s.license = { :type => "MIT", :file => "LICENSE" } 12 | s.author = { "Suyu Zhang" => "suyu_zhang@hotmail.com" } 13 | s.source = { :git => "https://github.com/coolbeet/CBStoreHouseRefreshControl.git", :tag => "1.0" } 14 | s.social_media_url = "http://twitter.com/coolbeet11" 15 | s.platform = :ios, '7.0' 16 | s.requires_arc = true 17 | s.source_files = 'Class' 18 | end 19 | -------------------------------------------------------------------------------- /CBStoreHouseRefreshControl.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 0BFB9BAA1A084144008C790A /* CBStoreHouseRefreshControl.m in Sources */ = {isa = PBXBuildFile; fileRef = 0BFB9BA91A084144008C790A /* CBStoreHouseRefreshControl.m */; }; 11 | FF6F542D1A086CC200BE5C52 /* storehouse.plist in Resources */ = {isa = PBXBuildFile; fileRef = FF6F542C1A086CC200BE5C52 /* storehouse.plist */; }; 12 | FFB290C919FCC1320058F2BF /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = FFB290C819FCC1320058F2BF /* main.m */; }; 13 | FFB290CC19FCC1320058F2BF /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = FFB290CB19FCC1320058F2BF /* AppDelegate.m */; }; 14 | FFB290CF19FCC1320058F2BF /* ContentViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = FFB290CE19FCC1320058F2BF /* ContentViewController.m */; }; 15 | FFB290D419FCC1320058F2BF /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = FFB290D319FCC1320058F2BF /* Images.xcassets */; }; 16 | FFB290D719FCC1320058F2BF /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = FFB290D519FCC1320058F2BF /* LaunchScreen.xib */; }; 17 | FFB290E319FCC1320058F2BF /* CBStoreHouseRefreshControlTests.m in Sources */ = {isa = PBXBuildFile; fileRef = FFB290E219FCC1320058F2BF /* CBStoreHouseRefreshControlTests.m */; }; 18 | FFFB8C961A02044C0007988E /* BarItem.m in Sources */ = {isa = PBXBuildFile; fileRef = FFFB8C951A02044C0007988E /* BarItem.m */; }; 19 | FFFB8C9C1A0325D50007988E /* AKTA.plist in Resources */ = {isa = PBXBuildFile; fileRef = FFFB8C9B1A0325D50007988E /* AKTA.plist */; }; 20 | /* End PBXBuildFile section */ 21 | 22 | /* Begin PBXContainerItemProxy section */ 23 | FFB290DD19FCC1320058F2BF /* PBXContainerItemProxy */ = { 24 | isa = PBXContainerItemProxy; 25 | containerPortal = FFB290BB19FCC1320058F2BF /* Project object */; 26 | proxyType = 1; 27 | remoteGlobalIDString = FFB290C219FCC1320058F2BF; 28 | remoteInfo = CBStoreHousePullToRefresh; 29 | }; 30 | /* End PBXContainerItemProxy section */ 31 | 32 | /* Begin PBXFileReference section */ 33 | 0BFB9BA91A084144008C790A /* CBStoreHouseRefreshControl.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = CBStoreHouseRefreshControl.m; path = Class/CBStoreHouseRefreshControl.m; sourceTree = ""; }; 34 | FF6F542C1A086CC200BE5C52 /* storehouse.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = storehouse.plist; sourceTree = ""; }; 35 | FFB290C319FCC1320058F2BF /* CBStoreHouseRefreshControl.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = CBStoreHouseRefreshControl.app; sourceTree = BUILT_PRODUCTS_DIR; }; 36 | FFB290C719FCC1320058F2BF /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = ""; }; 37 | FFB290C819FCC1320058F2BF /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 38 | FFB290CA19FCC1320058F2BF /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 39 | FFB290CB19FCC1320058F2BF /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 40 | FFB290CD19FCC1320058F2BF /* ContentViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ContentViewController.h; sourceTree = ""; }; 41 | FFB290CE19FCC1320058F2BF /* ContentViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ContentViewController.m; sourceTree = ""; }; 42 | FFB290D319FCC1320058F2BF /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 43 | FFB290D619FCC1320058F2BF /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; 44 | FFB290DC19FCC1320058F2BF /* CBStoreHouseRefreshControlTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = CBStoreHouseRefreshControlTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 45 | FFB290E119FCC1320058F2BF /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 46 | FFB290E219FCC1320058F2BF /* CBStoreHouseRefreshControlTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CBStoreHouseRefreshControlTests.m; sourceTree = ""; }; 47 | FFFB8C941A02044C0007988E /* BarItem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BarItem.h; path = Class/BarItem.h; sourceTree = ""; }; 48 | FFFB8C951A02044C0007988E /* BarItem.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = BarItem.m; path = Class/BarItem.m; sourceTree = ""; }; 49 | FFFB8C981A02F7DC0007988E /* CBStoreHouseRefreshControl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CBStoreHouseRefreshControl.h; path = Class/CBStoreHouseRefreshControl.h; sourceTree = ""; }; 50 | FFFB8C9B1A0325D50007988E /* AKTA.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist; path = AKTA.plist; sourceTree = ""; }; 51 | /* End PBXFileReference section */ 52 | 53 | /* Begin PBXFrameworksBuildPhase section */ 54 | FFB290C019FCC1320058F2BF /* Frameworks */ = { 55 | isa = PBXFrameworksBuildPhase; 56 | buildActionMask = 2147483647; 57 | files = ( 58 | ); 59 | runOnlyForDeploymentPostprocessing = 0; 60 | }; 61 | FFB290D919FCC1320058F2BF /* Frameworks */ = { 62 | isa = PBXFrameworksBuildPhase; 63 | buildActionMask = 2147483647; 64 | files = ( 65 | ); 66 | runOnlyForDeploymentPostprocessing = 0; 67 | }; 68 | /* End PBXFrameworksBuildPhase section */ 69 | 70 | /* Begin PBXGroup section */ 71 | FFB290BA19FCC1320058F2BF = { 72 | isa = PBXGroup; 73 | children = ( 74 | FFFB8C971A0204520007988E /* Class */, 75 | FFB290C519FCC1320058F2BF /* CBStoreHouseRefreshControl */, 76 | FFB290DF19FCC1320058F2BF /* CBStoreHouseRefreshControl Tests */, 77 | FFB290C419FCC1320058F2BF /* Products */, 78 | ); 79 | sourceTree = ""; 80 | }; 81 | FFB290C419FCC1320058F2BF /* Products */ = { 82 | isa = PBXGroup; 83 | children = ( 84 | FFB290C319FCC1320058F2BF /* CBStoreHouseRefreshControl.app */, 85 | FFB290DC19FCC1320058F2BF /* CBStoreHouseRefreshControlTests.xctest */, 86 | ); 87 | name = Products; 88 | sourceTree = ""; 89 | }; 90 | FFB290C519FCC1320058F2BF /* CBStoreHouseRefreshControl */ = { 91 | isa = PBXGroup; 92 | children = ( 93 | FFFB8C9B1A0325D50007988E /* AKTA.plist */, 94 | FF6F542C1A086CC200BE5C52 /* storehouse.plist */, 95 | FFB290CA19FCC1320058F2BF /* AppDelegate.h */, 96 | FFB290CB19FCC1320058F2BF /* AppDelegate.m */, 97 | FFB290CD19FCC1320058F2BF /* ContentViewController.h */, 98 | FFB290CE19FCC1320058F2BF /* ContentViewController.m */, 99 | FFB290D319FCC1320058F2BF /* Images.xcassets */, 100 | FFB290D519FCC1320058F2BF /* LaunchScreen.xib */, 101 | FFB290C619FCC1320058F2BF /* Supporting Files */, 102 | ); 103 | path = CBStoreHouseRefreshControl; 104 | sourceTree = ""; 105 | }; 106 | FFB290C619FCC1320058F2BF /* Supporting Files */ = { 107 | isa = PBXGroup; 108 | children = ( 109 | FFB290C719FCC1320058F2BF /* Info.plist */, 110 | FFB290C819FCC1320058F2BF /* main.m */, 111 | ); 112 | name = "Supporting Files"; 113 | sourceTree = ""; 114 | }; 115 | FFB290DF19FCC1320058F2BF /* CBStoreHouseRefreshControl Tests */ = { 116 | isa = PBXGroup; 117 | children = ( 118 | FFB290E219FCC1320058F2BF /* CBStoreHouseRefreshControlTests.m */, 119 | FFB290E019FCC1320058F2BF /* Supporting Files */, 120 | ); 121 | name = "CBStoreHouseRefreshControl Tests"; 122 | path = CBStoreHouseRefreshControlTests; 123 | sourceTree = ""; 124 | }; 125 | FFB290E019FCC1320058F2BF /* Supporting Files */ = { 126 | isa = PBXGroup; 127 | children = ( 128 | FFB290E119FCC1320058F2BF /* Info.plist */, 129 | ); 130 | name = "Supporting Files"; 131 | sourceTree = ""; 132 | }; 133 | FFFB8C971A0204520007988E /* Class */ = { 134 | isa = PBXGroup; 135 | children = ( 136 | FFFB8C941A02044C0007988E /* BarItem.h */, 137 | FFFB8C951A02044C0007988E /* BarItem.m */, 138 | FFFB8C981A02F7DC0007988E /* CBStoreHouseRefreshControl.h */, 139 | 0BFB9BA91A084144008C790A /* CBStoreHouseRefreshControl.m */, 140 | ); 141 | name = Class; 142 | sourceTree = ""; 143 | }; 144 | /* End PBXGroup section */ 145 | 146 | /* Begin PBXNativeTarget section */ 147 | FFB290C219FCC1320058F2BF /* CBStoreHouseRefreshControl */ = { 148 | isa = PBXNativeTarget; 149 | buildConfigurationList = FFB290E619FCC1320058F2BF /* Build configuration list for PBXNativeTarget "CBStoreHouseRefreshControl" */; 150 | buildPhases = ( 151 | FFB290BF19FCC1320058F2BF /* Sources */, 152 | FFB290C019FCC1320058F2BF /* Frameworks */, 153 | FFB290C119FCC1320058F2BF /* Resources */, 154 | ); 155 | buildRules = ( 156 | ); 157 | dependencies = ( 158 | ); 159 | name = CBStoreHouseRefreshControl; 160 | productName = CBStoreHousePullToRefresh; 161 | productReference = FFB290C319FCC1320058F2BF /* CBStoreHouseRefreshControl.app */; 162 | productType = "com.apple.product-type.application"; 163 | }; 164 | FFB290DB19FCC1320058F2BF /* CBStoreHouseRefreshControlTests */ = { 165 | isa = PBXNativeTarget; 166 | buildConfigurationList = FFB290E919FCC1320058F2BF /* Build configuration list for PBXNativeTarget "CBStoreHouseRefreshControlTests" */; 167 | buildPhases = ( 168 | FFB290D819FCC1320058F2BF /* Sources */, 169 | FFB290D919FCC1320058F2BF /* Frameworks */, 170 | FFB290DA19FCC1320058F2BF /* Resources */, 171 | ); 172 | buildRules = ( 173 | ); 174 | dependencies = ( 175 | FFB290DE19FCC1320058F2BF /* PBXTargetDependency */, 176 | ); 177 | name = CBStoreHouseRefreshControlTests; 178 | productName = CBStoreHousePullToRefreshTests; 179 | productReference = FFB290DC19FCC1320058F2BF /* CBStoreHouseRefreshControlTests.xctest */; 180 | productType = "com.apple.product-type.bundle.unit-test"; 181 | }; 182 | /* End PBXNativeTarget section */ 183 | 184 | /* Begin PBXProject section */ 185 | FFB290BB19FCC1320058F2BF /* Project object */ = { 186 | isa = PBXProject; 187 | attributes = { 188 | LastUpgradeCheck = 0610; 189 | ORGANIZATIONNAME = "Suyu Zhang"; 190 | TargetAttributes = { 191 | FFB290C219FCC1320058F2BF = { 192 | CreatedOnToolsVersion = 6.1; 193 | }; 194 | FFB290DB19FCC1320058F2BF = { 195 | CreatedOnToolsVersion = 6.1; 196 | TestTargetID = FFB290C219FCC1320058F2BF; 197 | }; 198 | }; 199 | }; 200 | buildConfigurationList = FFB290BE19FCC1320058F2BF /* Build configuration list for PBXProject "CBStoreHouseRefreshControl" */; 201 | compatibilityVersion = "Xcode 3.2"; 202 | developmentRegion = English; 203 | hasScannedForEncodings = 0; 204 | knownRegions = ( 205 | en, 206 | Base, 207 | ); 208 | mainGroup = FFB290BA19FCC1320058F2BF; 209 | productRefGroup = FFB290C419FCC1320058F2BF /* Products */; 210 | projectDirPath = ""; 211 | projectRoot = ""; 212 | targets = ( 213 | FFB290C219FCC1320058F2BF /* CBStoreHouseRefreshControl */, 214 | FFB290DB19FCC1320058F2BF /* CBStoreHouseRefreshControlTests */, 215 | ); 216 | }; 217 | /* End PBXProject section */ 218 | 219 | /* Begin PBXResourcesBuildPhase section */ 220 | FFB290C119FCC1320058F2BF /* Resources */ = { 221 | isa = PBXResourcesBuildPhase; 222 | buildActionMask = 2147483647; 223 | files = ( 224 | FFFB8C9C1A0325D50007988E /* AKTA.plist in Resources */, 225 | FFB290D719FCC1320058F2BF /* LaunchScreen.xib in Resources */, 226 | FFB290D419FCC1320058F2BF /* Images.xcassets in Resources */, 227 | FF6F542D1A086CC200BE5C52 /* storehouse.plist in Resources */, 228 | ); 229 | runOnlyForDeploymentPostprocessing = 0; 230 | }; 231 | FFB290DA19FCC1320058F2BF /* Resources */ = { 232 | isa = PBXResourcesBuildPhase; 233 | buildActionMask = 2147483647; 234 | files = ( 235 | ); 236 | runOnlyForDeploymentPostprocessing = 0; 237 | }; 238 | /* End PBXResourcesBuildPhase section */ 239 | 240 | /* Begin PBXSourcesBuildPhase section */ 241 | FFB290BF19FCC1320058F2BF /* Sources */ = { 242 | isa = PBXSourcesBuildPhase; 243 | buildActionMask = 2147483647; 244 | files = ( 245 | FFFB8C961A02044C0007988E /* BarItem.m in Sources */, 246 | FFB290CF19FCC1320058F2BF /* ContentViewController.m in Sources */, 247 | FFB290CC19FCC1320058F2BF /* AppDelegate.m in Sources */, 248 | 0BFB9BAA1A084144008C790A /* CBStoreHouseRefreshControl.m in Sources */, 249 | FFB290C919FCC1320058F2BF /* main.m in Sources */, 250 | ); 251 | runOnlyForDeploymentPostprocessing = 0; 252 | }; 253 | FFB290D819FCC1320058F2BF /* Sources */ = { 254 | isa = PBXSourcesBuildPhase; 255 | buildActionMask = 2147483647; 256 | files = ( 257 | FFB290E319FCC1320058F2BF /* CBStoreHouseRefreshControlTests.m in Sources */, 258 | ); 259 | runOnlyForDeploymentPostprocessing = 0; 260 | }; 261 | /* End PBXSourcesBuildPhase section */ 262 | 263 | /* Begin PBXTargetDependency section */ 264 | FFB290DE19FCC1320058F2BF /* PBXTargetDependency */ = { 265 | isa = PBXTargetDependency; 266 | target = FFB290C219FCC1320058F2BF /* CBStoreHouseRefreshControl */; 267 | targetProxy = FFB290DD19FCC1320058F2BF /* PBXContainerItemProxy */; 268 | }; 269 | /* End PBXTargetDependency section */ 270 | 271 | /* Begin PBXVariantGroup section */ 272 | FFB290D519FCC1320058F2BF /* LaunchScreen.xib */ = { 273 | isa = PBXVariantGroup; 274 | children = ( 275 | FFB290D619FCC1320058F2BF /* Base */, 276 | ); 277 | name = LaunchScreen.xib; 278 | sourceTree = ""; 279 | }; 280 | /* End PBXVariantGroup section */ 281 | 282 | /* Begin XCBuildConfiguration section */ 283 | FFB290E419FCC1320058F2BF /* Debug */ = { 284 | isa = XCBuildConfiguration; 285 | buildSettings = { 286 | ALWAYS_SEARCH_USER_PATHS = NO; 287 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 288 | CLANG_CXX_LIBRARY = "libc++"; 289 | CLANG_ENABLE_MODULES = YES; 290 | CLANG_ENABLE_OBJC_ARC = YES; 291 | CLANG_WARN_BOOL_CONVERSION = YES; 292 | CLANG_WARN_CONSTANT_CONVERSION = YES; 293 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 294 | CLANG_WARN_EMPTY_BODY = YES; 295 | CLANG_WARN_ENUM_CONVERSION = YES; 296 | CLANG_WARN_INT_CONVERSION = YES; 297 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 298 | CLANG_WARN_UNREACHABLE_CODE = YES; 299 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 300 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 301 | COPY_PHASE_STRIP = NO; 302 | ENABLE_STRICT_OBJC_MSGSEND = YES; 303 | GCC_C_LANGUAGE_STANDARD = gnu99; 304 | GCC_DYNAMIC_NO_PIC = NO; 305 | GCC_OPTIMIZATION_LEVEL = 0; 306 | GCC_PREPROCESSOR_DEFINITIONS = ( 307 | "DEBUG=1", 308 | "$(inherited)", 309 | ); 310 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 311 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 312 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 313 | GCC_WARN_UNDECLARED_SELECTOR = YES; 314 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 315 | GCC_WARN_UNUSED_FUNCTION = YES; 316 | GCC_WARN_UNUSED_VARIABLE = YES; 317 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 318 | MTL_ENABLE_DEBUG_INFO = YES; 319 | ONLY_ACTIVE_ARCH = YES; 320 | SDKROOT = iphoneos; 321 | }; 322 | name = Debug; 323 | }; 324 | FFB290E519FCC1320058F2BF /* Release */ = { 325 | isa = XCBuildConfiguration; 326 | buildSettings = { 327 | ALWAYS_SEARCH_USER_PATHS = NO; 328 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 329 | CLANG_CXX_LIBRARY = "libc++"; 330 | CLANG_ENABLE_MODULES = YES; 331 | CLANG_ENABLE_OBJC_ARC = YES; 332 | CLANG_WARN_BOOL_CONVERSION = YES; 333 | CLANG_WARN_CONSTANT_CONVERSION = YES; 334 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 335 | CLANG_WARN_EMPTY_BODY = YES; 336 | CLANG_WARN_ENUM_CONVERSION = YES; 337 | CLANG_WARN_INT_CONVERSION = YES; 338 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 339 | CLANG_WARN_UNREACHABLE_CODE = YES; 340 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 341 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 342 | COPY_PHASE_STRIP = YES; 343 | ENABLE_NS_ASSERTIONS = NO; 344 | ENABLE_STRICT_OBJC_MSGSEND = YES; 345 | GCC_C_LANGUAGE_STANDARD = gnu99; 346 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 347 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 348 | GCC_WARN_UNDECLARED_SELECTOR = YES; 349 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 350 | GCC_WARN_UNUSED_FUNCTION = YES; 351 | GCC_WARN_UNUSED_VARIABLE = YES; 352 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 353 | MTL_ENABLE_DEBUG_INFO = NO; 354 | SDKROOT = iphoneos; 355 | VALIDATE_PRODUCT = YES; 356 | }; 357 | name = Release; 358 | }; 359 | FFB290E719FCC1320058F2BF /* Debug */ = { 360 | isa = XCBuildConfiguration; 361 | buildSettings = { 362 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 363 | INFOPLIST_FILE = CBStoreHouseRefreshControl/Info.plist; 364 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 365 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 366 | PRODUCT_NAME = CBStoreHouseRefreshControl; 367 | }; 368 | name = Debug; 369 | }; 370 | FFB290E819FCC1320058F2BF /* Release */ = { 371 | isa = XCBuildConfiguration; 372 | buildSettings = { 373 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 374 | INFOPLIST_FILE = CBStoreHouseRefreshControl/Info.plist; 375 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 376 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 377 | PRODUCT_NAME = CBStoreHouseRefreshControl; 378 | }; 379 | name = Release; 380 | }; 381 | FFB290EA19FCC1320058F2BF /* Debug */ = { 382 | isa = XCBuildConfiguration; 383 | buildSettings = { 384 | BUNDLE_LOADER = "$(TEST_HOST)"; 385 | FRAMEWORK_SEARCH_PATHS = ( 386 | "$(SDKROOT)/Developer/Library/Frameworks", 387 | "$(inherited)", 388 | ); 389 | GCC_PREPROCESSOR_DEFINITIONS = ( 390 | "DEBUG=1", 391 | "$(inherited)", 392 | ); 393 | INFOPLIST_FILE = CBStoreHouseRefreshControl/Info.plist; 394 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 395 | PRODUCT_NAME = CBStoreHouseRefreshControlTests; 396 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/CBStoreHouseRefreshControl.app/CBStoreHouseRefreshControl"; 397 | }; 398 | name = Debug; 399 | }; 400 | FFB290EB19FCC1320058F2BF /* Release */ = { 401 | isa = XCBuildConfiguration; 402 | buildSettings = { 403 | BUNDLE_LOADER = "$(TEST_HOST)"; 404 | FRAMEWORK_SEARCH_PATHS = ( 405 | "$(SDKROOT)/Developer/Library/Frameworks", 406 | "$(inherited)", 407 | ); 408 | INFOPLIST_FILE = CBStoreHouseRefreshControl/Info.plist; 409 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 410 | PRODUCT_NAME = CBStoreHouseRefreshControlTests; 411 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/CBStoreHouseRefreshControl.app/CBStoreHouseRefreshControl"; 412 | }; 413 | name = Release; 414 | }; 415 | /* End XCBuildConfiguration section */ 416 | 417 | /* Begin XCConfigurationList section */ 418 | FFB290BE19FCC1320058F2BF /* Build configuration list for PBXProject "CBStoreHouseRefreshControl" */ = { 419 | isa = XCConfigurationList; 420 | buildConfigurations = ( 421 | FFB290E419FCC1320058F2BF /* Debug */, 422 | FFB290E519FCC1320058F2BF /* Release */, 423 | ); 424 | defaultConfigurationIsVisible = 0; 425 | defaultConfigurationName = Release; 426 | }; 427 | FFB290E619FCC1320058F2BF /* Build configuration list for PBXNativeTarget "CBStoreHouseRefreshControl" */ = { 428 | isa = XCConfigurationList; 429 | buildConfigurations = ( 430 | FFB290E719FCC1320058F2BF /* Debug */, 431 | FFB290E819FCC1320058F2BF /* Release */, 432 | ); 433 | defaultConfigurationIsVisible = 0; 434 | defaultConfigurationName = Release; 435 | }; 436 | FFB290E919FCC1320058F2BF /* Build configuration list for PBXNativeTarget "CBStoreHouseRefreshControlTests" */ = { 437 | isa = XCConfigurationList; 438 | buildConfigurations = ( 439 | FFB290EA19FCC1320058F2BF /* Debug */, 440 | FFB290EB19FCC1320058F2BF /* Release */, 441 | ); 442 | defaultConfigurationIsVisible = 0; 443 | defaultConfigurationName = Release; 444 | }; 445 | /* End XCConfigurationList section */ 446 | }; 447 | rootObject = FFB290BB19FCC1320058F2BF /* Project object */; 448 | } 449 | -------------------------------------------------------------------------------- /CBStoreHouseRefreshControl.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /CBStoreHouseRefreshControl.xcodeproj/project.xcworkspace/xcshareddata/CBStoreHouseRefreshControl.xccheckout: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDESourceControlProjectFavoriteDictionaryKey 6 | 7 | IDESourceControlProjectIdentifier 8 | 1B201147-7E2F-445D-88F7-F4C66A961A2D 9 | IDESourceControlProjectName 10 | CBStoreHouseRefreshControl 11 | IDESourceControlProjectOriginsDictionary 12 | 13 | 428AD6FE84D450D73793A668529C5EA842139F88 14 | https://github.com/StarClutch/CBStoreHouseRefreshControl.git 15 | 16 | IDESourceControlProjectPath 17 | CBStoreHouseRefreshControl.xcodeproj 18 | IDESourceControlProjectRelativeInstallPathDictionary 19 | 20 | 428AD6FE84D450D73793A668529C5EA842139F88 21 | ../.. 22 | 23 | IDESourceControlProjectURL 24 | https://github.com/StarClutch/CBStoreHouseRefreshControl.git 25 | IDESourceControlProjectVersion 26 | 111 27 | IDESourceControlProjectWCCIdentifier 28 | 428AD6FE84D450D73793A668529C5EA842139F88 29 | IDESourceControlProjectWCConfigurations 30 | 31 | 32 | IDESourceControlRepositoryExtensionIdentifierKey 33 | public.vcs.git 34 | IDESourceControlWCCIdentifierKey 35 | 428AD6FE84D450D73793A668529C5EA842139F88 36 | IDESourceControlWCCName 37 | CBStoreHouseRefreshControl 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /CBStoreHouseRefreshControl.xcodeproj/xcshareddata/xcschemes/CBStoreHouseRefreshControl.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 | 76 | 82 | 83 | 84 | 85 | 86 | 87 | 93 | 94 | 100 | 101 | 102 | 103 | 105 | 106 | 109 | 110 | 111 | -------------------------------------------------------------------------------- /CBStoreHouseRefreshControl/AKTA.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | startPoints 6 | 7 | {22,0} 8 | {22,0} 9 | {30,0} 10 | {0,30} 11 | {60,0} 12 | {60,15} 13 | {60,15} 14 | {85,15} 15 | {85,15} 16 | {117,0} 17 | {147,0} 18 | {147,0} 19 | {198,0} 20 | {198,0} 21 | {206,0} 22 | {176,30} 23 | 24 | endPoints 25 | 26 | {0,30} 27 | {30,0} 28 | {52,30} 29 | {26,30} 30 | {60,15} 31 | {60,30} 32 | {85,15} 33 | {108,0} 34 | {108,30} 35 | {147,0} 36 | {177,0} 37 | {147,32} 38 | {176,30} 39 | {206,0} 40 | {228,30} 41 | {202,30} 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /CBStoreHouseRefreshControl/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // CBStoreHouseRefreshControl 4 | // 5 | // Created by coolbeet on 10/26/14. 6 | // Copyright (c) 2014 Suyu Zhang. 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 | -------------------------------------------------------------------------------- /CBStoreHouseRefreshControl/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // CBStoreHouseRefreshControl 4 | // 5 | // Created by coolbeet on 10/26/14. 6 | // Copyright (c) 2014 Suyu Zhang. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | #import "ContentViewController.h" 11 | 12 | @interface AppDelegate () 13 | 14 | @end 15 | 16 | @implementation AppDelegate 17 | 18 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 19 | self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; 20 | self.window.backgroundColor = [UIColor blackColor]; 21 | ContentViewController *contentViewController = [[ContentViewController alloc] init]; 22 | UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:contentViewController]; 23 | self.window.rootViewController = navigationController; 24 | [self.window makeKeyAndVisible]; 25 | return YES; 26 | } 27 | 28 | @end 29 | -------------------------------------------------------------------------------- /CBStoreHouseRefreshControl/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 | -------------------------------------------------------------------------------- /CBStoreHouseRefreshControl/ContentViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ContentViewController.h 3 | // CBStoreHouseRefreshControl 4 | // 5 | // Created by coolbeet on 10/26/14. 6 | // Copyright (c) 2014 Suyu Zhang. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class CBStoreHouseRefreshControl; 12 | 13 | @interface ContentViewController : UITableViewController 14 | 15 | @property (nonatomic, strong) CBStoreHouseRefreshControl *storeHouseRefreshControl; 16 | 17 | @end 18 | 19 | -------------------------------------------------------------------------------- /CBStoreHouseRefreshControl/ContentViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ContentViewController.m 3 | // CBStoreHouseRefreshControl 4 | // 5 | // Created by coolbeet on 10/26/14. 6 | // Copyright (c) 2014 Suyu Zhang. All rights reserved. 7 | // 8 | 9 | #import "ContentViewController.h" 10 | #import "CBStoreHouseRefreshControl.h" 11 | 12 | @interface ContentViewController () 13 | 14 | @end 15 | 16 | @implementation ContentViewController 17 | 18 | - (void)viewDidLoad { 19 | [super viewDidLoad]; 20 | 21 | self.title = @"Storehouse"; 22 | self.navigationController.navigationBar.barStyle = UIBarStyleBlack; 23 | self.navigationController.navigationBar.barTintColor = [UIColor colorWithWhite:0.1 alpha:1]; 24 | self.navigationController.navigationBar.tintColor = [UIColor whiteColor]; 25 | self.navigationController.navigationBar.titleTextAttributes = @{NSForegroundColorAttributeName : [UIColor whiteColor]}; 26 | 27 | self.tableView.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"bg_pattern"]]; 28 | self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone; 29 | self.tableView.backgroundColor = [UIColor colorWithWhite:45.f/255.f alpha:1]; 30 | 31 | [self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"cell"]; 32 | self.tableView.alwaysBounceVertical = YES; 33 | 34 | UIView *footer = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.tableView.bounds.size.width, self.tableView.bounds.size.height)]; 35 | self.tableView.tableFooterView = footer; 36 | 37 | // Let the show begins 38 | self.storeHouseRefreshControl = [CBStoreHouseRefreshControl attachToScrollView:self.tableView target:self refreshAction:@selector(refreshTriggered:) plist:@"storehouse" color:[UIColor whiteColor] lineWidth:1.5 dropHeight:80 scale:1 horizontalRandomness:150 reverseLoadingAnimation:YES internalAnimationFactor:0.5]; 39 | 40 | //self.storeHouseRefreshControl = [CBStoreHouseRefreshControl attachToScrollView:self.tableView target:self refreshAction:@selector(refreshTriggered:) plist:@"AKTA" color:[UIColor whiteColor] lineWidth:2 dropHeight:80 scale:0.7 horizontalRandomness:300 reverseLoadingAnimation:NO internalAnimationFactor:0.7]; 41 | } 42 | 43 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 44 | { 45 | UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell" forIndexPath:indexPath]; 46 | 47 | UIImageView *image = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"cell"]]; 48 | image.translatesAutoresizingMaskIntoConstraints = NO; 49 | [cell.contentView addSubview:image]; 50 | 51 | [cell.contentView addConstraint:[NSLayoutConstraint constraintWithItem:image attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:cell.contentView attribute:NSLayoutAttributeCenterX multiplier:1 constant:0]]; 52 | [cell.contentView addConstraint:[NSLayoutConstraint constraintWithItem:image attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:cell.contentView attribute:NSLayoutAttributeCenterY multiplier:1 constant:0]]; 53 | 54 | cell.selectionStyle = UITableViewCellSelectionStyleNone; 55 | cell.backgroundColor = [UIColor clearColor]; 56 | 57 | return cell; 58 | } 59 | 60 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 61 | { 62 | return 1; 63 | } 64 | 65 | - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath 66 | { 67 | return 420; 68 | } 69 | 70 | #pragma mark - Notifying refresh control of scrolling 71 | 72 | - (void)scrollViewDidScroll:(UIScrollView *)scrollView 73 | { 74 | [self.storeHouseRefreshControl scrollViewDidScroll]; 75 | } 76 | 77 | - (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate 78 | { 79 | [self.storeHouseRefreshControl scrollViewDidEndDragging]; 80 | } 81 | 82 | #pragma mark - Listening for the user to trigger a refresh 83 | 84 | - (void)refreshTriggered:(id)sender 85 | { 86 | [self performSelector:@selector(finishRefreshControl) withObject:nil afterDelay:3 inModes:@[NSRunLoopCommonModes]]; 87 | } 88 | 89 | - (void)finishRefreshControl 90 | { 91 | [self.storeHouseRefreshControl finishingLoading]; 92 | } 93 | 94 | -(UIStatusBarStyle)preferredStatusBarStyle 95 | { 96 | return UIStatusBarStyleLightContent; 97 | } 98 | 99 | @end 100 | -------------------------------------------------------------------------------- /CBStoreHouseRefreshControl/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 | "info" : { 35 | "version" : 1, 36 | "author" : "xcode" 37 | } 38 | } -------------------------------------------------------------------------------- /CBStoreHouseRefreshControl/Images.xcassets/bg_pattern.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "bg_pattern@2x.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /CBStoreHouseRefreshControl/Images.xcassets/bg_pattern.imageset/bg_pattern@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coolbeet/CBStoreHouseRefreshControl/1d1fe2dc123c679f1e4f1cd583db5c8c65b1a0ac/CBStoreHouseRefreshControl/Images.xcassets/bg_pattern.imageset/bg_pattern@2x.png -------------------------------------------------------------------------------- /CBStoreHouseRefreshControl/Images.xcassets/cell.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "cell@2x.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /CBStoreHouseRefreshControl/Images.xcassets/cell.imageset/cell@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coolbeet/CBStoreHouseRefreshControl/1d1fe2dc123c679f1e4f1cd583db5c8c65b1a0ac/CBStoreHouseRefreshControl/Images.xcassets/cell.imageset/cell@2x.png -------------------------------------------------------------------------------- /CBStoreHouseRefreshControl/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | Suyu-Zhang.$(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 | NSMainNibFile 26 | LaunchScreen 27 | UILaunchStoryboardName 28 | LaunchScreen 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UIStatusBarHidden 34 | 35 | UIStatusBarStyle 36 | UIStatusBarStyleLightContent 37 | UISupportedInterfaceOrientations 38 | 39 | UIInterfaceOrientationPortrait 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /CBStoreHouseRefreshControl/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // CBStoreHouseRefreshControl 4 | // 5 | // Created by coolbeet on 10/26/14. 6 | // Copyright (c) 2014 Suyu Zhang. 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 | -------------------------------------------------------------------------------- /CBStoreHouseRefreshControl/storehouse.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | startPoints 6 | 7 | {0,35} 8 | {12,42} 9 | {24,35} 10 | {0,35} 11 | {0,21} 12 | {12,28} 13 | {24,35} 14 | {24,21} 15 | {0,21} 16 | {0,21} 17 | {12,14} 18 | {12,14} 19 | {24,7} 20 | {0,7} 21 | 22 | endPoints 23 | 24 | {12,42} 25 | {24,35} 26 | {12,28} 27 | {12,28} 28 | {12,28} 29 | {24,21} 30 | {24,21} 31 | {12,14} 32 | {12,14} 33 | {0,7} 34 | {0,7} 35 | {24,7} 36 | {12,0} 37 | {12,0} 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /CBStoreHouseRefreshControlTests/CBStoreHouseRefreshControlTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // CBStoreHouseRefreshControlTests.m 3 | // CBStoreHouseRefreshControlTests 4 | // 5 | // Created by coolbeet on 10/26/14. 6 | // Copyright (c) 2014 Suyu Zhang. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @interface CBStoreHouseRefreshControlTests : XCTestCase 13 | 14 | @end 15 | 16 | @implementation CBStoreHouseRefreshControlTests 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 | -------------------------------------------------------------------------------- /CBStoreHouseRefreshControlTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | UIViewControllerBasedStatusBarAppearance 6 | 7 | CFBundleDevelopmentRegion 8 | en 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | Suyu-Zhang.$(PRODUCT_NAME:rfc1034identifier) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | BNDL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1 25 | 26 | 27 | -------------------------------------------------------------------------------- /Class/BarItem.h: -------------------------------------------------------------------------------- 1 | // 2 | // BarItem.h 3 | // CBStoreHouseRefreshControl 4 | // 5 | // Created by coolbeet on 10/30/14. 6 | // Copyright (c) 2014 Suyu Zhang. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface BarItem : UIView 12 | 13 | @property (nonatomic) CGFloat translationX; 14 | 15 | - (instancetype)initWithFrame:(CGRect)frame startPoint:(CGPoint)startPoint endPoint:(CGPoint)endPoint color:(UIColor *)color lineWidth:(CGFloat)lineWidth; 16 | - (void)setupWithFrame:(CGRect)rect; 17 | - (void)setHorizontalRandomness:(int)horizontalRandomness dropHeight:(CGFloat)dropHeight; 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /Class/BarItem.m: -------------------------------------------------------------------------------- 1 | // 2 | // BarItem.m 3 | // CBStoreHouseRefreshControl 4 | // 5 | // Created by coolbeet on 10/30/14. 6 | // Copyright (c) 2014 Suyu Zhang. All rights reserved. 7 | // 8 | 9 | #import "BarItem.h" 10 | 11 | @interface BarItem () 12 | 13 | @property (nonatomic) CGPoint middlePoint; 14 | @property (nonatomic) CGFloat lineWidth; 15 | @property (nonatomic) CGPoint startPoint; 16 | @property (nonatomic) CGPoint endPoint; 17 | @property (nonatomic) UIColor *color; 18 | 19 | @end 20 | 21 | @implementation BarItem 22 | 23 | - (instancetype)initWithFrame:(CGRect)frame startPoint:(CGPoint)startPoint endPoint:(CGPoint)endPoint color:(UIColor *)color lineWidth:(CGFloat)lineWidth 24 | { 25 | self = [super initWithFrame:frame]; 26 | if (self) { 27 | _startPoint = startPoint; 28 | _endPoint = endPoint; 29 | _lineWidth = lineWidth; 30 | _color = color; 31 | 32 | CGPoint (^middlePoint)(CGPoint, CGPoint) = ^CGPoint(CGPoint a, CGPoint b) { 33 | CGFloat x = (a.x + b.x)/2.f; 34 | CGFloat y = (a.y + b.y)/2.f; 35 | return CGPointMake(x, y); 36 | }; 37 | _middlePoint = middlePoint(startPoint, endPoint); 38 | } 39 | return self; 40 | } 41 | 42 | - (void)setupWithFrame:(CGRect)rect 43 | { 44 | self.layer.anchorPoint = CGPointMake(self.middlePoint.x/self.frame.size.width, self.middlePoint.y/self.frame.size.height); 45 | self.frame = CGRectMake(self.frame.origin.x + self.middlePoint.x - self.frame.size.width/2, self.frame.origin.y + self.middlePoint.y - self.frame.size.height/2, self.frame.size.width, self.frame.size.height); 46 | } 47 | 48 | - (void)setHorizontalRandomness:(int)horizontalRandomness dropHeight:(CGFloat)dropHeight 49 | { 50 | int randomNumber = - horizontalRandomness + arc4random()%horizontalRandomness*2; 51 | self.translationX = randomNumber; 52 | self.transform = CGAffineTransformMakeTranslation(self.translationX, -dropHeight); 53 | } 54 | 55 | - (void)drawRect:(CGRect)rect { 56 | UIBezierPath* bezierPath = UIBezierPath.bezierPath; 57 | [bezierPath moveToPoint:self.startPoint]; 58 | [bezierPath addLineToPoint:self.endPoint]; 59 | [self.color setStroke]; 60 | bezierPath.lineWidth = self.lineWidth; 61 | [bezierPath stroke]; 62 | } 63 | 64 | @end 65 | -------------------------------------------------------------------------------- /Class/CBStoreHouseRefreshControl.h: -------------------------------------------------------------------------------- 1 | // 2 | // CBStoreHouseRefreshControl.h 3 | // CBStoreHouseRefreshControl 4 | // 5 | // Created by coolbeet on 10/30/14. 6 | // Copyright (c) 2014 Suyu Zhang. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface CBStoreHouseRefreshControl : UIView 12 | 13 | + (CBStoreHouseRefreshControl*)attachToScrollView:(UIScrollView *)scrollView 14 | target:(id)target 15 | refreshAction:(SEL)refreshAction 16 | plist:(NSString *)plist; 17 | 18 | + (CBStoreHouseRefreshControl*)attachToScrollView:(UIScrollView *)scrollView 19 | target:(id)target 20 | refreshAction:(SEL)refreshAction 21 | plist:(NSString *)plist 22 | color:(UIColor*)color 23 | lineWidth:(CGFloat)lineWidth 24 | dropHeight:(CGFloat)dropHeight 25 | scale:(CGFloat)scale 26 | horizontalRandomness:(CGFloat)horizontalRandomness 27 | reverseLoadingAnimation:(BOOL)reverseLoadingAnimation 28 | internalAnimationFactor:(CGFloat)internalAnimationFactor; 29 | 30 | - (void)scrollViewDidScroll; 31 | 32 | - (void)scrollViewDidEndDragging; 33 | 34 | - (void)finishingLoading; 35 | 36 | @end 37 | -------------------------------------------------------------------------------- /Class/CBStoreHouseRefreshControl.m: -------------------------------------------------------------------------------- 1 | // 2 | // CBStoreHouseRefreshControl.m 3 | // CBStoreHouseRefreshControl 4 | // 5 | // Created by coolbeet on 10/30/14. 6 | // Copyright (c) 2014 Suyu Zhang. All rights reserved. 7 | // 8 | 9 | #import "CBStoreHouseRefreshControl.h" 10 | #import "BarItem.h" 11 | 12 | static const CGFloat kloadingIndividualAnimationTiming = 0.8; 13 | static const CGFloat kbarDarkAlpha = 0.4; 14 | static const CGFloat kloadingTimingOffset = 0.1; 15 | static const CGFloat kdisappearDuration = 1.2; 16 | static const CGFloat krelativeHeightFactor = 2.f/5.f; 17 | 18 | typedef enum { 19 | CBStoreHouseRefreshControlStateIdle = 0, 20 | CBStoreHouseRefreshControlStateRefreshing = 1, 21 | CBStoreHouseRefreshControlStateDisappearing = 2 22 | } CBStoreHouseRefreshControlState; 23 | 24 | NSString *const startPointKey = @"startPoints"; 25 | NSString *const endPointKey = @"endPoints"; 26 | NSString *const xKey = @"x"; 27 | NSString *const yKey = @"y"; 28 | 29 | @interface CBStoreHouseRefreshControl () 30 | 31 | @property (nonatomic) CBStoreHouseRefreshControlState state; 32 | @property (nonatomic, weak) UIScrollView *scrollView; 33 | @property (nonatomic, strong) NSArray *barItems; 34 | @property (nonatomic, strong) CADisplayLink *displayLink; 35 | @property (nonatomic, assign) id target; 36 | @property (nonatomic) SEL action; 37 | 38 | @property (nonatomic) CGFloat dropHeight; 39 | @property (nonatomic) CGFloat originalTopContentInset; 40 | @property (nonatomic) CGFloat disappearProgress; 41 | @property (nonatomic) CGFloat internalAnimationFactor; 42 | @property (nonatomic) int horizontalRandomness; 43 | @property (nonatomic) BOOL reverseLoadingAnimation; 44 | 45 | @end 46 | 47 | @implementation CBStoreHouseRefreshControl 48 | 49 | + (CBStoreHouseRefreshControl*)attachToScrollView:(UIScrollView *)scrollView 50 | target:(id)target 51 | refreshAction:(SEL)refreshAction 52 | plist:(NSString *)plist 53 | { 54 | return [CBStoreHouseRefreshControl attachToScrollView:scrollView 55 | target:target 56 | refreshAction:refreshAction 57 | plist:plist 58 | color:[UIColor whiteColor] 59 | lineWidth:2 60 | dropHeight:80 61 | scale:1 62 | horizontalRandomness:150 63 | reverseLoadingAnimation:NO 64 | internalAnimationFactor:0.7]; 65 | } 66 | 67 | + (CBStoreHouseRefreshControl*)attachToScrollView:(UIScrollView *)scrollView 68 | target:(id)target 69 | refreshAction:(SEL)refreshAction 70 | plist:(NSString *)plist 71 | color:(UIColor*)color 72 | lineWidth:(CGFloat)lineWidth 73 | dropHeight:(CGFloat)dropHeight 74 | scale:(CGFloat)scale 75 | horizontalRandomness:(CGFloat)horizontalRandomness 76 | reverseLoadingAnimation:(BOOL)reverseLoadingAnimation 77 | internalAnimationFactor:(CGFloat)internalAnimationFactor 78 | { 79 | CBStoreHouseRefreshControl *refreshControl = [[CBStoreHouseRefreshControl alloc] init]; 80 | refreshControl.dropHeight = dropHeight; 81 | refreshControl.horizontalRandomness = horizontalRandomness; 82 | refreshControl.scrollView = scrollView; 83 | refreshControl.target = target; 84 | refreshControl.action = refreshAction; 85 | refreshControl.reverseLoadingAnimation = reverseLoadingAnimation; 86 | refreshControl.internalAnimationFactor = internalAnimationFactor; 87 | [scrollView addSubview:refreshControl]; 88 | 89 | // Calculate frame according to points max width and height 90 | CGFloat width = 0; 91 | CGFloat height = 0; 92 | NSDictionary *rootDictionary = [NSDictionary dictionaryWithContentsOfFile:[[NSBundle mainBundle] pathForResource:plist ofType:@"plist"]]; 93 | NSArray *startPoints = [rootDictionary objectForKey:startPointKey]; 94 | NSArray *endPoints = [rootDictionary objectForKey:endPointKey]; 95 | for (int i=0; i width) width = startPoint.x; 101 | if (endPoint.x > width) width = endPoint.x; 102 | if (startPoint.y > height) height = startPoint.y; 103 | if (endPoint.y > height) height = endPoint.y; 104 | } 105 | refreshControl.frame = CGRectMake(0, 0, width, height); 106 | 107 | // Create bar items 108 | NSMutableArray *mutableBarItems = [[NSMutableArray alloc] init]; 109 | for (int i=0; i= 1 - endPadding) { 195 | barItem.transform = CGAffineTransformIdentity; 196 | barItem.alpha = kbarDarkAlpha; 197 | } 198 | else if (progress == 0) { 199 | [barItem setHorizontalRandomness:self.horizontalRandomness dropHeight:self.dropHeight]; 200 | } 201 | else { 202 | CGFloat realProgress; 203 | if (progress <= startPadding) 204 | realProgress = 0; 205 | else 206 | realProgress = MIN(1, (progress - startPadding)/self.internalAnimationFactor); 207 | barItem.transform = CGAffineTransformMakeTranslation(barItem.translationX*(1-realProgress), -self.dropHeight*(1-realProgress)); 208 | barItem.transform = CGAffineTransformRotate(barItem.transform, M_PI*(realProgress)); 209 | barItem.transform = CGAffineTransformScale(barItem.transform, realProgress, realProgress); 210 | barItem.alpha = realProgress * kbarDarkAlpha; 211 | } 212 | } 213 | } 214 | 215 | - (void)startLoadingAnimation 216 | { 217 | if (self.reverseLoadingAnimation) { 218 | int count = (int)self.barItems.count; 219 | for (int i= count-1; i>=0; i--) { 220 | BarItem *barItem = [self.barItems objectAtIndex:i]; 221 | [self performSelector:@selector(barItemAnimation:) withObject:barItem afterDelay:(self.barItems.count-i-1)*kloadingTimingOffset inModes:@[NSRunLoopCommonModes]]; 222 | } 223 | } 224 | else { 225 | for (int i=0; i= 0 && self.disappearProgress <= 1) { 258 | self.disappearProgress -= 1/60.f/kdisappearDuration; 259 | //60.f means this method get called 60 times per second 260 | [self updateBarItemsWithProgress:self.disappearProgress]; 261 | } 262 | } 263 | 264 | #pragma mark Public Methods 265 | 266 | - (void)finishingLoading 267 | { 268 | self.state = CBStoreHouseRefreshControlStateDisappearing; 269 | UIEdgeInsets newInsets = self.scrollView.contentInset; 270 | newInsets.top = self.originalTopContentInset; 271 | [UIView animateWithDuration:kdisappearDuration animations:^(void) { 272 | self.scrollView.contentInset = newInsets; 273 | } completion:^(BOOL finished) { 274 | self.state = CBStoreHouseRefreshControlStateIdle; 275 | [self.displayLink invalidate]; 276 | self.disappearProgress = 1; 277 | }]; 278 | 279 | for (BarItem *barItem in self.barItems) { 280 | [barItem.layer removeAllAnimations]; 281 | barItem.alpha = kbarDarkAlpha; 282 | } 283 | 284 | self.displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(updateDisappearAnimation)]; 285 | [self.displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes]; 286 | self.disappearProgress = 1; 287 | } 288 | 289 | @end 290 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014 Suyu Zhang 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | CBStoreHouseRefreshControl ![License MIT](https://go-shields.herokuapp.com/license-MIT-blue.png) 2 | ======================= 3 | 4 | ![Version](http://cocoapod-badges.herokuapp.com/v/CBStoreHouseRefreshControl/badge.png) 5 | ![Platform](http://cocoapod-badges.herokuapp.com/p/CBStoreHouseRefreshControl/badge.png) 6 | 7 | What is it? 8 | --- 9 | 10 | A **fully customizable** pull-to-refresh control for iOS inspired by [Storehouse](https://www.storehouse.co/) iOS app 11 | 12 | ![screenshot1] (https://s3.amazonaws.com/suyu.test/CBStoreHouseRefreshControl1.gif) 13 | 14 | You can use any shape through a `plist` file, like this one: 15 | 16 | ![screenshot2] (https://s3.amazonaws.com/suyu.test/CBStoreHouseRefreshControl2.gif) 17 | 18 | Which files are needed? 19 | --- 20 | CBStoreHouseRefreshControl is available through [CocoaPods](http://cocoapods.org), to install 21 | it simply add the following line to your Podfile: 22 | 23 | pod 'CBStoreHouseRefreshControl' 24 | 25 | Alternatively, you can just drag `CBStoreHouseRefreshControl (.h .m)` and `BarItem (.h .m)` into your own project. 26 | 27 | How to use it 28 | --- 29 | You can attach it to any `UIScrollView` like `UITableView` or `UICollectionView` using following simple static method: 30 | 31 | ```objective-c 32 | + (CBStoreHouseRefreshControl*)attachToScrollView:(UIScrollView *)scrollView 33 | target:(id)target 34 | refreshAction:(SEL)refreshAction 35 | plist:(NSString *)plist; 36 | ``` 37 | ```objective-c 38 | self.storeHouseRefreshControl = [CBStoreHouseRefreshControl attachToScrollView:self.tableView target:self refreshAction:@selector(refreshTriggered:) plist:@"storehouse"]; 39 | ``` 40 | Or, using this method for more configurable options: 41 | 42 | ```objective-c 43 | + (CBStoreHouseRefreshControl*)attachToScrollView:(UIScrollView *)scrollView 44 | target:(id)target 45 | refreshAction:(SEL)refreshAction 46 | plist:(NSString *)plist 47 | color:(UIColor *)color 48 | lineWidth:(CGFloat)lineWidth 49 | dropHeight:(CGFloat)dropHeight 50 | scale:(CGFloat)scale 51 | horizontalRandomness:(CGFloat)horizontalRandomness 52 | reverseLoadingAnimation:(BOOL)reverseLoadingAnimation 53 | internalAnimationFactor:(CGFloat)internalAnimationFactor; 54 | ``` 55 | 56 | ```objective-c 57 | self.storeHouseRefreshControl = [CBStoreHouseRefreshControl attachToScrollView:self.tableView target:self refreshAction:@selector(refreshTriggered:) plist:@"storehouse" color:[UIColor whiteColor] lineWidth:1.5 dropHeight:80 scale:1 horizontalRandomness:150 reverseLoadingAnimation:YES internalAnimationFactor:0.5]; 58 | ``` 59 | 60 | Then, implement `UIScrollViewDelegate` in your `UIViewController` if you haven't already, and pass the calls through to the refresh control: 61 | 62 | ```objective-c 63 | - (void)scrollViewDidScroll:(UIScrollView *)scrollView 64 | { 65 | [self.storeHouseRefreshControl scrollViewDidScroll]; 66 | } 67 | 68 | - (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate 69 | { 70 | [self.storeHouseRefreshControl scrollViewDidEndDragging]; 71 | } 72 | ``` 73 | 74 | Lastly, make sure you've implemented the `refreshAction` you passed it earlier to listen for refresh triggers: 75 | 76 | ```objective-c 77 | - (void)refreshTriggered 78 | { 79 | //call your loading method here 80 | 81 | //Finshed loading the data, reset the refresh control 82 | [self.storeHouseRefreshControl finishingLoading]; 83 | } 84 | ``` 85 | For more details, please check out the demo app's code. 86 | 87 | How to use your own shape 88 | --- 89 | 90 | The CBStoreHouseRefreshControl's shape contains bunch of `BarItem` for animation, each `BarItem` is running its own animation, you need to provide `startPoint` and `endPoint` through a plist file. 91 | 92 | All `BarItem` will share one coordinate system whose origin is at the top-left corner. For example if you want to draw a square, the plist will look like this: 93 | 94 | ![screenshot2] (https://s3.amazonaws.com/suyu.test/square.png) 95 | 96 | The result will look like this: 97 | 98 | ![screenshot3] (https://s3.amazonaws.com/suyu.test/square.gif) 99 | 100 | #### Notes: 101 | - Make sure you put the right key which are `startPoints` and `endPoints`. 102 | - Make sure you are using the right format (`{x,y}`) for coordinates. 103 | - The highlight/loading animation will highlight each bar item in the same order you declare them in plist, use `reverseLoadingAnimation` to reverse the animation. 104 | 105 | Easy way to generate `startPoint` and `endPoint`? 106 | --- 107 | 108 | [@isaced](https://github.com/isaced) mentions that it's easier to use [PaintCode](http://www.paintcodeapp.com/) to generate `startPoint` and `endPoint`: 109 | 110 | ![screenshot4] (https://cloud.githubusercontent.com/assets/2088605/4948694/0ce2da74-667f-11e4-8ce7-a2067f15558d.png) 111 | 112 | Result: 113 | 114 | ![screenshot5] (https://cloud.githubusercontent.com/assets/2088605/4948707/3b76afb4-667f-11e4-91a4-9509d17356fa.gif) 115 | 116 | You can get more info [here](https://github.com/coolbeet/CBStoreHouseRefreshControl/issues/1). 117 | 118 | Configuration 119 | ------------- 120 | 121 | Play with following parameters to configure CBStoreHouseRefreshControl's view and animation: 122 | 123 | - Set the bar color with the `color` parameter 124 | - Set the bar width with the `lineWidth` parameter 125 | - Set the height of control with the `dropHeight` parameter 126 | - Set the scale of control with the `scale` parameter 127 | - Adjust how disperse the bar items appear/disappear by changing the `horizontalRandomness` parameter 128 | - Set if reversing the loading animation with the `reverseLoadingAnimation` parameter, if set to `YES`, the last bar item will be highlighted firstly. 129 | - Adjust the time offset of the appear/disappear animation by changing the `internalAnimationFactor` parameter, for example if `internalAnimationFactor` is 1 all bar items will appear/disappear all together. 130 | 131 | Who's using it? 132 | --------------- 133 | 134 | We've a [wiki page](https://github.com/coolbeet/CBStoreHouseRefreshControl/wiki) for that, feel free to add your projects there! 135 | 136 | Author 137 | ------ 138 | 139 | Suyu Zhang 140 | suyu_zhang@hotmail.com 141 | [suyuzhang.com](http://suyuzhang.com/) 142 | 143 | 144 | License 145 | ------- 146 | Copyright (c) 2014 Suyu Zhang . See the LICENSE file for license rights and limitations (MIT). 147 | 148 | 149 | 150 | 151 | --------------------------------------------------------------------------------