├── .gitignore ├── .swift-version ├── .travis.yml ├── 1.png ├── 2.png ├── 3.png ├── 4.png ├── 5.png ├── 6.png ├── 7.png ├── Example ├── JJCollectionViewRoundFlowLayout_Swift.xcodeproj │ ├── project.pbxproj │ └── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist ├── JJCollectionViewRoundFlowLayout_Swift.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist ├── JJCollectionViewRoundFlowLayout_Swift │ ├── AppDelegate.swift │ ├── Base.lproj │ │ ├── LaunchScreen.xib │ │ └── Main.storyboard │ ├── FifthlyViewController.swift │ ├── FourViewController.swift │ ├── Images.xcassets │ │ └── AppIcon.appiconset │ │ │ └── Contents.json │ ├── Info.plist │ ├── MyCollectionReusableView.swift │ ├── MyCollectionViewCell.swift │ ├── MyCollectionViewFlowLayout.swift │ ├── MyLabelCollectionViewCell.swift │ ├── NextViewController.swift │ ├── SecondViewController.swift │ ├── SixthViewController.swift │ ├── ThirdViewController.swift │ └── ViewController.swift ├── Podfile ├── Podfile.lock ├── Pods │ ├── Local Podspecs │ │ └── JJCollectionViewRoundFlowLayout_Swift.podspec.json │ ├── Manifest.lock │ ├── Pods.xcodeproj │ │ ├── project.pbxproj │ │ └── xcshareddata │ │ │ └── xcschemes │ │ │ ├── JJCollectionViewRoundFlowLayout_Swift-Example.xcscheme │ │ │ └── JJCollectionViewRoundFlowLayout_Swift.xcscheme │ └── Target Support Files │ │ ├── JJCollectionViewRoundFlowLayout_Swift │ │ ├── JJCollectionViewRoundFlowLayout_Swift-Info.plist │ │ ├── JJCollectionViewRoundFlowLayout_Swift-dummy.m │ │ ├── JJCollectionViewRoundFlowLayout_Swift-prefix.pch │ │ ├── JJCollectionViewRoundFlowLayout_Swift-umbrella.h │ │ ├── JJCollectionViewRoundFlowLayout_Swift.modulemap │ │ └── JJCollectionViewRoundFlowLayout_Swift.xcconfig │ │ ├── Pods-JJCollectionViewRoundFlowLayout_Swift_Example │ │ ├── Pods-JJCollectionViewRoundFlowLayout_Swift_Example-Info.plist │ │ ├── Pods-JJCollectionViewRoundFlowLayout_Swift_Example-acknowledgements.markdown │ │ ├── Pods-JJCollectionViewRoundFlowLayout_Swift_Example-acknowledgements.plist │ │ ├── Pods-JJCollectionViewRoundFlowLayout_Swift_Example-dummy.m │ │ ├── Pods-JJCollectionViewRoundFlowLayout_Swift_Example-frameworks.sh │ │ ├── Pods-JJCollectionViewRoundFlowLayout_Swift_Example-umbrella.h │ │ ├── Pods-JJCollectionViewRoundFlowLayout_Swift_Example.debug.xcconfig │ │ ├── Pods-JJCollectionViewRoundFlowLayout_Swift_Example.modulemap │ │ └── Pods-JJCollectionViewRoundFlowLayout_Swift_Example.release.xcconfig │ │ └── Pods-JJCollectionViewRoundFlowLayout_Swift_Tests │ │ ├── Pods-JJCollectionViewRoundFlowLayout_Swift_Tests-Info.plist │ │ ├── Pods-JJCollectionViewRoundFlowLayout_Swift_Tests-acknowledgements.markdown │ │ ├── Pods-JJCollectionViewRoundFlowLayout_Swift_Tests-acknowledgements.plist │ │ ├── Pods-JJCollectionViewRoundFlowLayout_Swift_Tests-dummy.m │ │ ├── Pods-JJCollectionViewRoundFlowLayout_Swift_Tests-frameworks.sh │ │ ├── Pods-JJCollectionViewRoundFlowLayout_Swift_Tests-umbrella.h │ │ ├── Pods-JJCollectionViewRoundFlowLayout_Swift_Tests.debug.xcconfig │ │ ├── Pods-JJCollectionViewRoundFlowLayout_Swift_Tests.modulemap │ │ └── Pods-JJCollectionViewRoundFlowLayout_Swift_Tests.release.xcconfig └── Tests │ ├── Info.plist │ └── Tests.swift ├── JJCollectionViewRoundFlowLayout_Swift.podspec ├── JJCollectionViewRoundFlowLayout_Swift ├── Assets │ └── .gitkeep └── Classes │ ├── .gitkeep │ ├── JJCollectionViewFlowLayoutConfig_Swift.swift │ ├── JJCollectionViewFlowLayoutUtils_Swift.swift │ ├── JJCollectionViewRoundConfigModel_Swift.swift │ ├── JJCollectionViewRoundFlowLayout+Alignment_Swift.swift │ └── JJCollectionViewRoundFlowLayout_Swift.swift ├── LICENSE ├── README.md ├── _Pods.xcodeproj └── show_video.gif /.gitignore: -------------------------------------------------------------------------------- 1 | # OS X 2 | .DS_Store 3 | 4 | # Xcode 5 | build/ 6 | *.pbxuser 7 | !default.pbxuser 8 | *.mode1v3 9 | !default.mode1v3 10 | *.mode2v3 11 | !default.mode2v3 12 | *.perspectivev3 13 | !default.perspectivev3 14 | xcuserdata/ 15 | *.xccheckout 16 | profile 17 | *.moved-aside 18 | DerivedData 19 | *.hmap 20 | *.ipa 21 | 22 | # Bundler 23 | .bundle 24 | 25 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 26 | # Carthage/Checkouts 27 | 28 | Carthage/Build 29 | 30 | # We recommend against adding the Pods directory to your .gitignore. However 31 | # you should judge for yourself, the pros and cons are mentioned at: 32 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control 33 | # 34 | # Note: if you ignore the Pods directory, make sure to uncomment 35 | # `pod install` in .travis.yml 36 | # 37 | # Pods/ 38 | -------------------------------------------------------------------------------- /.swift-version: -------------------------------------------------------------------------------- 1 | 4.2 2 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | # references: 2 | # * https://www.objc.io/issues/6-build-tools/travis-ci/ 3 | # * https://github.com/supermarin/xcpretty#usage 4 | 5 | osx_image: xcode11.3 6 | language: swift 7 | cache: cocoapods 8 | podfile: Example/Podfile 9 | before_install: 10 | - gem install cocoapods # Since Travis is not always on latest version 11 | - pod install --project-directory=Example 12 | script: 13 | #- set -o pipefail && xcodebuild test -enableCodeCoverage YES -workspace Example/JJCollectionViewRoundFlowLayout_Swift.xcworkspace -scheme JJCollectionViewRoundFlowLayout_Swift-Example -sdk iphonesimulator9.3 ONLY_ACTIVE_ARCH=NO | xcpretty 14 | - set -o pipefail && xcodebuild -workspace Example/JJCollectionViewRoundFlowLayout_Swift.xcworkspace -scheme JJCollectionViewRoundFlowLayout_Swift-Example -destination 'platform=iOS Simulator,name=iPhone 7,OS=10.3.1' ONLY_ACTIVE_ARCH=NO | xcpretty -c 15 | - pod lib lint 16 | -------------------------------------------------------------------------------- /1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingjiajie/JJCollectionViewRoundFlowLayout_Swift/53bfe8a61ebf2dac3e2f244c563a07d2ec58c7a5/1.png -------------------------------------------------------------------------------- /2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingjiajie/JJCollectionViewRoundFlowLayout_Swift/53bfe8a61ebf2dac3e2f244c563a07d2ec58c7a5/2.png -------------------------------------------------------------------------------- /3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingjiajie/JJCollectionViewRoundFlowLayout_Swift/53bfe8a61ebf2dac3e2f244c563a07d2ec58c7a5/3.png -------------------------------------------------------------------------------- /4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingjiajie/JJCollectionViewRoundFlowLayout_Swift/53bfe8a61ebf2dac3e2f244c563a07d2ec58c7a5/4.png -------------------------------------------------------------------------------- /5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingjiajie/JJCollectionViewRoundFlowLayout_Swift/53bfe8a61ebf2dac3e2f244c563a07d2ec58c7a5/5.png -------------------------------------------------------------------------------- /6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingjiajie/JJCollectionViewRoundFlowLayout_Swift/53bfe8a61ebf2dac3e2f244c563a07d2ec58c7a5/6.png -------------------------------------------------------------------------------- /7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingjiajie/JJCollectionViewRoundFlowLayout_Swift/53bfe8a61ebf2dac3e2f244c563a07d2ec58c7a5/7.png -------------------------------------------------------------------------------- /Example/JJCollectionViewRoundFlowLayout_Swift.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 042FEAA9238204E5000F73ED /* MyCollectionViewFlowLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 042FEAA4238204E4000F73ED /* MyCollectionViewFlowLayout.swift */; }; 11 | 042FEAAA238204E5000F73ED /* MyCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 042FEAA5238204E4000F73ED /* MyCollectionViewCell.swift */; }; 12 | 042FEAAB238204E5000F73ED /* SecondViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 042FEAA6238204E5000F73ED /* SecondViewController.swift */; }; 13 | 042FEAAC238204E5000F73ED /* NextViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 042FEAA7238204E5000F73ED /* NextViewController.swift */; }; 14 | 042FEAAD238204E5000F73ED /* MyCollectionReusableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 042FEAA8238204E5000F73ED /* MyCollectionReusableView.swift */; }; 15 | 0434FE1D23BD98EE0094B247 /* ThirdViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0434FE1C23BD98EE0094B247 /* ThirdViewController.swift */; }; 16 | 043B0A6523E80C9900C2C6B4 /* FourViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 043B0A6423E80C9900C2C6B4 /* FourViewController.swift */; }; 17 | 047B195025F53F2800468C9B /* SixthViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 047B194F25F53F2800468C9B /* SixthViewController.swift */; }; 18 | 0484A647251CF3610019A0FF /* FifthlyViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0484A646251CF3610019A0FF /* FifthlyViewController.swift */; }; 19 | 04DC685423E95CC100488DFA /* MyLabelCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04DC685323E95CC100488DFA /* MyLabelCollectionViewCell.swift */; }; 20 | 37F3E3CC11D28F983A3FEE06 /* Pods_JJCollectionViewRoundFlowLayout_Swift_Tests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 11512C0B1DF9F20F73A3765F /* Pods_JJCollectionViewRoundFlowLayout_Swift_Tests.framework */; }; 21 | 607FACD61AFB9204008FA782 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 607FACD51AFB9204008FA782 /* AppDelegate.swift */; }; 22 | 607FACD81AFB9204008FA782 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 607FACD71AFB9204008FA782 /* ViewController.swift */; }; 23 | 607FACDB1AFB9204008FA782 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 607FACD91AFB9204008FA782 /* Main.storyboard */; }; 24 | 607FACDD1AFB9204008FA782 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 607FACDC1AFB9204008FA782 /* Images.xcassets */; }; 25 | 607FACE01AFB9204008FA782 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 607FACDE1AFB9204008FA782 /* LaunchScreen.xib */; }; 26 | 607FACEC1AFB9204008FA782 /* Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 607FACEB1AFB9204008FA782 /* Tests.swift */; }; 27 | EB2744B36E7FABF6255751B4 /* Pods_JJCollectionViewRoundFlowLayout_Swift_Example.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 76FEA1FB54AA24FE976CF5F9 /* Pods_JJCollectionViewRoundFlowLayout_Swift_Example.framework */; }; 28 | /* End PBXBuildFile section */ 29 | 30 | /* Begin PBXContainerItemProxy section */ 31 | 607FACE61AFB9204008FA782 /* PBXContainerItemProxy */ = { 32 | isa = PBXContainerItemProxy; 33 | containerPortal = 607FACC81AFB9204008FA782 /* Project object */; 34 | proxyType = 1; 35 | remoteGlobalIDString = 607FACCF1AFB9204008FA782; 36 | remoteInfo = JJCollectionViewRoundFlowLayout_Swift; 37 | }; 38 | /* End PBXContainerItemProxy section */ 39 | 40 | /* Begin PBXFileReference section */ 41 | 042FEAA4238204E4000F73ED /* MyCollectionViewFlowLayout.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MyCollectionViewFlowLayout.swift; sourceTree = ""; }; 42 | 042FEAA5238204E4000F73ED /* MyCollectionViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MyCollectionViewCell.swift; sourceTree = ""; }; 43 | 042FEAA6238204E5000F73ED /* SecondViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SecondViewController.swift; sourceTree = ""; }; 44 | 042FEAA7238204E5000F73ED /* NextViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NextViewController.swift; sourceTree = ""; }; 45 | 042FEAA8238204E5000F73ED /* MyCollectionReusableView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MyCollectionReusableView.swift; sourceTree = ""; }; 46 | 0434FE1C23BD98EE0094B247 /* ThirdViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThirdViewController.swift; sourceTree = ""; }; 47 | 043B0A6423E80C9900C2C6B4 /* FourViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FourViewController.swift; sourceTree = ""; }; 48 | 047B194F25F53F2800468C9B /* SixthViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SixthViewController.swift; sourceTree = ""; }; 49 | 0484A646251CF3610019A0FF /* FifthlyViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FifthlyViewController.swift; sourceTree = ""; }; 50 | 04DC685323E95CC100488DFA /* MyLabelCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MyLabelCollectionViewCell.swift; sourceTree = ""; }; 51 | 11512C0B1DF9F20F73A3765F /* Pods_JJCollectionViewRoundFlowLayout_Swift_Tests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_JJCollectionViewRoundFlowLayout_Swift_Tests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 52 | 4CDE4D46CCB2623C8E330E6C /* Pods-JJCollectionViewRoundFlowLayout_Swift_Example.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-JJCollectionViewRoundFlowLayout_Swift_Example.debug.xcconfig"; path = "Target Support Files/Pods-JJCollectionViewRoundFlowLayout_Swift_Example/Pods-JJCollectionViewRoundFlowLayout_Swift_Example.debug.xcconfig"; sourceTree = ""; }; 53 | 607FACD01AFB9204008FA782 /* JJCollectionViewRoundFlowLayout_Swift_Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = JJCollectionViewRoundFlowLayout_Swift_Example.app; sourceTree = BUILT_PRODUCTS_DIR; }; 54 | 607FACD41AFB9204008FA782 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 55 | 607FACD51AFB9204008FA782 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 56 | 607FACD71AFB9204008FA782 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; 57 | 607FACDA1AFB9204008FA782 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 58 | 607FACDC1AFB9204008FA782 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 59 | 607FACDF1AFB9204008FA782 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; 60 | 607FACE51AFB9204008FA782 /* JJCollectionViewRoundFlowLayout_Swift_Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = JJCollectionViewRoundFlowLayout_Swift_Tests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 61 | 607FACEA1AFB9204008FA782 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 62 | 607FACEB1AFB9204008FA782 /* Tests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Tests.swift; sourceTree = ""; }; 63 | 6BF34387F98D1E1C5DE51FE0 /* LICENSE */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = LICENSE; path = ../LICENSE; sourceTree = ""; }; 64 | 76FEA1FB54AA24FE976CF5F9 /* Pods_JJCollectionViewRoundFlowLayout_Swift_Example.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_JJCollectionViewRoundFlowLayout_Swift_Example.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 65 | A5CC266CD3ADCE42EEA32913 /* Pods-JJCollectionViewRoundFlowLayout_Swift_Tests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-JJCollectionViewRoundFlowLayout_Swift_Tests.release.xcconfig"; path = "Target Support Files/Pods-JJCollectionViewRoundFlowLayout_Swift_Tests/Pods-JJCollectionViewRoundFlowLayout_Swift_Tests.release.xcconfig"; sourceTree = ""; }; 66 | B69AE1BCB93229B78E287642 /* Pods-JJCollectionViewRoundFlowLayout_Swift_Example.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-JJCollectionViewRoundFlowLayout_Swift_Example.release.xcconfig"; path = "Target Support Files/Pods-JJCollectionViewRoundFlowLayout_Swift_Example/Pods-JJCollectionViewRoundFlowLayout_Swift_Example.release.xcconfig"; sourceTree = ""; }; 67 | B8762D58511991EF1512F55A /* JJCollectionViewRoundFlowLayout_Swift.podspec */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = JJCollectionViewRoundFlowLayout_Swift.podspec; path = ../JJCollectionViewRoundFlowLayout_Swift.podspec; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; 68 | B8946EE15A16CDD20699FC40 /* Pods-JJCollectionViewRoundFlowLayout_Swift_Tests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-JJCollectionViewRoundFlowLayout_Swift_Tests.debug.xcconfig"; path = "Target Support Files/Pods-JJCollectionViewRoundFlowLayout_Swift_Tests/Pods-JJCollectionViewRoundFlowLayout_Swift_Tests.debug.xcconfig"; sourceTree = ""; }; 69 | E30150A0BDA84AFACAB03297 /* README.md */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = net.daringfireball.markdown; name = README.md; path = ../README.md; sourceTree = ""; }; 70 | /* End PBXFileReference section */ 71 | 72 | /* Begin PBXFrameworksBuildPhase section */ 73 | 607FACCD1AFB9204008FA782 /* Frameworks */ = { 74 | isa = PBXFrameworksBuildPhase; 75 | buildActionMask = 2147483647; 76 | files = ( 77 | EB2744B36E7FABF6255751B4 /* Pods_JJCollectionViewRoundFlowLayout_Swift_Example.framework in Frameworks */, 78 | ); 79 | runOnlyForDeploymentPostprocessing = 0; 80 | }; 81 | 607FACE21AFB9204008FA782 /* Frameworks */ = { 82 | isa = PBXFrameworksBuildPhase; 83 | buildActionMask = 2147483647; 84 | files = ( 85 | 37F3E3CC11D28F983A3FEE06 /* Pods_JJCollectionViewRoundFlowLayout_Swift_Tests.framework in Frameworks */, 86 | ); 87 | runOnlyForDeploymentPostprocessing = 0; 88 | }; 89 | /* End PBXFrameworksBuildPhase section */ 90 | 91 | /* Begin PBXGroup section */ 92 | 3D0CC844EC6D5200BB79CFF0 /* Frameworks */ = { 93 | isa = PBXGroup; 94 | children = ( 95 | 76FEA1FB54AA24FE976CF5F9 /* Pods_JJCollectionViewRoundFlowLayout_Swift_Example.framework */, 96 | 11512C0B1DF9F20F73A3765F /* Pods_JJCollectionViewRoundFlowLayout_Swift_Tests.framework */, 97 | ); 98 | name = Frameworks; 99 | sourceTree = ""; 100 | }; 101 | 5F4EC15E2584FB5F69FEEDC3 /* Pods */ = { 102 | isa = PBXGroup; 103 | children = ( 104 | 4CDE4D46CCB2623C8E330E6C /* Pods-JJCollectionViewRoundFlowLayout_Swift_Example.debug.xcconfig */, 105 | B69AE1BCB93229B78E287642 /* Pods-JJCollectionViewRoundFlowLayout_Swift_Example.release.xcconfig */, 106 | B8946EE15A16CDD20699FC40 /* Pods-JJCollectionViewRoundFlowLayout_Swift_Tests.debug.xcconfig */, 107 | A5CC266CD3ADCE42EEA32913 /* Pods-JJCollectionViewRoundFlowLayout_Swift_Tests.release.xcconfig */, 108 | ); 109 | path = Pods; 110 | sourceTree = ""; 111 | }; 112 | 607FACC71AFB9204008FA782 = { 113 | isa = PBXGroup; 114 | children = ( 115 | 607FACF51AFB993E008FA782 /* Podspec Metadata */, 116 | 607FACD21AFB9204008FA782 /* Example for JJCollectionViewRoundFlowLayout_Swift */, 117 | 607FACE81AFB9204008FA782 /* Tests */, 118 | 607FACD11AFB9204008FA782 /* Products */, 119 | 5F4EC15E2584FB5F69FEEDC3 /* Pods */, 120 | 3D0CC844EC6D5200BB79CFF0 /* Frameworks */, 121 | ); 122 | sourceTree = ""; 123 | }; 124 | 607FACD11AFB9204008FA782 /* Products */ = { 125 | isa = PBXGroup; 126 | children = ( 127 | 607FACD01AFB9204008FA782 /* JJCollectionViewRoundFlowLayout_Swift_Example.app */, 128 | 607FACE51AFB9204008FA782 /* JJCollectionViewRoundFlowLayout_Swift_Tests.xctest */, 129 | ); 130 | name = Products; 131 | sourceTree = ""; 132 | }; 133 | 607FACD21AFB9204008FA782 /* Example for JJCollectionViewRoundFlowLayout_Swift */ = { 134 | isa = PBXGroup; 135 | children = ( 136 | 607FACD51AFB9204008FA782 /* AppDelegate.swift */, 137 | 607FACD71AFB9204008FA782 /* ViewController.swift */, 138 | 607FACD91AFB9204008FA782 /* Main.storyboard */, 139 | 042FEAA8238204E5000F73ED /* MyCollectionReusableView.swift */, 140 | 042FEAA5238204E4000F73ED /* MyCollectionViewCell.swift */, 141 | 04DC685323E95CC100488DFA /* MyLabelCollectionViewCell.swift */, 142 | 042FEAA4238204E4000F73ED /* MyCollectionViewFlowLayout.swift */, 143 | 042FEAA7238204E5000F73ED /* NextViewController.swift */, 144 | 042FEAA6238204E5000F73ED /* SecondViewController.swift */, 145 | 0434FE1C23BD98EE0094B247 /* ThirdViewController.swift */, 146 | 043B0A6423E80C9900C2C6B4 /* FourViewController.swift */, 147 | 0484A646251CF3610019A0FF /* FifthlyViewController.swift */, 148 | 047B194F25F53F2800468C9B /* SixthViewController.swift */, 149 | 607FACDC1AFB9204008FA782 /* Images.xcassets */, 150 | 607FACDE1AFB9204008FA782 /* LaunchScreen.xib */, 151 | 607FACD31AFB9204008FA782 /* Supporting Files */, 152 | ); 153 | name = "Example for JJCollectionViewRoundFlowLayout_Swift"; 154 | path = JJCollectionViewRoundFlowLayout_Swift; 155 | sourceTree = ""; 156 | }; 157 | 607FACD31AFB9204008FA782 /* Supporting Files */ = { 158 | isa = PBXGroup; 159 | children = ( 160 | 607FACD41AFB9204008FA782 /* Info.plist */, 161 | ); 162 | name = "Supporting Files"; 163 | sourceTree = ""; 164 | }; 165 | 607FACE81AFB9204008FA782 /* Tests */ = { 166 | isa = PBXGroup; 167 | children = ( 168 | 607FACEB1AFB9204008FA782 /* Tests.swift */, 169 | 607FACE91AFB9204008FA782 /* Supporting Files */, 170 | ); 171 | path = Tests; 172 | sourceTree = ""; 173 | }; 174 | 607FACE91AFB9204008FA782 /* Supporting Files */ = { 175 | isa = PBXGroup; 176 | children = ( 177 | 607FACEA1AFB9204008FA782 /* Info.plist */, 178 | ); 179 | name = "Supporting Files"; 180 | sourceTree = ""; 181 | }; 182 | 607FACF51AFB993E008FA782 /* Podspec Metadata */ = { 183 | isa = PBXGroup; 184 | children = ( 185 | B8762D58511991EF1512F55A /* JJCollectionViewRoundFlowLayout_Swift.podspec */, 186 | E30150A0BDA84AFACAB03297 /* README.md */, 187 | 6BF34387F98D1E1C5DE51FE0 /* LICENSE */, 188 | ); 189 | name = "Podspec Metadata"; 190 | sourceTree = ""; 191 | }; 192 | /* End PBXGroup section */ 193 | 194 | /* Begin PBXNativeTarget section */ 195 | 607FACCF1AFB9204008FA782 /* JJCollectionViewRoundFlowLayout_Swift_Example */ = { 196 | isa = PBXNativeTarget; 197 | buildConfigurationList = 607FACEF1AFB9204008FA782 /* Build configuration list for PBXNativeTarget "JJCollectionViewRoundFlowLayout_Swift_Example" */; 198 | buildPhases = ( 199 | DFCD4CB5D5A4DB9138E3D27A /* [CP] Check Pods Manifest.lock */, 200 | 607FACCC1AFB9204008FA782 /* Sources */, 201 | 607FACCD1AFB9204008FA782 /* Frameworks */, 202 | 607FACCE1AFB9204008FA782 /* Resources */, 203 | 8FBDBA568316027A3FDA57C4 /* [CP] Embed Pods Frameworks */, 204 | ); 205 | buildRules = ( 206 | ); 207 | dependencies = ( 208 | ); 209 | name = JJCollectionViewRoundFlowLayout_Swift_Example; 210 | productName = JJCollectionViewRoundFlowLayout_Swift; 211 | productReference = 607FACD01AFB9204008FA782 /* JJCollectionViewRoundFlowLayout_Swift_Example.app */; 212 | productType = "com.apple.product-type.application"; 213 | }; 214 | 607FACE41AFB9204008FA782 /* JJCollectionViewRoundFlowLayout_Swift_Tests */ = { 215 | isa = PBXNativeTarget; 216 | buildConfigurationList = 607FACF21AFB9204008FA782 /* Build configuration list for PBXNativeTarget "JJCollectionViewRoundFlowLayout_Swift_Tests" */; 217 | buildPhases = ( 218 | A0F1D99125DE7E2C5097F93B /* [CP] Check Pods Manifest.lock */, 219 | 607FACE11AFB9204008FA782 /* Sources */, 220 | 607FACE21AFB9204008FA782 /* Frameworks */, 221 | 607FACE31AFB9204008FA782 /* Resources */, 222 | ); 223 | buildRules = ( 224 | ); 225 | dependencies = ( 226 | 607FACE71AFB9204008FA782 /* PBXTargetDependency */, 227 | ); 228 | name = JJCollectionViewRoundFlowLayout_Swift_Tests; 229 | productName = Tests; 230 | productReference = 607FACE51AFB9204008FA782 /* JJCollectionViewRoundFlowLayout_Swift_Tests.xctest */; 231 | productType = "com.apple.product-type.bundle.unit-test"; 232 | }; 233 | /* End PBXNativeTarget section */ 234 | 235 | /* Begin PBXProject section */ 236 | 607FACC81AFB9204008FA782 /* Project object */ = { 237 | isa = PBXProject; 238 | attributes = { 239 | LastSwiftUpdateCheck = 0830; 240 | LastUpgradeCheck = 1110; 241 | ORGANIZATIONNAME = CocoaPods; 242 | TargetAttributes = { 243 | 607FACCF1AFB9204008FA782 = { 244 | CreatedOnToolsVersion = 6.3.1; 245 | LastSwiftMigration = 0900; 246 | }; 247 | 607FACE41AFB9204008FA782 = { 248 | CreatedOnToolsVersion = 6.3.1; 249 | LastSwiftMigration = 0900; 250 | TestTargetID = 607FACCF1AFB9204008FA782; 251 | }; 252 | }; 253 | }; 254 | buildConfigurationList = 607FACCB1AFB9204008FA782 /* Build configuration list for PBXProject "JJCollectionViewRoundFlowLayout_Swift" */; 255 | compatibilityVersion = "Xcode 3.2"; 256 | developmentRegion = en; 257 | hasScannedForEncodings = 0; 258 | knownRegions = ( 259 | en, 260 | Base, 261 | ); 262 | mainGroup = 607FACC71AFB9204008FA782; 263 | productRefGroup = 607FACD11AFB9204008FA782 /* Products */; 264 | projectDirPath = ""; 265 | projectRoot = ""; 266 | targets = ( 267 | 607FACCF1AFB9204008FA782 /* JJCollectionViewRoundFlowLayout_Swift_Example */, 268 | 607FACE41AFB9204008FA782 /* JJCollectionViewRoundFlowLayout_Swift_Tests */, 269 | ); 270 | }; 271 | /* End PBXProject section */ 272 | 273 | /* Begin PBXResourcesBuildPhase section */ 274 | 607FACCE1AFB9204008FA782 /* Resources */ = { 275 | isa = PBXResourcesBuildPhase; 276 | buildActionMask = 2147483647; 277 | files = ( 278 | 607FACDB1AFB9204008FA782 /* Main.storyboard in Resources */, 279 | 607FACE01AFB9204008FA782 /* LaunchScreen.xib in Resources */, 280 | 607FACDD1AFB9204008FA782 /* Images.xcassets in Resources */, 281 | ); 282 | runOnlyForDeploymentPostprocessing = 0; 283 | }; 284 | 607FACE31AFB9204008FA782 /* Resources */ = { 285 | isa = PBXResourcesBuildPhase; 286 | buildActionMask = 2147483647; 287 | files = ( 288 | ); 289 | runOnlyForDeploymentPostprocessing = 0; 290 | }; 291 | /* End PBXResourcesBuildPhase section */ 292 | 293 | /* Begin PBXShellScriptBuildPhase section */ 294 | 8FBDBA568316027A3FDA57C4 /* [CP] Embed Pods Frameworks */ = { 295 | isa = PBXShellScriptBuildPhase; 296 | buildActionMask = 2147483647; 297 | files = ( 298 | ); 299 | inputPaths = ( 300 | "${PODS_ROOT}/Target Support Files/Pods-JJCollectionViewRoundFlowLayout_Swift_Example/Pods-JJCollectionViewRoundFlowLayout_Swift_Example-frameworks.sh", 301 | "${BUILT_PRODUCTS_DIR}/JJCollectionViewRoundFlowLayout_Swift/JJCollectionViewRoundFlowLayout_Swift.framework", 302 | ); 303 | name = "[CP] Embed Pods Frameworks"; 304 | outputPaths = ( 305 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/JJCollectionViewRoundFlowLayout_Swift.framework", 306 | ); 307 | runOnlyForDeploymentPostprocessing = 0; 308 | shellPath = /bin/sh; 309 | shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-JJCollectionViewRoundFlowLayout_Swift_Example/Pods-JJCollectionViewRoundFlowLayout_Swift_Example-frameworks.sh\"\n"; 310 | showEnvVarsInLog = 0; 311 | }; 312 | A0F1D99125DE7E2C5097F93B /* [CP] Check Pods Manifest.lock */ = { 313 | isa = PBXShellScriptBuildPhase; 314 | buildActionMask = 2147483647; 315 | files = ( 316 | ); 317 | inputFileListPaths = ( 318 | ); 319 | inputPaths = ( 320 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 321 | "${PODS_ROOT}/Manifest.lock", 322 | ); 323 | name = "[CP] Check Pods Manifest.lock"; 324 | outputFileListPaths = ( 325 | ); 326 | outputPaths = ( 327 | "$(DERIVED_FILE_DIR)/Pods-JJCollectionViewRoundFlowLayout_Swift_Tests-checkManifestLockResult.txt", 328 | ); 329 | runOnlyForDeploymentPostprocessing = 0; 330 | shellPath = /bin/sh; 331 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; 332 | showEnvVarsInLog = 0; 333 | }; 334 | DFCD4CB5D5A4DB9138E3D27A /* [CP] Check Pods Manifest.lock */ = { 335 | isa = PBXShellScriptBuildPhase; 336 | buildActionMask = 2147483647; 337 | files = ( 338 | ); 339 | inputFileListPaths = ( 340 | ); 341 | inputPaths = ( 342 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 343 | "${PODS_ROOT}/Manifest.lock", 344 | ); 345 | name = "[CP] Check Pods Manifest.lock"; 346 | outputFileListPaths = ( 347 | ); 348 | outputPaths = ( 349 | "$(DERIVED_FILE_DIR)/Pods-JJCollectionViewRoundFlowLayout_Swift_Example-checkManifestLockResult.txt", 350 | ); 351 | runOnlyForDeploymentPostprocessing = 0; 352 | shellPath = /bin/sh; 353 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; 354 | showEnvVarsInLog = 0; 355 | }; 356 | /* End PBXShellScriptBuildPhase section */ 357 | 358 | /* Begin PBXSourcesBuildPhase section */ 359 | 607FACCC1AFB9204008FA782 /* Sources */ = { 360 | isa = PBXSourcesBuildPhase; 361 | buildActionMask = 2147483647; 362 | files = ( 363 | 607FACD81AFB9204008FA782 /* ViewController.swift in Sources */, 364 | 042FEAAD238204E5000F73ED /* MyCollectionReusableView.swift in Sources */, 365 | 042FEAAC238204E5000F73ED /* NextViewController.swift in Sources */, 366 | 042FEAA9238204E5000F73ED /* MyCollectionViewFlowLayout.swift in Sources */, 367 | 0484A647251CF3610019A0FF /* FifthlyViewController.swift in Sources */, 368 | 042FEAAA238204E5000F73ED /* MyCollectionViewCell.swift in Sources */, 369 | 042FEAAB238204E5000F73ED /* SecondViewController.swift in Sources */, 370 | 047B195025F53F2800468C9B /* SixthViewController.swift in Sources */, 371 | 0434FE1D23BD98EE0094B247 /* ThirdViewController.swift in Sources */, 372 | 04DC685423E95CC100488DFA /* MyLabelCollectionViewCell.swift in Sources */, 373 | 607FACD61AFB9204008FA782 /* AppDelegate.swift in Sources */, 374 | 043B0A6523E80C9900C2C6B4 /* FourViewController.swift in Sources */, 375 | ); 376 | runOnlyForDeploymentPostprocessing = 0; 377 | }; 378 | 607FACE11AFB9204008FA782 /* Sources */ = { 379 | isa = PBXSourcesBuildPhase; 380 | buildActionMask = 2147483647; 381 | files = ( 382 | 607FACEC1AFB9204008FA782 /* Tests.swift in Sources */, 383 | ); 384 | runOnlyForDeploymentPostprocessing = 0; 385 | }; 386 | /* End PBXSourcesBuildPhase section */ 387 | 388 | /* Begin PBXTargetDependency section */ 389 | 607FACE71AFB9204008FA782 /* PBXTargetDependency */ = { 390 | isa = PBXTargetDependency; 391 | target = 607FACCF1AFB9204008FA782 /* JJCollectionViewRoundFlowLayout_Swift_Example */; 392 | targetProxy = 607FACE61AFB9204008FA782 /* PBXContainerItemProxy */; 393 | }; 394 | /* End PBXTargetDependency section */ 395 | 396 | /* Begin PBXVariantGroup section */ 397 | 607FACD91AFB9204008FA782 /* Main.storyboard */ = { 398 | isa = PBXVariantGroup; 399 | children = ( 400 | 607FACDA1AFB9204008FA782 /* Base */, 401 | ); 402 | name = Main.storyboard; 403 | sourceTree = ""; 404 | }; 405 | 607FACDE1AFB9204008FA782 /* LaunchScreen.xib */ = { 406 | isa = PBXVariantGroup; 407 | children = ( 408 | 607FACDF1AFB9204008FA782 /* Base */, 409 | ); 410 | name = LaunchScreen.xib; 411 | sourceTree = ""; 412 | }; 413 | /* End PBXVariantGroup section */ 414 | 415 | /* Begin XCBuildConfiguration section */ 416 | 607FACED1AFB9204008FA782 /* Debug */ = { 417 | isa = XCBuildConfiguration; 418 | buildSettings = { 419 | ALWAYS_SEARCH_USER_PATHS = NO; 420 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; 421 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 422 | CLANG_CXX_LIBRARY = "libc++"; 423 | CLANG_ENABLE_MODULES = YES; 424 | CLANG_ENABLE_OBJC_ARC = YES; 425 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 426 | CLANG_WARN_BOOL_CONVERSION = YES; 427 | CLANG_WARN_COMMA = YES; 428 | CLANG_WARN_CONSTANT_CONVERSION = YES; 429 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 430 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 431 | CLANG_WARN_EMPTY_BODY = YES; 432 | CLANG_WARN_ENUM_CONVERSION = YES; 433 | CLANG_WARN_INFINITE_RECURSION = YES; 434 | CLANG_WARN_INT_CONVERSION = YES; 435 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 436 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 437 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 438 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 439 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 440 | CLANG_WARN_STRICT_PROTOTYPES = YES; 441 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 442 | CLANG_WARN_UNREACHABLE_CODE = YES; 443 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 444 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 445 | COPY_PHASE_STRIP = NO; 446 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 447 | ENABLE_STRICT_OBJC_MSGSEND = YES; 448 | ENABLE_TESTABILITY = YES; 449 | GCC_C_LANGUAGE_STANDARD = gnu99; 450 | GCC_DYNAMIC_NO_PIC = NO; 451 | GCC_NO_COMMON_BLOCKS = YES; 452 | GCC_OPTIMIZATION_LEVEL = 0; 453 | GCC_PREPROCESSOR_DEFINITIONS = ( 454 | "DEBUG=1", 455 | "$(inherited)", 456 | ); 457 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 458 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 459 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 460 | GCC_WARN_UNDECLARED_SELECTOR = YES; 461 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 462 | GCC_WARN_UNUSED_FUNCTION = YES; 463 | GCC_WARN_UNUSED_VARIABLE = YES; 464 | IPHONEOS_DEPLOYMENT_TARGET = 9.3; 465 | MTL_ENABLE_DEBUG_INFO = YES; 466 | ONLY_ACTIVE_ARCH = YES; 467 | SDKROOT = iphoneos; 468 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 469 | SWIFT_VERSION = 4.2; 470 | }; 471 | name = Debug; 472 | }; 473 | 607FACEE1AFB9204008FA782 /* Release */ = { 474 | isa = XCBuildConfiguration; 475 | buildSettings = { 476 | ALWAYS_SEARCH_USER_PATHS = NO; 477 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; 478 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 479 | CLANG_CXX_LIBRARY = "libc++"; 480 | CLANG_ENABLE_MODULES = YES; 481 | CLANG_ENABLE_OBJC_ARC = YES; 482 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 483 | CLANG_WARN_BOOL_CONVERSION = YES; 484 | CLANG_WARN_COMMA = YES; 485 | CLANG_WARN_CONSTANT_CONVERSION = YES; 486 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 487 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 488 | CLANG_WARN_EMPTY_BODY = YES; 489 | CLANG_WARN_ENUM_CONVERSION = YES; 490 | CLANG_WARN_INFINITE_RECURSION = YES; 491 | CLANG_WARN_INT_CONVERSION = YES; 492 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 493 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 494 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 495 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 496 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 497 | CLANG_WARN_STRICT_PROTOTYPES = YES; 498 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 499 | CLANG_WARN_UNREACHABLE_CODE = YES; 500 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 501 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 502 | COPY_PHASE_STRIP = NO; 503 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 504 | ENABLE_NS_ASSERTIONS = NO; 505 | ENABLE_STRICT_OBJC_MSGSEND = YES; 506 | GCC_C_LANGUAGE_STANDARD = gnu99; 507 | GCC_NO_COMMON_BLOCKS = YES; 508 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 509 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 510 | GCC_WARN_UNDECLARED_SELECTOR = YES; 511 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 512 | GCC_WARN_UNUSED_FUNCTION = YES; 513 | GCC_WARN_UNUSED_VARIABLE = YES; 514 | IPHONEOS_DEPLOYMENT_TARGET = 9.3; 515 | MTL_ENABLE_DEBUG_INFO = NO; 516 | SDKROOT = iphoneos; 517 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 518 | SWIFT_VERSION = 4.2; 519 | VALIDATE_PRODUCT = YES; 520 | }; 521 | name = Release; 522 | }; 523 | 607FACF01AFB9204008FA782 /* Debug */ = { 524 | isa = XCBuildConfiguration; 525 | baseConfigurationReference = 4CDE4D46CCB2623C8E330E6C /* Pods-JJCollectionViewRoundFlowLayout_Swift_Example.debug.xcconfig */; 526 | buildSettings = { 527 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 528 | INFOPLIST_FILE = JJCollectionViewRoundFlowLayout_Swift/Info.plist; 529 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 530 | MODULE_NAME = ExampleApp; 531 | PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.demo.$(PRODUCT_NAME:rfc1034identifier)"; 532 | PRODUCT_NAME = "$(TARGET_NAME)"; 533 | SWIFT_SWIFT3_OBJC_INFERENCE = Default; 534 | SWIFT_VERSION = 4.0; 535 | }; 536 | name = Debug; 537 | }; 538 | 607FACF11AFB9204008FA782 /* Release */ = { 539 | isa = XCBuildConfiguration; 540 | baseConfigurationReference = B69AE1BCB93229B78E287642 /* Pods-JJCollectionViewRoundFlowLayout_Swift_Example.release.xcconfig */; 541 | buildSettings = { 542 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 543 | INFOPLIST_FILE = JJCollectionViewRoundFlowLayout_Swift/Info.plist; 544 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 545 | MODULE_NAME = ExampleApp; 546 | PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.demo.$(PRODUCT_NAME:rfc1034identifier)"; 547 | PRODUCT_NAME = "$(TARGET_NAME)"; 548 | SWIFT_SWIFT3_OBJC_INFERENCE = Default; 549 | SWIFT_VERSION = 4.0; 550 | }; 551 | name = Release; 552 | }; 553 | 607FACF31AFB9204008FA782 /* Debug */ = { 554 | isa = XCBuildConfiguration; 555 | baseConfigurationReference = B8946EE15A16CDD20699FC40 /* Pods-JJCollectionViewRoundFlowLayout_Swift_Tests.debug.xcconfig */; 556 | buildSettings = { 557 | FRAMEWORK_SEARCH_PATHS = ( 558 | "$(PLATFORM_DIR)/Developer/Library/Frameworks", 559 | "$(inherited)", 560 | ); 561 | GCC_PREPROCESSOR_DEFINITIONS = ( 562 | "DEBUG=1", 563 | "$(inherited)", 564 | ); 565 | INFOPLIST_FILE = Tests/Info.plist; 566 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 567 | PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.$(PRODUCT_NAME:rfc1034identifier)"; 568 | PRODUCT_NAME = "$(TARGET_NAME)"; 569 | SWIFT_SWIFT3_OBJC_INFERENCE = Default; 570 | SWIFT_VERSION = 4.0; 571 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/JJCollectionViewRoundFlowLayout_Swift_Example.app/JJCollectionViewRoundFlowLayout_Swift_Example"; 572 | }; 573 | name = Debug; 574 | }; 575 | 607FACF41AFB9204008FA782 /* Release */ = { 576 | isa = XCBuildConfiguration; 577 | baseConfigurationReference = A5CC266CD3ADCE42EEA32913 /* Pods-JJCollectionViewRoundFlowLayout_Swift_Tests.release.xcconfig */; 578 | buildSettings = { 579 | FRAMEWORK_SEARCH_PATHS = ( 580 | "$(PLATFORM_DIR)/Developer/Library/Frameworks", 581 | "$(inherited)", 582 | ); 583 | INFOPLIST_FILE = Tests/Info.plist; 584 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 585 | PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.$(PRODUCT_NAME:rfc1034identifier)"; 586 | PRODUCT_NAME = "$(TARGET_NAME)"; 587 | SWIFT_SWIFT3_OBJC_INFERENCE = Default; 588 | SWIFT_VERSION = 4.0; 589 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/JJCollectionViewRoundFlowLayout_Swift_Example.app/JJCollectionViewRoundFlowLayout_Swift_Example"; 590 | }; 591 | name = Release; 592 | }; 593 | /* End XCBuildConfiguration section */ 594 | 595 | /* Begin XCConfigurationList section */ 596 | 607FACCB1AFB9204008FA782 /* Build configuration list for PBXProject "JJCollectionViewRoundFlowLayout_Swift" */ = { 597 | isa = XCConfigurationList; 598 | buildConfigurations = ( 599 | 607FACED1AFB9204008FA782 /* Debug */, 600 | 607FACEE1AFB9204008FA782 /* Release */, 601 | ); 602 | defaultConfigurationIsVisible = 0; 603 | defaultConfigurationName = Release; 604 | }; 605 | 607FACEF1AFB9204008FA782 /* Build configuration list for PBXNativeTarget "JJCollectionViewRoundFlowLayout_Swift_Example" */ = { 606 | isa = XCConfigurationList; 607 | buildConfigurations = ( 608 | 607FACF01AFB9204008FA782 /* Debug */, 609 | 607FACF11AFB9204008FA782 /* Release */, 610 | ); 611 | defaultConfigurationIsVisible = 0; 612 | defaultConfigurationName = Release; 613 | }; 614 | 607FACF21AFB9204008FA782 /* Build configuration list for PBXNativeTarget "JJCollectionViewRoundFlowLayout_Swift_Tests" */ = { 615 | isa = XCConfigurationList; 616 | buildConfigurations = ( 617 | 607FACF31AFB9204008FA782 /* Debug */, 618 | 607FACF41AFB9204008FA782 /* Release */, 619 | ); 620 | defaultConfigurationIsVisible = 0; 621 | defaultConfigurationName = Release; 622 | }; 623 | /* End XCConfigurationList section */ 624 | }; 625 | rootObject = 607FACC81AFB9204008FA782 /* Project object */; 626 | } 627 | -------------------------------------------------------------------------------- /Example/JJCollectionViewRoundFlowLayout_Swift.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Example/JJCollectionViewRoundFlowLayout_Swift.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Example/JJCollectionViewRoundFlowLayout_Swift.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Example/JJCollectionViewRoundFlowLayout_Swift.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Example/JJCollectionViewRoundFlowLayout_Swift/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // JJCollectionViewRoundFlowLayout_Swift 4 | // 5 | // Created by kingjiajie on 11/18/2019. 6 | // Copyright (c) 2019 kingjiajie. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @UIApplicationMain 12 | class AppDelegate: UIResponder, UIApplicationDelegate { 13 | 14 | var window: UIWindow? 15 | 16 | 17 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { 18 | // Override point for customization after application launch. 19 | return true 20 | } 21 | 22 | func applicationWillResignActive(_ application: UIApplication) { 23 | // 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. 24 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 25 | } 26 | 27 | func applicationDidEnterBackground(_ application: UIApplication) { 28 | // 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. 29 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 30 | } 31 | 32 | func applicationWillEnterForeground(_ application: UIApplication) { 33 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. 34 | } 35 | 36 | func applicationDidBecomeActive(_ application: UIApplication) { 37 | // 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. 38 | } 39 | 40 | func applicationWillTerminate(_ application: UIApplication) { 41 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 42 | } 43 | 44 | 45 | } 46 | 47 | -------------------------------------------------------------------------------- /Example/JJCollectionViewRoundFlowLayout_Swift/Base.lproj/LaunchScreen.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 22 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /Example/JJCollectionViewRoundFlowLayout_Swift/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 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /Example/JJCollectionViewRoundFlowLayout_Swift/FifthlyViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FifthlyViewController.swift 3 | // JJCollectionViewRoundFlowLayout_Swift_Example 4 | // 5 | // Created by jiajie on 2020/9/24. 6 | // Copyright © 2020 CocoaPods. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import JJCollectionViewRoundFlowLayout_Swift 11 | 12 | class FifthlyViewController: UIViewController { 13 | 14 | lazy var myCollectionView : UICollectionView = { 15 | let layout = JJCollectionViewRoundFlowLayout_Swift.init(); 16 | //setting 17 | layout.sectionInset = UIEdgeInsets.init(top: 20, left: 20, bottom: 20, right: 20); 18 | layout.itemSize = CGSize.init(width: 100, height: 100) 19 | layout.minimumLineSpacing = 10 20 | layout.minimumInteritemSpacing = 5 21 | 22 | //init 23 | let collectionView = UICollectionView.init(frame: CGRect.init(x: 0, y: 0, width: 100.0, height: 100.0), collectionViewLayout: layout); 24 | collectionView.translatesAutoresizingMaskIntoConstraints = false; 25 | collectionView.delegate = self; 26 | collectionView.dataSource = self; 27 | 28 | collectionView.showsVerticalScrollIndicator = false 29 | collectionView.showsHorizontalScrollIndicator = false 30 | collectionView.backgroundColor = UIColor.init(white: 1.0, alpha: 1.0) 31 | collectionView.register(MyCollectionViewCell.self, forCellWithReuseIdentifier: "MyCollectionViewCell") 32 | collectionView.register(MyCollectionReusableView.self, forSupplementaryViewOfKind: UICollectionElementKindSectionHeader, withReuseIdentifier: "MyCollectionReusableView") 33 | collectionView.register(MyCollectionReusableView.self, forSupplementaryViewOfKind: UICollectionElementKindSectionFooter, withReuseIdentifier: "MyCollectionReusableView") 34 | 35 | return collectionView; 36 | }() 37 | 38 | override func viewDidLoad() { 39 | super.viewDidLoad() 40 | 41 | // Do any additional setup after loading the view. 42 | initialization() 43 | } 44 | 45 | func initialization() { 46 | self.navigationItem.title = "JJCollectionViewRoundFlowLayout_Swift"; 47 | self.view.backgroundColor = UIColor.init(white: 1.0, alpha: 1.0) 48 | self.initSetup(); 49 | self.initLayout(); 50 | } 51 | 52 | func initSetup() { 53 | 54 | } 55 | 56 | func initLayout() { 57 | view.addSubview(myCollectionView) 58 | let myView = myCollectionView; 59 | let superview = self.view; 60 | 61 | view.addConstraints([ 62 | //view constraints 63 | NSLayoutConstraint.init(item: myView, 64 | attribute: .top, 65 | relatedBy: .equal, 66 | toItem: superview, 67 | attribute: .top, 68 | multiplier: 1.0, 69 | constant: 0), 70 | NSLayoutConstraint.init(item: myView, 71 | attribute: .leading, 72 | relatedBy: .equal, 73 | toItem: superview, 74 | attribute: .leading, 75 | multiplier: 1.0, 76 | constant: 0), 77 | NSLayoutConstraint.init(item: myView, 78 | attribute: .bottom, 79 | relatedBy: .equal, 80 | toItem: superview, 81 | attribute: .bottom, 82 | multiplier: 1.0, 83 | constant: 0), 84 | NSLayoutConstraint.init(item: myView, 85 | attribute: .trailing, 86 | relatedBy: .equal, 87 | toItem: superview, 88 | attribute: .trailing, 89 | multiplier: 1.0, 90 | constant: 0), 91 | 92 | ]); 93 | } 94 | } 95 | 96 | extension FifthlyViewController :UICollectionViewDataSource{ 97 | 98 | func numberOfSections(in collectionView: UICollectionView) -> Int { 99 | return 10 100 | } 101 | 102 | func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { 103 | return 12; 104 | } 105 | 106 | func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { 107 | let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "MyCollectionViewCell", for: indexPath) as! MyCollectionViewCell 108 | cell.labelText.text = "测试内容" 109 | return cell 110 | } 111 | } 112 | 113 | 114 | extension FifthlyViewController :UICollectionViewDelegate { 115 | 116 | } 117 | 118 | extension FifthlyViewController : JJCollectionViewDelegateRoundFlowLayout_Swift{ 119 | func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, borderEdgeInsertsForSectionAtIndex section: Int) -> UIEdgeInsets { 120 | return UIEdgeInsets.init(top: 5, left: 12, bottom: 5, right: 12) 121 | } 122 | 123 | func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, configModelForSectionAtIndex section: Int) -> JJCollectionViewRoundConfigModel_Swift { 124 | let model = JJCollectionViewRoundConfigModel_Swift.init(); 125 | 126 | 127 | if #available(iOS 13.0, *) { 128 | model.backgroundColor = UIColor.init { (traitCollection:UITraitCollection) -> UIColor in 129 | return traitCollection.userInterfaceStyle == .dark ? UIColor.black : UIColor.init(red: 233/255.0, green:233/255.0 ,blue:233/255.0,alpha:1.0); 130 | } 131 | } else { 132 | // Fallback on earlier versions 133 | model.backgroundColor = UIColor.init(red: 233/255.0, green:233/255.0 ,blue:233/255.0,alpha:1.0) 134 | } 135 | 136 | model.cornerRadius = 10; 137 | return model; 138 | 139 | } 140 | 141 | func collectionView(collectionView: UICollectionView, didSelectDecorationViewAtIndexPath indexPath: IndexPath) { 142 | let message = String.init(format: "section --- %ld \n row --- %ld", indexPath.section,indexPath.row) 143 | let alert = UIAlertController.init(title: "JJCollectionViewRoundFlowLayout_Swift", message: message, preferredStyle: .alert); 144 | alert.addAction(UIAlertAction.init(title: "确定", style: .default, handler: nil)); 145 | self.present(alert, animated: true, completion: nil); 146 | } 147 | } 148 | 149 | -------------------------------------------------------------------------------- /Example/JJCollectionViewRoundFlowLayout_Swift/FourViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FourViewController.swift 3 | // JJCollectionViewRoundFlowLayout_Swift_Example 4 | // 5 | // Created by jiajie on 2020/2/3. 6 | // Copyright © 2020 CocoaPods. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import JJCollectionViewRoundFlowLayout_Swift 11 | 12 | class FourViewController: UIViewController { 13 | 14 | var isHaveRoundBGView:Bool = false; 15 | var myAlignmentType:JJCollectionViewRoundFlowLayoutSwiftAlignmentType = .System; 16 | 17 | lazy var myCollectionView : UICollectionView = { 18 | let layout = JJCollectionViewRoundFlowLayout_Swift.init(); 19 | 20 | layout.collectionCellAlignmentType = self.myAlignmentType; 21 | layout.isRoundEnabled = self.isHaveRoundBGView; 22 | 23 | 24 | //setting 25 | layout.sectionInset = UIEdgeInsets.init(top: 20, left: 20, bottom: 20, right: 20); 26 | layout.itemSize = CGSize.init(width: 100, height: 100) 27 | layout.minimumLineSpacing = 10 28 | layout.minimumInteritemSpacing = 5 29 | 30 | //init 31 | let collectionView = UICollectionView.init(frame: CGRect.init(x: 0, y: 0, width: 100, height: 100), collectionViewLayout: layout); 32 | collectionView.translatesAutoresizingMaskIntoConstraints = false; 33 | collectionView.delegate = self; 34 | collectionView.dataSource = self; 35 | 36 | collectionView.showsVerticalScrollIndicator = false 37 | collectionView.showsHorizontalScrollIndicator = false 38 | collectionView.backgroundColor = UIColor.init(white: 1.0, alpha: 1.0) 39 | collectionView.register(MyLabelCollectionViewCell.self, forCellWithReuseIdentifier: "MyLabelCollectionViewCell") 40 | 41 | return collectionView; 42 | }(); 43 | 44 | let myDataArr : Array = ["Hello", 45 | "你好", 46 | "您好啊。", 47 | "大家好,这里是JJCollectionView", 48 | "标签", 49 | "对应不错的东西哦", 50 | "GitHub", 51 | "支持左对齐方式", 52 | "这个东西就是很长,就想弄一个很长的出来", 53 | "上面的文字好像不够长", 54 | "想一下接下来做什么功能呢", 55 | "嗯,知道了", 56 | "优秀"]; 57 | 58 | 59 | override func viewDidLoad() { 60 | super.viewDidLoad() 61 | 62 | // Do any additional setup after loading the view. 63 | 64 | self.initialization(); 65 | } 66 | deinit { 67 | 68 | } 69 | 70 | func initialization() { 71 | self.initSetup(); 72 | self.initLayout(); 73 | } 74 | 75 | func initSetup() { 76 | 77 | } 78 | 79 | func initLayout() { 80 | view.addSubview(myCollectionView) 81 | let myView = myCollectionView; 82 | let superview = self.view; 83 | 84 | view.addConstraints([ 85 | //view constraints 86 | NSLayoutConstraint.init(item: myView, 87 | attribute: .top, 88 | relatedBy: .equal, 89 | toItem: superview, 90 | attribute: .top, 91 | multiplier: 1.0, 92 | constant: 0), 93 | NSLayoutConstraint.init(item: myView, 94 | attribute: .leading, 95 | relatedBy: .equal, 96 | toItem: superview, 97 | attribute: .leading, 98 | multiplier: 1.0, 99 | constant: 0), 100 | NSLayoutConstraint.init(item: myView, 101 | attribute: .bottom, 102 | relatedBy: .equal, 103 | toItem: superview, 104 | attribute: .bottom, 105 | multiplier: 1.0, 106 | constant: 0), 107 | NSLayoutConstraint.init(item: myView, 108 | attribute: .trailing, 109 | relatedBy: .equal, 110 | toItem: superview, 111 | attribute: .trailing, 112 | multiplier: 1.0, 113 | constant: 0), 114 | 115 | ]); 116 | } 117 | } 118 | 119 | extension FourViewController{ 120 | 121 | static func calculateStringViewSizeWithShowSize(_ showSize : CGSize , fontSize : UIFont , string : String) -> CGSize { 122 | let size = showSize; 123 | 124 | let dic = [NSAttributedStringKey.font:fontSize]; 125 | let stringDrawingOptions = NSStringDrawingOptions.init(rawValue: NSStringDrawingOptions.usesLineFragmentOrigin.rawValue 126 | | NSStringDrawingOptions.usesFontLeading.rawValue); 127 | let cur = ((string as NSString).boundingRect(with: size, options: stringDrawingOptions, attributes: dic, context: nil)).size; 128 | return cur; 129 | } 130 | } 131 | 132 | extension FourViewController :UICollectionViewDataSource{ 133 | 134 | func numberOfSections(in collectionView: UICollectionView) -> Int { 135 | return 5 136 | } 137 | 138 | func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { 139 | return self.myDataArr.count; 140 | } 141 | 142 | func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { 143 | let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "MyLabelCollectionViewCell", for: indexPath) as! MyLabelCollectionViewCell 144 | cell.labelText.text = self.myDataArr[indexPath.row]; 145 | return cell 146 | } 147 | } 148 | 149 | extension FourViewController :UICollectionViewDelegate { 150 | func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { 151 | let string = self.myDataArr[indexPath.row]; 152 | 153 | let size = FourViewController.calculateStringViewSizeWithShowSize(CGSize.init(width: CGFloat.greatestFiniteMagnitude, height: 38), fontSize: UIFont.systemFont(ofSize: 15), string: string); 154 | return CGSize.init(width: size.width + 10 + 1, height: 30) 155 | } 156 | 157 | func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat { 158 | return 10; 159 | } 160 | 161 | func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat { 162 | return 5; 163 | } 164 | } 165 | 166 | extension FourViewController : JJCollectionViewDelegateRoundFlowLayout_Swift{ 167 | func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, borderEdgeInsertsForSectionAtIndex section: Int) -> UIEdgeInsets { 168 | return UIEdgeInsets.init(top: 5, left: 12, bottom: 5, right: 12) 169 | } 170 | 171 | func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, configModelForSectionAtIndex section: Int) -> JJCollectionViewRoundConfigModel_Swift { 172 | let model = JJCollectionViewRoundConfigModel_Swift.init(); 173 | model.backgroundColor = UIColor.init(red: 233/255.0, green: 233/255.0, blue: 233/255.0, alpha: 1.0) 174 | model.cornerRadius = 10; 175 | return model; 176 | } 177 | } 178 | -------------------------------------------------------------------------------- /Example/JJCollectionViewRoundFlowLayout_Swift/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "60x60", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "3x" 42 | }, 43 | { 44 | "idiom" : "ios-marketing", 45 | "size" : "1024x1024", 46 | "scale" : "1x" 47 | } 48 | ], 49 | "info" : { 50 | "version" : 1, 51 | "author" : "xcode" 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /Example/JJCollectionViewRoundFlowLayout_Swift/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 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationLandscapeLeft 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /Example/JJCollectionViewRoundFlowLayout_Swift/MyCollectionReusableView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MyCollectionReusableView.swift 3 | // JJCollectionViewRoundFlowLayout_Swift 4 | // 5 | // Created by jiajie on 2019/11/17. 6 | // Copyright © 2019 aihuo. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class MyCollectionReusableView: UICollectionReusableView { 12 | var myLabel : UILabel = { 13 | let label = UILabel.init() 14 | label.translatesAutoresizingMaskIntoConstraints = false 15 | return label 16 | }() 17 | 18 | 19 | override init(frame: CGRect) { 20 | super.init(frame: frame) 21 | initialization(); 22 | } 23 | required init?(coder: NSCoder) { 24 | fatalError("init(coder:) has not been implemented") 25 | } 26 | 27 | func initialization() { 28 | initSetup() 29 | initLayout() 30 | } 31 | 32 | func initSetup() { 33 | 34 | } 35 | 36 | func initLayout() { 37 | addSubview(myLabel) 38 | addConstraints([ 39 | NSLayoutConstraint.init(item: myLabel, attribute: .top, relatedBy: .equal, toItem: self, attribute: .top, multiplier: 1.0, constant: 0), 40 | NSLayoutConstraint.init(item: myLabel, attribute: .leading, relatedBy: .equal, toItem: self, attribute: .leading, multiplier: 1.0, constant: 20), 41 | NSLayoutConstraint.init(item: myLabel, attribute: .bottom, relatedBy: .equal, toItem: self, attribute: .bottom, multiplier: 1.0, constant: 0), 42 | NSLayoutConstraint.init(item: myLabel, attribute: .trailing, relatedBy: .equal, toItem: self, attribute: .trailing, multiplier: 1.0, constant: 0) 43 | ]) 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /Example/JJCollectionViewRoundFlowLayout_Swift/MyCollectionViewCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MyCollectionViewCell.swift 3 | // JJCollectionViewRoundFlowLayout_Swift 4 | // 5 | // Created by jiajie on 2019/11/17. 6 | // Copyright © 2019 aihuo. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class MyCollectionViewCell: UICollectionViewCell { 12 | var labelText : UILabel = { 13 | let label = UILabel.init(); 14 | label.translatesAutoresizingMaskIntoConstraints = false 15 | 16 | return label; 17 | }() 18 | 19 | override init(frame: CGRect) { 20 | super.init(frame: frame); 21 | initialization() 22 | } 23 | 24 | required init?(coder: NSCoder) { 25 | fatalError("init(coder:) has not been implemented") 26 | } 27 | 28 | func initialization() { 29 | self.backgroundColor = UIColor.init(red: 250/255.0, green: 185/255.0, blue: 105/255.0, alpha: 1.0); 30 | initSetup() 31 | initLayout() 32 | } 33 | 34 | func initSetup() { 35 | 36 | } 37 | 38 | func initLayout() { 39 | addSubview(labelText) 40 | addConstraints([ 41 | NSLayoutConstraint.init(item: labelText, attribute: .centerX, relatedBy: .equal, toItem: self, attribute: .centerX, multiplier: 1.0, constant: 0), 42 | NSLayoutConstraint.init(item: labelText, attribute: .centerY, relatedBy: .equal, toItem: self, attribute: .centerY, multiplier: 1.0, constant: 0) 43 | ]) 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /Example/JJCollectionViewRoundFlowLayout_Swift/MyCollectionViewFlowLayout.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MyCollectionViewFlowLayout.swift 3 | // JJCollectionViewRoundFlowLayout_Swift 4 | // 5 | // Created by jiajie on 2019/11/17. 6 | // Copyright © 2019 aihuo. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class MyCollectionViewFlowLayout: UICollectionViewFlowLayout { 12 | 13 | } 14 | -------------------------------------------------------------------------------- /Example/JJCollectionViewRoundFlowLayout_Swift/MyLabelCollectionViewCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MyLabelCollectionViewCell.swift 3 | // JJCollectionViewRoundFlowLayout_Swift_Example 4 | // 5 | // Created by jiajie on 2020/2/4. 6 | // Copyright © 2020 CocoaPods. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class MyLabelCollectionViewCell: UICollectionViewCell { 12 | var labelText : UILabel = { 13 | let label = UILabel.init(); 14 | label.translatesAutoresizingMaskIntoConstraints = false 15 | 16 | label.backgroundColor = UIColor.clear; 17 | label.textColor = #colorLiteral(red: 1, green: 1, blue: 1, alpha: 1); 18 | label.font = UIFont.systemFont(ofSize: 15); 19 | label.textAlignment = .center; 20 | return label; 21 | }() 22 | 23 | override init(frame: CGRect) { 24 | super.init(frame: frame); 25 | initialization() 26 | } 27 | 28 | required init?(coder: NSCoder) { 29 | fatalError("init(coder:) has not been implemented") 30 | } 31 | 32 | func initialization() { 33 | self.layer.cornerRadius = 15; 34 | self.backgroundColor = UIColor.init(red: 250/255.0, green: 185/255.0, blue: 105/255.0, alpha: 1.0); 35 | initSetup() 36 | initLayout() 37 | } 38 | 39 | 40 | func initSetup() { 41 | 42 | } 43 | 44 | func initLayout() { 45 | addSubview(labelText) 46 | addConstraints([ 47 | NSLayoutConstraint.init(item: labelText, attribute: .centerX, relatedBy: .equal, toItem: self, attribute: .centerX, multiplier: 1.0, constant: 0), 48 | NSLayoutConstraint.init(item: labelText, attribute: .centerY, relatedBy: .equal, toItem: self, attribute: .centerY, multiplier: 1.0, constant: 0) 49 | ]) 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /Example/JJCollectionViewRoundFlowLayout_Swift/NextViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // NextViewController.swift 3 | // JJCollectionViewRoundFlowLayout_Swift 4 | // 5 | // Created by jiajie on 2019/11/17. 6 | // Copyright © 2019 aihuo. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import JJCollectionViewRoundFlowLayout_Swift 11 | 12 | class NextViewController: UIViewController { 13 | 14 | lazy var myCollectionView : UICollectionView = { 15 | let layout = JJCollectionViewRoundFlowLayout_Swift.init(); 16 | //setting 17 | layout.sectionInset = UIEdgeInsets.init(top: 20, left: 20, bottom: 20, right: 20); 18 | layout.itemSize = CGSize.init(width: 100, height: 100) 19 | layout.minimumLineSpacing = 10 20 | layout.minimumInteritemSpacing = 5 21 | 22 | layout.scrollDirection = self.isHorizontal ? UICollectionView.ScrollDirection.horizontal : UICollectionView.ScrollDirection.vertical; 23 | layout.isCalculateHeader = self.isRoundWithHeaerView; 24 | layout.isCalculateFooter = self.isRoundWithFooterView; 25 | 26 | //init 27 | let collectionView = UICollectionView.init(frame: CGRect.init(x: 0, y: 0, width: 100.0, height: 100.0), collectionViewLayout: layout); 28 | collectionView.translatesAutoresizingMaskIntoConstraints = false; 29 | collectionView.delegate = self; 30 | collectionView.dataSource = self; 31 | 32 | collectionView.showsVerticalScrollIndicator = false 33 | collectionView.showsHorizontalScrollIndicator = false 34 | collectionView.backgroundColor = UIColor.init(white: 1.0, alpha: 1.0) 35 | collectionView.register(MyCollectionViewCell.self, forCellWithReuseIdentifier: "MyCollectionViewCell") 36 | collectionView.register(MyCollectionReusableView.self, forSupplementaryViewOfKind: UICollectionElementKindSectionHeader, withReuseIdentifier: "MyCollectionReusableView") 37 | collectionView.register(MyCollectionReusableView.self, forSupplementaryViewOfKind: UICollectionElementKindSectionFooter, withReuseIdentifier: "MyCollectionReusableView") 38 | 39 | return collectionView; 40 | }() 41 | 42 | var isHaveHeaderFooterView :Bool = false 43 | var isRoundWithHeaerView :Bool = false 44 | var isRoundWithFooterView :Bool = false 45 | var isHorizontal :Bool = false 46 | var isShowDifferentColor :Bool = false 47 | 48 | 49 | 50 | override func viewDidLoad() { 51 | super.viewDidLoad() 52 | 53 | // Do any additional setup after loading the view. 54 | initialization() 55 | } 56 | 57 | func initialization() { 58 | self.navigationItem.title = "JJCollectionViewRoundFlowLayout_Swift"; 59 | self.view.backgroundColor = UIColor.init(white: 1.0, alpha: 1.0) 60 | self.initSetup(); 61 | self.initLayout(); 62 | } 63 | 64 | func initSetup() { 65 | 66 | } 67 | 68 | func initLayout() { 69 | view.addSubview(myCollectionView) 70 | let myView = myCollectionView; 71 | let superview = self.view; 72 | 73 | view.addConstraints([ 74 | //view constraints 75 | NSLayoutConstraint.init(item: myView, 76 | attribute: .top, 77 | relatedBy: .equal, 78 | toItem: superview, 79 | attribute: .top, 80 | multiplier: 1.0, 81 | constant: 0), 82 | NSLayoutConstraint.init(item: myView, 83 | attribute: .leading, 84 | relatedBy: .equal, 85 | toItem: superview, 86 | attribute: .leading, 87 | multiplier: 1.0, 88 | constant: 0), 89 | NSLayoutConstraint.init(item: myView, 90 | attribute: .bottom, 91 | relatedBy: .equal, 92 | toItem: superview, 93 | attribute: .bottom, 94 | multiplier: 1.0, 95 | constant: 0), 96 | NSLayoutConstraint.init(item: myView, 97 | attribute: .trailing, 98 | relatedBy: .equal, 99 | toItem: superview, 100 | attribute: .trailing, 101 | multiplier: 1.0, 102 | constant: 0), 103 | 104 | ]); 105 | } 106 | } 107 | 108 | extension NextViewController :UICollectionViewDataSource{ 109 | 110 | func numberOfSections(in collectionView: UICollectionView) -> Int { 111 | return 2 112 | } 113 | 114 | func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { 115 | return 12; 116 | } 117 | 118 | func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { 119 | let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "MyCollectionViewCell", for: indexPath) as! MyCollectionViewCell 120 | cell.labelText.text = "测试内容" 121 | return cell 122 | } 123 | 124 | func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView { 125 | let view = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "MyCollectionReusableView", for: indexPath) as! MyCollectionReusableView 126 | if kind == UICollectionElementKindSectionHeader { 127 | view.myLabel.text = "Header"; 128 | return view; 129 | }else{ 130 | view.myLabel.text = "Footer"; 131 | return view; 132 | } 133 | } 134 | } 135 | 136 | 137 | extension NextViewController :UICollectionViewDelegate { 138 | 139 | } 140 | 141 | extension NextViewController : UICollectionViewDelegateFlowLayout{ 142 | func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize { 143 | guard self.isHaveHeaderFooterView else { 144 | return CGSize.init(width: 0, height: 0) 145 | } 146 | return CGSize.init(width: 100, height: 60) 147 | } 148 | 149 | func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForFooterInSection section: Int) -> CGSize { 150 | guard self.isHaveHeaderFooterView else { 151 | return CGSize.init(width: 0, height: 0) 152 | } 153 | return CGSize.init(width: 100, height: 60) 154 | } 155 | 156 | //测试不规则Cell 157 | // func randomIntNumber(lower: Int = 0,upper: Int = Int(UInt32.max)) -> Int { 158 | // return lower + Int(arc4random_uniform(UInt32(upper - lower))) 159 | // } 160 | // 161 | // func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { 162 | // if indexPath.row == 0 { 163 | // return CGSize.init(width: self.randomIntNumber(lower: 40, upper: 50), height: self.randomIntNumber(lower: 30, upper: 50)) 164 | // }else if indexPath.row == 11{ 165 | // return CGSize.init(width: self.randomIntNumber(lower: 40, upper: 50), height: self.randomIntNumber(lower: 30, upper: 50)) 166 | // } 167 | // return CGSize.init(width: self.randomIntNumber(lower: 50, upper: 100), height: self.randomIntNumber(lower: 50, upper: 100)) 168 | // } 169 | } 170 | 171 | extension NextViewController : JJCollectionViewDelegateRoundFlowLayout_Swift{ 172 | func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, borderEdgeInsertsForSectionAtIndex section: Int) -> UIEdgeInsets { 173 | return UIEdgeInsets.init(top: 5, left: 12, bottom: 5, right: 12) 174 | } 175 | 176 | func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, configModelForSectionAtIndex section: Int) -> JJCollectionViewRoundConfigModel_Swift { 177 | let model = JJCollectionViewRoundConfigModel_Swift.init(); 178 | 179 | 180 | if #available(iOS 13.0, *) { 181 | model.backgroundColor = UIColor.init { (traitCollection:UITraitCollection) -> UIColor in 182 | return traitCollection.userInterfaceStyle == .dark ? UIColor.black : UIColor.init(red: 233/255.0, green:233/255.0 ,blue:233/255.0,alpha:1.0); 183 | } 184 | } else { 185 | // Fallback on earlier versions 186 | model.backgroundColor = UIColor.init(red: 233/255.0, green:233/255.0 ,blue:233/255.0,alpha:1.0) 187 | } 188 | 189 | model.cornerRadius = 10; 190 | 191 | if (self.isShowDifferentColor) { 192 | if (section == 0) { 193 | model.backgroundColor = UIColor.init(red: 233/255.0, green:233/255.0 ,blue:233/255.0,alpha:1.0); 194 | }else{ 195 | model.backgroundColor = UIColor.init(red: 100/255.0, green:233/255.0 ,blue:233/255.0,alpha:1.0); 196 | } 197 | } 198 | 199 | return model; 200 | 201 | } 202 | } 203 | 204 | -------------------------------------------------------------------------------- /Example/JJCollectionViewRoundFlowLayout_Swift/SecondViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SecondViewController.swift 3 | // JJCollectionViewRoundFlowLayout_Swift 4 | // 5 | // Created by jiajie on 2019/11/17. 6 | // Copyright © 2019 aihuo. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import JJCollectionViewRoundFlowLayout_Swift 11 | 12 | class SecondViewController: UIViewController { 13 | 14 | lazy var myCollectionView : UICollectionView = { 15 | let layout = JJCollectionViewRoundFlowLayout_Swift.init(); 16 | //setting 17 | layout.sectionInset = UIEdgeInsets.init(top: 20, left: 20, bottom: 20, right: 20); 18 | layout.itemSize = CGSize.init(width: 100, height: 100) 19 | layout.minimumLineSpacing = 10 20 | layout.minimumInteritemSpacing = 5 21 | 22 | //init 23 | let collectionView = UICollectionView.init(frame: CGRect.init(x: 0, y: 0, width: 100.0, height: 100.0), collectionViewLayout: layout); 24 | collectionView.translatesAutoresizingMaskIntoConstraints = false; 25 | collectionView.delegate = self; 26 | collectionView.dataSource = self; 27 | 28 | collectionView.showsVerticalScrollIndicator = false 29 | collectionView.showsHorizontalScrollIndicator = false 30 | collectionView.backgroundColor = UIColor.init(white: 1.0, alpha: 1.0) 31 | collectionView.register(MyCollectionViewCell.self, forCellWithReuseIdentifier: "MyCollectionViewCell") 32 | collectionView.register(MyCollectionReusableView.self, forSupplementaryViewOfKind: UICollectionElementKindSectionHeader, withReuseIdentifier: "MyCollectionReusableView") 33 | collectionView.register(MyCollectionReusableView.self, forSupplementaryViewOfKind: UICollectionElementKindSectionFooter, withReuseIdentifier: "MyCollectionReusableView") 34 | 35 | return collectionView; 36 | }() 37 | 38 | var isHaveShadow :Bool = false 39 | var isHaveBGColor :Bool = false 40 | 41 | 42 | override func viewDidLoad() { 43 | super.viewDidLoad() 44 | 45 | // Do any additional setup after loading the view. 46 | initialization() 47 | } 48 | 49 | func initialization() { 50 | self.navigationItem.title = "JJCollectionViewRoundFlowLayout_Swift"; 51 | self.view.backgroundColor = UIColor.init(white: 1.0, alpha: 1.0) 52 | self.initSetup(); 53 | self.initLayout(); 54 | } 55 | 56 | func initSetup() { 57 | 58 | } 59 | 60 | func initLayout() { 61 | view.addSubview(myCollectionView) 62 | let myView = myCollectionView; 63 | let superview = self.view; 64 | 65 | view.addConstraints([ 66 | //view constraints 67 | NSLayoutConstraint.init(item: myView, 68 | attribute: .top, 69 | relatedBy: .equal, 70 | toItem: superview, 71 | attribute: .top, 72 | multiplier: 1.0, 73 | constant: 0), 74 | NSLayoutConstraint.init(item: myView, 75 | attribute: .leading, 76 | relatedBy: .equal, 77 | toItem: superview, 78 | attribute: .leading, 79 | multiplier: 1.0, 80 | constant: 0), 81 | NSLayoutConstraint.init(item: myView, 82 | attribute: .bottom, 83 | relatedBy: .equal, 84 | toItem: superview, 85 | attribute: .bottom, 86 | multiplier: 1.0, 87 | constant: 0), 88 | NSLayoutConstraint.init(item: myView, 89 | attribute: .trailing, 90 | relatedBy: .equal, 91 | toItem: superview, 92 | attribute: .trailing, 93 | multiplier: 1.0, 94 | constant: 0), 95 | 96 | ]); 97 | } 98 | } 99 | 100 | extension SecondViewController :UICollectionViewDataSource{ 101 | 102 | func numberOfSections(in collectionView: UICollectionView) -> Int { 103 | return 2 104 | } 105 | 106 | func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { 107 | return 12; 108 | } 109 | 110 | func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { 111 | let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "MyCollectionViewCell", for: indexPath) as! MyCollectionViewCell 112 | cell.labelText.text = "测试内容" 113 | return cell 114 | } 115 | 116 | func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView { 117 | let view = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "MyCollectionReusableView", for: indexPath) as! MyCollectionReusableView 118 | if kind == UICollectionElementKindSectionHeader { 119 | view.myLabel.text = "Header"; 120 | return view; 121 | }else{ 122 | view.myLabel.text = "Footer"; 123 | return view; 124 | } 125 | } 126 | } 127 | 128 | 129 | extension SecondViewController :UICollectionViewDelegate { 130 | 131 | } 132 | 133 | extension SecondViewController : JJCollectionViewDelegateRoundFlowLayout_Swift{ 134 | func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, borderEdgeInsertsForSectionAtIndex section: Int) -> UIEdgeInsets { 135 | return UIEdgeInsets.init(top: 5, left: 12, bottom: 5, right: 12) 136 | } 137 | 138 | func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, configModelForSectionAtIndex section: Int) -> JJCollectionViewRoundConfigModel_Swift { 139 | let model = JJCollectionViewRoundConfigModel_Swift.init(); 140 | model.cornerRadius = 4; 141 | 142 | if (self.isHaveShadow) { 143 | if (self.isHaveBGColor) { 144 | model.backgroundColor = UIColor.init(red: 236/255.0, green:236/255.0 ,blue:236/255.0,alpha:1.0) 145 | model.shadowColor = UIColor.black.withAlphaComponent(0.6) 146 | }else{ 147 | model.backgroundColor = UIColor.init(red: 255/255.0, green:255/255.0 ,blue:255/255.0,alpha:1.0) 148 | model.shadowColor = UIColor.init(red: 204/255.0, green:204/255.0 ,blue:204/255.0,alpha:0.6) 149 | } 150 | model.shadowOffset = CGSize.init(width: 0, height: 0) 151 | model.shadowOpacity = 1; 152 | model.shadowRadius = 4; 153 | }else{ 154 | model.borderColor = UIColor.init(red: 204/255.0, green:204/255.0 ,blue:204/255.0,alpha:1.0); 155 | model.borderWidth = 1.0; 156 | } 157 | 158 | return model; 159 | 160 | } 161 | } 162 | -------------------------------------------------------------------------------- /Example/JJCollectionViewRoundFlowLayout_Swift/SixthViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SixthViewController.swift 3 | // JJCollectionViewRoundFlowLayout_Swift_Example 4 | // 5 | // Created by jiajie on 2021/3/8. 6 | // Copyright © 2021 CocoaPods. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import JJCollectionViewRoundFlowLayout_Swift 11 | 12 | class SixthViewController: UIViewController { 13 | 14 | lazy var myCollectionView : UICollectionView = { 15 | let layout = JJCollectionViewRoundFlowLayout_Swift.init(); 16 | //setting 17 | layout.sectionInset = UIEdgeInsets.init(top: 0, left: 0, bottom: 0, right: 0); 18 | layout.itemSize = CGSize.init(width: 100, height: 100) 19 | layout.minimumLineSpacing = 10 20 | layout.minimumInteritemSpacing = 5 21 | 22 | layout.isCalculateHeader = self.isRoundWithHeaerView; 23 | layout.isCalculateFooter = self.isRoundWithFooterView; 24 | 25 | //init 26 | let collectionView = UICollectionView.init(frame: CGRect.init(x: 0, y: 0, width: 100.0, height: 100.0), collectionViewLayout: layout); 27 | collectionView.translatesAutoresizingMaskIntoConstraints = false; 28 | collectionView.delegate = self; 29 | collectionView.dataSource = self; 30 | 31 | collectionView.showsVerticalScrollIndicator = false 32 | collectionView.showsHorizontalScrollIndicator = false 33 | collectionView.backgroundColor = UIColor.init(white: 1.0, alpha: 1.0) 34 | collectionView.register(MyCollectionViewCell.self, forCellWithReuseIdentifier: "MyCollectionViewCell") 35 | collectionView.register(MyCollectionReusableView.self, forSupplementaryViewOfKind: UICollectionElementKindSectionHeader, withReuseIdentifier: "MyCollectionReusableView") 36 | collectionView.register(MyCollectionReusableView.self, forSupplementaryViewOfKind: UICollectionElementKindSectionFooter, withReuseIdentifier: "MyCollectionReusableView") 37 | 38 | return collectionView; 39 | }() 40 | 41 | var isHaveHeaderFooterView :Bool = false 42 | var isRoundWithHeaerView :Bool = false 43 | var isRoundWithFooterView :Bool = false 44 | 45 | override func viewDidLoad() { 46 | super.viewDidLoad() 47 | 48 | // Do any additional setup after loading the view. 49 | initialization() 50 | } 51 | 52 | func initialization() { 53 | self.navigationItem.title = "JJCollectionViewRoundFlowLayout_Swift"; 54 | self.view.backgroundColor = UIColor.init(white: 1.0, alpha: 1.0) 55 | self.initSetup(); 56 | self.initLayout(); 57 | } 58 | 59 | func initSetup() { 60 | 61 | } 62 | 63 | func initLayout() { 64 | view.addSubview(myCollectionView) 65 | let myView = myCollectionView; 66 | let superview = self.view; 67 | 68 | view.addConstraints([ 69 | //view constraints 70 | NSLayoutConstraint.init(item: myView, 71 | attribute: .top, 72 | relatedBy: .equal, 73 | toItem: superview, 74 | attribute: .top, 75 | multiplier: 1.0, 76 | constant: 0), 77 | NSLayoutConstraint.init(item: myView, 78 | attribute: .leading, 79 | relatedBy: .equal, 80 | toItem: superview, 81 | attribute: .leading, 82 | multiplier: 1.0, 83 | constant: 0), 84 | NSLayoutConstraint.init(item: myView, 85 | attribute: .bottom, 86 | relatedBy: .equal, 87 | toItem: superview, 88 | attribute: .bottom, 89 | multiplier: 1.0, 90 | constant: 0), 91 | NSLayoutConstraint.init(item: myView, 92 | attribute: .trailing, 93 | relatedBy: .equal, 94 | toItem: superview, 95 | attribute: .trailing, 96 | multiplier: 1.0, 97 | constant: 0), 98 | 99 | ]); 100 | } 101 | } 102 | 103 | extension SixthViewController :UICollectionViewDataSource{ 104 | 105 | func numberOfSections(in collectionView: UICollectionView) -> Int { 106 | return 10; 107 | } 108 | 109 | func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { 110 | return 0; 111 | } 112 | 113 | func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { 114 | let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "MyCollectionViewCell", for: indexPath) as! MyCollectionViewCell 115 | cell.labelText.text = "测试内容" 116 | return cell 117 | } 118 | 119 | func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView { 120 | let view = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "MyCollectionReusableView", for: indexPath) as! MyCollectionReusableView 121 | if kind == UICollectionElementKindSectionHeader { 122 | view.myLabel.text = "Header"; 123 | return view; 124 | }else{ 125 | view.myLabel.text = "Footer"; 126 | return view; 127 | } 128 | } 129 | } 130 | 131 | 132 | extension SixthViewController :UICollectionViewDelegate { 133 | 134 | } 135 | 136 | extension SixthViewController : UICollectionViewDelegateFlowLayout{ 137 | func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize { 138 | guard self.isHaveHeaderFooterView else { 139 | return CGSize.init(width: 0, height: 0) 140 | } 141 | return CGSize.init(width: 100, height: 60) 142 | } 143 | 144 | func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForFooterInSection section: Int) -> CGSize { 145 | guard self.isHaveHeaderFooterView else { 146 | return CGSize.init(width: 0, height: 0) 147 | } 148 | return CGSize.init(width: 100, height: 60) 149 | } 150 | 151 | //测试不规则Cell 152 | // func randomIntNumber(lower: Int = 0,upper: Int = Int(UInt32.max)) -> Int { 153 | // return lower + Int(arc4random_uniform(UInt32(upper - lower))) 154 | // } 155 | // 156 | // func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { 157 | // if indexPath.row == 0 { 158 | // return CGSize.init(width: self.randomIntNumber(lower: 40, upper: 50), height: self.randomIntNumber(lower: 30, upper: 50)) 159 | // }else if indexPath.row == 11{ 160 | // return CGSize.init(width: self.randomIntNumber(lower: 40, upper: 50), height: self.randomIntNumber(lower: 30, upper: 50)) 161 | // } 162 | // return CGSize.init(width: self.randomIntNumber(lower: 50, upper: 100), height: self.randomIntNumber(lower: 50, upper: 100)) 163 | // } 164 | } 165 | 166 | extension SixthViewController : JJCollectionViewDelegateRoundFlowLayout_Swift{ 167 | func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, borderEdgeInsertsForSectionAtIndex section: Int) -> UIEdgeInsets { 168 | return UIEdgeInsets.init(top: 0, left: 10, bottom: 0, right: 10) 169 | } 170 | 171 | func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, configModelForSectionAtIndex section: Int) -> JJCollectionViewRoundConfigModel_Swift { 172 | let model = JJCollectionViewRoundConfigModel_Swift.init(); 173 | 174 | 175 | if #available(iOS 13.0, *) { 176 | model.backgroundColor = UIColor.init { (traitCollection:UITraitCollection) -> UIColor in 177 | return traitCollection.userInterfaceStyle == .dark ? UIColor.black : UIColor.init(red: 233/255.0, green:233/255.0 ,blue:233/255.0,alpha:1.0); 178 | } 179 | } else { 180 | // Fallback on earlier versions 181 | model.backgroundColor = UIColor.init(red: 233/255.0, green:233/255.0 ,blue:233/255.0,alpha:1.0) 182 | } 183 | 184 | model.cornerRadius = 10; 185 | 186 | return model; 187 | } 188 | 189 | func collectionView(collectionView: UICollectionView, layout: UICollectionViewLayout, isCalculateHeaderViewIndex section: NSInteger) -> Bool { 190 | return true; 191 | } 192 | 193 | func collectionView(collectionView: UICollectionView, layout: UICollectionViewLayout, isCalculateFooterViewIndex section: NSInteger) -> Bool { 194 | return true; 195 | } 196 | 197 | func collectionView(collectionView: UICollectionView, layout: UICollectionViewLayout, isCanCalculateWhenRowEmptyWithSection section: NSInteger) -> Bool { 198 | if section % 2 == 0 { 199 | return true; 200 | } 201 | return false; 202 | } 203 | } 204 | 205 | -------------------------------------------------------------------------------- /Example/JJCollectionViewRoundFlowLayout_Swift/ThirdViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ThirdViewController.swift 3 | // JJCollectionViewRoundFlowLayout_Swift_Example 4 | // 5 | // Created by jiajie on 2020/1/2. 6 | // Copyright © 2020 CocoaPods. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import JJCollectionViewRoundFlowLayout_Swift 11 | 12 | class ThirdViewController: UIViewController { 13 | 14 | lazy var myCollectionView: UICollectionView = { 15 | let layout = JJCollectionViewRoundFlowLayout_Swift.init(); 16 | //setting 17 | layout.sectionInset = UIEdgeInsets.init(top: 20, left: 20, bottom: 20, right: 20); 18 | layout.itemSize = CGSize.init(width: 100, height: 100) 19 | layout.minimumLineSpacing = 10 20 | layout.minimumInteritemSpacing = 5 21 | 22 | //init 23 | let collectionView = UICollectionView.init(frame: CGRect.init(x: 0, y: 0, width: 100, height: 100), collectionViewLayout: layout); 24 | collectionView.translatesAutoresizingMaskIntoConstraints = false; 25 | collectionView.delegate = self; 26 | collectionView.dataSource = self; 27 | 28 | collectionView.showsVerticalScrollIndicator = false 29 | collectionView.showsHorizontalScrollIndicator = false 30 | collectionView.backgroundColor = UIColor.init(white: 1.0, alpha: 1.0) 31 | collectionView.register(MyCollectionViewCell.self, forCellWithReuseIdentifier: "MyCollectionViewCell") 32 | collectionView.register(MyCollectionReusableView.self, forSupplementaryViewOfKind: UICollectionElementKindSectionHeader, withReuseIdentifier: "MyCollectionReusableView") 33 | collectionView.register(MyCollectionReusableView.self, forSupplementaryViewOfKind: UICollectionElementKindSectionFooter, withReuseIdentifier: "MyCollectionReusableView") 34 | 35 | 36 | return collectionView; 37 | }() 38 | 39 | var isHaveHeaderFooterView:Bool = false; 40 | var isRoundWithHeaerView:Bool = false; 41 | var isRoundWithFooterView:Bool = false; 42 | 43 | 44 | override func viewDidLoad() { 45 | super.viewDidLoad() 46 | 47 | // Do any additional setup after loading the view. 48 | 49 | self.initialization(); 50 | } 51 | 52 | func initialization() { 53 | self.navigationItem.title = "JJCollectionViewRoundFlowLayout_Swift"; 54 | self.view.backgroundColor = UIColor.init(white: 1.0, alpha: 1.0) 55 | self.initSetup(); 56 | self.initLayout(); 57 | } 58 | 59 | func initSetup() { 60 | 61 | } 62 | 63 | func initLayout() { 64 | view.addSubview(myCollectionView) 65 | let myView = myCollectionView; 66 | let superview = self.view; 67 | 68 | view.addConstraints([ 69 | //view constraints 70 | NSLayoutConstraint.init(item: myView, 71 | attribute: .top, 72 | relatedBy: .equal, 73 | toItem: superview, 74 | attribute: .top, 75 | multiplier: 1.0, 76 | constant: 0), 77 | NSLayoutConstraint.init(item: myView, 78 | attribute: .leading, 79 | relatedBy: .equal, 80 | toItem: superview, 81 | attribute: .leading, 82 | multiplier: 1.0, 83 | constant: 0), 84 | NSLayoutConstraint.init(item: myView, 85 | attribute: .bottom, 86 | relatedBy: .equal, 87 | toItem: superview, 88 | attribute: .bottom, 89 | multiplier: 1.0, 90 | constant: 0), 91 | NSLayoutConstraint.init(item: myView, 92 | attribute: .trailing, 93 | relatedBy: .equal, 94 | toItem: superview, 95 | attribute: .trailing, 96 | multiplier: 1.0, 97 | constant: 0), 98 | 99 | ]); 100 | } 101 | } 102 | 103 | extension ThirdViewController :UICollectionViewDataSource{ 104 | 105 | func numberOfSections(in collectionView: UICollectionView) -> Int { 106 | return 5 107 | } 108 | 109 | func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { 110 | return 12; 111 | } 112 | 113 | func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { 114 | let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "MyCollectionViewCell", for: indexPath) as! MyCollectionViewCell 115 | cell.labelText.text = "测试内容" 116 | return cell 117 | } 118 | 119 | 120 | func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForFooterInSection section: Int) -> CGSize { 121 | if self.isHaveHeaderFooterView{ 122 | return CGSize.init(width: 100, height: 60); 123 | } 124 | return CGSize.init(width: 0, height: 0); 125 | } 126 | 127 | func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize { 128 | if self.isHaveHeaderFooterView{ 129 | return CGSize.init(width: 100, height: 60); 130 | } 131 | return CGSize.init(width: 0, height: 0); 132 | } 133 | 134 | func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView { 135 | let view = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "MyCollectionReusableView", for: indexPath) as! MyCollectionReusableView 136 | if kind == UICollectionElementKindSectionHeader { 137 | view.myLabel.text = "Header"; 138 | return view; 139 | }else{ 140 | view.myLabel.text = "Footer"; 141 | return view; 142 | } 143 | } 144 | } 145 | 146 | extension ThirdViewController :UICollectionViewDelegate { 147 | 148 | } 149 | 150 | extension ThirdViewController : JJCollectionViewDelegateRoundFlowLayout_Swift{ 151 | func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, borderEdgeInsertsForSectionAtIndex section: Int) -> UIEdgeInsets { 152 | return UIEdgeInsets.init(top: 5, left: 12, bottom: 5, right: 12) 153 | } 154 | 155 | func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, configModelForSectionAtIndex section: Int) -> JJCollectionViewRoundConfigModel_Swift { 156 | let model = JJCollectionViewRoundConfigModel_Swift.init(); 157 | model.backgroundColor = UIColor.init(red: 233/255.0, green: 233/255.0, blue: 233/255.0, alpha: 1.0) 158 | model.cornerRadius = 10; 159 | return model; 160 | } 161 | 162 | /// 根据section设置是否包含headerview(实现该方法后,isCalculateHeader将不会生效) 163 | /// - Parameters: 164 | /// - collectionView: collectionView description 165 | /// - layout: layout description 166 | /// - section: section description 167 | func collectionView(collectionView: UICollectionView,layout: UICollectionViewLayout, isCalculateHeaderViewIndex section: NSInteger) -> Bool { 168 | 169 | if (self.isRoundWithHeaerView) { 170 | if (section % 2 == 0) { 171 | return true; 172 | } 173 | }else{ 174 | if (section == 0) { 175 | return true; 176 | } 177 | } 178 | return false; 179 | } 180 | 181 | /// 根据section设置是否包含footerview(实现该方法后,isCalculateFooter将不会生效) 182 | /// - Parameters: 183 | /// - collectionView: collectionView description 184 | /// - layout: layout description 185 | /// - section: section description 186 | func collectionView(collectionView: UICollectionView,layout: UICollectionViewLayout, isCalculateFooterViewIndex section: NSInteger) -> Bool { 187 | if (self.isRoundWithFooterView) { 188 | if (section % 2 == 0) { 189 | return true; 190 | } 191 | }else{ 192 | if (section == 0) { 193 | return true; 194 | } 195 | } 196 | return false; 197 | } 198 | } 199 | -------------------------------------------------------------------------------- /Example/JJCollectionViewRoundFlowLayout_Swift/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // JJCollectionViewRoundFlowLayout_Swift 4 | // 5 | // Created by kingjiajie on 11/18/2019. 6 | // Copyright (c) 2019 kingjiajie. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class ViewController: UIViewController { 12 | 13 | lazy var myTableView : UITableView = { 14 | let tableview = UITableView.init(frame: CGRect.init(x: 0, y: 0, width: 100.0, height: 100.0), style: UITableView.Style.plain) 15 | tableview.translatesAutoresizingMaskIntoConstraints = false; 16 | tableview.delegate = self; 17 | tableview.dataSource = self; 18 | tableview.tableFooterView = UIView(); 19 | return tableview 20 | }() 21 | let myTitleArr : Array = ["CollectionView(包住section圆角)",//1 22 | "有Header&Footer,包Header,不包Footer",//2 23 | "有Header&Footer,包Header,包Footer",//3 24 | "有Header&Footer,不包Header,包Footer",//4 25 | "CollectionView(包住section圆角)(横向)",//5 26 | "CollectionView (横向 有H&F View)",//6 27 | "borderLine 包Section",//7 28 | "borderLine 包Section(带投影)",//8 29 | "BackgroundColor 底色(带投影)",//9 30 | "CollectionView(底色 圆角 分别不同颜色)",//10 31 | "CollectionView(单独设置某个 header 底色)", 32 | "CollectionView(单独设置某个 footer 底色))", 33 | "CollectionView,无sections底色,cell左对齐", 34 | "CollectionView,有sections底色,cell左对齐", 35 | "CollectionView,无sections底色,cell居中", 36 | "CollectionView,无sections底色,cell右对齐", 37 | "CollectionView,cell右对齐与cell右侧开始", 38 | "CollectionView,背景图点击事件响应", 39 | "有H&F,Cell为0,判断是否计算H&F" 40 | ]; 41 | 42 | override func viewDidLoad() { 43 | super.viewDidLoad() 44 | // Do any additional setup after loading the view. 45 | initialization() 46 | } 47 | 48 | func initialization() { 49 | self.navigationItem.title = "JJCollectionViewRoundFlowLayout_Swift"; 50 | self.initSetup(); 51 | self.initLayout(); 52 | } 53 | 54 | func initSetup() { 55 | 56 | } 57 | 58 | func initLayout() { 59 | view.addSubview(myTableView) 60 | let myView = myTableView; 61 | let superview = self.view; 62 | 63 | view.addConstraints([ 64 | //view constraints 65 | NSLayoutConstraint.init(item: myView, 66 | attribute: .topMargin, 67 | relatedBy: .equal, 68 | toItem: superview, 69 | attribute: .topMargin, 70 | multiplier: 1.0, 71 | constant: 0), 72 | NSLayoutConstraint.init(item: myView, 73 | attribute: .leading, 74 | relatedBy: .equal, 75 | toItem: superview, 76 | attribute: .leading, 77 | multiplier: 1.0, 78 | constant: 0), 79 | NSLayoutConstraint.init(item: myView, 80 | attribute: .bottomMargin, 81 | relatedBy: .equal, 82 | toItem: superview, 83 | attribute: .bottomMargin, 84 | multiplier: 1.0, 85 | constant: 0), 86 | NSLayoutConstraint.init(item: myView, 87 | attribute: .trailing, 88 | relatedBy: .equal, 89 | toItem: superview, 90 | attribute: .trailing, 91 | multiplier: 1.0, 92 | constant: 0), 93 | 94 | ]); 95 | } 96 | } 97 | 98 | extension ViewController : UITableViewDataSource { 99 | func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 100 | return self.myTitleArr.count; 101 | } 102 | 103 | func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 104 | let cellIdentifier = "Cell" 105 | var cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier); 106 | if cell == nil { 107 | cell = UITableViewCell.init(style: .default, reuseIdentifier: cellIdentifier); 108 | } 109 | cell?.textLabel?.text = self.myTitleArr[indexPath.row]; 110 | return cell!; 111 | } 112 | } 113 | 114 | extension ViewController : UITableViewDelegate { 115 | func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { 116 | let VC = NextViewController.init(); 117 | switch (indexPath.row) { 118 | case 0: 119 | VC.isHaveHeaderFooterView = false; 120 | case 1: 121 | VC.isHaveHeaderFooterView = true; 122 | VC.isRoundWithHeaerView = true; 123 | case 2: 124 | VC.isHaveHeaderFooterView = true; 125 | VC.isRoundWithHeaerView = true; 126 | VC.isRoundWithFooterView = true; 127 | case 3: 128 | VC.isHaveHeaderFooterView = true; 129 | VC.isRoundWithFooterView = true; 130 | case 4: 131 | VC.isHaveHeaderFooterView = false; 132 | VC.isHorizontal = true; 133 | case 5: 134 | VC.isHaveHeaderFooterView = true; 135 | VC.isRoundWithHeaerView = true; 136 | VC.isRoundWithFooterView = true; 137 | VC.isHorizontal = true; 138 | case 6: 139 | let secondVC = SecondViewController.init(); 140 | secondVC.isHaveShadow = false; 141 | self.navigationController?.pushViewController(secondVC, animated: true); 142 | return; 143 | case 7: 144 | let secondVC = SecondViewController.init(); 145 | secondVC.isHaveShadow = true; 146 | self.navigationController?.pushViewController(secondVC, animated: true); 147 | return 148 | case 8: 149 | let secondVC = SecondViewController.init(); 150 | secondVC.isHaveShadow = true; 151 | secondVC.isHaveBGColor = true; 152 | self.navigationController?.pushViewController(secondVC, animated: true); 153 | return 154 | case 9: 155 | VC.isHaveHeaderFooterView = false; 156 | VC.isShowDifferentColor = true; 157 | case 10: 158 | let thirdVC = ThirdViewController.init(); 159 | thirdVC.isHaveHeaderFooterView = true; 160 | thirdVC.isRoundWithHeaerView = true; 161 | self.navigationController?.pushViewController(thirdVC, animated: true); 162 | return 163 | case 11: 164 | let thirdVC = ThirdViewController.init(); 165 | thirdVC.isHaveHeaderFooterView = true; 166 | thirdVC.isRoundWithFooterView = true; 167 | self.navigationController?.pushViewController(thirdVC, animated: true); 168 | return 169 | case 12: 170 | let fourVC = FourViewController.init(); 171 | fourVC.myAlignmentType = .Left; 172 | self.navigationController?.pushViewController(fourVC, animated: true); 173 | return; 174 | case 13: 175 | let fourVC = FourViewController.init(); 176 | fourVC.myAlignmentType = .Left; 177 | fourVC.isHaveRoundBGView = true; 178 | self.navigationController?.pushViewController(fourVC, animated: true); 179 | return; 180 | case 14: 181 | let fourVC = FourViewController.init(); 182 | fourVC.myAlignmentType = .Center 183 | self.navigationController?.pushViewController(fourVC, animated: true); 184 | return; 185 | case 15: 186 | let fourVC = FourViewController.init(); 187 | fourVC.myAlignmentType = .Right 188 | self.navigationController?.pushViewController(fourVC, animated: true); 189 | return; 190 | case 16: 191 | let fourVC = FourViewController.init(); 192 | fourVC.myAlignmentType = .RightAndStartR; 193 | self.navigationController?.pushViewController(fourVC, animated: true); 194 | return; 195 | case 17: 196 | let fifthly = FifthlyViewController.init(); 197 | self.navigationController?.pushViewController(fifthly, animated: true); 198 | return; 199 | case 18: 200 | let sixth = SixthViewController.init(); 201 | sixth.isHaveHeaderFooterView = true; 202 | sixth.isRoundWithHeaerView = true; 203 | sixth.isRoundWithFooterView = true; 204 | self.navigationController?.pushViewController(sixth, animated: true); 205 | return; 206 | default: 207 | break; 208 | } 209 | self.navigationController?.pushViewController(VC, animated: true) 210 | } 211 | } 212 | -------------------------------------------------------------------------------- /Example/Podfile: -------------------------------------------------------------------------------- 1 | use_frameworks! 2 | 3 | target 'JJCollectionViewRoundFlowLayout_Swift_Example' do 4 | pod 'JJCollectionViewRoundFlowLayout_Swift', :path => '../' 5 | 6 | target 'JJCollectionViewRoundFlowLayout_Swift_Tests' do 7 | inherit! :search_paths 8 | 9 | #pod 'FBSnapshotTestCase' , '~> 2.1.4' 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /Example/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - JJCollectionViewRoundFlowLayout_Swift (2.0.0) 3 | 4 | DEPENDENCIES: 5 | - JJCollectionViewRoundFlowLayout_Swift (from `../`) 6 | 7 | EXTERNAL SOURCES: 8 | JJCollectionViewRoundFlowLayout_Swift: 9 | :path: "../" 10 | 11 | SPEC CHECKSUMS: 12 | JJCollectionViewRoundFlowLayout_Swift: 5efccbeee578d82b0bfe2b2aded9a7d52b447b8b 13 | 14 | PODFILE CHECKSUM: 0a7860dab9968464ba91cdd55552f510076bc2d6 15 | 16 | COCOAPODS: 1.8.4 17 | -------------------------------------------------------------------------------- /Example/Pods/Local Podspecs/JJCollectionViewRoundFlowLayout_Swift.podspec.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "JJCollectionViewRoundFlowLayout_Swift", 3 | "version": "2.0.0", 4 | "summary": "JJCollectionViewRoundFlowLayout_Swift可设置CollectionView的BackgroundColor,设置简单,可自定义背景颜色偏移、设置cell对齐方式等功能,.", 5 | "description": "TODO: JJCollectionViewRoundFlowLayout_Swift是JJCollectionViewRoundFlowLayout(OC:https://github.com/kingjiajie/JJCollectionViewRoundFlowLayout)的Swift版本,JJCollectionViewRoundFlowLayout可设置CollectionView的BackgroundColor,可根据用户Cell个数计算背景图尺寸,可自定义是否包括计算CollectionViewHeaderView、CollectionViewFootererView或只计算Cells。设置简单,可自定义背景颜色偏移,设置显示方向(竖向、横向)显示,不同Section设置不同的背景颜色,可设置cell对齐方式。.", 6 | "homepage": "https://github.com/kingjiajie/JJCollectionViewRoundFlowLayout_Swift", 7 | "license": { 8 | "type": "MIT", 9 | "file": "LICENSE" 10 | }, 11 | "authors": { 12 | "kingjiajie": "kingjiajie@sina.com" 13 | }, 14 | "source": { 15 | "git": "https://github.com/kingjiajie/JJCollectionViewRoundFlowLayout_Swift.git", 16 | "tag": "2.0.0" 17 | }, 18 | "platforms": { 19 | "ios": "9.0" 20 | }, 21 | "source_files": "JJCollectionViewRoundFlowLayout_Swift/Classes/**/*", 22 | "frameworks": "UIKit", 23 | "swift_versions": [ 24 | "4.2", 25 | "5.0" 26 | ], 27 | "swift_version": "5.0" 28 | } 29 | -------------------------------------------------------------------------------- /Example/Pods/Manifest.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - JJCollectionViewRoundFlowLayout_Swift (2.0.0) 3 | 4 | DEPENDENCIES: 5 | - JJCollectionViewRoundFlowLayout_Swift (from `../`) 6 | 7 | EXTERNAL SOURCES: 8 | JJCollectionViewRoundFlowLayout_Swift: 9 | :path: "../" 10 | 11 | SPEC CHECKSUMS: 12 | JJCollectionViewRoundFlowLayout_Swift: 5efccbeee578d82b0bfe2b2aded9a7d52b447b8b 13 | 14 | PODFILE CHECKSUM: 0a7860dab9968464ba91cdd55552f510076bc2d6 15 | 16 | COCOAPODS: 1.8.4 17 | -------------------------------------------------------------------------------- /Example/Pods/Pods.xcodeproj/xcshareddata/xcschemes/JJCollectionViewRoundFlowLayout_Swift-Example.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 29 | 35 | 36 | 37 | 38 | 39 | 44 | 45 | 51 | 52 | 53 | 54 | 56 | 62 | 63 | 64 | 65 | 66 | 76 | 78 | 84 | 85 | 86 | 87 | 93 | 95 | 101 | 102 | 103 | 104 | 106 | 107 | 110 | 111 | 112 | -------------------------------------------------------------------------------- /Example/Pods/Pods.xcodeproj/xcshareddata/xcschemes/JJCollectionViewRoundFlowLayout_Swift.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 43 | 44 | 50 | 51 | 53 | 54 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/JJCollectionViewRoundFlowLayout_Swift/JJCollectionViewRoundFlowLayout_Swift-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 | FMWK 17 | CFBundleShortVersionString 18 | 2.0.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/JJCollectionViewRoundFlowLayout_Swift/JJCollectionViewRoundFlowLayout_Swift-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_JJCollectionViewRoundFlowLayout_Swift : NSObject 3 | @end 4 | @implementation PodsDummy_JJCollectionViewRoundFlowLayout_Swift 5 | @end 6 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/JJCollectionViewRoundFlowLayout_Swift/JJCollectionViewRoundFlowLayout_Swift-prefix.pch: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/JJCollectionViewRoundFlowLayout_Swift/JJCollectionViewRoundFlowLayout_Swift-umbrella.h: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | 14 | FOUNDATION_EXPORT double JJCollectionViewRoundFlowLayout_SwiftVersionNumber; 15 | FOUNDATION_EXPORT const unsigned char JJCollectionViewRoundFlowLayout_SwiftVersionString[]; 16 | 17 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/JJCollectionViewRoundFlowLayout_Swift/JJCollectionViewRoundFlowLayout_Swift.modulemap: -------------------------------------------------------------------------------- 1 | framework module JJCollectionViewRoundFlowLayout_Swift { 2 | umbrella header "JJCollectionViewRoundFlowLayout_Swift-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/JJCollectionViewRoundFlowLayout_Swift/JJCollectionViewRoundFlowLayout_Swift.xcconfig: -------------------------------------------------------------------------------- 1 | CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/JJCollectionViewRoundFlowLayout_Swift 2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 3 | OTHER_LDFLAGS = $(inherited) -framework "UIKit" 4 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS 5 | PODS_BUILD_DIR = ${BUILD_DIR} 6 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 7 | PODS_ROOT = ${SRCROOT} 8 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/../.. 9 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} 10 | SKIP_INSTALL = YES 11 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 12 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-JJCollectionViewRoundFlowLayout_Swift_Example/Pods-JJCollectionViewRoundFlowLayout_Swift_Example-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 | FMWK 17 | CFBundleShortVersionString 18 | 1.0.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-JJCollectionViewRoundFlowLayout_Swift_Example/Pods-JJCollectionViewRoundFlowLayout_Swift_Example-acknowledgements.markdown: -------------------------------------------------------------------------------- 1 | # Acknowledgements 2 | This application makes use of the following third party libraries: 3 | 4 | ## JJCollectionViewRoundFlowLayout_Swift 5 | 6 | Copyright (c) 2019 kingjiajie 7 | 8 | Permission is hereby granted, free of charge, to any person obtaining a copy 9 | of this software and associated documentation files (the "Software"), to deal 10 | in the Software without restriction, including without limitation the rights 11 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | copies of the Software, and to permit persons to whom the Software is 13 | furnished to do so, subject to the following conditions: 14 | 15 | The above copyright notice and this permission notice shall be included in 16 | all copies or substantial portions of the Software. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | THE SOFTWARE. 25 | 26 | Generated by CocoaPods - https://cocoapods.org 27 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-JJCollectionViewRoundFlowLayout_Swift_Example/Pods-JJCollectionViewRoundFlowLayout_Swift_Example-acknowledgements.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreferenceSpecifiers 6 | 7 | 8 | FooterText 9 | This application makes use of the following third party libraries: 10 | Title 11 | Acknowledgements 12 | Type 13 | PSGroupSpecifier 14 | 15 | 16 | FooterText 17 | Copyright (c) 2019 kingjiajie <kingjiajie@sina.com> 18 | 19 | Permission is hereby granted, free of charge, to any person obtaining a copy 20 | of this software and associated documentation files (the "Software"), to deal 21 | in the Software without restriction, including without limitation the rights 22 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 23 | copies of the Software, and to permit persons to whom the Software is 24 | furnished to do so, subject to the following conditions: 25 | 26 | The above copyright notice and this permission notice shall be included in 27 | all copies or substantial portions of the Software. 28 | 29 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 30 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 31 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 32 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 33 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 34 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 35 | THE SOFTWARE. 36 | 37 | License 38 | MIT 39 | Title 40 | JJCollectionViewRoundFlowLayout_Swift 41 | Type 42 | PSGroupSpecifier 43 | 44 | 45 | FooterText 46 | Generated by CocoaPods - https://cocoapods.org 47 | Title 48 | 49 | Type 50 | PSGroupSpecifier 51 | 52 | 53 | StringsTable 54 | Acknowledgements 55 | Title 56 | Acknowledgements 57 | 58 | 59 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-JJCollectionViewRoundFlowLayout_Swift_Example/Pods-JJCollectionViewRoundFlowLayout_Swift_Example-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Pods_JJCollectionViewRoundFlowLayout_Swift_Example : NSObject 3 | @end 4 | @implementation PodsDummy_Pods_JJCollectionViewRoundFlowLayout_Swift_Example 5 | @end 6 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-JJCollectionViewRoundFlowLayout_Swift_Example/Pods-JJCollectionViewRoundFlowLayout_Swift_Example-frameworks.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | set -u 4 | set -o pipefail 5 | 6 | function on_error { 7 | echo "$(realpath -mq "${0}"):$1: error: Unexpected failure" 8 | } 9 | trap 'on_error $LINENO' ERR 10 | 11 | if [ -z ${FRAMEWORKS_FOLDER_PATH+x} ]; then 12 | # If FRAMEWORKS_FOLDER_PATH is not set, then there's nowhere for us to copy 13 | # frameworks to, so exit 0 (signalling the script phase was successful). 14 | exit 0 15 | fi 16 | 17 | echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 18 | mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 19 | 20 | COCOAPODS_PARALLEL_CODE_SIGN="${COCOAPODS_PARALLEL_CODE_SIGN:-false}" 21 | SWIFT_STDLIB_PATH="${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" 22 | 23 | # Used as a return value for each invocation of `strip_invalid_archs` function. 24 | STRIP_BINARY_RETVAL=0 25 | 26 | # This protects against multiple targets copying the same framework dependency at the same time. The solution 27 | # was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html 28 | RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????") 29 | 30 | # Copies and strips a vendored framework 31 | install_framework() 32 | { 33 | if [ -r "${BUILT_PRODUCTS_DIR}/$1" ]; then 34 | local source="${BUILT_PRODUCTS_DIR}/$1" 35 | elif [ -r "${BUILT_PRODUCTS_DIR}/$(basename "$1")" ]; then 36 | local source="${BUILT_PRODUCTS_DIR}/$(basename "$1")" 37 | elif [ -r "$1" ]; then 38 | local source="$1" 39 | fi 40 | 41 | local destination="${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 42 | 43 | if [ -L "${source}" ]; then 44 | echo "Symlinked..." 45 | source="$(readlink "${source}")" 46 | fi 47 | 48 | # Use filter instead of exclude so missing patterns don't throw errors. 49 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\"" 50 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}" 51 | 52 | local basename 53 | basename="$(basename -s .framework "$1")" 54 | binary="${destination}/${basename}.framework/${basename}" 55 | 56 | if ! [ -r "$binary" ]; then 57 | binary="${destination}/${basename}" 58 | elif [ -L "${binary}" ]; then 59 | echo "Destination binary is symlinked..." 60 | dirname="$(dirname "${binary}")" 61 | binary="${dirname}/$(readlink "${binary}")" 62 | fi 63 | 64 | # Strip invalid architectures so "fat" simulator / device frameworks work on device 65 | if [[ "$(file "$binary")" == *"dynamically linked shared library"* ]]; then 66 | strip_invalid_archs "$binary" 67 | fi 68 | 69 | # Resign the code if required by the build settings to avoid unstable apps 70 | code_sign_if_enabled "${destination}/$(basename "$1")" 71 | 72 | # Embed linked Swift runtime libraries. No longer necessary as of Xcode 7. 73 | if [ "${XCODE_VERSION_MAJOR}" -lt 7 ]; then 74 | local swift_runtime_libs 75 | swift_runtime_libs=$(xcrun otool -LX "$binary" | grep --color=never @rpath/libswift | sed -E s/@rpath\\/\(.+dylib\).*/\\1/g | uniq -u) 76 | for lib in $swift_runtime_libs; do 77 | echo "rsync -auv \"${SWIFT_STDLIB_PATH}/${lib}\" \"${destination}\"" 78 | rsync -auv "${SWIFT_STDLIB_PATH}/${lib}" "${destination}" 79 | code_sign_if_enabled "${destination}/${lib}" 80 | done 81 | fi 82 | } 83 | 84 | # Copies and strips a vendored dSYM 85 | install_dsym() { 86 | local source="$1" 87 | if [ -r "$source" ]; then 88 | # Copy the dSYM into a the targets temp dir. 89 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${DERIVED_FILES_DIR}\"" 90 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${DERIVED_FILES_DIR}" 91 | 92 | local basename 93 | basename="$(basename -s .framework.dSYM "$source")" 94 | binary="${DERIVED_FILES_DIR}/${basename}.framework.dSYM/Contents/Resources/DWARF/${basename}" 95 | 96 | # Strip invalid architectures so "fat" simulator / device frameworks work on device 97 | if [[ "$(file "$binary")" == *"Mach-O "*"dSYM companion"* ]]; then 98 | strip_invalid_archs "$binary" 99 | fi 100 | 101 | if [[ $STRIP_BINARY_RETVAL == 1 ]]; then 102 | # Move the stripped file into its final destination. 103 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${DERIVED_FILES_DIR}/${basename}.framework.dSYM\" \"${DWARF_DSYM_FOLDER_PATH}\"" 104 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${DERIVED_FILES_DIR}/${basename}.framework.dSYM" "${DWARF_DSYM_FOLDER_PATH}" 105 | else 106 | # The dSYM was not stripped at all, in this case touch a fake folder so the input/output paths from Xcode do not reexecute this script because the file is missing. 107 | touch "${DWARF_DSYM_FOLDER_PATH}/${basename}.framework.dSYM" 108 | fi 109 | fi 110 | } 111 | 112 | # Copies the bcsymbolmap files of a vendored framework 113 | install_bcsymbolmap() { 114 | local bcsymbolmap_path="$1" 115 | local destination="${BUILT_PRODUCTS_DIR}" 116 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${bcsymbolmap_path}" "${destination}"" 117 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${bcsymbolmap_path}" "${destination}" 118 | } 119 | 120 | # Signs a framework with the provided identity 121 | code_sign_if_enabled() { 122 | if [ -n "${EXPANDED_CODE_SIGN_IDENTITY:-}" -a "${CODE_SIGNING_REQUIRED:-}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then 123 | # Use the current code_sign_identity 124 | echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}" 125 | local code_sign_cmd="/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS:-} --preserve-metadata=identifier,entitlements '$1'" 126 | 127 | if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then 128 | code_sign_cmd="$code_sign_cmd &" 129 | fi 130 | echo "$code_sign_cmd" 131 | eval "$code_sign_cmd" 132 | fi 133 | } 134 | 135 | # Strip invalid architectures 136 | strip_invalid_archs() { 137 | binary="$1" 138 | # Get architectures for current target binary 139 | binary_archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | awk '{$1=$1;print}' | rev)" 140 | # Intersect them with the architectures we are building for 141 | intersected_archs="$(echo ${ARCHS[@]} ${binary_archs[@]} | tr ' ' '\n' | sort | uniq -d)" 142 | # If there are no archs supported by this binary then warn the user 143 | if [[ -z "$intersected_archs" ]]; then 144 | echo "warning: [CP] Vendored binary '$binary' contains architectures ($binary_archs) none of which match the current build architectures ($ARCHS)." 145 | STRIP_BINARY_RETVAL=0 146 | return 147 | fi 148 | stripped="" 149 | for arch in $binary_archs; do 150 | if ! [[ "${ARCHS}" == *"$arch"* ]]; then 151 | # Strip non-valid architectures in-place 152 | lipo -remove "$arch" -output "$binary" "$binary" 153 | stripped="$stripped $arch" 154 | fi 155 | done 156 | if [[ "$stripped" ]]; then 157 | echo "Stripped $binary of architectures:$stripped" 158 | fi 159 | STRIP_BINARY_RETVAL=1 160 | } 161 | 162 | 163 | if [[ "$CONFIGURATION" == "Debug" ]]; then 164 | install_framework "${BUILT_PRODUCTS_DIR}/JJCollectionViewRoundFlowLayout_Swift/JJCollectionViewRoundFlowLayout_Swift.framework" 165 | fi 166 | if [[ "$CONFIGURATION" == "Release" ]]; then 167 | install_framework "${BUILT_PRODUCTS_DIR}/JJCollectionViewRoundFlowLayout_Swift/JJCollectionViewRoundFlowLayout_Swift.framework" 168 | fi 169 | if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then 170 | wait 171 | fi 172 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-JJCollectionViewRoundFlowLayout_Swift_Example/Pods-JJCollectionViewRoundFlowLayout_Swift_Example-umbrella.h: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | 14 | FOUNDATION_EXPORT double Pods_JJCollectionViewRoundFlowLayout_Swift_ExampleVersionNumber; 15 | FOUNDATION_EXPORT const unsigned char Pods_JJCollectionViewRoundFlowLayout_Swift_ExampleVersionString[]; 16 | 17 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-JJCollectionViewRoundFlowLayout_Swift_Example/Pods-JJCollectionViewRoundFlowLayout_Swift_Example.debug.xcconfig: -------------------------------------------------------------------------------- 1 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES 2 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/JJCollectionViewRoundFlowLayout_Swift" 3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 4 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/JJCollectionViewRoundFlowLayout_Swift/JJCollectionViewRoundFlowLayout_Swift.framework/Headers" 5 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' 6 | OTHER_LDFLAGS = $(inherited) -framework "JJCollectionViewRoundFlowLayout_Swift" -framework "UIKit" 7 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS 8 | PODS_BUILD_DIR = ${BUILD_DIR} 9 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 10 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 11 | PODS_ROOT = ${SRCROOT}/Pods 12 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 13 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-JJCollectionViewRoundFlowLayout_Swift_Example/Pods-JJCollectionViewRoundFlowLayout_Swift_Example.modulemap: -------------------------------------------------------------------------------- 1 | framework module Pods_JJCollectionViewRoundFlowLayout_Swift_Example { 2 | umbrella header "Pods-JJCollectionViewRoundFlowLayout_Swift_Example-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-JJCollectionViewRoundFlowLayout_Swift_Example/Pods-JJCollectionViewRoundFlowLayout_Swift_Example.release.xcconfig: -------------------------------------------------------------------------------- 1 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES 2 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/JJCollectionViewRoundFlowLayout_Swift" 3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 4 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/JJCollectionViewRoundFlowLayout_Swift/JJCollectionViewRoundFlowLayout_Swift.framework/Headers" 5 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' 6 | OTHER_LDFLAGS = $(inherited) -framework "JJCollectionViewRoundFlowLayout_Swift" -framework "UIKit" 7 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS 8 | PODS_BUILD_DIR = ${BUILD_DIR} 9 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 10 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 11 | PODS_ROOT = ${SRCROOT}/Pods 12 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 13 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-JJCollectionViewRoundFlowLayout_Swift_Tests/Pods-JJCollectionViewRoundFlowLayout_Swift_Tests-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 | FMWK 17 | CFBundleShortVersionString 18 | 1.0.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-JJCollectionViewRoundFlowLayout_Swift_Tests/Pods-JJCollectionViewRoundFlowLayout_Swift_Tests-acknowledgements.markdown: -------------------------------------------------------------------------------- 1 | # Acknowledgements 2 | This application makes use of the following third party libraries: 3 | Generated by CocoaPods - https://cocoapods.org 4 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-JJCollectionViewRoundFlowLayout_Swift_Tests/Pods-JJCollectionViewRoundFlowLayout_Swift_Tests-acknowledgements.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreferenceSpecifiers 6 | 7 | 8 | FooterText 9 | This application makes use of the following third party libraries: 10 | Title 11 | Acknowledgements 12 | Type 13 | PSGroupSpecifier 14 | 15 | 16 | FooterText 17 | Generated by CocoaPods - https://cocoapods.org 18 | Title 19 | 20 | Type 21 | PSGroupSpecifier 22 | 23 | 24 | StringsTable 25 | Acknowledgements 26 | Title 27 | Acknowledgements 28 | 29 | 30 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-JJCollectionViewRoundFlowLayout_Swift_Tests/Pods-JJCollectionViewRoundFlowLayout_Swift_Tests-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Pods_JJCollectionViewRoundFlowLayout_Swift_Tests : NSObject 3 | @end 4 | @implementation PodsDummy_Pods_JJCollectionViewRoundFlowLayout_Swift_Tests 5 | @end 6 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-JJCollectionViewRoundFlowLayout_Swift_Tests/Pods-JJCollectionViewRoundFlowLayout_Swift_Tests-frameworks.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | set -u 4 | set -o pipefail 5 | 6 | function on_error { 7 | echo "$(realpath -mq "${0}"):$1: error: Unexpected failure" 8 | } 9 | trap 'on_error $LINENO' ERR 10 | 11 | if [ -z ${FRAMEWORKS_FOLDER_PATH+x} ]; then 12 | # If FRAMEWORKS_FOLDER_PATH is not set, then there's nowhere for us to copy 13 | # frameworks to, so exit 0 (signalling the script phase was successful). 14 | exit 0 15 | fi 16 | 17 | echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 18 | mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 19 | 20 | COCOAPODS_PARALLEL_CODE_SIGN="${COCOAPODS_PARALLEL_CODE_SIGN:-false}" 21 | SWIFT_STDLIB_PATH="${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" 22 | 23 | # Used as a return value for each invocation of `strip_invalid_archs` function. 24 | STRIP_BINARY_RETVAL=0 25 | 26 | # This protects against multiple targets copying the same framework dependency at the same time. The solution 27 | # was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html 28 | RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????") 29 | 30 | # Copies and strips a vendored framework 31 | install_framework() 32 | { 33 | if [ -r "${BUILT_PRODUCTS_DIR}/$1" ]; then 34 | local source="${BUILT_PRODUCTS_DIR}/$1" 35 | elif [ -r "${BUILT_PRODUCTS_DIR}/$(basename "$1")" ]; then 36 | local source="${BUILT_PRODUCTS_DIR}/$(basename "$1")" 37 | elif [ -r "$1" ]; then 38 | local source="$1" 39 | fi 40 | 41 | local destination="${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 42 | 43 | if [ -L "${source}" ]; then 44 | echo "Symlinked..." 45 | source="$(readlink "${source}")" 46 | fi 47 | 48 | # Use filter instead of exclude so missing patterns don't throw errors. 49 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\"" 50 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}" 51 | 52 | local basename 53 | basename="$(basename -s .framework "$1")" 54 | binary="${destination}/${basename}.framework/${basename}" 55 | 56 | if ! [ -r "$binary" ]; then 57 | binary="${destination}/${basename}" 58 | elif [ -L "${binary}" ]; then 59 | echo "Destination binary is symlinked..." 60 | dirname="$(dirname "${binary}")" 61 | binary="${dirname}/$(readlink "${binary}")" 62 | fi 63 | 64 | # Strip invalid architectures so "fat" simulator / device frameworks work on device 65 | if [[ "$(file "$binary")" == *"dynamically linked shared library"* ]]; then 66 | strip_invalid_archs "$binary" 67 | fi 68 | 69 | # Resign the code if required by the build settings to avoid unstable apps 70 | code_sign_if_enabled "${destination}/$(basename "$1")" 71 | 72 | # Embed linked Swift runtime libraries. No longer necessary as of Xcode 7. 73 | if [ "${XCODE_VERSION_MAJOR}" -lt 7 ]; then 74 | local swift_runtime_libs 75 | swift_runtime_libs=$(xcrun otool -LX "$binary" | grep --color=never @rpath/libswift | sed -E s/@rpath\\/\(.+dylib\).*/\\1/g | uniq -u) 76 | for lib in $swift_runtime_libs; do 77 | echo "rsync -auv \"${SWIFT_STDLIB_PATH}/${lib}\" \"${destination}\"" 78 | rsync -auv "${SWIFT_STDLIB_PATH}/${lib}" "${destination}" 79 | code_sign_if_enabled "${destination}/${lib}" 80 | done 81 | fi 82 | } 83 | 84 | # Copies and strips a vendored dSYM 85 | install_dsym() { 86 | local source="$1" 87 | if [ -r "$source" ]; then 88 | # Copy the dSYM into a the targets temp dir. 89 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${DERIVED_FILES_DIR}\"" 90 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${DERIVED_FILES_DIR}" 91 | 92 | local basename 93 | basename="$(basename -s .framework.dSYM "$source")" 94 | binary="${DERIVED_FILES_DIR}/${basename}.framework.dSYM/Contents/Resources/DWARF/${basename}" 95 | 96 | # Strip invalid architectures so "fat" simulator / device frameworks work on device 97 | if [[ "$(file "$binary")" == *"Mach-O "*"dSYM companion"* ]]; then 98 | strip_invalid_archs "$binary" 99 | fi 100 | 101 | if [[ $STRIP_BINARY_RETVAL == 1 ]]; then 102 | # Move the stripped file into its final destination. 103 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${DERIVED_FILES_DIR}/${basename}.framework.dSYM\" \"${DWARF_DSYM_FOLDER_PATH}\"" 104 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${DERIVED_FILES_DIR}/${basename}.framework.dSYM" "${DWARF_DSYM_FOLDER_PATH}" 105 | else 106 | # The dSYM was not stripped at all, in this case touch a fake folder so the input/output paths from Xcode do not reexecute this script because the file is missing. 107 | touch "${DWARF_DSYM_FOLDER_PATH}/${basename}.framework.dSYM" 108 | fi 109 | fi 110 | } 111 | 112 | # Copies the bcsymbolmap files of a vendored framework 113 | install_bcsymbolmap() { 114 | local bcsymbolmap_path="$1" 115 | local destination="${BUILT_PRODUCTS_DIR}" 116 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${bcsymbolmap_path}" "${destination}"" 117 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${bcsymbolmap_path}" "${destination}" 118 | } 119 | 120 | # Signs a framework with the provided identity 121 | code_sign_if_enabled() { 122 | if [ -n "${EXPANDED_CODE_SIGN_IDENTITY:-}" -a "${CODE_SIGNING_REQUIRED:-}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then 123 | # Use the current code_sign_identity 124 | echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}" 125 | local code_sign_cmd="/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS:-} --preserve-metadata=identifier,entitlements '$1'" 126 | 127 | if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then 128 | code_sign_cmd="$code_sign_cmd &" 129 | fi 130 | echo "$code_sign_cmd" 131 | eval "$code_sign_cmd" 132 | fi 133 | } 134 | 135 | # Strip invalid architectures 136 | strip_invalid_archs() { 137 | binary="$1" 138 | # Get architectures for current target binary 139 | binary_archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | awk '{$1=$1;print}' | rev)" 140 | # Intersect them with the architectures we are building for 141 | intersected_archs="$(echo ${ARCHS[@]} ${binary_archs[@]} | tr ' ' '\n' | sort | uniq -d)" 142 | # If there are no archs supported by this binary then warn the user 143 | if [[ -z "$intersected_archs" ]]; then 144 | echo "warning: [CP] Vendored binary '$binary' contains architectures ($binary_archs) none of which match the current build architectures ($ARCHS)." 145 | STRIP_BINARY_RETVAL=0 146 | return 147 | fi 148 | stripped="" 149 | for arch in $binary_archs; do 150 | if ! [[ "${ARCHS}" == *"$arch"* ]]; then 151 | # Strip non-valid architectures in-place 152 | lipo -remove "$arch" -output "$binary" "$binary" 153 | stripped="$stripped $arch" 154 | fi 155 | done 156 | if [[ "$stripped" ]]; then 157 | echo "Stripped $binary of architectures:$stripped" 158 | fi 159 | STRIP_BINARY_RETVAL=1 160 | } 161 | 162 | 163 | if [[ "$CONFIGURATION" == "Debug" ]]; then 164 | install_framework "${BUILT_PRODUCTS_DIR}/FBSnapshotTestCase/FBSnapshotTestCase.framework" 165 | fi 166 | if [[ "$CONFIGURATION" == "Release" ]]; then 167 | install_framework "${BUILT_PRODUCTS_DIR}/FBSnapshotTestCase/FBSnapshotTestCase.framework" 168 | fi 169 | if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then 170 | wait 171 | fi 172 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-JJCollectionViewRoundFlowLayout_Swift_Tests/Pods-JJCollectionViewRoundFlowLayout_Swift_Tests-umbrella.h: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | 14 | FOUNDATION_EXPORT double Pods_JJCollectionViewRoundFlowLayout_Swift_TestsVersionNumber; 15 | FOUNDATION_EXPORT const unsigned char Pods_JJCollectionViewRoundFlowLayout_Swift_TestsVersionString[]; 16 | 17 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-JJCollectionViewRoundFlowLayout_Swift_Tests/Pods-JJCollectionViewRoundFlowLayout_Swift_Tests.debug.xcconfig: -------------------------------------------------------------------------------- 1 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/JJCollectionViewRoundFlowLayout_Swift" 2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 3 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/JJCollectionViewRoundFlowLayout_Swift/JJCollectionViewRoundFlowLayout_Swift.framework/Headers" 4 | OTHER_LDFLAGS = $(inherited) -framework "JJCollectionViewRoundFlowLayout_Swift" -framework "UIKit" 5 | PODS_BUILD_DIR = ${BUILD_DIR} 6 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 7 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 8 | PODS_ROOT = ${SRCROOT}/Pods 9 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 10 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-JJCollectionViewRoundFlowLayout_Swift_Tests/Pods-JJCollectionViewRoundFlowLayout_Swift_Tests.modulemap: -------------------------------------------------------------------------------- 1 | framework module Pods_JJCollectionViewRoundFlowLayout_Swift_Tests { 2 | umbrella header "Pods-JJCollectionViewRoundFlowLayout_Swift_Tests-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-JJCollectionViewRoundFlowLayout_Swift_Tests/Pods-JJCollectionViewRoundFlowLayout_Swift_Tests.release.xcconfig: -------------------------------------------------------------------------------- 1 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/JJCollectionViewRoundFlowLayout_Swift" 2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 3 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/JJCollectionViewRoundFlowLayout_Swift/JJCollectionViewRoundFlowLayout_Swift.framework/Headers" 4 | OTHER_LDFLAGS = $(inherited) -framework "JJCollectionViewRoundFlowLayout_Swift" -framework "UIKit" 5 | PODS_BUILD_DIR = ${BUILD_DIR} 6 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 7 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 8 | PODS_ROOT = ${SRCROOT}/Pods 9 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 10 | -------------------------------------------------------------------------------- /Example/Tests/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 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /Example/Tests/Tests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | import JJCollectionViewRoundFlowLayout_Swift 3 | 4 | class Tests: XCTestCase { 5 | 6 | override func setUp() { 7 | super.setUp() 8 | // Put setup code here. This method is called before the invocation of each test method in the class. 9 | } 10 | 11 | override func tearDown() { 12 | // Put teardown code here. This method is called after the invocation of each test method in the class. 13 | super.tearDown() 14 | } 15 | 16 | func testExample() { 17 | // This is an example of a functional test case. 18 | XCTAssert(true, "Pass") 19 | } 20 | 21 | func testPerformanceExample() { 22 | // This is an example of a performance test case. 23 | self.measure() { 24 | // Put the code you want to measure the time of here. 25 | } 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /JJCollectionViewRoundFlowLayout_Swift.podspec: -------------------------------------------------------------------------------- 1 | # 2 | # Be sure to run `pod lib lint JJCollectionViewRoundFlowLayout_Swift.podspec' to ensure this is a 3 | # valid spec before submitting. 4 | # 5 | # Any lines starting with a # are optional, but their use is encouraged 6 | # To learn more about a Podspec see https://guides.cocoapods.org/syntax/podspec.html 7 | # 8 | 9 | Pod::Spec.new do |s| 10 | s.name = 'JJCollectionViewRoundFlowLayout_Swift' 11 | s.version = '2.5.2' 12 | s.summary = 'JJCollectionViewRoundFlowLayout_Swift可设置CollectionView的BackgroundColor,设置简单,可自定义背景颜色偏移、设置cell对齐方式等功能,.' 13 | 14 | # This description is used to generate tags and improve search results. 15 | # * Think: What does it do? Why did you write it? What is the focus? 16 | # * Try to keep it short, snappy and to the point. 17 | # * Write the description between the DESC delimiters below. 18 | # * Finally, don't worry about the indent, CocoaPods strips it! 19 | 20 | s.description = <<-DESC 21 | TODO: JJCollectionViewRoundFlowLayout_Swift是JJCollectionViewRoundFlowLayout(OC:https://github.com/kingjiajie/JJCollectionViewRoundFlowLayout)的Swift版本,JJCollectionViewRoundFlowLayout可设置CollectionView的BackgroundColor,可根据用户Cell个数计算背景图尺寸,可自定义是否包括计算CollectionViewHeaderView、CollectionViewFootererView或只计算Cells。设置简单,可自定义背景颜色偏移,设置显示方向(竖向、横向)显示,不同Section设置不同的背景颜色,可设置cell对齐方式。支持Cell对齐模式。支持左、中、右、右开启模式。支持背景图点击事件响应. 22 | DESC 23 | 24 | s.homepage = 'https://github.com/kingjiajie/JJCollectionViewRoundFlowLayout_Swift' 25 | s.license = { :type => 'MIT', :file => 'LICENSE' } 26 | s.author = { 'kingjiajie' => 'kingjiajie@sina.com' } 27 | s.source = { :git => 'https://github.com/kingjiajie/JJCollectionViewRoundFlowLayout_Swift.git', :tag => s.version.to_s } 28 | # s.social_media_url = 'https://twitter.com/' 29 | 30 | s.ios.deployment_target = '9.0' 31 | 32 | s.source_files = 'JJCollectionViewRoundFlowLayout_Swift/Classes/**/*' 33 | 34 | s.frameworks = 'UIKit' 35 | if s.respond_to? 'swift_version' 36 | s.swift_versions = ['4.2', '5.0'] 37 | end 38 | s.ios.deployment_target = '9.0' 39 | 40 | # s.resource_bundles = { 41 | # 'JJCollectionViewRoundFlowLayout_Swift' => ['JJCollectionViewRoundFlowLayout_Swift/Assets/*.png'] 42 | # } 43 | 44 | # s.public_header_files = 'Pod/Classes/**/*.h' 45 | # s.frameworks = 'UIKit', 'MapKit' 46 | # s.dependency 'AFNetworking', '~> 2.3' 47 | 48 | end 49 | -------------------------------------------------------------------------------- /JJCollectionViewRoundFlowLayout_Swift/Assets/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingjiajie/JJCollectionViewRoundFlowLayout_Swift/53bfe8a61ebf2dac3e2f244c563a07d2ec58c7a5/JJCollectionViewRoundFlowLayout_Swift/Assets/.gitkeep -------------------------------------------------------------------------------- /JJCollectionViewRoundFlowLayout_Swift/Classes/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingjiajie/JJCollectionViewRoundFlowLayout_Swift/53bfe8a61ebf2dac3e2f244c563a07d2ec58c7a5/JJCollectionViewRoundFlowLayout_Swift/Classes/.gitkeep -------------------------------------------------------------------------------- /JJCollectionViewRoundFlowLayout_Swift/Classes/JJCollectionViewFlowLayoutConfig_Swift.swift: -------------------------------------------------------------------------------- 1 | // 2 | // JJCollectionViewFlowLayoutConfig_Swift.swift 3 | // JJCollectionViewRoundFlowLayout_Swift 4 | // 5 | // Created by jiajie on 2020/1/19. 6 | // 7 | 8 | import UIKit 9 | 10 | @objc public enum JJCollectionViewRoundFlowLayoutSwiftAlignmentType:Int { 11 | case System 12 | case Left 13 | case Center 14 | case Right 15 | case RightAndStartR 16 | } 17 | -------------------------------------------------------------------------------- /JJCollectionViewRoundFlowLayout_Swift/Classes/JJCollectionViewFlowLayoutUtils_Swift.swift: -------------------------------------------------------------------------------- 1 | // 2 | // JJCollectionViewFlowLayoutUtils_Swift.swift 3 | // JJCollectionViewRoundFlowLayout_Swift 4 | // 5 | // Created by jiajie on 2020/2/4. 6 | // 7 | 8 | import UIKit 9 | 10 | class JJCollectionViewFlowLayoutUtils_Swift: NSObject { 11 | 12 | /// 获取cell间距 13 | /// - Parameters: 14 | /// - layout: layout description 15 | /// - sectionIndex: sectionIndex description 16 | static func evaluatedMinimumInteritemSpacingForSectionWithCollectionLayout(_ layout:UICollectionViewFlowLayout, atIndex sectionIndex:Int) -> CGFloat{ 17 | var minimumInteritemSpacing = layout.minimumInteritemSpacing; 18 | 19 | guard let delegate = layout.collectionView?.delegate else { return minimumInteritemSpacing;} 20 | 21 | if delegate.responds(to: #selector((delegate as! UICollectionViewDelegateFlowLayout).collectionView(_:layout:minimumInteritemSpacingForSectionAt:))) { 22 | minimumInteritemSpacing = (delegate as! UICollectionViewDelegateFlowLayout).collectionView!(layout.collectionView!, layout: layout, minimumInteritemSpacingForSectionAt: sectionIndex); 23 | } 24 | return minimumInteritemSpacing; 25 | } 26 | 27 | static func evaluatedSectionInsetForItemWithCollectionLayout(_ layout:UICollectionViewFlowLayout, atIndex index:Int) -> UIEdgeInsets { 28 | var sectionInset = layout.sectionInset; 29 | guard let delegate = layout.collectionView?.delegate else { return sectionInset;} 30 | 31 | if delegate.responds(to: #selector((delegate as! UICollectionViewDelegateFlowLayout).collectionView(_:layout:insetForSectionAt:))) { 32 | sectionInset = (delegate as! UICollectionViewDelegateFlowLayout).collectionView!(layout.collectionView!, layout: layout, insetForSectionAt: index); 33 | } 34 | return sectionInset; 35 | } 36 | 37 | } 38 | 39 | 40 | //MARK: - 不规则Cell计算方案 41 | extension JJCollectionViewFlowLayoutUtils_Swift{ 42 | 43 | /// 不规则cell找出top最高位置 44 | /// - Parameters: 45 | /// - layout: layout description 46 | /// - section: section description 47 | /// - numberOfItems: numberOfItems description 48 | /// - defaultFrame: defaultFrame description 49 | static func calculateIrregularitiesCellByMinTopFrameWithLayout(_ layout : UICollectionViewFlowLayout, 50 | section:Int, 51 | numberOfItems:Int, 52 | defaultFrame:CGRect) -> CGRect { 53 | var firstFrame = defaultFrame; 54 | if layout.scrollDirection == .vertical { 55 | //竖向 56 | var minY = firstFrame.minY; 57 | for i in 0...numberOfItems-1{ 58 | guard let attr = layout.layoutAttributesForItem(at: IndexPath.init(row: i, section: section)) else { 59 | continue; 60 | } 61 | minY = min(minY, attr.frame.minY); 62 | } 63 | let rect = firstFrame; 64 | firstFrame = CGRect.init(x: rect.origin.x, y: minY, width: rect.size.width, height: rect.size.height) 65 | }else{ 66 | var minX = firstFrame.minX; 67 | for i in 0...numberOfItems-1{ 68 | guard let attr = layout.layoutAttributesForItem(at: IndexPath.init(row: i, section: section)) else { 69 | continue; 70 | } 71 | 72 | minX = min(minX, attr.frame.minX); 73 | } 74 | let rect = firstFrame; 75 | firstFrame = CGRect.init(x: minX, y: rect.origin.y, width: rect.size.width, height: rect.size.height) 76 | } 77 | return firstFrame; 78 | } 79 | 80 | /// 不规则cell找出bootom最低位置 81 | /// - Parameters: 82 | /// - layout: layout description 83 | /// - section: section description 84 | /// - numberOfItems: numberOfItems description 85 | /// - defaultFrame: defaultFrame description 86 | static func calculateIrregularitiesCellByMaxBottomFrameWithLayout(_ layout : UICollectionViewFlowLayout, 87 | section : Int, 88 | numberOfItems : Int, 89 | defaultFrame : CGRect) -> CGRect { 90 | var lastFrame = defaultFrame; 91 | if layout.scrollDirection == .vertical { 92 | //竖向 93 | var maxY = lastFrame.maxY; 94 | var index = numberOfItems-1; 95 | for i in 0...numberOfItems-1{ 96 | guard let attr = layout.layoutAttributesForItem(at: IndexPath.init(row: i, section: section)) else { 97 | continue; 98 | } 99 | if maxY < max(maxY, attr.frame.maxY) { 100 | maxY = max(maxY, attr.frame.maxY) 101 | index = i; 102 | } 103 | } 104 | lastFrame = layout.layoutAttributesForItem(at: IndexPath.init(row: index, section: section))!.frame; 105 | }else{ 106 | //横向 107 | var maxX = lastFrame.maxX; 108 | var index = numberOfItems-1; 109 | for i in 0...numberOfItems - 1{ 110 | guard let attr = layout.layoutAttributesForItem(at: IndexPath.init(row: i, section: section)) else { 111 | continue; 112 | } 113 | if maxX < max(maxX, attr.frame.maxX) { 114 | maxX = max(maxX, attr.frame.maxX); 115 | index = i; 116 | } 117 | } 118 | lastFrame = layout.layoutAttributesForItem(at: IndexPath.init(row: index, section: section))!.frame; 119 | } 120 | return lastFrame; 121 | } 122 | } 123 | 124 | -------------------------------------------------------------------------------- /JJCollectionViewRoundFlowLayout_Swift/Classes/JJCollectionViewRoundConfigModel_Swift.swift: -------------------------------------------------------------------------------- 1 | // 2 | // JJCollectionViewRoundConfigModel.swift 3 | // JJCollectionViewRoundFlowLayout_Swift 4 | // 5 | // Created by jiajie on 2019/11/17. 6 | // Copyright © 2019 aihuo. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @objcMembers 12 | open class JJCollectionViewRoundConfigModel_Swift: NSObject { 13 | open var borderWidth : CGFloat = 0; 14 | open var borderColor : UIColor? 15 | 16 | open var backgroundColor : UIColor? 17 | open var shadowColor : UIColor? 18 | open var shadowOffset : CGSize? 19 | open var shadowOpacity : Float = 0; 20 | open var shadowRadius : CGFloat = 0; 21 | open var cornerRadius : CGFloat = 0; 22 | 23 | } 24 | -------------------------------------------------------------------------------- /JJCollectionViewRoundFlowLayout_Swift/Classes/JJCollectionViewRoundFlowLayout+Alignment_Swift.swift: -------------------------------------------------------------------------------- 1 | // 2 | // JJCollectionViewRoundFlowLayout+Alignment_Swift.swift 3 | // JJCollectionViewRoundFlowLayout_Swift 4 | // 5 | // Created by jiajie on 2020/1/19. 6 | // 7 | 8 | import UIKit 9 | 10 | extension JJCollectionViewRoundFlowLayout_Swift{ 11 | 12 | /// 将相同y位置的cell集合到一个列表中(竖向) 13 | /// - Parameter layoutAttributesAttrs: layoutAttributesAttrs description 14 | func groupLayoutAttributesForElementsByYLineWithLayoutAttributesAttrs(_ layoutAttributesAttrs:Array) -> Array> { 15 | 16 | var allDict = Dictionary(); 17 | 18 | for (_,attr) in layoutAttributesAttrs.enumerated() { 19 | 20 | let dictArr = allDict[attr.frame.midY] 21 | if dictArr != nil { 22 | dictArr?.add(attr.copy()) 23 | }else{ 24 | let arr = NSMutableArray.init(object: attr.copy()); 25 | allDict[attr.frame.midY] = arr 26 | } 27 | } 28 | return (allDict as NSDictionary).allValues as! Array>; 29 | } 30 | 31 | /// 将相同x位置的cell集合到一个列表中(横向) 32 | /// - Parameter layoutAttributesAttrs: layoutAttributesAttrs description 33 | func groupLayoutAttributesForElementsByXLineWithLayoutAttributesAttrs(_ layoutAttributesAttrs : Array) -> Array> { 34 | 35 | var allDict = Dictionary(); 36 | for (_,attr) in layoutAttributesAttrs.enumerated() { 37 | let dictArr = allDict[attr.frame.origin.x] 38 | if dictArr != nil { 39 | dictArr?.add(attr.copy()) 40 | }else{ 41 | let arr = NSMutableArray.init(object: attr.copy()); 42 | allDict[attr.frame.origin.x] = arr 43 | } 44 | } 45 | return (allDict as NSDictionary).allValues as! Array>; 46 | } 47 | 48 | func evaluatedAllCellSettingFrameWithLayoutAttributesAttrs(_ layoutAttributesAttrs:Array> , toChangeAttributesAttrsList:inout Array ,cellAlignmentType alignmentType : JJCollectionViewRoundFlowLayoutSwiftAlignmentType) -> Array { 49 | 50 | toChangeAttributesAttrsList.removeAll() 51 | for calculateAttributesAttrsArr in layoutAttributesAttrs { 52 | switch alignmentType { 53 | case .Left: 54 | self.evaluatedCellSettingFrameByLeftWithWithJJCollectionLayout(self, layoutAttributesAttrs: calculateAttributesAttrsArr); 55 | break 56 | case .Center: 57 | self.evaluatedCellSettingFrameByCenterWithWithJJCollectionLayout(self,layoutAttributesAttrs:calculateAttributesAttrsArr); 58 | break; 59 | case .Right: 60 | var reversedArray = Array.init(calculateAttributesAttrsArr); 61 | reversedArray.reverse(); 62 | self.evaluatedCellSettingFrameByRightWithWithJJCollectionLayout(self, layoutAttributesAttrs: reversedArray); 63 | break; 64 | case .RightAndStartR: 65 | self.evaluatedCellSettingFrameByRightWithWithJJCollectionLayout(self, layoutAttributesAttrs: calculateAttributesAttrsArr); 66 | break; 67 | default: 68 | break; 69 | } 70 | toChangeAttributesAttrsList += calculateAttributesAttrsArr; 71 | } 72 | return toChangeAttributesAttrsList; 73 | } 74 | } 75 | 76 | //MARK: - alignmentLeft 77 | extension JJCollectionViewRoundFlowLayout_Swift{ 78 | 79 | /// 计算AttributesAttrs左对齐 80 | /// - Parameters: 81 | /// - layout: layout description 82 | /// - layoutAttributesAttrs: 需计算的AttributesAttrs列表 83 | func evaluatedCellSettingFrameByLeftWithWithJJCollectionLayout(_ layout:JJCollectionViewRoundFlowLayout_Swift, layoutAttributesAttrs : Array){ 84 | //left 85 | var pAttr:UICollectionViewLayoutAttributes? = nil; 86 | for attr in layoutAttributesAttrs { 87 | if attr.representedElementKind != nil { 88 | //nil when representedElementCategory is UICollectionElementCategoryCell (空的时候为cell) 89 | continue; 90 | } 91 | 92 | var frame = attr.frame; 93 | if layout.scrollDirection == .vertical { 94 | //竖向 95 | if pAttr != nil { 96 | frame.origin.x = pAttr!.frame.origin.x + pAttr!.frame.size.width + JJCollectionViewFlowLayoutUtils_Swift.evaluatedMinimumInteritemSpacingForSectionWithCollectionLayout(layout, atIndex: attr.indexPath.section); 97 | }else{ 98 | frame.origin.x = JJCollectionViewFlowLayoutUtils_Swift.evaluatedSectionInsetForItemWithCollectionLayout(layout, atIndex: attr.indexPath.section).left; 99 | } 100 | }else{ 101 | //横向 102 | if pAttr != nil { 103 | frame.origin.y = pAttr!.frame.origin.y + pAttr!.frame.size.height + JJCollectionViewFlowLayoutUtils_Swift.evaluatedMinimumInteritemSpacingForSectionWithCollectionLayout(layout, atIndex: attr.indexPath.section); 104 | }else{ 105 | frame.origin.y = JJCollectionViewFlowLayoutUtils_Swift.evaluatedSectionInsetForItemWithCollectionLayout(layout, atIndex: attr.indexPath.section).top; 106 | } 107 | } 108 | attr.frame = frame; 109 | pAttr = attr; 110 | } 111 | } 112 | } 113 | 114 | //MARK: - alignmentCenter 115 | extension JJCollectionViewRoundFlowLayout_Swift{ 116 | func evaluatedCellSettingFrameByCenterWithWithJJCollectionLayout(_ layout:JJCollectionViewRoundFlowLayout_Swift, layoutAttributesAttrs : Array){ 117 | //center 118 | var pAttr : UICollectionViewLayoutAttributes? = nil; 119 | 120 | var useWidth : CGFloat = 0.0; 121 | let theSection = layoutAttributesAttrs.first!.indexPath.section; 122 | for attr in layoutAttributesAttrs{ 123 | useWidth += attr.bounds.size.width; 124 | } 125 | 126 | let firstLeft = (layout.collectionView!.bounds.size.width - useWidth - (JJCollectionViewFlowLayoutUtils_Swift.evaluatedMinimumInteritemSpacingForSectionWithCollectionLayout(layout, atIndex: theSection) * CGFloat(layoutAttributesAttrs.count)))/2.0; 127 | 128 | for attr in layoutAttributesAttrs{ 129 | if attr.representedElementKind != nil { 130 | //nil when representedElementCategory is UICollectionElementCategoryCell (空的时候为cell) 131 | continue; 132 | } 133 | 134 | var frame = attr.frame; 135 | if layout.scrollDirection == .vertical { 136 | //竖向 137 | if pAttr != nil { 138 | frame.origin.x = pAttr!.frame.origin.x + pAttr!.frame.size.width + JJCollectionViewFlowLayoutUtils_Swift.evaluatedMinimumInteritemSpacingForSectionWithCollectionLayout(layout, atIndex: attr.indexPath.section); 139 | }else{ 140 | frame.origin.x = firstLeft; 141 | } 142 | }else{ 143 | //横向 144 | if pAttr != nil { 145 | frame.origin.y = pAttr!.frame.origin.y + pAttr!.frame.size.height + JJCollectionViewFlowLayoutUtils_Swift.evaluatedMinimumInteritemSpacingForSectionWithCollectionLayout(layout, atIndex: attr.indexPath.section); 146 | }else{ 147 | frame.origin.y = JJCollectionViewFlowLayoutUtils_Swift.evaluatedSectionInsetForItemWithCollectionLayout(layout, atIndex: attr.indexPath.section).top; 148 | } 149 | } 150 | attr.frame = frame; 151 | pAttr = attr; 152 | } 153 | } 154 | } 155 | 156 | 157 | //MARK: - alignmentRight 158 | extension JJCollectionViewRoundFlowLayout_Swift{ 159 | 160 | /// 计算AttributesAttrs左对齐 161 | /// - Parameters: 162 | /// - layout: layout description 163 | /// - layoutAttributesAttrs: 需计算的AttributesAttrs列表 164 | func evaluatedCellSettingFrameByRightWithWithJJCollectionLayout(_ layout:JJCollectionViewRoundFlowLayout_Swift, layoutAttributesAttrs : Array){ 165 | //left 166 | var pAttr:UICollectionViewLayoutAttributes? = nil; 167 | for attr in layoutAttributesAttrs { 168 | if attr.representedElementKind != nil { 169 | //nil when representedElementCategory is UICollectionElementCategoryCell (空的时候为cell) 170 | continue; 171 | } 172 | 173 | var frame = attr.frame; 174 | if layout.scrollDirection == .vertical { 175 | //竖向 176 | if pAttr != nil { 177 | frame.origin.x = pAttr!.frame.origin.x - JJCollectionViewFlowLayoutUtils_Swift.evaluatedMinimumInteritemSpacingForSectionWithCollectionLayout(layout, atIndex: attr.indexPath.section) - frame.size.width; 178 | }else{ 179 | frame.origin.x = layout.collectionView!.bounds.size.width - JJCollectionViewFlowLayoutUtils_Swift.evaluatedSectionInsetForItemWithCollectionLayout(layout, atIndex: attr.indexPath.section).right - frame.size.width; 180 | } 181 | }else{ 182 | 183 | } 184 | attr.frame = frame; 185 | pAttr = attr; 186 | } 187 | } 188 | } 189 | -------------------------------------------------------------------------------- /JJCollectionViewRoundFlowLayout_Swift/Classes/JJCollectionViewRoundFlowLayout_Swift.swift: -------------------------------------------------------------------------------- 1 | // 2 | // JJCollectionViewRoundFlowLayout_Swift.swift 3 | // JJCollectionViewRoundFlowLayout_Swift 4 | // 5 | // Created by jiajie on 2019/11/16. 6 | // Copyright © 2019 aihuo. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class JJCollectionReusableView_Swift: UICollectionReusableView { 12 | 13 | var myCacheAttr : JJCollectionViewRoundLayoutAttributes_Swift = { 14 | return JJCollectionViewRoundLayoutAttributes_Swift.init(); 15 | }() 16 | 17 | override func apply(_ layoutAttributes: UICollectionViewLayoutAttributes) { 18 | super.apply(layoutAttributes) 19 | let attr = layoutAttributes as! JJCollectionViewRoundLayoutAttributes_Swift 20 | myCacheAttr = attr; 21 | self.toChangeCollectionReusableViewRoundInfo(myCacheAttr); 22 | } 23 | 24 | override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) { 25 | super.traitCollectionDidChange(previousTraitCollection); 26 | self.toChangeCollectionReusableViewRoundInfo(myCacheAttr); 27 | } 28 | 29 | func toChangeCollectionReusableViewRoundInfo(_ layoutAttributes: UICollectionViewLayoutAttributes) { 30 | let attr = layoutAttributes as! JJCollectionViewRoundLayoutAttributes_Swift 31 | if (attr.myConfigModel != nil) { 32 | let model = attr.myConfigModel!; 33 | let view = self; 34 | 35 | if #available(iOS 13.0, *) { 36 | view.layer.backgroundColor = model.backgroundColor?.resolvedColor(with: self.traitCollection).cgColor 37 | } else { 38 | // Fallback on earlier versions 39 | view.layer.backgroundColor = model.backgroundColor?.cgColor; 40 | }; 41 | 42 | if #available(iOS 13.0, *) { 43 | view.layer.shadowColor = model.shadowColor?.resolvedColor(with: self.traitCollection).cgColor 44 | } else { 45 | // Fallback on earlier versions 46 | view.layer.shadowColor = model.shadowColor?.cgColor; 47 | }; 48 | view.layer.shadowOffset = model.shadowOffset ?? CGSize.init(width: 0, height: 0); 49 | view.layer.shadowOpacity = model.shadowOpacity; 50 | view.layer.shadowRadius = model.shadowRadius; 51 | view.layer.cornerRadius = model.cornerRadius; 52 | view.layer.borderWidth = model.borderWidth; 53 | 54 | if #available(iOS 13.0, *) { 55 | view.layer.borderColor = model.borderColor?.resolvedColor(with: self.traitCollection).cgColor 56 | } else { 57 | // Fallback on earlier versions 58 | view.layer.borderColor = model.borderColor?.cgColor; 59 | }; 60 | } 61 | } 62 | 63 | override func touchesEnded(_ touches: Set, with event: UIEvent?) { 64 | if event?.type == UIEvent.EventType.touches { 65 | self.decorationViewUserDidSelectEvent(); 66 | } 67 | } 68 | 69 | func decorationViewUserDidSelectEvent() { 70 | guard let collectionView = self.superview else { 71 | return; 72 | } 73 | 74 | if collectionView.isKind(of: UICollectionView.self) { 75 | let myCollectionView = collectionView as! UICollectionView; 76 | let delegate = myCollectionView.delegate as! JJCollectionViewDelegateRoundFlowLayout_Swift; 77 | if delegate.responds(to: #selector(delegate.collectionView(collectionView:didSelectDecorationViewAtIndexPath:))) { 78 | delegate .collectionView?(collectionView: myCollectionView, didSelectDecorationViewAtIndexPath: myCacheAttr.indexPath); 79 | } 80 | } 81 | } 82 | } 83 | 84 | class JJCollectionViewRoundLayoutAttributes_Swift: UICollectionViewLayoutAttributes { 85 | var borderEdgeInsets : UIEdgeInsets? 86 | var myConfigModel : JJCollectionViewRoundConfigModel_Swift? 87 | } 88 | 89 | extension JJCollectionViewRoundFlowLayout_Swift{ 90 | public static let JJCollectionViewRoundSectionSwift: String = "com.JJCollectionViewRoundSectionSwift" 91 | } 92 | 93 | @objc public protocol JJCollectionViewDelegateRoundFlowLayout_Swift : UICollectionViewDelegateFlowLayout{ 94 | 95 | /// 设置底色相关 96 | /// - Parameter collectionView: collectionView description 97 | /// - Parameter collectionViewLayout: collectionViewLayout description 98 | /// - Parameter section: section description 99 | func collectionView(_ collectionView : UICollectionView, layout collectionViewLayout : UICollectionViewLayout , configModelForSectionAtIndex section : Int ) -> JJCollectionViewRoundConfigModel_Swift; 100 | 101 | /// 设置底色偏移量(该设置只设置底色,与collectionview原sectioninsets区分) 102 | /// - Parameter collectionView: collectionView description 103 | /// - Parameter collectionViewLayout: collectionViewLayout description 104 | /// - Parameter section: section description 105 | @objc optional func collectionView(_ collectionView : UICollectionView , layout collectionViewLayout:UICollectionViewLayout,borderEdgeInsertsForSectionAtIndex section : Int) -> UIEdgeInsets; 106 | 107 | /// 设置是否计算headerview(根据section判断是否单独计算) 108 | /// - Parameters: 109 | /// - collectionView: collectionView description 110 | /// - layout: layout description 111 | /// - section: section description 112 | @objc optional func collectionView(collectionView:UICollectionView ,layout:UICollectionViewLayout , isCalculateHeaderViewIndex section : NSInteger) -> Bool; 113 | 114 | /// 设置是否计算footerview(根据section判断是否单独计算) 115 | /// - Parameters: 116 | /// - collectionView: collectionView description 117 | /// - layout: layout description 118 | /// - section: section description 119 | @objc optional func collectionView(collectionView:UICollectionView , layout:UICollectionViewLayout , isCalculateFooterViewIndex section : NSInteger) -> Bool; 120 | 121 | /// 当Cell个数为0时,是否允许进行计算(根据section判断是否单独计算,Cell个数为0时,会检测计算Header或Footer) 122 | /// - Parameters: 123 | /// - collectionView: collectionView description 124 | /// - layout: layout description 125 | /// - section: section description 126 | @objc optional func collectionView(collectionView:UICollectionView , layout:UICollectionViewLayout , isCanCalculateWhenRowEmptyWithSection section : NSInteger) -> Bool; 127 | 128 | 129 | /// 背景图点击事件 130 | /// - Parameters: 131 | /// - collectionView: collectionView description 132 | /// - indexPath: 点击背景图的indexPath 133 | @objc optional func collectionView(collectionView:UICollectionView , didSelectDecorationViewAtIndexPath indexPath:IndexPath); 134 | } 135 | 136 | @objcMembers 137 | open class JJCollectionViewRoundFlowLayout_Swift: UICollectionViewFlowLayout { 138 | 139 | /// 设置cell对齐方式,不设置为使用系统默认,支持Left 140 | open var collectionCellAlignmentType : JJCollectionViewRoundFlowLayoutSwiftAlignmentType = .System; 141 | 142 | /// 是否开始Round计算,(默认YES),当该位置为false时,计算模块都不开启,包括设置的代理 143 | open var isRoundEnabled : Bool = true; 144 | 145 | open var isCalculateHeader : Bool = false // 是否计算header 146 | open var isCalculateFooter : Bool = false // 是否计算footer 147 | 148 | //是否使用不规则Cell大小的计算方式(若Cell的大小是相同固定大小,则无需开启该方法),默认false 149 | open var isCalculateTypeOpenIrregularitiesCell : Bool = false 150 | 151 | /**************************************************************************************/ 152 | /// 当Cell个数为0时,是否允许进行计算(开启后,Cell个数为0时,会检测计算Header或Footer) 153 | /// 注意!!!是否计算Header或Footer,会根据设置的isCalculateHeader、isCalculateFooter和对应代理方法进行判断!!!请注意!!! 154 | ///(若实现collectionView:layout:isCanCalculateWhenRowEmptyWithSection:)该字段不起作用 155 | /// 注意!!!!!! 在使用该功能的时候,请自行检测和处理sectionInset的偏移量,Cell无数据时,有header&footer,设置了的sectionInset还是生效的,底色在计算时候会进行sectionInset相关的偏移处理。 156 | /**************************************************************************************/ 157 | open var isCanCalculateWhenRowEmpty : Bool = false 158 | 159 | //自定义Attr数组 160 | var decorationViewAttrs : [UICollectionViewLayoutAttributes] = { 161 | let arr = NSMutableArray.init(capacity: 0) 162 | return arr as! [UICollectionViewLayoutAttributes] 163 | }() 164 | } 165 | 166 | extension JJCollectionViewRoundFlowLayout_Swift{ 167 | 168 | override public func prepare() { 169 | super.prepare() 170 | 171 | if !self.isRoundEnabled { 172 | //为NO,不需要开启时直接return 173 | return; 174 | } 175 | 176 | guard let sections = collectionView?.numberOfSections else { return }; 177 | let delegate = collectionView?.delegate as! JJCollectionViewDelegateRoundFlowLayout_Swift 178 | 179 | //检测是否实现了背景样式模块代理 180 | if delegate.responds(to: #selector(delegate.collectionView(_:layout:configModelForSectionAtIndex:))) { 181 | 182 | }else{ 183 | return; 184 | } 185 | 186 | //init 187 | self.register(JJCollectionReusableView_Swift.self, forDecorationViewOfKind: JJCollectionViewRoundFlowLayout_Swift.JJCollectionViewRoundSectionSwift) 188 | decorationViewAttrs.removeAll() 189 | 190 | for section in 0.. 0 { 195 | let firstAttr = layoutAttributesForItem(at: IndexPath.init(row: 0, section: section)) 196 | firstFrame = firstAttr!.frame; 197 | } else if delegate.responds(to: #selector(delegate.collectionView(collectionView:layout:isCanCalculateWhenRowEmptyWithSection:))) { 198 | //如果没有设置当Cell个数为0时,实现了代理,执行代理方法判断section是否进行计算 199 | if !delegate.collectionView!(collectionView: self.collectionView!, layout: self, isCanCalculateWhenRowEmptyWithSection: section) { 200 | continue; 201 | } 202 | }else if(!isCanCalculateWhenRowEmpty) { 203 | //如果没有设置当Cell个数为0时,进行是否计算的字段 204 | continue; 205 | } 206 | 207 | //判断是否计算headerview 208 | var isCalculateHeaderView = false; 209 | if delegate.responds(to: #selector(delegate.collectionView(collectionView:layout:isCalculateHeaderViewIndex:))) { 210 | isCalculateHeaderView = delegate.collectionView!(collectionView: self.collectionView!, layout: self, isCalculateHeaderViewIndex: section); 211 | }else{ 212 | isCalculateHeaderView = self.isCalculateHeader; 213 | } 214 | 215 | if isCalculateHeaderView { 216 | //headerView 217 | let headerAttr = layoutAttributesForSupplementaryView(ofKind: UICollectionView.elementKindSectionHeader, at: IndexPath.init(row: 0, section: section)) 218 | if headerAttr != nil && 219 | (headerAttr?.frame.size.width != 0 || 220 | headerAttr?.frame.size.height != 0) { 221 | firstFrame = headerAttr!.frame; 222 | }else{ 223 | var rect = firstFrame; 224 | if !rect.isNull { 225 | if isCalculateTypeOpenIrregularitiesCell { 226 | rect = JJCollectionViewFlowLayoutUtils_Swift.calculateIrregularitiesCellByMinTopFrameWithLayout(self, section: section, numberOfItems: numberOfItems!, defaultFrame: rect); 227 | } 228 | 229 | firstFrame = self.scrollDirection == .vertical ? 230 | CGRect.init(x: rect.origin.x, 231 | y: rect.origin.y, 232 | width: collectionView!.bounds.size.width, 233 | height: rect.size.height): 234 | CGRect.init(x: rect.origin.x, 235 | y: rect.origin.y, 236 | width: rect.size.width, 237 | height: collectionView!.bounds.size.height); 238 | } 239 | } 240 | }else{ 241 | //不计算headerview的情况 242 | if isCalculateTypeOpenIrregularitiesCell { 243 | if !firstFrame.isNull { 244 | firstFrame = JJCollectionViewFlowLayoutUtils_Swift.calculateIrregularitiesCellByMinTopFrameWithLayout(self, section: section, numberOfItems: numberOfItems!, defaultFrame: firstFrame); 245 | } 246 | } 247 | } 248 | 249 | var lastFrame = CGRect.null; 250 | if numberOfItems != nil && numberOfItems! > 0 { 251 | let lastAttr = layoutAttributesForItem(at: IndexPath.init(row:(numberOfItems! - 1), section: section)) 252 | lastFrame = lastAttr!.frame; 253 | } 254 | 255 | //判断是否计算headerview 256 | var isCalculateFooterView = false; 257 | if delegate.responds(to: #selector(delegate.collectionView(collectionView:layout:isCalculateFooterViewIndex:))) { 258 | isCalculateFooterView = delegate.collectionView!(collectionView: self.collectionView!, layout: self, isCalculateFooterViewIndex: section); 259 | }else{ 260 | isCalculateFooterView = self.isCalculateFooter; 261 | } 262 | 263 | if isCalculateFooterView { 264 | //footerView 265 | let footerAttr = layoutAttributesForSupplementaryView(ofKind: UICollectionView.elementKindSectionFooter, at: IndexPath.init(row: 0, section: section)) 266 | if footerAttr != nil && 267 | (footerAttr?.frame.size.width != 0 || 268 | footerAttr?.frame.size.height != 0) { 269 | lastFrame = footerAttr!.frame; 270 | }else{ 271 | var rect = lastFrame; 272 | if !rect.isNull { 273 | if self.isCalculateTypeOpenIrregularitiesCell { 274 | rect = JJCollectionViewFlowLayoutUtils_Swift.calculateIrregularitiesCellByMaxBottomFrameWithLayout(self, section: section, numberOfItems: numberOfItems!, defaultFrame: rect); 275 | } 276 | lastFrame = self.scrollDirection == .vertical ? 277 | CGRect.init(x: rect.origin.x, 278 | y: rect.origin.y, 279 | width: collectionView!.bounds.size.width, 280 | height: rect.size.height): 281 | CGRect.init(x: rect.origin.x, 282 | y: rect.origin.y, 283 | width: rect.size.width, 284 | height: collectionView!.bounds.size.height) 285 | } 286 | } 287 | }else{ 288 | //不计算footerView的情况 289 | if self.isCalculateTypeOpenIrregularitiesCell { 290 | if !lastFrame.isNull { 291 | lastFrame = JJCollectionViewFlowLayoutUtils_Swift.calculateIrregularitiesCellByMaxBottomFrameWithLayout(self, section: section, numberOfItems: numberOfItems!, defaultFrame: lastFrame); 292 | } 293 | } 294 | } 295 | 296 | //获取sectionInset 297 | var sectionInset = self.sectionInset 298 | if (delegate.responds(to: #selector(delegate.collectionView(_:layout:insetForSectionAt:)))) { 299 | let inset = delegate.collectionView!(self.collectionView!, layout: self, insetForSectionAt: section) 300 | if inset != sectionInset { 301 | sectionInset = inset 302 | } 303 | } 304 | 305 | var userCustomSectionInset = UIEdgeInsets.init(top: 0, left: 0, bottom: 0, right: 0) 306 | if delegate.responds(to: #selector(delegate.collectionView(_:layout:borderEdgeInsertsForSectionAtIndex:))) { 307 | //检测是否实现了该方法,进行赋值 308 | userCustomSectionInset = delegate.collectionView!(self.collectionView!, layout: self, borderEdgeInsertsForSectionAtIndex: section) 309 | } 310 | 311 | var sectionFrame = CGRect.null; 312 | if !firstFrame.isNull && !lastFrame.isNull { 313 | sectionFrame = firstFrame.union(lastFrame); 314 | }else if(!firstFrame.isNull) { 315 | sectionFrame = firstFrame.union(firstFrame); 316 | }else if(!lastFrame.isNull) { 317 | sectionFrame = lastFrame.union(lastFrame); 318 | } 319 | 320 | if sectionFrame.isNull { 321 | continue; 322 | } 323 | 324 | if !isCalculateHeaderView && !isCalculateFooterView{ 325 | //都没有headerView&footerView 326 | sectionFrame = self.calculateDefaultFrameWithSectionFrame(sectionFrame, sectionInset: sectionInset) 327 | }else{ 328 | if (isCalculateHeaderView && !isCalculateFooterView) { 329 | //headerView 330 | let headerAttr = self.layoutAttributesForSupplementaryView(ofKind: UICollectionView.elementKindSectionHeader, at: IndexPath.init(row: 0, section: section)) 331 | //判断是否有headerview 332 | if headerAttr != nil && 333 | (headerAttr?.frame.size.width != 0 || headerAttr?.frame.size.height != 0){ 334 | if self.scrollDirection == UICollectionView.ScrollDirection.horizontal { 335 | //判断包含headerview, left位置已经计算在内,不需要补偏移 336 | sectionFrame.size.width += sectionInset.right 337 | 338 | //减去系统adjustInset的top 339 | if #available(iOS 11.0, *) { 340 | sectionFrame.size.height = self.collectionView!.frame.size.height - self.collectionView!.adjustedContentInset.top 341 | }else{ 342 | sectionFrame.size.height = self.collectionView!.frame.size.height - abs(self.collectionView!.contentOffset.y)/*适配iOS11以下*/; 343 | } 344 | }else{ 345 | //判断包含headerview, top位置已经计算在内,不需要补偏移 346 | sectionFrame.size.height += sectionInset.bottom; 347 | } 348 | }else{ 349 | sectionFrame = self.calculateDefaultFrameWithSectionFrame(sectionFrame, sectionInset: sectionInset) 350 | } 351 | }else if(!isCalculateHeaderView && isCalculateFooterView){ 352 | //footerView 353 | let footerAttr = self.layoutAttributesForSupplementaryView(ofKind: UICollectionView.elementKindSectionFooter, at: IndexPath.init(row: 0, section: section)) 354 | if footerAttr != nil && 355 | (footerAttr?.frame.size.width != 0 || footerAttr?.frame.size.height != 0) { 356 | if self.scrollDirection == UICollectionView.ScrollDirection.horizontal { 357 | //判断包含footerView, right位置已经计算在内,不需要补偏移 358 | //(需要补充x偏移) 359 | sectionFrame.origin.x -= sectionInset.left; 360 | sectionFrame.size.width += sectionInset.left; 361 | 362 | //减去系统adjustInset的top 363 | if #available(iOS 11.0, *) { 364 | sectionFrame.size.height = self.collectionView!.frame.size.height - self.collectionView!.adjustedContentInset.top 365 | }else{ 366 | sectionFrame.size.height = self.collectionView!.frame.size.height - abs(self.collectionView!.contentOffset.y)/*适配iOS11以下*/; 367 | } 368 | }else{ 369 | //判断包含footerView, bottom位置已经计算在内,不需要补偏移 370 | //(需要补充y偏移) 371 | sectionFrame.origin.y -= sectionInset.top 372 | sectionFrame.size.width = self.collectionView!.frame.size.width 373 | sectionFrame.size.height += sectionInset.top 374 | } 375 | }else{ 376 | sectionFrame = self.calculateDefaultFrameWithSectionFrame(sectionFrame, sectionInset: sectionInset); 377 | } 378 | }else{ 379 | //headerView 380 | let headerAttr = self.layoutAttributesForSupplementaryView(ofKind: UICollectionView.elementKindSectionHeader, at: IndexPath.init(row: 0, section: section)) 381 | 382 | //footerView 383 | let footerAttr = self.layoutAttributesForSupplementaryView(ofKind: UICollectionView.elementKindSectionFooter, at: IndexPath.init(row: 0, section: section)) 384 | 385 | if headerAttr != nil && 386 | footerAttr != nil && 387 | (headerAttr?.frame.size.width != 0 || headerAttr?.frame.size.height != 0) && 388 | (footerAttr?.frame.size.width != 0 || footerAttr?.frame.size.height != 0){ 389 | //都有headerview和footerview就不用计算了 390 | }else{ 391 | sectionFrame = self.calculateDefaultFrameWithSectionFrame(sectionFrame, sectionInset: sectionInset); 392 | } 393 | } 394 | } 395 | 396 | sectionFrame.origin.x += userCustomSectionInset.left; 397 | sectionFrame.origin.y += userCustomSectionInset.top; 398 | if self.scrollDirection == UICollectionView.ScrollDirection.horizontal { 399 | sectionFrame.size.width -= (userCustomSectionInset.left + userCustomSectionInset.right); 400 | sectionFrame.size.height -= (userCustomSectionInset.top + userCustomSectionInset.bottom); 401 | }else{ 402 | sectionFrame.size.width -= (userCustomSectionInset.left + userCustomSectionInset.right); 403 | sectionFrame.size.height -= (userCustomSectionInset.top + userCustomSectionInset.bottom); 404 | } 405 | 406 | //2. 定义 407 | let attr = JJCollectionViewRoundLayoutAttributes_Swift.init(forDecorationViewOfKind:JJCollectionViewRoundFlowLayout_Swift.JJCollectionViewRoundSectionSwift, with: IndexPath.init(row: 0, section: section)) 408 | attr.frame = sectionFrame 409 | attr.zIndex = -1 410 | attr.borderEdgeInsets = userCustomSectionInset 411 | if delegate.responds(to: #selector(delegate.collectionView(_:layout:configModelForSectionAtIndex:))) { 412 | attr.myConfigModel = delegate.collectionView(self.collectionView!, layout: self, configModelForSectionAtIndex: section) 413 | } 414 | self.decorationViewAttrs.append(attr) 415 | 416 | } 417 | } 418 | } 419 | 420 | //MARK: 默认section无偏移大小 421 | extension JJCollectionViewRoundFlowLayout_Swift{ 422 | func calculateDefaultFrameWithSectionFrame(_ frame:CGRect ,sectionInset:UIEdgeInsets) -> CGRect{ 423 | var sectionFrame = frame; 424 | sectionFrame.origin.x -= sectionInset.left; 425 | sectionFrame.origin.y -= sectionInset.top; 426 | if (self.scrollDirection == UICollectionView.ScrollDirection.horizontal) { 427 | sectionFrame.size.width += sectionInset.left + sectionInset.right; 428 | //减去系统adjustInset的top 429 | if #available(iOS 11, *) { 430 | sectionFrame.size.height = self.collectionView!.frame.size.height - self.collectionView!.adjustedContentInset.top; 431 | } else { 432 | sectionFrame.size.height = self.collectionView!.frame.size.height - abs(self.collectionView!.contentOffset.y)/*适配iOS11以下*/; 433 | } 434 | }else{ 435 | sectionFrame.origin.x = 0 ; 436 | sectionFrame.size.width = self.collectionView!.frame.size.width; 437 | sectionFrame.size.height += sectionInset.top + sectionInset.bottom; 438 | } 439 | return sectionFrame; 440 | } 441 | } 442 | 443 | //MARK: -- 444 | 445 | public extension JJCollectionViewRoundFlowLayout_Swift{ 446 | override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? { 447 | var attrs = super.layoutAttributesForElements(in: rect) ?? [] 448 | 449 | //用户设置了对称方式,进行对称设置 (若没设置,不执行,继续其他计算) 450 | if self.collectionCellAlignmentType != .System 451 | && self.scrollDirection == .vertical{ 452 | //竖向,Cell对齐方式暂不支持横向 453 | let formatGroudAttr = self.groupLayoutAttributesForElementsByYLineWithLayoutAttributesAttrs(attrs); //竖向 454 | 455 | _ = self.evaluatedAllCellSettingFrameWithLayoutAttributesAttrs(formatGroudAttr, toChangeAttributesAttrsList: &attrs, cellAlignmentType: self.collectionCellAlignmentType) 456 | } 457 | 458 | for attr in self.decorationViewAttrs { 459 | attrs.append(attr); 460 | } 461 | return attrs 462 | } 463 | } 464 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2019 kingjiajie 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # JJCollectionViewRoundFlowLayout_Swift 2 | 3 | [![CI Status](https://img.shields.io/travis/kingjiajie/JJCollectionViewRoundFlowLayout_Swift.svg?style=flat)](https://travis-ci.org/kingjiajie/JJCollectionViewRoundFlowLayout_Swift) 4 | [![Version](https://img.shields.io/cocoapods/v/JJCollectionViewRoundFlowLayout_Swift.svg?style=flat)](https://cocoapods.org/pods/JJCollectionViewRoundFlowLayout_Swift) 5 | [![License](https://img.shields.io/cocoapods/l/JJCollectionViewRoundFlowLayout_Swift.svg?style=flat)](https://cocoapods.org/pods/JJCollectionViewRoundFlowLayout_Swift) 6 | [![Platform](https://img.shields.io/cocoapods/p/JJCollectionViewRoundFlowLayout_Swift.svg?style=flat)](https://cocoapods.org/pods/JJCollectionViewRoundFlowLayout_Swift) 7 | 8 | 9 | JJCollectionViewRoundFlowLayout_Swift是JJCollectionViewRoundFlowLayout(OC:https://github.com/kingjiajie/JJCollectionViewRoundFlowLayout ) 的Swift版本,JJCollectionViewRoundFlowLayout可设置CollectionView的BackgroundColor,可根据用户Cell个数计算背景图尺寸,可自定义是否包括计算CollectionViewHeaderView、CollectionViewFootererView或只计算Cells。设置简单,可自定义背景颜色偏移,设置显示方向(竖向、横向)显示,不同Section设置不同的背景颜色,可设置cell对齐方式。 10 | 11 | 可设置内容: 12 | 1、collectionView section底色。 13 | 2、是否包含headerview。 14 | 3、是否包含footerview。 15 | 4、支持borderWidth、borderColor。 16 | 5、支持shadow投影。 17 | 6、支持collectionView,Vertical,Horizontal。 18 | 7、支持根据不同section分别设置不同底色显示。 19 | 8、支持根据section单独判断是否计算对应headerview和footerview 20 | 9、新增对Cell的对齐模式进行设置,支持(左对齐)--- V2.0.0 21 | 10、增加对不规则Cell大小的计算方式支持,支持对不规则Cell计算实际背景视图大小,默认不开启计算,如使用不规则计算需手动开启isCalculateTypeOpenIrregularitiesCell字段 22 | 11、新增对Cell的对齐模式进行设置,支持(居中对齐)--- V2.1.0 23 | 12、新增对Cell的对齐模式进行设置,支持(右对齐)--- V2.2.0 24 | 13、新增对Cell的对齐模式进行设置,支持(右对齐和首个Cell右侧开始)--- V2.3.0 25 | 14、内部优化 --- V2.3.1 26 | 15、增加对背景图的点击事件处理和控制,通过代理返回点击的背景图的IndexPath --- V2.4.0 27 | 16、增加支持Cell个数为0时,可以单独对Section的Header&Footer进行计算,支持全局设置和单独根据Section设置是否计算。---V2.5.0 28 | 17、解决设置了计算头和尾后, 但返回的第一个section的footer大小为0, 引起的crash。(感谢mengshun对问题的指出合修复)---V2.5.2 29 | 30 | 31 | 32 | 33 | Swift版本地址:[GitHub地址](https://github.com/kingjiajie/JJCollectionViewRoundFlowLayout_Swift) 34 | 35 | OC版本地址:[GitHub地址](https://github.com/kingjiajie/JJCollectionViewRoundFlowLayout) 36 | 37 | 38 | ## 更新日志 39 | --- 40 | * `2.5.2`:解决设置了计算头和尾后, 但返回的第一个section的footer大小为0, 引起的crash。(感谢mengshun对问题的指出合修复)。 41 | - `2.5.1`:修复当cell大小不一时,首个Cell单独在首行显示时,底色判断出错问题。 42 | - `2.5.0`:增加支持Cell个数为0时,可以单独对Section的Header&Footer进行计算,支持全局设置和单独根据Section设置是否计算。 43 | - `2.4.0`:增加对背景图的点击事件处理和控制,通过代理返回点击的背景图的IndexPath。 44 | - `2.3.1`:解决对暗黑模式的支持问题(感谢Whaiyan小伙伴发现了问题)。 45 | - `2.3.0`:新增对Cell的对齐模式进行设置,支持(右对齐和首个Cell右侧开始)。 46 | - `2.2.0`:新增支持设置Cell对齐模式(右对齐)。 47 | - `2.1.0`:新增支持设置Cell对齐模式(居中对齐)。 48 | - `2.0.1`: 增加对不规则Cell大小的计算方式支持,支持对不规则Cell计算实际背景视图大小,默认不开启计算,如使用不规则计算需手动开启isCalculateTypeOpenIrregularitiesCell字段 49 | - `2.0.0`: 50 | 1、优化代码,对代码逻辑进行抽离,增加工具类等。 51 | 2、新增支持设置Cell对齐模式(左对齐)。 52 | - `1.1.0`:增加支持根据section单独判断是否计算对应headerview和footerview 53 | - `1.0.0`:初始项目 54 | 1、collectionView section底色。 55 | 2、是否包含headerview。 56 | 3、是否包含footerview。 57 | 4、支持borderWidth、borderColor。 58 | 5、支持shadow投影。 59 | 6、支持collectionView,Vertical,Horizontal。 60 | 7、支持根据不同section分别设置不同底色显示。 61 | 8、优化代码逻辑,增加根据支持根据不同section分别设置不同底色逻辑和demo 62 | 63 | ## Example 64 | 65 | To run the example project, clone the repo, and run `pod install` from the Example directory first. 66 | 67 | ## Requirements 68 | 69 | * iOS 8.0 70 | * Swift 4.2 71 | 72 | 73 | ## Installation 74 | 75 | JJCollectionViewRoundFlowLayout_Swift is available through [CocoaPods](https://cocoapods.org). To install 76 | it, simply add the following line to your Podfile: 77 | 78 | 79 | ```ruby 80 | pod 'JJCollectionViewRoundFlowLayout_Swift' 81 | ``` 82 | 83 | ## Overview 84 | 85 | ![](https://github.com/kingjiajie/JJCollectionViewRoundFlowLayout_Swift/blob/master/show_video.gif) 86 | 87 | ## Usage 88 | 89 | ### Import 90 | 91 | ``` swift 92 | @import JJCollectionViewRoundFlowLayout_Swift; 93 | ``` 94 | 95 | ### Enable 96 | 97 | ``` swift 98 | //可选设置 99 | open var isCalculateHeader : Bool = false // 是否计算header 100 | open var isCalculateFooter : Bool = false // 是否计算footer 101 | ``` 102 | 103 | ``` swift 104 | 105 | /// 设置底色偏移量(该设置只设置底色,与collectionview原sectioninsets区分) 106 | /// - Parameter collectionView: collectionView description 107 | /// - Parameter collectionViewLayout: collectionViewLayout description 108 | /// - Parameter section: section description 109 | func collectionView(_ collectionView : UICollectionView , layout collectionViewLayout:UICollectionViewLayout,borderEdgeInsertsForSectionAtIndex section : Int) -> UIEdgeInsets; 110 | 111 | /// 设置底色相关 112 | /// - Parameter collectionView: collectionView description 113 | /// - Parameter collectionViewLayout: collectionViewLayout description 114 | /// - Parameter section: section description 115 | func collectionView(_ collectionView : UICollectionView, layout collectionViewLayout : UICollectionViewLayout , configModelForSectionAtIndex section : Int ) -> JJCollectionViewRoundConfigModel_Swift; 116 | 117 | ``` 118 | 119 | ### Example 120 | 121 | ``` swift 122 | 123 | #pragma mark - JJCollectionViewDelegateRoundFlowLayout 124 | 125 | func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, borderEdgeInsertsForSectionAtIndex section: Int) -> UIEdgeInsets { 126 | return UIEdgeInsets.init(top: 5, left: 12, bottom: 5, right: 12) 127 | } 128 | 129 | func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, configModelForSectionAtIndex section: Int) -> JJCollectionViewRoundConfigModel_Swift { 130 | let model = JJCollectionViewRoundConfigModel_Swift.init(); 131 | 132 | model.backgroundColor = UIColor.init(red: 233/255.0, green:233/255.0 ,blue:233/255.0,alpha:1.0) 133 | model.cornerRadius = 10; 134 | return model; 135 | } 136 | 137 | ``` 138 | 139 | ### Setting 140 | #### collectionView section底色 141 | 142 | 143 | ![](https://github.com/kingjiajie/JJCollectionViewRoundFlowLayout_Swift/blob/master/1.png) 144 | 145 | ``` swift 146 | 147 | func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, configModelForSectionAtIndex section: Int) -> JJCollectionViewRoundConfigModel_Swift { 148 | let model = JJCollectionViewRoundConfigModel_Swift.init(); 149 | 150 | model.backgroundColor = UIColor.init(red: 233/255.0, green:233/255.0 ,blue:233/255.0,alpha:1.0) 151 | model.cornerRadius = 10; 152 | return model; 153 | } 154 | 155 | ``` 156 | 157 | 158 | #### 包含headerview、包含footerview 159 | 160 | 161 | ![](https://github.com/kingjiajie/JJCollectionViewRoundFlowLayout_Swift/blob/master/2.png) 162 | 163 | ``` swift 164 | 165 | let layout = JJCollectionViewRoundFlowLayout_Swift.init(); 166 | layout.isCalculateHeader = self.isRoundWithHeaerView; 167 | layout.isCalculateFooter = self.isRoundWithFooterView; 168 | 169 | func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, configModelForSectionAtIndex section: Int) -> JJCollectionViewRoundConfigModel_Swift { 170 | let model = JJCollectionViewRoundConfigModel_Swift.init(); 171 | 172 | model.backgroundColor = UIColor.init(red: 233/255.0, green:233/255.0 ,blue:233/255.0,alpha:1.0) 173 | model.cornerRadius = 10; 174 | return model; 175 | } 176 | 177 | ``` 178 | 179 | 180 | #### 支持collectionView,Vertical,Horizontal 181 | 182 | 183 | ![](https://github.com/kingjiajie/JJCollectionViewRoundFlowLayout_Swift/blob/master/3.png) 184 | 185 | 186 | ``` swift 187 | //显示方向不需要进行另外设置,根据CollectionView设置好的方面,底色自动进行检测判断。 188 | 189 | ``` 190 | 191 | 192 | #### 支持shadow投影 193 | 194 | ![](https://github.com/kingjiajie/JJCollectionViewRoundFlowLayout_Swift/blob/master/4.png) 195 | 196 | ``` swift 197 | 198 | func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, configModelForSectionAtIndex section: Int) -> JJCollectionViewRoundConfigModel_Swift { 199 | let model = JJCollectionViewRoundConfigModel_Swift.init(); 200 | model.cornerRadius = 4; 201 | 202 | 203 | model.backgroundColor = UIColor.init(red: 255/255.0, green:255/255.0 ,blue:255/255.0,alpha:1.0) 204 | model.shadowColor = UIColor.init(red: 204/255.0, green:204/255.0 ,blue:204/255.0,alpha:0.6) 205 | model.shadowOffset = CGSize.init(width: 0, height: 0) 206 | model.shadowOpacity = 1; 207 | model.shadowRadius = 4; 208 | return model; 209 | } 210 | 211 | 212 | ``` 213 | 214 | 215 | #### 支持根据不同section分别设置不同底色显示 216 | 217 | ![](https://github.com/kingjiajie/JJCollectionViewRoundFlowLayout_Swift/blob/master/5.png) 218 | 219 | 220 | ``` swift 221 | 222 | func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, configModelForSectionAtIndex section: Int) -> JJCollectionViewRoundConfigModel_Swift { 223 | let model = JJCollectionViewRoundConfigModel_Swift.init(); 224 | model.cornerRadius = 10 225 | model.backgroundColor = UIColor.init(red: 233/255.0, green:233/255.0 ,blue:233/255.0,alpha:1.0) 226 | if (section == 0) { 227 | model.backgroundColor = UIColor.init(red: 233/255.0, green:233/255.0 ,blue:233/255.0,alpha:1.0) 228 | }else if(section == 1){ 229 | model.backgroundColor =UIColor.init(red: 100/255.0, green:233/255.0 ,blue:233/255.0,alpha:1.0) 230 | }else{ 231 | //... 232 | } 233 | 234 | return model; 235 | } 236 | 237 | 238 | 239 | ``` 240 | 241 | #### 支持根据不同section分别单独设置是否计算对应Headerview和footerview 242 | 243 | ![](https://github.com/kingjiajie/JJCollectionViewRoundFlowLayout_Swift/blob/master/6.png) 244 | 245 | ``` swift 246 | 247 | /// 根据section设置是否包含headerview(实现该方法后,isCalculateHeader将不会生效) 248 | /// - Parameters: 249 | /// - collectionView: collectionView description 250 | /// - layout: layout description 251 | /// - section: section description 252 | func collectionView(collectionView: UICollectionView,layout: UICollectionViewLayout, isCalculateHeaderViewIndex section: NSInteger) -> Bool { 253 | //这里简单设置了默认间隔一个就计算footerview,后续根据实际业务进行设置 254 | if (section % 2 == 0) { 255 | return true; 256 | } 257 | return false; 258 | } 259 | 260 | /// 根据section设置是否包含footerview(实现该方法后,isCalculateFooter将不会生效) 261 | /// - Parameters: 262 | /// - collectionView: collectionView description 263 | /// - layout: layout description 264 | /// - section: section description 265 | func collectionView(collectionView: UICollectionView,layout: UICollectionViewLayout, isCalculateFooterViewIndex section: NSInteger) -> Bool { 266 | //这里简单设置了默认间隔一个就计算footerview,后续根据实际业务进行设置 267 | if (section % 2 == 0) { 268 | return true; 269 | } 270 | return false; 271 | } 272 | 273 | ``` 274 | 275 | #### 支持对Cell的对齐模式进行设置、可选是否填充底色(左对齐) 276 | 277 | ![](https://github.com/kingjiajie/JJCollectionViewRoundFlowLayout_Swift/blob/master/7.png) 278 | 279 | ``` swift 280 | 281 | let layout = JJCollectionViewRoundFlowLayout_Swift.init(); 282 | layout.isRoundEnabled = false; //设置是否填充底色 283 | layout.collectionCellAlignmentType = .Left; //设置对齐方式 284 | //layout.collectionCellAlignmentType = .Center; //设置对齐方式 285 | //layout.collectionCellAlignmentType = .Right; //设置对齐方式 286 | //layout.collectionCellAlignmentType = .RightAndStartR; //设置对齐方式(右对齐和首个Cell右侧开始) 287 | 288 | ``` 289 | 290 | #### 增加对背景图的点击事件处理和控制,通过代理返回点击的背景图的IndexPath 291 | 292 | ``` swift 293 | func collectionView(collectionView: UICollectionView, didSelectDecorationViewAtIndexPath indexPath: IndexPath) { 294 | let message = String.init(format: "section --- %ld \n row --- %ld", indexPath.section,indexPath.row) 295 | } 296 | 297 | ``` 298 | 299 | 300 | ## Author 301 | 302 | kingjiajie, kingjiajie@sina.com 303 | 304 | ## License 305 | 306 | JJCollectionViewRoundFlowLayout_Swift is available under the MIT license. See the LICENSE file for more info. 307 | -------------------------------------------------------------------------------- /_Pods.xcodeproj: -------------------------------------------------------------------------------- 1 | Example/Pods/Pods.xcodeproj -------------------------------------------------------------------------------- /show_video.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingjiajie/JJCollectionViewRoundFlowLayout_Swift/53bfe8a61ebf2dac3e2f244c563a07d2ec58c7a5/show_video.gif --------------------------------------------------------------------------------