├── .gitignore ├── BRCollectionViewDemo.xcodeproj ├── project.pbxproj └── project.xcworkspace │ └── contents.xcworkspacedata ├── BRCollectionViewDemo ├── AppDelegate.h ├── AppDelegate.m ├── Assets.xcassets │ └── AppIcon.appiconset │ │ └── Contents.json ├── BRCirclePickerView │ ├── BRCircleLayout.h │ ├── BRCircleLayout.m │ ├── BRCirclePickerView.h │ └── BRCirclePickerView.m ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard ├── Info.plist ├── NSDate+BRAdd.h ├── NSDate+BRAdd.m ├── NSString+BRAdd.h ├── NSString+BRAdd.m ├── PrefixHeader.pch ├── ViewController.h ├── ViewController.m └── main.m ├── LICENSE └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 4 | 5 | ## Build generated 6 | build/ 7 | DerivedData/ 8 | 9 | ## Various settings 10 | *.pbxuser 11 | !default.pbxuser 12 | *.mode1v3 13 | !default.mode1v3 14 | *.mode2v3 15 | !default.mode2v3 16 | *.perspectivev3 17 | !default.perspectivev3 18 | xcuserdata/ 19 | 20 | ## Other 21 | *.moved-aside 22 | *.xccheckout 23 | *.xcscmblueprint 24 | 25 | ## Obj-C/Swift specific 26 | *.hmap 27 | *.ipa 28 | *.dSYM.zip 29 | *.dSYM 30 | 31 | # CocoaPods 32 | # 33 | # We recommend against adding the Pods directory to your .gitignore. However 34 | # you should judge for yourself, the pros and cons are mentioned at: 35 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 36 | # 37 | # Pods/ 38 | 39 | # Carthage 40 | # 41 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 42 | # Carthage/Checkouts 43 | 44 | Carthage/Build 45 | 46 | # fastlane 47 | # 48 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 49 | # screenshots whenever they are needed. 50 | # For more information about the recommended setup visit: 51 | # https://docs.fastlane.tools/best-practices/source-control/#source-control 52 | 53 | fastlane/report.xml 54 | fastlane/Preview.html 55 | fastlane/screenshots 56 | fastlane/test_output 57 | 58 | # Code Injection 59 | # 60 | # After new code Injection tools there's a generated folder /iOSInjectionProject 61 | # https://github.com/johnno1962/injectionforxcode 62 | 63 | iOSInjectionProject/ 64 | -------------------------------------------------------------------------------- /BRCollectionViewDemo.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | C5ACE5541F452C4D0069978B /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = C5ACE5531F452C4D0069978B /* main.m */; }; 11 | C5ACE5571F452C4D0069978B /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = C5ACE5561F452C4D0069978B /* AppDelegate.m */; }; 12 | C5ACE55A1F452C4D0069978B /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = C5ACE5591F452C4D0069978B /* ViewController.m */; }; 13 | C5ACE55D1F452C4D0069978B /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = C5ACE55B1F452C4D0069978B /* Main.storyboard */; }; 14 | C5ACE55F1F452C4D0069978B /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C5ACE55E1F452C4D0069978B /* Assets.xcassets */; }; 15 | C5ACE5621F452C4D0069978B /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = C5ACE5601F452C4D0069978B /* LaunchScreen.storyboard */; }; 16 | C5ACE56E1F452C9F0069978B /* BRCircleLayout.m in Sources */ = {isa = PBXBuildFile; fileRef = C5ACE56B1F452C9F0069978B /* BRCircleLayout.m */; }; 17 | C5ACE56F1F452C9F0069978B /* BRCirclePickerView.m in Sources */ = {isa = PBXBuildFile; fileRef = C5ACE56D1F452C9F0069978B /* BRCirclePickerView.m */; }; 18 | C5E9AA7F1FFE5BE50000CE7E /* NSDate+BRAdd.m in Sources */ = {isa = PBXBuildFile; fileRef = C5E9AA7E1FFE5BE50000CE7E /* NSDate+BRAdd.m */; }; 19 | C5E9AA821FFE5F6E0000CE7E /* NSString+BRAdd.m in Sources */ = {isa = PBXBuildFile; fileRef = C5E9AA811FFE5F6E0000CE7E /* NSString+BRAdd.m */; }; 20 | /* End PBXBuildFile section */ 21 | 22 | /* Begin PBXFileReference section */ 23 | C5ACE54F1F452C4D0069978B /* BRCollectionViewDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = BRCollectionViewDemo.app; sourceTree = BUILT_PRODUCTS_DIR; }; 24 | C5ACE5531F452C4D0069978B /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 25 | C5ACE5551F452C4D0069978B /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 26 | C5ACE5561F452C4D0069978B /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 27 | C5ACE5581F452C4D0069978B /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; 28 | C5ACE5591F452C4D0069978B /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; 29 | C5ACE55C1F452C4D0069978B /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 30 | C5ACE55E1F452C4D0069978B /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 31 | C5ACE5611F452C4D0069978B /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 32 | C5ACE5631F452C4D0069978B /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 33 | C5ACE56A1F452C9F0069978B /* BRCircleLayout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BRCircleLayout.h; sourceTree = ""; }; 34 | C5ACE56B1F452C9F0069978B /* BRCircleLayout.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BRCircleLayout.m; sourceTree = ""; }; 35 | C5ACE56C1F452C9F0069978B /* BRCirclePickerView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BRCirclePickerView.h; sourceTree = ""; }; 36 | C5ACE56D1F452C9F0069978B /* BRCirclePickerView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BRCirclePickerView.m; sourceTree = ""; }; 37 | C5ACE5701F452CCE0069978B /* PrefixHeader.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PrefixHeader.pch; sourceTree = ""; }; 38 | C5E9AA7D1FFE5BE50000CE7E /* NSDate+BRAdd.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSDate+BRAdd.h"; sourceTree = ""; }; 39 | C5E9AA7E1FFE5BE50000CE7E /* NSDate+BRAdd.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSDate+BRAdd.m"; sourceTree = ""; }; 40 | C5E9AA801FFE5F6E0000CE7E /* NSString+BRAdd.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "NSString+BRAdd.h"; sourceTree = ""; }; 41 | C5E9AA811FFE5F6E0000CE7E /* NSString+BRAdd.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "NSString+BRAdd.m"; sourceTree = ""; }; 42 | /* End PBXFileReference section */ 43 | 44 | /* Begin PBXFrameworksBuildPhase section */ 45 | C5ACE54C1F452C4D0069978B /* Frameworks */ = { 46 | isa = PBXFrameworksBuildPhase; 47 | buildActionMask = 2147483647; 48 | files = ( 49 | ); 50 | runOnlyForDeploymentPostprocessing = 0; 51 | }; 52 | /* End PBXFrameworksBuildPhase section */ 53 | 54 | /* Begin PBXGroup section */ 55 | C5ACE5461F452C4D0069978B = { 56 | isa = PBXGroup; 57 | children = ( 58 | C5ACE5511F452C4D0069978B /* BRCollectionViewDemo */, 59 | C5ACE5501F452C4D0069978B /* Products */, 60 | ); 61 | sourceTree = ""; 62 | }; 63 | C5ACE5501F452C4D0069978B /* Products */ = { 64 | isa = PBXGroup; 65 | children = ( 66 | C5ACE54F1F452C4D0069978B /* BRCollectionViewDemo.app */, 67 | ); 68 | name = Products; 69 | sourceTree = ""; 70 | }; 71 | C5ACE5511F452C4D0069978B /* BRCollectionViewDemo */ = { 72 | isa = PBXGroup; 73 | children = ( 74 | C5ACE5691F452C9F0069978B /* BRCirclePickerView */, 75 | C5ACE5551F452C4D0069978B /* AppDelegate.h */, 76 | C5ACE5561F452C4D0069978B /* AppDelegate.m */, 77 | C5E9AA7D1FFE5BE50000CE7E /* NSDate+BRAdd.h */, 78 | C5E9AA7E1FFE5BE50000CE7E /* NSDate+BRAdd.m */, 79 | C5E9AA801FFE5F6E0000CE7E /* NSString+BRAdd.h */, 80 | C5E9AA811FFE5F6E0000CE7E /* NSString+BRAdd.m */, 81 | C5ACE5581F452C4D0069978B /* ViewController.h */, 82 | C5ACE5591F452C4D0069978B /* ViewController.m */, 83 | C5ACE55B1F452C4D0069978B /* Main.storyboard */, 84 | C5ACE55E1F452C4D0069978B /* Assets.xcassets */, 85 | C5ACE5601F452C4D0069978B /* LaunchScreen.storyboard */, 86 | C5ACE5631F452C4D0069978B /* Info.plist */, 87 | C5ACE5521F452C4D0069978B /* Supporting Files */, 88 | ); 89 | path = BRCollectionViewDemo; 90 | sourceTree = ""; 91 | }; 92 | C5ACE5521F452C4D0069978B /* Supporting Files */ = { 93 | isa = PBXGroup; 94 | children = ( 95 | C5ACE5701F452CCE0069978B /* PrefixHeader.pch */, 96 | C5ACE5531F452C4D0069978B /* main.m */, 97 | ); 98 | name = "Supporting Files"; 99 | sourceTree = ""; 100 | }; 101 | C5ACE5691F452C9F0069978B /* BRCirclePickerView */ = { 102 | isa = PBXGroup; 103 | children = ( 104 | C5ACE56A1F452C9F0069978B /* BRCircleLayout.h */, 105 | C5ACE56B1F452C9F0069978B /* BRCircleLayout.m */, 106 | C5ACE56C1F452C9F0069978B /* BRCirclePickerView.h */, 107 | C5ACE56D1F452C9F0069978B /* BRCirclePickerView.m */, 108 | ); 109 | path = BRCirclePickerView; 110 | sourceTree = ""; 111 | }; 112 | /* End PBXGroup section */ 113 | 114 | /* Begin PBXNativeTarget section */ 115 | C5ACE54E1F452C4D0069978B /* BRCollectionViewDemo */ = { 116 | isa = PBXNativeTarget; 117 | buildConfigurationList = C5ACE5661F452C4D0069978B /* Build configuration list for PBXNativeTarget "BRCollectionViewDemo" */; 118 | buildPhases = ( 119 | C5ACE54B1F452C4D0069978B /* Sources */, 120 | C5ACE54C1F452C4D0069978B /* Frameworks */, 121 | C5ACE54D1F452C4D0069978B /* Resources */, 122 | ); 123 | buildRules = ( 124 | ); 125 | dependencies = ( 126 | ); 127 | name = BRCollectionViewDemo; 128 | productName = BRCollectionViewDemo; 129 | productReference = C5ACE54F1F452C4D0069978B /* BRCollectionViewDemo.app */; 130 | productType = "com.apple.product-type.application"; 131 | }; 132 | /* End PBXNativeTarget section */ 133 | 134 | /* Begin PBXProject section */ 135 | C5ACE5471F452C4D0069978B /* Project object */ = { 136 | isa = PBXProject; 137 | attributes = { 138 | LastUpgradeCheck = 0830; 139 | ORGANIZATIONNAME = renb; 140 | TargetAttributes = { 141 | C5ACE54E1F452C4D0069978B = { 142 | CreatedOnToolsVersion = 8.3.2; 143 | ProvisioningStyle = Automatic; 144 | }; 145 | }; 146 | }; 147 | buildConfigurationList = C5ACE54A1F452C4D0069978B /* Build configuration list for PBXProject "BRCollectionViewDemo" */; 148 | compatibilityVersion = "Xcode 3.2"; 149 | developmentRegion = English; 150 | hasScannedForEncodings = 0; 151 | knownRegions = ( 152 | en, 153 | Base, 154 | ); 155 | mainGroup = C5ACE5461F452C4D0069978B; 156 | productRefGroup = C5ACE5501F452C4D0069978B /* Products */; 157 | projectDirPath = ""; 158 | projectRoot = ""; 159 | targets = ( 160 | C5ACE54E1F452C4D0069978B /* BRCollectionViewDemo */, 161 | ); 162 | }; 163 | /* End PBXProject section */ 164 | 165 | /* Begin PBXResourcesBuildPhase section */ 166 | C5ACE54D1F452C4D0069978B /* Resources */ = { 167 | isa = PBXResourcesBuildPhase; 168 | buildActionMask = 2147483647; 169 | files = ( 170 | C5ACE5621F452C4D0069978B /* LaunchScreen.storyboard in Resources */, 171 | C5ACE55F1F452C4D0069978B /* Assets.xcassets in Resources */, 172 | C5ACE55D1F452C4D0069978B /* Main.storyboard in Resources */, 173 | ); 174 | runOnlyForDeploymentPostprocessing = 0; 175 | }; 176 | /* End PBXResourcesBuildPhase section */ 177 | 178 | /* Begin PBXSourcesBuildPhase section */ 179 | C5ACE54B1F452C4D0069978B /* Sources */ = { 180 | isa = PBXSourcesBuildPhase; 181 | buildActionMask = 2147483647; 182 | files = ( 183 | C5ACE56F1F452C9F0069978B /* BRCirclePickerView.m in Sources */, 184 | C5ACE55A1F452C4D0069978B /* ViewController.m in Sources */, 185 | C5ACE5571F452C4D0069978B /* AppDelegate.m in Sources */, 186 | C5ACE5541F452C4D0069978B /* main.m in Sources */, 187 | C5E9AA7F1FFE5BE50000CE7E /* NSDate+BRAdd.m in Sources */, 188 | C5E9AA821FFE5F6E0000CE7E /* NSString+BRAdd.m in Sources */, 189 | C5ACE56E1F452C9F0069978B /* BRCircleLayout.m in Sources */, 190 | ); 191 | runOnlyForDeploymentPostprocessing = 0; 192 | }; 193 | /* End PBXSourcesBuildPhase section */ 194 | 195 | /* Begin PBXVariantGroup section */ 196 | C5ACE55B1F452C4D0069978B /* Main.storyboard */ = { 197 | isa = PBXVariantGroup; 198 | children = ( 199 | C5ACE55C1F452C4D0069978B /* Base */, 200 | ); 201 | name = Main.storyboard; 202 | sourceTree = ""; 203 | }; 204 | C5ACE5601F452C4D0069978B /* LaunchScreen.storyboard */ = { 205 | isa = PBXVariantGroup; 206 | children = ( 207 | C5ACE5611F452C4D0069978B /* Base */, 208 | ); 209 | name = LaunchScreen.storyboard; 210 | sourceTree = ""; 211 | }; 212 | /* End PBXVariantGroup section */ 213 | 214 | /* Begin XCBuildConfiguration section */ 215 | C5ACE5641F452C4D0069978B /* Debug */ = { 216 | isa = XCBuildConfiguration; 217 | buildSettings = { 218 | ALWAYS_SEARCH_USER_PATHS = NO; 219 | CLANG_ANALYZER_NONNULL = YES; 220 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 221 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 222 | CLANG_CXX_LIBRARY = "libc++"; 223 | CLANG_ENABLE_MODULES = YES; 224 | CLANG_ENABLE_OBJC_ARC = YES; 225 | CLANG_WARN_BOOL_CONVERSION = YES; 226 | CLANG_WARN_CONSTANT_CONVERSION = YES; 227 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 228 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 229 | CLANG_WARN_EMPTY_BODY = YES; 230 | CLANG_WARN_ENUM_CONVERSION = YES; 231 | CLANG_WARN_INFINITE_RECURSION = YES; 232 | CLANG_WARN_INT_CONVERSION = YES; 233 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 234 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 235 | CLANG_WARN_UNREACHABLE_CODE = YES; 236 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 237 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 238 | COPY_PHASE_STRIP = NO; 239 | DEBUG_INFORMATION_FORMAT = dwarf; 240 | ENABLE_STRICT_OBJC_MSGSEND = YES; 241 | ENABLE_TESTABILITY = YES; 242 | GCC_C_LANGUAGE_STANDARD = gnu99; 243 | GCC_DYNAMIC_NO_PIC = NO; 244 | GCC_NO_COMMON_BLOCKS = YES; 245 | GCC_OPTIMIZATION_LEVEL = 0; 246 | GCC_PREPROCESSOR_DEFINITIONS = ( 247 | "DEBUG=1", 248 | "$(inherited)", 249 | ); 250 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 251 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 252 | GCC_WARN_UNDECLARED_SELECTOR = YES; 253 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 254 | GCC_WARN_UNUSED_FUNCTION = YES; 255 | GCC_WARN_UNUSED_VARIABLE = YES; 256 | IPHONEOS_DEPLOYMENT_TARGET = 10.3; 257 | MTL_ENABLE_DEBUG_INFO = YES; 258 | ONLY_ACTIVE_ARCH = YES; 259 | SDKROOT = iphoneos; 260 | }; 261 | name = Debug; 262 | }; 263 | C5ACE5651F452C4D0069978B /* Release */ = { 264 | isa = XCBuildConfiguration; 265 | buildSettings = { 266 | ALWAYS_SEARCH_USER_PATHS = NO; 267 | CLANG_ANALYZER_NONNULL = YES; 268 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 269 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 270 | CLANG_CXX_LIBRARY = "libc++"; 271 | CLANG_ENABLE_MODULES = YES; 272 | CLANG_ENABLE_OBJC_ARC = YES; 273 | CLANG_WARN_BOOL_CONVERSION = YES; 274 | CLANG_WARN_CONSTANT_CONVERSION = YES; 275 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 276 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 277 | CLANG_WARN_EMPTY_BODY = YES; 278 | CLANG_WARN_ENUM_CONVERSION = YES; 279 | CLANG_WARN_INFINITE_RECURSION = YES; 280 | CLANG_WARN_INT_CONVERSION = YES; 281 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 282 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 283 | CLANG_WARN_UNREACHABLE_CODE = YES; 284 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 285 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 286 | COPY_PHASE_STRIP = NO; 287 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 288 | ENABLE_NS_ASSERTIONS = NO; 289 | ENABLE_STRICT_OBJC_MSGSEND = YES; 290 | GCC_C_LANGUAGE_STANDARD = gnu99; 291 | GCC_NO_COMMON_BLOCKS = YES; 292 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 293 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 294 | GCC_WARN_UNDECLARED_SELECTOR = YES; 295 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 296 | GCC_WARN_UNUSED_FUNCTION = YES; 297 | GCC_WARN_UNUSED_VARIABLE = YES; 298 | IPHONEOS_DEPLOYMENT_TARGET = 10.3; 299 | MTL_ENABLE_DEBUG_INFO = NO; 300 | SDKROOT = iphoneos; 301 | VALIDATE_PRODUCT = YES; 302 | }; 303 | name = Release; 304 | }; 305 | C5ACE5671F452C4D0069978B /* Debug */ = { 306 | isa = XCBuildConfiguration; 307 | buildSettings = { 308 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 309 | GCC_PREFIX_HEADER = "$(PRODUCT_NAME)/PrefixHeader.pch"; 310 | INFOPLIST_FILE = BRCollectionViewDemo/Info.plist; 311 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 312 | PRODUCT_BUNDLE_IDENTIFIER = com.renb.BRCollectionViewDemo; 313 | PRODUCT_NAME = "$(TARGET_NAME)"; 314 | }; 315 | name = Debug; 316 | }; 317 | C5ACE5681F452C4D0069978B /* Release */ = { 318 | isa = XCBuildConfiguration; 319 | buildSettings = { 320 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 321 | GCC_PREFIX_HEADER = "$(PRODUCT_NAME)/PrefixHeader.pch"; 322 | INFOPLIST_FILE = BRCollectionViewDemo/Info.plist; 323 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 324 | PRODUCT_BUNDLE_IDENTIFIER = com.renb.BRCollectionViewDemo; 325 | PRODUCT_NAME = "$(TARGET_NAME)"; 326 | }; 327 | name = Release; 328 | }; 329 | /* End XCBuildConfiguration section */ 330 | 331 | /* Begin XCConfigurationList section */ 332 | C5ACE54A1F452C4D0069978B /* Build configuration list for PBXProject "BRCollectionViewDemo" */ = { 333 | isa = XCConfigurationList; 334 | buildConfigurations = ( 335 | C5ACE5641F452C4D0069978B /* Debug */, 336 | C5ACE5651F452C4D0069978B /* Release */, 337 | ); 338 | defaultConfigurationIsVisible = 0; 339 | defaultConfigurationName = Release; 340 | }; 341 | C5ACE5661F452C4D0069978B /* Build configuration list for PBXNativeTarget "BRCollectionViewDemo" */ = { 342 | isa = XCConfigurationList; 343 | buildConfigurations = ( 344 | C5ACE5671F452C4D0069978B /* Debug */, 345 | C5ACE5681F452C4D0069978B /* Release */, 346 | ); 347 | defaultConfigurationIsVisible = 0; 348 | defaultConfigurationName = Release; 349 | }; 350 | /* End XCConfigurationList section */ 351 | }; 352 | rootObject = C5ACE5471F452C4D0069978B /* Project object */; 353 | } 354 | -------------------------------------------------------------------------------- /BRCollectionViewDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /BRCollectionViewDemo/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // BRCollectionViewDemo 4 | // 5 | // Created by 任波 on 2017/8/17. 6 | // Copyright © 2017年 renb. 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 | -------------------------------------------------------------------------------- /BRCollectionViewDemo/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // BRCollectionViewDemo 4 | // 5 | // Created by 任波 on 2017/8/17. 6 | // Copyright © 2017年 renb. 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 | 24 | - (void)applicationWillResignActive:(UIApplication *)application { 25 | // 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. 26 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. 27 | } 28 | 29 | 30 | - (void)applicationDidEnterBackground:(UIApplication *)application { 31 | // 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. 32 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 33 | } 34 | 35 | 36 | - (void)applicationWillEnterForeground:(UIApplication *)application { 37 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. 38 | } 39 | 40 | 41 | - (void)applicationDidBecomeActive:(UIApplication *)application { 42 | // 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. 43 | } 44 | 45 | 46 | - (void)applicationWillTerminate:(UIApplication *)application { 47 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 48 | } 49 | 50 | 51 | @end 52 | -------------------------------------------------------------------------------- /BRCollectionViewDemo/Assets.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 | } -------------------------------------------------------------------------------- /BRCollectionViewDemo/BRCirclePickerView/BRCircleLayout.h: -------------------------------------------------------------------------------- 1 | // 2 | // BRCircleLayout.h 3 | // AiBaoYun 4 | // 5 | // Created by 任波 on 2017/6/6. 6 | // Copyright © 2017年 aby. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface BRCircleLayout : UICollectionViewLayout 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /BRCollectionViewDemo/BRCirclePickerView/BRCircleLayout.m: -------------------------------------------------------------------------------- 1 | // 2 | // BRCircleLayout.m 3 | // AiBaoYun 4 | // 5 | // Created by 任波 on 2017/6/6. 6 | // Copyright © 2017年 aby. All rights reserved. 7 | // 8 | 9 | #import "BRCircleLayout.h" 10 | 11 | #define angular 60 12 | 13 | @interface BRCircleLayout () 14 | // item 的大小 15 | @property (nonatomic, assign) CGSize itemSize; 16 | // item 中心点围成的圆的半径 17 | @property (nonatomic, assign) NSInteger radius; 18 | // item 的个数 19 | @property (nonatomic, assign) NSInteger itemCount; 20 | 21 | @end 22 | 23 | @implementation BRCircleLayout 24 | 25 | /** 用来做布局的初始化操作 */ 26 | - (void)prepareLayout { 27 | [super prepareLayout]; 28 | // 初始化布局 29 | [self setupLayout]; 30 | } 31 | 32 | // 初始化布局 33 | - (void)setupLayout { 34 | self.itemSize = CGSizeMake(100 * kScaleFit, 100 * kScaleFit); 35 | self.radius = (self.collectionView.frame.size.width - self.itemSize.width) / 2; 36 | self.itemCount = [self.collectionView numberOfItemsInSection:0]; 37 | } 38 | 39 | // 设置内容区域的大小 40 | - (CGSize)collectionViewContentSize { 41 | return CGSizeMake(self.collectionView.bounds.size.width + (self.itemCount - 180 / angular) * self.collectionView.bounds.size.width, self.collectionView.bounds.size.height); 42 | } 43 | 44 | /** 这个方法的返回值是一个数组,数组里面存放着rect范围内所有元素的布局排布 */ 45 | - (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect { 46 | NSMutableArray *attributes = [[NSMutableArray alloc] init]; 47 | for (int i = 0; i < self.itemCount; i++) { 48 | UICollectionViewLayoutAttributes *attribute = [self layoutAttributesForItemAtIndexPath:[NSIndexPath indexPathForItem:i inSection:0]]; 49 | if (CGRectContainsRect(rect, attribute.frame) || CGRectIntersectsRect(rect, attribute.frame)) { 50 | [attributes addObject:attribute]; 51 | } 52 | } 53 | return attributes; 54 | } 55 | 56 | - (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath { 57 | CGFloat visibleItemIndex = indexPath.item - self.collectionView.contentOffset.x / (self.collectionView.bounds.size.width * 1.0f); 58 | UICollectionViewLayoutAttributes *attribute = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath]; 59 | attribute.size = self.itemSize; 60 | attribute.hidden = YES; 61 | attribute.center = CGPointMake(self.collectionView.contentOffset.x + self.collectionView.frame.size.width / 2, self.collectionView.frame.size.height / 2); 62 | CGFloat angle = visibleItemIndex * (angular / 180.0 * M_PI); 63 | //NSLog(@"angle[%ld] = %f", indexPath.item, angle); 64 | CGAffineTransform transform = CGAffineTransformIdentity; 65 | if (angle < M_PI && angle > - M_PI / 3) { 66 | if (angle > 2 * M_PI / 3 && angle < M_PI) { 67 | attribute.alpha = (M_PI - angle) / (M_PI / 3); 68 | attribute.hidden = NO; 69 | } else if (angle > - M_PI / 3 && angle < 0) { 70 | attribute.alpha = 1 - (0 - angle) / (M_PI / 3); 71 | attribute.hidden = NO; 72 | } else { 73 | attribute.alpha = 1; 74 | attribute.hidden = NO; 75 | } 76 | // 1.位移移动,平移 (CGFloat tx, CGFloat ty), 起始位置 x 会加上tx , y 会加上 ty 77 | CGFloat tx = -(self.radius - 18 * kScaleFit) * cos(angle + M_PI / 6); 78 | CGFloat ty = (self.radius - 18 * kScaleFit) * sin(angle + M_PI / 6); 79 | transform = CGAffineTransformMakeTranslation(tx, ty); 80 | // 2.设置每个item相对于自己中心点旋转的角度 81 | transform = CGAffineTransformRotate(transform, -(angle - M_PI / 3)); 82 | } 83 | 84 | attribute.transform = transform; 85 | 86 | return attribute; 87 | } 88 | 89 | // 返回yes,当collectionView的显示范围发生改变的时候,就会重新刷新布局 90 | // 一旦重新刷新布局,就会重新调用下面的方法:prepareLayout、layoutAttributesForElementsInRect:方法 91 | - (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds { 92 | return YES; 93 | } 94 | 95 | @end 96 | -------------------------------------------------------------------------------- /BRCollectionViewDemo/BRCirclePickerView/BRCirclePickerView.h: -------------------------------------------------------------------------------- 1 | // 2 | // BRCirclePickerView.h 3 | // AiBaoYun 4 | // 5 | // Created by 任波 on 2017/6/6. 6 | // Copyright © 2017年 aby. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | typedef void(^BRDidTapBlock)(); 12 | typedef void(^BRDidScrollEndBlock)(NSString *currentValue); 13 | 14 | @interface BRCirclePickerView : UIView 15 | /** 圆盘labelText数组 */ 16 | @property (nonatomic, strong) NSArray *circleTextArr; 17 | /** 当前日期字符串 */ 18 | @property (nonatomic, strong) NSString *nowDateString; 19 | /** 圆盘中心label文本 */ 20 | @property (nonatomic, strong) NSMutableAttributedString *centerText; 21 | /** 当前怀孕周数对应的索引 */ 22 | @property (nonatomic, assign) NSInteger currentSelIndex; 23 | /** 当前怀孕几率 */ 24 | @property (nonatomic, assign) CGFloat currentProbability; 25 | 26 | /** 中心label点击事件的回调 */ 27 | @property (nonatomic, copy) BRDidTapBlock didTapCenterLabelBlock; 28 | /** 滚动停止后的回调 */ 29 | @property (nonatomic, copy) BRDidScrollEndBlock didScrollEndBlock; 30 | 31 | /** 初始化方法 */ 32 | - (instancetype)initWithFrame:(CGRect)frame homePageFlag:(NSInteger)flag; 33 | 34 | /** 刷新初始化转盘数据 */ 35 | - (void)reloadDataForInit; 36 | 37 | /** 刷新滚动结束转盘数据 */ 38 | - (void)reloadDataForSrcollEnd; 39 | 40 | @end 41 | -------------------------------------------------------------------------------- /BRCollectionViewDemo/BRCirclePickerView/BRCirclePickerView.m: -------------------------------------------------------------------------------- 1 | // 2 | // BRCirclePickerView.m 3 | // AiBaoYun 4 | // 5 | // Created by 任波 on 2017/6/6. 6 | // Copyright © 2017年 aby. All rights reserved. 7 | // 8 | 9 | #import "BRCirclePickerView.h" 10 | #import "BRCircleLayout.h" 11 | #import "NSDate+BRAdd.h" 12 | #import "NSString+BRAdd.h" 13 | 14 | /** 圆盘弧形文本个数 */ 15 | #define itemCount 6 16 | /** 圆盘半径 */ 17 | #define RADIUS (self.bounds.size.width / 2) 18 | /** 弧度转角度 */ 19 | #define RADIAN_TO_ANGLE(__VALUE__) ((__VALUE__) * 180 / M_PI) 20 | /** 角度转弧度 */ 21 | #define ANGLE_TO_RADIAN(__VALUE__) ((__VALUE__) * M_PI / 180.0) 22 | 23 | @interface BRCirclePickerView () 24 | { 25 | NSInteger _identityFlag; // 身份标识(1:备孕期,2:孕产期,3:育儿期) 26 | NSInteger _lastSelIndex; // 上一个选中的index 27 | } 28 | /** 底部背景图层 */ 29 | @property (nonatomic, strong) UIImageView *bgImageView; 30 | /** 底部转动图层 */ 31 | @property (nonatomic, strong) UIImageView *rotateImageView; 32 | /** 圆盘滚动视图 */ 33 | @property (nonatomic, strong) UICollectionView *collectionView; 34 | /** 圆盘中心背景图片 */ 35 | @property (nonatomic, strong) UIImageView *centerImageView; 36 | /** 圆盘中心Label */ 37 | @property (nonatomic, strong) UILabel *centerLabel; 38 | 39 | /** 日期 */ 40 | @property (nonatomic, strong) UILabel *dateLabel; 41 | 42 | @end 43 | 44 | @implementation BRCirclePickerView 45 | 46 | - (instancetype)initWithFrame:(CGRect)frame homePageFlag:(NSInteger)flag { 47 | if (self = [super initWithFrame:frame]) { 48 | _identityFlag = flag; 49 | 50 | [self setupUI]; 51 | } 52 | return self; 53 | } 54 | 55 | #pragma mark - 添加子视图 56 | - (void)setupUI { 57 | self.bgImageView.hidden = NO; 58 | self.rotateImageView.hidden = NO; 59 | self.collectionView.hidden = NO; 60 | self.centerImageView.hidden = NO; 61 | self.dateLabel.hidden = NO; 62 | } 63 | 64 | #pragma mark - 刷新数据 65 | - (void)reloadDataForInit { 66 | // 刷新collectionView 67 | [self.collectionView reloadData]; 68 | // 加载当前日期label 69 | self.dateLabel.text = self.nowDateString; 70 | // 刷新centerLabel的数据 71 | self.centerLabel.attributedText = self.centerText; 72 | 73 | // 默认滚动 74 | [self scrollToItemAtIndex:self.currentSelIndex animated:YES]; 75 | } 76 | 77 | - (void)reloadDataForSrcollEnd { 78 | if (_identityFlag == 1) { 79 | // 刷新centerLabel的数据 80 | self.centerLabel.attributedText = self.centerText; 81 | } 82 | } 83 | 84 | #pragma mark - 懒加载 子视图 85 | - (UIImageView *)bgImageView { 86 | if (!_bgImageView) { 87 | _bgImageView = [[UIImageView alloc]initWithFrame:CGRectMake(5 * kScaleFit, 5 * kScaleFit, 310 * kScaleFit, 310 * kScaleFit)]; 88 | _bgImageView.backgroundColor = [UIColor clearColor]; 89 | NSString *imageName = [NSString stringWithFormat:@"home%ld_disc_bottom_shadow", _identityFlag]; 90 | _bgImageView.image = [UIImage imageNamed:imageName]; 91 | [self addSubview:_bgImageView]; 92 | } 93 | return _bgImageView; 94 | } 95 | 96 | - (UIImageView *)rotateImageView { 97 | if (!_rotateImageView) { 98 | _rotateImageView = [[UIImageView alloc]initWithFrame:CGRectMake(5 * kScaleFit, 5 * kScaleFit, 310 * kScaleFit, 310 * kScaleFit)]; 99 | _rotateImageView.backgroundColor = [UIColor clearColor]; 100 | NSString *imageName = [NSString stringWithFormat:@"home%ld_disc_bottom", _identityFlag]; 101 | _rotateImageView.image = [UIImage imageNamed:imageName]; 102 | [self addSubview:_rotateImageView]; 103 | } 104 | return _rotateImageView; 105 | } 106 | 107 | - (UICollectionView *)collectionView { 108 | if (!_collectionView) { 109 | BRCircleLayout *layout = [[BRCircleLayout alloc]init]; 110 | _collectionView = [[UICollectionView alloc]initWithFrame:self.bounds collectionViewLayout:layout]; 111 | _collectionView.backgroundColor = [UIColor clearColor]; 112 | // 开启分页 113 | _collectionView.pagingEnabled = YES; 114 | // 隐藏水平滚动条 115 | _collectionView.showsHorizontalScrollIndicator = NO; 116 | _collectionView.delegate = self; 117 | _collectionView.dataSource = self; 118 | [_collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:@"cellID"]; 119 | [self addSubview:_collectionView]; 120 | } 121 | return _collectionView; 122 | } 123 | 124 | - (UIImageView *)centerImageView { 125 | if (!_centerImageView) { 126 | _centerImageView = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, 162 * kScaleFit, 162 * kScaleFit)]; 127 | _centerImageView.center = self.collectionView.center; 128 | _centerImageView.backgroundColor = [UIColor clearColor]; 129 | NSString *imageName = [NSString stringWithFormat:@"home%ld_disc_center", _identityFlag]; 130 | _centerImageView.image = [UIImage imageNamed:imageName]; 131 | [self addSubview:_centerImageView]; 132 | } 133 | return _centerImageView; 134 | } 135 | 136 | - (UILabel *)centerLabel { 137 | if (!_centerLabel) { 138 | _centerLabel = [[UILabel alloc]initWithFrame:CGRectMake(0, 0, 80 * kScaleFit, 80 * kScaleFit)]; 139 | _centerLabel.center = self.center; 140 | _centerLabel.backgroundColor = [UIColor clearColor]; 141 | _centerLabel.textAlignment = NSTextAlignmentCenter; 142 | _centerLabel.textColor = [UIColor whiteColor]; 143 | _centerLabel.font = [UIFont boldSystemFontOfSize:10.0f * kScaleFit]; 144 | _centerLabel.numberOfLines = 0; 145 | _centerLabel.layer.cornerRadius = 40.0f * kScaleFit; 146 | _centerLabel.layer.masksToBounds = YES; 147 | [self addSubview:_centerLabel]; 148 | _centerLabel.attributedText = self.centerText; 149 | // label 点击事件 150 | _centerLabel.userInteractionEnabled = YES; 151 | UITapGestureRecognizer *myTap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(didTapCenterLabel)]; 152 | [_centerLabel addGestureRecognizer:myTap]; 153 | } 154 | return _centerLabel; 155 | } 156 | 157 | - (void)didTapCenterLabel { 158 | // 执行外界传来的block 159 | self.didTapCenterLabelBlock(); 160 | } 161 | 162 | - (UILabel *)dateLabel { 163 | if (!_dateLabel) { 164 | _dateLabel = [[UILabel alloc]initWithFrame:CGRectMake(0, 0, 100 * kScaleFit, 20 * kScaleFit)]; 165 | _dateLabel.center = CGPointMake(self.center.x, self.center.y + 100 * kScaleFit); 166 | _dateLabel.backgroundColor = [UIColor clearColor]; 167 | _dateLabel.font = [UIFont systemFontOfSize:14.0f * kScaleFit]; 168 | _dateLabel.textColor = [UIColor whiteColor]; 169 | _dateLabel.textAlignment = NSTextAlignmentCenter; 170 | _dateLabel.text = self.nowDateString; 171 | [self addSubview:_dateLabel]; 172 | } 173 | return _dateLabel; 174 | } 175 | 176 | - (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView { 177 | return 1; 178 | } 179 | 180 | - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section { 181 | return self.circleTextArr.count; 182 | } 183 | 184 | - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { 185 | UICollectionViewCell * cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"cellID" forIndexPath:indexPath]; 186 | cell.backgroundColor = [UIColor clearColor]; 187 | 188 | for (UIView *view in cell.contentView.subviews) { 189 | [view removeFromSuperview]; 190 | } 191 | 192 | if (self.circleTextArr.count > 0) { 193 | UILabel *arcTextLabel = [[UILabel alloc]initWithFrame:CGRectMake(0, 0, 100 * kScaleFit, 100 * kScaleFit)]; 194 | arcTextLabel.backgroundColor = [UIColor clearColor]; 195 | arcTextLabel.font = [UIFont systemFontOfSize:14.0f * kScaleFit]; 196 | arcTextLabel.textColor = [UIColor whiteColor]; 197 | arcTextLabel.textAlignment = NSTextAlignmentCenter; 198 | arcTextLabel.text = self.circleTextArr[indexPath.item]; 199 | [cell.contentView addSubview:arcTextLabel]; 200 | } 201 | 202 | return cell; 203 | } 204 | 205 | 206 | - (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath { 207 | NSLog(@"点击了:%ld, 当前索引:%ld", indexPath.item, self.currentSelIndex); 208 | if (indexPath.item > 0 && indexPath.item < self.circleTextArr.count - 1) { 209 | _lastSelIndex = self.currentSelIndex; 210 | if (indexPath.item <= self.currentSelIndex - 1) { 211 | NSLog(@"上一页"); 212 | // 滚动到新位置 213 | [self scrollToItemAtIndex:indexPath.item animated:YES]; 214 | self.currentSelIndex = indexPath.item; 215 | [self handlerReloadDidScrollEnd]; 216 | } 217 | if (indexPath.item >= self.currentSelIndex + 1) { 218 | NSLog(@"下一页"); 219 | [self scrollToItemAtIndex:indexPath.item animated:YES]; 220 | self.currentSelIndex = indexPath.item; 221 | [self handlerReloadDidScrollEnd]; 222 | } 223 | } 224 | } 225 | 226 | #pragma mark - 滚动到指定位置 227 | /** 滚动到指定位置 */ 228 | - (void)scrollToItemAtIndex:(NSInteger)index animated:(BOOL)animated { 229 | [self.collectionView setContentOffset:CGPointMake(self.collectionView.bounds.size.width * (index - 1), 0) animated:animated]; 230 | } 231 | 232 | #pragma mark - UIScrollViewDelegate 233 | // 滚动就会触发 这里对滑动的contentOffset进行监控,实现循环滚动 234 | - (void)scrollViewDidScroll:(UIScrollView *)scrollView { 235 | CGFloat offsetX = scrollView.contentOffset.x; 236 | // 旋转的弧度 237 | CGFloat radianOffset = offsetX * (M_PI / itemCount) / RADIUS; 238 | self.rotateImageView.transform = CGAffineTransformMakeRotation(radianOffset); 239 | // 旋转的角度 240 | //CGFloat angleOffset = RADIAN_TO_ANGLE(radianOffset); 241 | //NSLog(@"滚动进行中... offSetX:%f, 旋转角度:%f", offsetX, angleOffset); 242 | 243 | } 244 | 245 | /** 结束减速时触发(滚动停止) */ 246 | - (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView { 247 | _lastSelIndex = self.currentSelIndex; 248 | NSInteger index = roundf(scrollView.contentOffset.x / self.collectionView.bounds.size.width); 249 | self.currentSelIndex = index + 1; 250 | [self handlerReloadDidScrollEnd]; 251 | } 252 | 253 | /** 回调,执行外部刷新 */ 254 | - (void)handlerReloadDidScrollEnd { 255 | NSLog(@"currentSelIndex = %ld, lastSelIndex = %ld", self.currentSelIndex, _lastSelIndex); 256 | NSLog(@"改变索引:%ld", self.currentSelIndex - _lastSelIndex); 257 | // 执行回调 258 | if (self.didScrollEndBlock) { 259 | if (_identityFlag == 1) { 260 | self.nowDateString = [NSDate date:self.nowDateString formatter:@"yyyy-MM-dd" addDays:self.currentSelIndex - _lastSelIndex]; 261 | self.dateLabel.text = self.nowDateString; 262 | // 获取当前日期 263 | NSLog(@"获取当前日期:%@", self.nowDateString); 264 | self.didScrollEndBlock(self.nowDateString); 265 | } 266 | if (_identityFlag == 2) { 267 | self.nowDateString = [NSDate date:self.nowDateString formatter:@"M月d日" addDays:self.currentSelIndex - _lastSelIndex]; 268 | self.dateLabel.text = self.nowDateString; 269 | // 获取当前怀孕周 270 | NSString *weekStr = [self.circleTextArr objectAtIndex:self.currentSelIndex]; 271 | if ([weekStr containsString:@"周"]) { 272 | NSString *tempStr = [weekStr componentsSeparatedByString:@"周"][0]; 273 | weekStr = [NSString stringWithFormat:@"%ld", [tempStr IntegerInString]]; 274 | } else { 275 | weekStr = @"0"; 276 | } 277 | NSLog(@"获取当前孕周:%@", weekStr); 278 | self.didScrollEndBlock(weekStr); 279 | } 280 | if (_identityFlag == 3) { 281 | self.nowDateString = [NSDate date:self.nowDateString formatter:@"M月d日" addDays:self.currentSelIndex - _lastSelIndex]; 282 | self.dateLabel.text = self.nowDateString; 283 | // 获取宝宝出生天数 284 | NSString *dayStr = [self.circleTextArr objectAtIndex:self.currentSelIndex]; 285 | dayStr = [NSString stringWithFormat:@"%ld", [dayStr IntegerInString]]; 286 | NSLog(@"宝宝出生天数:%@", dayStr); 287 | self.didScrollEndBlock(dayStr); 288 | } 289 | } 290 | } 291 | 292 | - (NSArray *)circleTextArr { 293 | if (!_circleTextArr) { 294 | _circleTextArr = [NSArray array]; 295 | } 296 | return _circleTextArr; 297 | } 298 | 299 | @end 300 | -------------------------------------------------------------------------------- /BRCollectionViewDemo/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /BRCollectionViewDemo/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /BRCollectionViewDemo/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UILaunchStoryboardName 24 | LaunchScreen 25 | UIMainStoryboardFile 26 | Main 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /BRCollectionViewDemo/NSDate+BRAdd.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSData+BRAdd.h 3 | // MyBaseProject 4 | // 5 | // Created by 任波 on 2017/5/25. 6 | // Copyright © 2017年 apple. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NSDate (BRAdd) 12 | 13 | /** 获取系统当前的时间戳,即当前时间距1970的秒数(以毫秒为单位) */ 14 | + (NSString *)currentTimestamp; 15 | 16 | 17 | /** 获取当前的时间 */ 18 | + (NSString *)currentDateString; 19 | 20 | 21 | /** 22 | * 按指定格式获取当前的时间 23 | * 24 | * @param formatterStr 设置格式:yyyy-MM-dd HH:mm:ss 25 | */ 26 | + (NSString *)currentDateStringWithFormat:(NSString *)formatterStr; 27 | 28 | 29 | /** 30 | * 计算两个日期之间的天数 31 | * 32 | * @param beginDateString 设置格式:yyyy-MM-dd 33 | * @param endDateString 设置格式:yyyy-MM-dd 34 | */ 35 | + (NSInteger)deltaDaysFrombeginDate:(NSString *)beginDateString endDate:(NSString *)endDateString; 36 | 37 | /** 38 | * 返回指定时间差值的日期字符串 39 | * 40 | * @param delta 时间差值 41 | * @return 日期字符串,格式:yyyy-MM-dd HH:mm:ss 42 | */ 43 | + (NSString *)dateStringWithDelta:(NSTimeInterval)delta; 44 | 45 | 46 | /** 47 | * 指定时间加指定天数 48 | * 49 | * @param dateString 日期 50 | * @param days 天数 51 | * @return 日期字符串,格式:yyyy-MM-dd 52 | */ 53 | + (NSString *)date:(NSString *)dateString formatter:(NSString *)formatterStr addDays:(NSInteger)days; 54 | 55 | 56 | /** 57 | * 返回日期格式字符串 58 | * 59 | * @param dateStr 需要转换的时间点 60 | * @return 日期字符串 61 | * 返回具体格式如下: 62 | * - 刚刚(一分钟内) 63 | * - X分钟前(一小时内) 64 | * - X小时前(当天) 65 | * - MM-dd HH:mm(一年内) 66 | * - yyyy-MM-dd HH:mm(更早期) 67 | */ 68 | + (NSString *)dateDescriptionWithTargetDate:(NSString *)dateStr andTargetDateFormat:(NSString *)dateFormatStr; 69 | 70 | @end 71 | -------------------------------------------------------------------------------- /BRCollectionViewDemo/NSDate+BRAdd.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSData+BRAdd.m 3 | // MyBaseProject 4 | // 5 | // Created by 任波 on 2017/5/25. 6 | // Copyright © 2017年 apple. All rights reserved. 7 | // 8 | 9 | #import "NSDate+BRAdd.h" 10 | 11 | @implementation NSDate (BRAdd) 12 | 13 | // yyyy-MM-dd hh:mm:ss 12小时制 14 | // yyyy-MM-dd HH:mm:ss 24小时制 15 | // yyyy-MM-dd HH:mm:ss.SSS (SSS毫秒) 16 | 17 | #pragma mark - 获取系统当前的时间戳,即当前时间距1970的秒数(以毫秒为单位) 18 | + (NSString *)currentTimestamp { 19 | NSDate *date = [NSDate dateWithTimeIntervalSinceNow:0]; 20 | /** 当前时间距1970的秒数。*1000 是精确到毫秒,不乘就是精确到秒 */ 21 | NSTimeInterval interval = [date timeIntervalSince1970] * 1000; 22 | NSString *timeString = [NSString stringWithFormat:@"%0.f", interval]; 23 | 24 | return timeString; 25 | } 26 | 27 | #pragma mark - 获取当前的时间 28 | + (NSString *)currentDateString { 29 | return [self currentDateStringWithFormat:@"yyyy-MM-dd HH:mm:ss"]; 30 | } 31 | 32 | #pragma mark - 按指定格式获取当前的时间 33 | + (NSString *)currentDateStringWithFormat:(NSString *)formatterStr { 34 | // 获取系统当前时间 35 | NSDate *currentDate = [NSDate date]; 36 | // 用于格式化NSDate对象 37 | NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; 38 | // 设置格式:yyyy-MM-dd HH:mm:ss 39 | formatter.dateFormat = formatterStr; 40 | // 将 NSDate 按 formatter格式 转成 NSString 41 | NSString *currentDateStr = [formatter stringFromDate:currentDate]; 42 | // 输出currentDateStr 43 | return currentDateStr; 44 | } 45 | 46 | #pragma mark - 返回指定时间差值的日期字符串 47 | + (NSString *)dateStringWithDelta:(NSTimeInterval)delta { 48 | NSDate *date = [NSDate dateWithTimeIntervalSinceNow:delta]; 49 | NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; 50 | formatter.dateFormat = @"yyyy-MM-dd HH:mm:ss"; 51 | return [formatter stringFromDate:date]; 52 | } 53 | 54 | //计算两个日期之间的天数 55 | + (NSInteger)deltaDaysFrombeginDate:(NSString *)beginDateString endDate:(NSString *)endDateString { 56 | //创建日期格式化对象 57 | NSDateFormatter *dateFormatter=[[NSDateFormatter alloc] init]; 58 | dateFormatter.dateFormat = @"yyyy-MM-dd"; 59 | NSDate *beginDate = [dateFormatter dateFromString:beginDateString]; 60 | NSDate *endDate = [dateFormatter dateFromString:endDateString]; 61 | //取两个日期对象的时间间隔 62 | NSTimeInterval deltaTime = [endDate timeIntervalSinceDate:beginDate]; 63 | NSInteger days = (NSInteger)deltaTime / (24 * 60 * 60); 64 | //NSInteger hours = ((NSInteger)deltaTime - days * 24 * 60 * 60) / (60 * 60); 65 | //NSInteger minute = ((NSInteger)deltaTime - days * 24 * 60 * 60 - hours * 60 * 60) / 60; 66 | //NSInteger second = (NSInteger)deltaTime - days * 24 * 60 * 60 - hours * 60 * 60 - minute * 60; 67 | 68 | return days; 69 | } 70 | 71 | #pragma mark - 返回 指定时间加指定天数 结果日期字符串 72 | + (NSString *)date:(NSString *)dateString formatter:(NSString *)formatterStr addDays:(NSInteger)days { 73 | NSDateFormatter *dateFormatter = [[NSDateFormatter alloc]init]; 74 | dateFormatter.dateFormat = formatterStr; //yyyy-MM-dd 75 | NSDate *myDate = [dateFormatter dateFromString:dateString]; 76 | NSDate *newDate = [myDate dateByAddingTimeInterval:60 * 60 * 24 * days]; 77 | //NSDate *newDate = [NSDate dateWithTimeInterval:60 * 60 * 24 * days sinceDate:myDate]; 78 | NSString *newDateString = [dateFormatter stringFromDate:newDate]; 79 | NSLog(@"%@", newDateString); 80 | return newDateString; 81 | } 82 | 83 | #pragma mark - 返回日期格式字符串 @"2016-10-16 14:30:30" @"yyyy-MM-dd HH:mm:ss" 84 | // 注意:一个日期字符串必须 与 它相应的日期格式对应,这个才能被系统识别为日期 85 | + (NSString *)dateDescriptionWithTargetDate:(NSString *)dateStr andTargetDateFormat:(NSString *)dateFormatStr { 86 | // 1.获取当前时间 87 | NSDate *currentDate = [NSDate date]; 88 | // 2.目标时间 89 | NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; 90 | formatter.dateFormat = dateFormatStr; 91 | NSDate *targetDate = [formatter dateFromString:dateStr]; 92 | 93 | NSCalendar *calendar = [NSCalendar currentCalendar]; 94 | NSDateFormatter *returnFormatter = [[NSDateFormatter alloc] init]; 95 | if ([calendar isDate:targetDate equalToDate:currentDate toUnitGranularity:NSCalendarUnitYear]) { 96 | if ([calendar isDateInToday:targetDate]) { 97 | NSDateComponents *components = [calendar components:NSCalendarUnitMinute | NSCalendarUnitHour fromDate:targetDate toDate:currentDate options:0]; 98 | if (components.hour == 0) { 99 | if (components.minute == 0) { 100 | return @"刚刚"; 101 | } else { 102 | return [NSString stringWithFormat:@"%ld分钟前", (long)components.minute]; 103 | } 104 | } else { 105 | return [NSString stringWithFormat:@"%ld小时前", (long)components.hour]; 106 | } 107 | } else if ([calendar isDateInYesterday:targetDate]) { 108 | return @"昨天"; 109 | } else { 110 | returnFormatter.dateFormat = @"M-d"; 111 | return [returnFormatter stringFromDate:targetDate]; 112 | } 113 | } else { 114 | returnFormatter.dateFormat = @"yyyy-M-d"; 115 | return [returnFormatter stringFromDate:targetDate]; 116 | } 117 | return nil; 118 | } 119 | 120 | 121 | @end 122 | -------------------------------------------------------------------------------- /BRCollectionViewDemo/NSString+BRAdd.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSString+BRAdd.h 3 | // BRCollectionViewDemo 4 | // 5 | // Created by 任波 on 2018/1/4. 6 | // Copyright © 2018年 renb. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NSString (BRAdd) 12 | 13 | /** 获取字符串中的数字 */ 14 | - (NSInteger)IntegerInString; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /BRCollectionViewDemo/NSString+BRAdd.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSString+BRAdd.m 3 | // BRCollectionViewDemo 4 | // 5 | // Created by 任波 on 2018/1/4. 6 | // Copyright © 2018年 renb. All rights reserved. 7 | // 8 | 9 | #import "NSString+BRAdd.h" 10 | 11 | @implementation NSString (BRAdd) 12 | 13 | #pragma mark - 扫瞄器(NSScanner),获取字符串中的数字 14 | - (NSInteger)IntegerInString { 15 | NSScanner *scanner = [NSScanner scannerWithString:self]; 16 | [scanner scanUpToCharactersFromSet:[NSCharacterSet decimalDigitCharacterSet] intoString:nil]; 17 | int number; 18 | [scanner scanInt:&number]; 19 | return number; 20 | } 21 | 22 | @end 23 | -------------------------------------------------------------------------------- /BRCollectionViewDemo/PrefixHeader.pch: -------------------------------------------------------------------------------- 1 | // 2 | // PrefixHeader.pch 3 | // BRCollectionViewDemo 4 | // 5 | // Created by 任波 on 2017/8/17. 6 | // Copyright © 2017年 renb. All rights reserved. 7 | // 8 | 9 | #ifndef PrefixHeader_pch 10 | #define PrefixHeader_pch 11 | 12 | // Include any system framework and library headers here that should be included in all compilation units. 13 | // You will also need to set the Prefix Header build setting of one or more of your targets to reference this file. 14 | 15 | /// 屏幕大小、宽、高 16 | #define SCREEN_BOUNDS [UIScreen mainScreen].bounds 17 | #define SCREEN_WIDTH [UIScreen mainScreen].bounds.size.width 18 | #define SCREEN_HEIGHT [UIScreen mainScreen].bounds.size.height 19 | 20 | // 等比例适配系数 21 | #define kScaleFit (SCREEN_WIDTH / 375.0f) 22 | 23 | /// RGB颜色(10进制) 24 | #define RGB(r, g, b, a) [UIColor colorWithRed:(r) / 255.0 green:(g) / 255.0 blue:(b) / 255.0 alpha:(a)] 25 | 26 | /// RGB颜色(16进制) 27 | #define RGB_HEX(rgbValue, a) \ 28 | [UIColor colorWithRed:((CGFloat)((rgbValue & 0xFF0000) >> 16)) / 255.0 \ 29 | green:((CGFloat)((rgbValue & 0xFF00) >> 8)) / 255.0 \ 30 | blue:((CGFloat)(rgbValue & 0xFF)) / 255.0 alpha:(a)] 31 | 32 | #endif /* PrefixHeader_pch */ 33 | -------------------------------------------------------------------------------- /BRCollectionViewDemo/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // BRCollectionViewDemo 4 | // 5 | // Created by 任波 on 2017/8/17. 6 | // Copyright © 2017年 renb. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ViewController : UIViewController 12 | 13 | 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /BRCollectionViewDemo/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // BRCollectionViewDemo 4 | // 5 | // Created by 任波 on 2017/8/17. 6 | // Copyright © 2017年 renb. All rights reserved. 7 | // 8 | 9 | #import "ViewController.h" 10 | 11 | @interface ViewController () 12 | 13 | @end 14 | 15 | @implementation ViewController 16 | 17 | - (void)viewDidLoad { 18 | [super viewDidLoad]; 19 | // Do any additional setup after loading the view, typically from a nib. 20 | } 21 | 22 | 23 | - (void)didReceiveMemoryWarning { 24 | [super didReceiveMemoryWarning]; 25 | // Dispose of any resources that can be recreated. 26 | } 27 | 28 | 29 | @end 30 | -------------------------------------------------------------------------------- /BRCollectionViewDemo/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // BRCollectionViewDemo 4 | // 5 | // Created by 任波 on 2017/8/17. 6 | // Copyright © 2017年 renb. 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 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # BRCollectionViewDemo 2 | CollectionView的各种使用,自定义layout 3 | --------------------------------------------------------------------------------