├── README.md ├── UIollectionViewLayout.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcuserdata │ │ └── lipanxiang.xcuserdatad │ │ └── UserInterfaceState.xcuserstate └── xcuserdata │ └── lipanxiang.xcuserdatad │ └── xcschemes │ ├── UIollectionViewLayout.xcscheme │ └── xcschememanagement.plist ├── UIollectionViewLayout ├── AppDelegate.h ├── AppDelegate.m ├── Assets.xcassets │ ├── AppIcon.appiconset │ │ └── Contents.json │ ├── photos │ │ ├── 1.imageset │ │ │ ├── 1.jpg │ │ │ └── Contents.json │ │ ├── 10.imageset │ │ │ ├── 10.jpg │ │ │ └── Contents.json │ │ ├── 11.imageset │ │ │ ├── 11.jpg │ │ │ └── Contents.json │ │ ├── 12.imageset │ │ │ ├── 12.jpg │ │ │ └── Contents.json │ │ ├── 13.imageset │ │ │ ├── 13.jpg │ │ │ └── Contents.json │ │ ├── 14.imageset │ │ │ ├── 14.jpg │ │ │ └── Contents.json │ │ ├── 15.imageset │ │ │ ├── 15.jpg │ │ │ └── Contents.json │ │ ├── 16.imageset │ │ │ ├── 16.jpg │ │ │ └── Contents.json │ │ ├── 17.imageset │ │ │ ├── 17.jpg │ │ │ └── Contents.json │ │ ├── 18.imageset │ │ │ ├── 18.jpg │ │ │ └── Contents.json │ │ ├── 19.imageset │ │ │ ├── 19.jpg │ │ │ └── Contents.json │ │ ├── 2.imageset │ │ │ ├── 2.jpg │ │ │ └── Contents.json │ │ ├── 20.imageset │ │ │ ├── 20.jpg │ │ │ └── Contents.json │ │ ├── 3.imageset │ │ │ ├── 3.jpg │ │ │ └── Contents.json │ │ ├── 4.imageset │ │ │ ├── 4.jpg │ │ │ └── Contents.json │ │ ├── 5.imageset │ │ │ ├── 5.jpg │ │ │ └── Contents.json │ │ ├── 6.imageset │ │ │ ├── 6.jpg │ │ │ └── Contents.json │ │ ├── 7.imageset │ │ │ ├── 7.jpg │ │ │ └── Contents.json │ │ ├── 8.imageset │ │ │ ├── 8.jpg │ │ │ └── Contents.json │ │ └── 9.imageset │ │ │ ├── 9.jpg │ │ │ └── Contents.json │ ├── sub_add.imageset │ │ ├── Contents.json │ │ ├── sub_add@2x.png │ │ └── sub_add@3x.png │ └── sub_add_h.imageset │ │ ├── Contents.json │ │ ├── sub_add_h.png │ │ ├── sub_add_h@2x.png │ │ └── sub_add_h@3x.png ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard ├── Cell │ ├── PhotoCell.h │ ├── PhotoCell.m │ └── PhotoCell.xib ├── Info.plist ├── ViewController.h ├── ViewController.m ├── main.m ├── 流水布局 │ ├── CustomFlowLayout.h │ └── CustomFlowLayout.m └── 自定义布局 │ ├── CircleLayout.h │ ├── CircleLayout.m │ ├── SquareLayout.h │ └── SquareLayout.m ├── UIollectionViewLayoutTests ├── Info.plist └── UIollectionViewLayoutTests.m └── UIollectionViewLayoutUITests ├── Info.plist └── UIollectionViewLayoutUITests.m /README.md: -------------------------------------------------------------------------------- 1 | ###首先我们先看一下 我们今天要最终实现的效果图 2 | 3 | 4 | *** 5 | ###UICollectionView的简单介绍### 6 | * UICollectionView的结构 7 | ``` 8 | Cells 9 | Supplementary Views 追加视图 (类似Header或者Footer) 10 | Decoration Views 装饰视图 (用作背景展示) 11 | ``` 12 | * 由两个方面对UICollectionView进行支持。 13 | * 和tableView一样,即提供数据的UICollectionViewDataSource以及处理用户交互的UICollectionViewDelegate。 14 | * 另一方面,对于cell的样式和组织方式,由于collectionView比tableView要复杂得多,因此没有按照类似于tableView的style的方式来定义,而是专门使用了一个类来对collectionView的布局和行为进行描述,这就是`UICollectionViewLayout`。 15 | 16 | * 而我们主要讲UICollectionViewLayout,因为这不仅是collectionView和tableView的最重要求的区别,也是整个UICollectionView的精髓所在。 17 | * 如果对UICollectionView的基本构成要素和使用方法还不清楚的话,可以查看:[UICollectionView详解](http://www.onevcat.com/2012/06/introducing-collection-views/)中进行一些了解。 18 | 19 | *** 20 | * 21 | ### UICollectionViewLayoutAttributes类的介绍### 22 | ``` 23 | @property (nonatomic) CGRect frame 24 | @property (nonatomic) CGPoint center 25 | @property (nonatomic) CGSize size 26 | @property (nonatomic) CATransform3D transform3D 27 | @property (nonatomic) CGFloat alpha 28 | @property (nonatomic) NSInteger zIndex 29 | @property (nonatomic, getter=isHidden) BOOL hidden 30 | ``` 31 | >可以看到,UICollectionViewLayoutAttributes的实例中包含了诸如边框,中心点,大小,形状,透明度,层次关系和是否隐藏等信息。 32 | 1.一个cell对应一个UICollectionViewLayoutAttributes对象 33 | 2.UICollectionViewLayoutAttributes对象决定了cell的摆设位置(frame) 34 | 35 | ###自定义的UICollectionViewLayout 36 | * UICollectionViewLayout的功能为向UICollectionView提供布局信息,不仅包括cell的布局信息,也包括追加视图和装饰视图的布局信息。实现一个自定义layout的常规做法是继承UICollectionViewLayout类,然后重载下列方法: 37 | 38 | ``` 39 | -(void)prepareLayout 40 | 准备方法被自动调用,以保证layout实例的正确。 41 | 42 | -(CGSize)collectionViewContentSize 43 | 返回collectionView的内容的尺寸 44 | 45 | -(NSArray *)layoutAttributesForElementsInRect:(CGRect)rect 46 | 1.返回rect中的所有的元素的布局属性 47 | 2.返回的是包含UICollectionViewLayoutAttributes的NSArray 48 | 3.UICollectionViewLayoutAttributes可以是cell,追加视图或装饰视图的信息,通过不同的UICollectionViewLayoutAttributes初始化方法可以得到不同类型的UICollectionViewLayoutAttributes: 49 | 1)layoutAttributesForCellWithIndexPath: 50 | 2)layoutAttributesForSupplementaryViewOfKind:withIndexPath: 51 | 3)layoutAttributesForDecorationViewOfKind:withIndexPath: 52 | 53 | -(UICollectionViewLayoutAttributes )layoutAttributesForItemAtIndexPath:(NSIndexPath )indexPath 54 | 返回对应于indexPath的位置的cell的布局属性 55 | 56 | -(UICollectionViewLayoutAttributes )layoutAttributesForSupplementaryViewOfKind:(NSString )kind atIndexPath:(NSIndexPath *)indexPath 57 | 返回对应于indexPath的位置的追加视图的布局属性,如果没有追加视图可不重载 58 | 59 | -(UICollectionViewLayoutAttributes * )layoutAttributesForDecorationViewOfKind:(NSString)decorationViewKind atIndexPath:(NSIndexPath )indexPath 60 | 返回对应于indexPath的位置的装饰视图的布局属性,如果没有装饰视图可不重载 61 | 62 | -(BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds 63 | 当边界发生改变时,是否应该刷新布局。如果YES则在边界变化(一般是scroll到其他地方)时,将重新计算需要的布局信息。 64 | ``` 65 | * 调用顺序 66 | 67 | ``` 68 | 1)-(void)prepareLayout 设置layout的结构和初始需要的参数等。 69 | 70 | 2) -(CGSize) collectionViewContentSize 确定collectionView的所有内容的尺寸。 71 | 72 | 3)-(NSArray *)layoutAttributesForElementsInRect:(CGRect)rect初始的layout的外观将由该方法返回的UICollectionViewLayoutAttributes来决定。 73 | 74 | 4)在需要更新layout时,需要给当前layout发送 75 | 1)-invalidateLayout, 该消息会立即返回,并且预约在下一个loop的时候刷新当前layout 76 | 2)-prepareLayout, 77 | 3)依次再调用-collectionViewContentSize和-layoutAttributesForElementsInRect来生成更新后的布局。 78 | ``` 79 | 80 | [LineLayout](http://www.jianshu.com/p/a16ffb4bbcc2):**流水布局实例**http://www.jianshu.com/p/a16ffb4bbcc2 81 | ![流水布局](http://upload-images.jianshu.io/upload_images/1418424-2d1ced7aba5fae41.gif?imageMogr2/auto-orient/strip) 82 | *** 83 | [圆形布局CircleLayout](http://www.jianshu.com/p/83e31a2f18d9) http://www.jianshu.com/p/83e31a2f18d9 84 | ![圆形布局](http://upload-images.jianshu.io/upload_images/1418424-5c7d83b061a53437.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 85 | *** 86 | [方行布局](http://www.jianshu.com/p/58e06e1f2f6d)http://www.jianshu.com/p/58e06e1f2f6d 87 | ![SquareLayout](http://upload-images.jianshu.io/upload_images/1418424-a790ec383a44c5e9.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) -------------------------------------------------------------------------------- /UIollectionViewLayout.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 07B5E27F1C93DB050097820E /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 07B5E27E1C93DB050097820E /* main.m */; }; 11 | 07B5E2821C93DB050097820E /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 07B5E2811C93DB050097820E /* AppDelegate.m */; }; 12 | 07B5E2851C93DB050097820E /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 07B5E2841C93DB050097820E /* ViewController.m */; }; 13 | 07B5E2881C93DB050097820E /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 07B5E2861C93DB050097820E /* Main.storyboard */; }; 14 | 07B5E28A1C93DB050097820E /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 07B5E2891C93DB050097820E /* Assets.xcassets */; }; 15 | 07B5E28D1C93DB050097820E /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 07B5E28B1C93DB050097820E /* LaunchScreen.storyboard */; }; 16 | 07B5E2981C93DB050097820E /* UIollectionViewLayoutTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 07B5E2971C93DB050097820E /* UIollectionViewLayoutTests.m */; }; 17 | 07B5E2A31C93DB050097820E /* UIollectionViewLayoutUITests.m in Sources */ = {isa = PBXBuildFile; fileRef = 07B5E2A21C93DB050097820E /* UIollectionViewLayoutUITests.m */; }; 18 | 07B5E2B81C93DB760097820E /* CircleLayout.m in Sources */ = {isa = PBXBuildFile; fileRef = 07B5E2B51C93DB760097820E /* CircleLayout.m */; }; 19 | 07B5E2B91C93DB760097820E /* SquareLayout.m in Sources */ = {isa = PBXBuildFile; fileRef = 07B5E2B71C93DB760097820E /* SquareLayout.m */; }; 20 | 07B5E2BC1C93DBC80097820E /* CustomFlowLayout.m in Sources */ = {isa = PBXBuildFile; fileRef = 07B5E2BB1C93DBC80097820E /* CustomFlowLayout.m */; }; 21 | 07B5E2C61C93DCB20097820E /* PhotoCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 07B5E2C41C93DCB20097820E /* PhotoCell.m */; }; 22 | 07B5E2C71C93DCB20097820E /* PhotoCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 07B5E2C51C93DCB20097820E /* PhotoCell.xib */; }; 23 | /* End PBXBuildFile section */ 24 | 25 | /* Begin PBXContainerItemProxy section */ 26 | 07B5E2941C93DB050097820E /* PBXContainerItemProxy */ = { 27 | isa = PBXContainerItemProxy; 28 | containerPortal = 07B5E2721C93DB050097820E /* Project object */; 29 | proxyType = 1; 30 | remoteGlobalIDString = 07B5E2791C93DB050097820E; 31 | remoteInfo = UIollectionViewLayout; 32 | }; 33 | 07B5E29F1C93DB050097820E /* PBXContainerItemProxy */ = { 34 | isa = PBXContainerItemProxy; 35 | containerPortal = 07B5E2721C93DB050097820E /* Project object */; 36 | proxyType = 1; 37 | remoteGlobalIDString = 07B5E2791C93DB050097820E; 38 | remoteInfo = UIollectionViewLayout; 39 | }; 40 | /* End PBXContainerItemProxy section */ 41 | 42 | /* Begin PBXFileReference section */ 43 | 07B5E27A1C93DB050097820E /* UIollectionViewLayout.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = UIollectionViewLayout.app; sourceTree = BUILT_PRODUCTS_DIR; }; 44 | 07B5E27E1C93DB050097820E /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 45 | 07B5E2801C93DB050097820E /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 46 | 07B5E2811C93DB050097820E /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 47 | 07B5E2831C93DB050097820E /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; 48 | 07B5E2841C93DB050097820E /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; 49 | 07B5E2871C93DB050097820E /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 50 | 07B5E2891C93DB050097820E /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 51 | 07B5E28C1C93DB050097820E /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 52 | 07B5E28E1C93DB050097820E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 53 | 07B5E2931C93DB050097820E /* UIollectionViewLayoutTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = UIollectionViewLayoutTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 54 | 07B5E2971C93DB050097820E /* UIollectionViewLayoutTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = UIollectionViewLayoutTests.m; sourceTree = ""; }; 55 | 07B5E2991C93DB050097820E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 56 | 07B5E29E1C93DB050097820E /* UIollectionViewLayoutUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = UIollectionViewLayoutUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 57 | 07B5E2A21C93DB050097820E /* UIollectionViewLayoutUITests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = UIollectionViewLayoutUITests.m; sourceTree = ""; }; 58 | 07B5E2A41C93DB050097820E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 59 | 07B5E2B41C93DB760097820E /* CircleLayout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CircleLayout.h; sourceTree = ""; }; 60 | 07B5E2B51C93DB760097820E /* CircleLayout.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CircleLayout.m; sourceTree = ""; }; 61 | 07B5E2B61C93DB760097820E /* SquareLayout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SquareLayout.h; sourceTree = ""; }; 62 | 07B5E2B71C93DB760097820E /* SquareLayout.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SquareLayout.m; sourceTree = ""; }; 63 | 07B5E2BA1C93DBC80097820E /* CustomFlowLayout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CustomFlowLayout.h; sourceTree = ""; }; 64 | 07B5E2BB1C93DBC80097820E /* CustomFlowLayout.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CustomFlowLayout.m; sourceTree = ""; }; 65 | 07B5E2C31C93DCB20097820E /* PhotoCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PhotoCell.h; sourceTree = ""; }; 66 | 07B5E2C41C93DCB20097820E /* PhotoCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PhotoCell.m; sourceTree = ""; }; 67 | 07B5E2C51C93DCB20097820E /* PhotoCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = PhotoCell.xib; sourceTree = ""; }; 68 | /* End PBXFileReference section */ 69 | 70 | /* Begin PBXFrameworksBuildPhase section */ 71 | 07B5E2771C93DB050097820E /* Frameworks */ = { 72 | isa = PBXFrameworksBuildPhase; 73 | buildActionMask = 2147483647; 74 | files = ( 75 | ); 76 | runOnlyForDeploymentPostprocessing = 0; 77 | }; 78 | 07B5E2901C93DB050097820E /* Frameworks */ = { 79 | isa = PBXFrameworksBuildPhase; 80 | buildActionMask = 2147483647; 81 | files = ( 82 | ); 83 | runOnlyForDeploymentPostprocessing = 0; 84 | }; 85 | 07B5E29B1C93DB050097820E /* Frameworks */ = { 86 | isa = PBXFrameworksBuildPhase; 87 | buildActionMask = 2147483647; 88 | files = ( 89 | ); 90 | runOnlyForDeploymentPostprocessing = 0; 91 | }; 92 | /* End PBXFrameworksBuildPhase section */ 93 | 94 | /* Begin PBXGroup section */ 95 | 07B5E2711C93DB050097820E = { 96 | isa = PBXGroup; 97 | children = ( 98 | 07B5E27C1C93DB050097820E /* UIollectionViewLayout */, 99 | 07B5E2961C93DB050097820E /* UIollectionViewLayoutTests */, 100 | 07B5E2A11C93DB050097820E /* UIollectionViewLayoutUITests */, 101 | 07B5E27B1C93DB050097820E /* Products */, 102 | ); 103 | sourceTree = ""; 104 | }; 105 | 07B5E27B1C93DB050097820E /* Products */ = { 106 | isa = PBXGroup; 107 | children = ( 108 | 07B5E27A1C93DB050097820E /* UIollectionViewLayout.app */, 109 | 07B5E2931C93DB050097820E /* UIollectionViewLayoutTests.xctest */, 110 | 07B5E29E1C93DB050097820E /* UIollectionViewLayoutUITests.xctest */, 111 | ); 112 | name = Products; 113 | sourceTree = ""; 114 | }; 115 | 07B5E27C1C93DB050097820E /* UIollectionViewLayout */ = { 116 | isa = PBXGroup; 117 | children = ( 118 | 07B5E2B01C93DB650097820E /* 流水布局 */, 119 | 07B5E2B11C93DB650097820E /* 自定义布局 */, 120 | 07B5E2BD1C93DC540097820E /* Cell */, 121 | 07B5E2801C93DB050097820E /* AppDelegate.h */, 122 | 07B5E2811C93DB050097820E /* AppDelegate.m */, 123 | 07B5E2831C93DB050097820E /* ViewController.h */, 124 | 07B5E2841C93DB050097820E /* ViewController.m */, 125 | 07B5E2861C93DB050097820E /* Main.storyboard */, 126 | 07B5E2891C93DB050097820E /* Assets.xcassets */, 127 | 07B5E28B1C93DB050097820E /* LaunchScreen.storyboard */, 128 | 07B5E28E1C93DB050097820E /* Info.plist */, 129 | 07B5E27D1C93DB050097820E /* Supporting Files */, 130 | ); 131 | path = UIollectionViewLayout; 132 | sourceTree = ""; 133 | }; 134 | 07B5E27D1C93DB050097820E /* Supporting Files */ = { 135 | isa = PBXGroup; 136 | children = ( 137 | 07B5E27E1C93DB050097820E /* main.m */, 138 | ); 139 | name = "Supporting Files"; 140 | sourceTree = ""; 141 | }; 142 | 07B5E2961C93DB050097820E /* UIollectionViewLayoutTests */ = { 143 | isa = PBXGroup; 144 | children = ( 145 | 07B5E2971C93DB050097820E /* UIollectionViewLayoutTests.m */, 146 | 07B5E2991C93DB050097820E /* Info.plist */, 147 | ); 148 | path = UIollectionViewLayoutTests; 149 | sourceTree = ""; 150 | }; 151 | 07B5E2A11C93DB050097820E /* UIollectionViewLayoutUITests */ = { 152 | isa = PBXGroup; 153 | children = ( 154 | 07B5E2A21C93DB050097820E /* UIollectionViewLayoutUITests.m */, 155 | 07B5E2A41C93DB050097820E /* Info.plist */, 156 | ); 157 | path = UIollectionViewLayoutUITests; 158 | sourceTree = ""; 159 | }; 160 | 07B5E2B01C93DB650097820E /* 流水布局 */ = { 161 | isa = PBXGroup; 162 | children = ( 163 | 07B5E2BA1C93DBC80097820E /* CustomFlowLayout.h */, 164 | 07B5E2BB1C93DBC80097820E /* CustomFlowLayout.m */, 165 | ); 166 | path = "流水布局"; 167 | sourceTree = ""; 168 | }; 169 | 07B5E2B11C93DB650097820E /* 自定义布局 */ = { 170 | isa = PBXGroup; 171 | children = ( 172 | 07B5E2B41C93DB760097820E /* CircleLayout.h */, 173 | 07B5E2B51C93DB760097820E /* CircleLayout.m */, 174 | 07B5E2B61C93DB760097820E /* SquareLayout.h */, 175 | 07B5E2B71C93DB760097820E /* SquareLayout.m */, 176 | ); 177 | path = "自定义布局"; 178 | sourceTree = ""; 179 | }; 180 | 07B5E2BD1C93DC540097820E /* Cell */ = { 181 | isa = PBXGroup; 182 | children = ( 183 | 07B5E2C31C93DCB20097820E /* PhotoCell.h */, 184 | 07B5E2C41C93DCB20097820E /* PhotoCell.m */, 185 | 07B5E2C51C93DCB20097820E /* PhotoCell.xib */, 186 | ); 187 | path = Cell; 188 | sourceTree = ""; 189 | }; 190 | /* End PBXGroup section */ 191 | 192 | /* Begin PBXNativeTarget section */ 193 | 07B5E2791C93DB050097820E /* UIollectionViewLayout */ = { 194 | isa = PBXNativeTarget; 195 | buildConfigurationList = 07B5E2A71C93DB050097820E /* Build configuration list for PBXNativeTarget "UIollectionViewLayout" */; 196 | buildPhases = ( 197 | 07B5E2761C93DB050097820E /* Sources */, 198 | 07B5E2771C93DB050097820E /* Frameworks */, 199 | 07B5E2781C93DB050097820E /* Resources */, 200 | ); 201 | buildRules = ( 202 | ); 203 | dependencies = ( 204 | ); 205 | name = UIollectionViewLayout; 206 | productName = UIollectionViewLayout; 207 | productReference = 07B5E27A1C93DB050097820E /* UIollectionViewLayout.app */; 208 | productType = "com.apple.product-type.application"; 209 | }; 210 | 07B5E2921C93DB050097820E /* UIollectionViewLayoutTests */ = { 211 | isa = PBXNativeTarget; 212 | buildConfigurationList = 07B5E2AA1C93DB050097820E /* Build configuration list for PBXNativeTarget "UIollectionViewLayoutTests" */; 213 | buildPhases = ( 214 | 07B5E28F1C93DB050097820E /* Sources */, 215 | 07B5E2901C93DB050097820E /* Frameworks */, 216 | 07B5E2911C93DB050097820E /* Resources */, 217 | ); 218 | buildRules = ( 219 | ); 220 | dependencies = ( 221 | 07B5E2951C93DB050097820E /* PBXTargetDependency */, 222 | ); 223 | name = UIollectionViewLayoutTests; 224 | productName = UIollectionViewLayoutTests; 225 | productReference = 07B5E2931C93DB050097820E /* UIollectionViewLayoutTests.xctest */; 226 | productType = "com.apple.product-type.bundle.unit-test"; 227 | }; 228 | 07B5E29D1C93DB050097820E /* UIollectionViewLayoutUITests */ = { 229 | isa = PBXNativeTarget; 230 | buildConfigurationList = 07B5E2AD1C93DB050097820E /* Build configuration list for PBXNativeTarget "UIollectionViewLayoutUITests" */; 231 | buildPhases = ( 232 | 07B5E29A1C93DB050097820E /* Sources */, 233 | 07B5E29B1C93DB050097820E /* Frameworks */, 234 | 07B5E29C1C93DB050097820E /* Resources */, 235 | ); 236 | buildRules = ( 237 | ); 238 | dependencies = ( 239 | 07B5E2A01C93DB050097820E /* PBXTargetDependency */, 240 | ); 241 | name = UIollectionViewLayoutUITests; 242 | productName = UIollectionViewLayoutUITests; 243 | productReference = 07B5E29E1C93DB050097820E /* UIollectionViewLayoutUITests.xctest */; 244 | productType = "com.apple.product-type.bundle.ui-testing"; 245 | }; 246 | /* End PBXNativeTarget section */ 247 | 248 | /* Begin PBXProject section */ 249 | 07B5E2721C93DB050097820E /* Project object */ = { 250 | isa = PBXProject; 251 | attributes = { 252 | LastUpgradeCheck = 0720; 253 | ORGANIZATIONNAME = "李攀祥"; 254 | TargetAttributes = { 255 | 07B5E2791C93DB050097820E = { 256 | CreatedOnToolsVersion = 7.2.1; 257 | DevelopmentTeam = 3QRSQX6ZR9; 258 | }; 259 | 07B5E2921C93DB050097820E = { 260 | CreatedOnToolsVersion = 7.2.1; 261 | DevelopmentTeam = 3QRSQX6ZR9; 262 | TestTargetID = 07B5E2791C93DB050097820E; 263 | }; 264 | 07B5E29D1C93DB050097820E = { 265 | CreatedOnToolsVersion = 7.2.1; 266 | DevelopmentTeam = 3QRSQX6ZR9; 267 | TestTargetID = 07B5E2791C93DB050097820E; 268 | }; 269 | }; 270 | }; 271 | buildConfigurationList = 07B5E2751C93DB050097820E /* Build configuration list for PBXProject "UIollectionViewLayout" */; 272 | compatibilityVersion = "Xcode 3.2"; 273 | developmentRegion = English; 274 | hasScannedForEncodings = 0; 275 | knownRegions = ( 276 | en, 277 | Base, 278 | ); 279 | mainGroup = 07B5E2711C93DB050097820E; 280 | productRefGroup = 07B5E27B1C93DB050097820E /* Products */; 281 | projectDirPath = ""; 282 | projectRoot = ""; 283 | targets = ( 284 | 07B5E2791C93DB050097820E /* UIollectionViewLayout */, 285 | 07B5E2921C93DB050097820E /* UIollectionViewLayoutTests */, 286 | 07B5E29D1C93DB050097820E /* UIollectionViewLayoutUITests */, 287 | ); 288 | }; 289 | /* End PBXProject section */ 290 | 291 | /* Begin PBXResourcesBuildPhase section */ 292 | 07B5E2781C93DB050097820E /* Resources */ = { 293 | isa = PBXResourcesBuildPhase; 294 | buildActionMask = 2147483647; 295 | files = ( 296 | 07B5E2C71C93DCB20097820E /* PhotoCell.xib in Resources */, 297 | 07B5E28D1C93DB050097820E /* LaunchScreen.storyboard in Resources */, 298 | 07B5E28A1C93DB050097820E /* Assets.xcassets in Resources */, 299 | 07B5E2881C93DB050097820E /* Main.storyboard in Resources */, 300 | ); 301 | runOnlyForDeploymentPostprocessing = 0; 302 | }; 303 | 07B5E2911C93DB050097820E /* Resources */ = { 304 | isa = PBXResourcesBuildPhase; 305 | buildActionMask = 2147483647; 306 | files = ( 307 | ); 308 | runOnlyForDeploymentPostprocessing = 0; 309 | }; 310 | 07B5E29C1C93DB050097820E /* Resources */ = { 311 | isa = PBXResourcesBuildPhase; 312 | buildActionMask = 2147483647; 313 | files = ( 314 | ); 315 | runOnlyForDeploymentPostprocessing = 0; 316 | }; 317 | /* End PBXResourcesBuildPhase section */ 318 | 319 | /* Begin PBXSourcesBuildPhase section */ 320 | 07B5E2761C93DB050097820E /* Sources */ = { 321 | isa = PBXSourcesBuildPhase; 322 | buildActionMask = 2147483647; 323 | files = ( 324 | 07B5E2BC1C93DBC80097820E /* CustomFlowLayout.m in Sources */, 325 | 07B5E2B91C93DB760097820E /* SquareLayout.m in Sources */, 326 | 07B5E2851C93DB050097820E /* ViewController.m in Sources */, 327 | 07B5E2C61C93DCB20097820E /* PhotoCell.m in Sources */, 328 | 07B5E2B81C93DB760097820E /* CircleLayout.m in Sources */, 329 | 07B5E2821C93DB050097820E /* AppDelegate.m in Sources */, 330 | 07B5E27F1C93DB050097820E /* main.m in Sources */, 331 | ); 332 | runOnlyForDeploymentPostprocessing = 0; 333 | }; 334 | 07B5E28F1C93DB050097820E /* Sources */ = { 335 | isa = PBXSourcesBuildPhase; 336 | buildActionMask = 2147483647; 337 | files = ( 338 | 07B5E2981C93DB050097820E /* UIollectionViewLayoutTests.m in Sources */, 339 | ); 340 | runOnlyForDeploymentPostprocessing = 0; 341 | }; 342 | 07B5E29A1C93DB050097820E /* Sources */ = { 343 | isa = PBXSourcesBuildPhase; 344 | buildActionMask = 2147483647; 345 | files = ( 346 | 07B5E2A31C93DB050097820E /* UIollectionViewLayoutUITests.m in Sources */, 347 | ); 348 | runOnlyForDeploymentPostprocessing = 0; 349 | }; 350 | /* End PBXSourcesBuildPhase section */ 351 | 352 | /* Begin PBXTargetDependency section */ 353 | 07B5E2951C93DB050097820E /* PBXTargetDependency */ = { 354 | isa = PBXTargetDependency; 355 | target = 07B5E2791C93DB050097820E /* UIollectionViewLayout */; 356 | targetProxy = 07B5E2941C93DB050097820E /* PBXContainerItemProxy */; 357 | }; 358 | 07B5E2A01C93DB050097820E /* PBXTargetDependency */ = { 359 | isa = PBXTargetDependency; 360 | target = 07B5E2791C93DB050097820E /* UIollectionViewLayout */; 361 | targetProxy = 07B5E29F1C93DB050097820E /* PBXContainerItemProxy */; 362 | }; 363 | /* End PBXTargetDependency section */ 364 | 365 | /* Begin PBXVariantGroup section */ 366 | 07B5E2861C93DB050097820E /* Main.storyboard */ = { 367 | isa = PBXVariantGroup; 368 | children = ( 369 | 07B5E2871C93DB050097820E /* Base */, 370 | ); 371 | name = Main.storyboard; 372 | sourceTree = ""; 373 | }; 374 | 07B5E28B1C93DB050097820E /* LaunchScreen.storyboard */ = { 375 | isa = PBXVariantGroup; 376 | children = ( 377 | 07B5E28C1C93DB050097820E /* Base */, 378 | ); 379 | name = LaunchScreen.storyboard; 380 | sourceTree = ""; 381 | }; 382 | /* End PBXVariantGroup section */ 383 | 384 | /* Begin XCBuildConfiguration section */ 385 | 07B5E2A51C93DB050097820E /* Debug */ = { 386 | isa = XCBuildConfiguration; 387 | buildSettings = { 388 | ALWAYS_SEARCH_USER_PATHS = NO; 389 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 390 | CLANG_CXX_LIBRARY = "libc++"; 391 | CLANG_ENABLE_MODULES = YES; 392 | CLANG_ENABLE_OBJC_ARC = YES; 393 | CLANG_WARN_BOOL_CONVERSION = YES; 394 | CLANG_WARN_CONSTANT_CONVERSION = YES; 395 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 396 | CLANG_WARN_EMPTY_BODY = YES; 397 | CLANG_WARN_ENUM_CONVERSION = YES; 398 | CLANG_WARN_INT_CONVERSION = YES; 399 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 400 | CLANG_WARN_UNREACHABLE_CODE = YES; 401 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 402 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 403 | COPY_PHASE_STRIP = NO; 404 | DEBUG_INFORMATION_FORMAT = dwarf; 405 | ENABLE_STRICT_OBJC_MSGSEND = YES; 406 | ENABLE_TESTABILITY = YES; 407 | GCC_C_LANGUAGE_STANDARD = gnu99; 408 | GCC_DYNAMIC_NO_PIC = NO; 409 | GCC_NO_COMMON_BLOCKS = YES; 410 | GCC_OPTIMIZATION_LEVEL = 0; 411 | GCC_PREPROCESSOR_DEFINITIONS = ( 412 | "DEBUG=1", 413 | "$(inherited)", 414 | ); 415 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 416 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 417 | GCC_WARN_UNDECLARED_SELECTOR = YES; 418 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 419 | GCC_WARN_UNUSED_FUNCTION = YES; 420 | GCC_WARN_UNUSED_VARIABLE = YES; 421 | IPHONEOS_DEPLOYMENT_TARGET = 9.2; 422 | MTL_ENABLE_DEBUG_INFO = YES; 423 | ONLY_ACTIVE_ARCH = YES; 424 | SDKROOT = iphoneos; 425 | TARGETED_DEVICE_FAMILY = "1,2"; 426 | }; 427 | name = Debug; 428 | }; 429 | 07B5E2A61C93DB050097820E /* Release */ = { 430 | isa = XCBuildConfiguration; 431 | buildSettings = { 432 | ALWAYS_SEARCH_USER_PATHS = NO; 433 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 434 | CLANG_CXX_LIBRARY = "libc++"; 435 | CLANG_ENABLE_MODULES = YES; 436 | CLANG_ENABLE_OBJC_ARC = YES; 437 | CLANG_WARN_BOOL_CONVERSION = YES; 438 | CLANG_WARN_CONSTANT_CONVERSION = YES; 439 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 440 | CLANG_WARN_EMPTY_BODY = YES; 441 | CLANG_WARN_ENUM_CONVERSION = YES; 442 | CLANG_WARN_INT_CONVERSION = YES; 443 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 444 | CLANG_WARN_UNREACHABLE_CODE = YES; 445 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 446 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 447 | COPY_PHASE_STRIP = NO; 448 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 449 | ENABLE_NS_ASSERTIONS = NO; 450 | ENABLE_STRICT_OBJC_MSGSEND = YES; 451 | GCC_C_LANGUAGE_STANDARD = gnu99; 452 | GCC_NO_COMMON_BLOCKS = YES; 453 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 454 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 455 | GCC_WARN_UNDECLARED_SELECTOR = YES; 456 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 457 | GCC_WARN_UNUSED_FUNCTION = YES; 458 | GCC_WARN_UNUSED_VARIABLE = YES; 459 | IPHONEOS_DEPLOYMENT_TARGET = 9.2; 460 | MTL_ENABLE_DEBUG_INFO = NO; 461 | SDKROOT = iphoneos; 462 | TARGETED_DEVICE_FAMILY = "1,2"; 463 | VALIDATE_PRODUCT = YES; 464 | }; 465 | name = Release; 466 | }; 467 | 07B5E2A81C93DB050097820E /* Debug */ = { 468 | isa = XCBuildConfiguration; 469 | buildSettings = { 470 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 471 | INFOPLIST_FILE = UIollectionViewLayout/Info.plist; 472 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 473 | PRODUCT_BUNDLE_IDENTIFIER = com.lipanxiang.UIollectionViewLayout; 474 | PRODUCT_NAME = "$(TARGET_NAME)"; 475 | }; 476 | name = Debug; 477 | }; 478 | 07B5E2A91C93DB050097820E /* Release */ = { 479 | isa = XCBuildConfiguration; 480 | buildSettings = { 481 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 482 | INFOPLIST_FILE = UIollectionViewLayout/Info.plist; 483 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 484 | PRODUCT_BUNDLE_IDENTIFIER = com.lipanxiang.UIollectionViewLayout; 485 | PRODUCT_NAME = "$(TARGET_NAME)"; 486 | }; 487 | name = Release; 488 | }; 489 | 07B5E2AB1C93DB050097820E /* Debug */ = { 490 | isa = XCBuildConfiguration; 491 | buildSettings = { 492 | BUNDLE_LOADER = "$(TEST_HOST)"; 493 | INFOPLIST_FILE = UIollectionViewLayoutTests/Info.plist; 494 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 495 | PRODUCT_BUNDLE_IDENTIFIER = com.lipanxiang.UIollectionViewLayoutTests; 496 | PRODUCT_NAME = "$(TARGET_NAME)"; 497 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/UIollectionViewLayout.app/UIollectionViewLayout"; 498 | }; 499 | name = Debug; 500 | }; 501 | 07B5E2AC1C93DB050097820E /* Release */ = { 502 | isa = XCBuildConfiguration; 503 | buildSettings = { 504 | BUNDLE_LOADER = "$(TEST_HOST)"; 505 | INFOPLIST_FILE = UIollectionViewLayoutTests/Info.plist; 506 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 507 | PRODUCT_BUNDLE_IDENTIFIER = com.lipanxiang.UIollectionViewLayoutTests; 508 | PRODUCT_NAME = "$(TARGET_NAME)"; 509 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/UIollectionViewLayout.app/UIollectionViewLayout"; 510 | }; 511 | name = Release; 512 | }; 513 | 07B5E2AE1C93DB050097820E /* Debug */ = { 514 | isa = XCBuildConfiguration; 515 | buildSettings = { 516 | INFOPLIST_FILE = UIollectionViewLayoutUITests/Info.plist; 517 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 518 | PRODUCT_BUNDLE_IDENTIFIER = com.lipanxiang.UIollectionViewLayoutUITests; 519 | PRODUCT_NAME = "$(TARGET_NAME)"; 520 | TEST_TARGET_NAME = UIollectionViewLayout; 521 | USES_XCTRUNNER = YES; 522 | }; 523 | name = Debug; 524 | }; 525 | 07B5E2AF1C93DB050097820E /* Release */ = { 526 | isa = XCBuildConfiguration; 527 | buildSettings = { 528 | INFOPLIST_FILE = UIollectionViewLayoutUITests/Info.plist; 529 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 530 | PRODUCT_BUNDLE_IDENTIFIER = com.lipanxiang.UIollectionViewLayoutUITests; 531 | PRODUCT_NAME = "$(TARGET_NAME)"; 532 | TEST_TARGET_NAME = UIollectionViewLayout; 533 | USES_XCTRUNNER = YES; 534 | }; 535 | name = Release; 536 | }; 537 | /* End XCBuildConfiguration section */ 538 | 539 | /* Begin XCConfigurationList section */ 540 | 07B5E2751C93DB050097820E /* Build configuration list for PBXProject "UIollectionViewLayout" */ = { 541 | isa = XCConfigurationList; 542 | buildConfigurations = ( 543 | 07B5E2A51C93DB050097820E /* Debug */, 544 | 07B5E2A61C93DB050097820E /* Release */, 545 | ); 546 | defaultConfigurationIsVisible = 0; 547 | defaultConfigurationName = Release; 548 | }; 549 | 07B5E2A71C93DB050097820E /* Build configuration list for PBXNativeTarget "UIollectionViewLayout" */ = { 550 | isa = XCConfigurationList; 551 | buildConfigurations = ( 552 | 07B5E2A81C93DB050097820E /* Debug */, 553 | 07B5E2A91C93DB050097820E /* Release */, 554 | ); 555 | defaultConfigurationIsVisible = 0; 556 | }; 557 | 07B5E2AA1C93DB050097820E /* Build configuration list for PBXNativeTarget "UIollectionViewLayoutTests" */ = { 558 | isa = XCConfigurationList; 559 | buildConfigurations = ( 560 | 07B5E2AB1C93DB050097820E /* Debug */, 561 | 07B5E2AC1C93DB050097820E /* Release */, 562 | ); 563 | defaultConfigurationIsVisible = 0; 564 | }; 565 | 07B5E2AD1C93DB050097820E /* Build configuration list for PBXNativeTarget "UIollectionViewLayoutUITests" */ = { 566 | isa = XCConfigurationList; 567 | buildConfigurations = ( 568 | 07B5E2AE1C93DB050097820E /* Debug */, 569 | 07B5E2AF1C93DB050097820E /* Release */, 570 | ); 571 | defaultConfigurationIsVisible = 0; 572 | }; 573 | /* End XCConfigurationList section */ 574 | }; 575 | rootObject = 07B5E2721C93DB050097820E /* Project object */; 576 | } 577 | -------------------------------------------------------------------------------- /UIollectionViewLayout.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /UIollectionViewLayout.xcodeproj/project.xcworkspace/xcuserdata/lipanxiang.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lpx0312/UIollectionViewLayout/52772b8a15f4892d1b982ec90818714588bba2b9/UIollectionViewLayout.xcodeproj/project.xcworkspace/xcuserdata/lipanxiang.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /UIollectionViewLayout.xcodeproj/xcuserdata/lipanxiang.xcuserdatad/xcschemes/UIollectionViewLayout.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 43 | 49 | 50 | 51 | 52 | 53 | 59 | 60 | 61 | 62 | 63 | 64 | 74 | 76 | 82 | 83 | 84 | 85 | 86 | 87 | 93 | 95 | 101 | 102 | 103 | 104 | 106 | 107 | 110 | 111 | 112 | -------------------------------------------------------------------------------- /UIollectionViewLayout.xcodeproj/xcuserdata/lipanxiang.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | UIollectionViewLayout.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | 07B5E2791C93DB050097820E 16 | 17 | primary 18 | 19 | 20 | 07B5E2921C93DB050097820E 21 | 22 | primary 23 | 24 | 25 | 07B5E29D1C93DB050097820E 26 | 27 | primary 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /UIollectionViewLayout/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // UIollectionViewLayout 4 | // 5 | // Created by 李攀祥 on 16/3/12. 6 | // Copyright © 2016年 李攀祥. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | 16 | @end 17 | 18 | -------------------------------------------------------------------------------- /UIollectionViewLayout/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // UIollectionViewLayout 4 | // 5 | // Created by 李攀祥 on 16/3/12. 6 | // Copyright © 2016年 李攀祥. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | 11 | @interface AppDelegate () 12 | 13 | @end 14 | 15 | @implementation AppDelegate 16 | 17 | 18 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 19 | // Override point for customization after application launch. 20 | return YES; 21 | } 22 | 23 | - (void)applicationWillResignActive:(UIApplication *)application { 24 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 25 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 26 | } 27 | 28 | - (void)applicationDidEnterBackground:(UIApplication *)application { 29 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 30 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 31 | } 32 | 33 | - (void)applicationWillEnterForeground:(UIApplication *)application { 34 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. 35 | } 36 | 37 | - (void)applicationDidBecomeActive:(UIApplication *)application { 38 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 39 | } 40 | 41 | - (void)applicationWillTerminate:(UIApplication *)application { 42 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 43 | } 44 | 45 | @end 46 | -------------------------------------------------------------------------------- /UIollectionViewLayout/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "29x29", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "40x40", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "40x40", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "60x60", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "60x60", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "ipad", 35 | "size" : "29x29", 36 | "scale" : "1x" 37 | }, 38 | { 39 | "idiom" : "ipad", 40 | "size" : "29x29", 41 | "scale" : "2x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "40x40", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "40x40", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "76x76", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "76x76", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "size" : "83.5x83.5", 66 | "scale" : "2x" 67 | } 68 | ], 69 | "info" : { 70 | "version" : 1, 71 | "author" : "xcode" 72 | } 73 | } -------------------------------------------------------------------------------- /UIollectionViewLayout/Assets.xcassets/photos/1.imageset/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lpx0312/UIollectionViewLayout/52772b8a15f4892d1b982ec90818714588bba2b9/UIollectionViewLayout/Assets.xcassets/photos/1.imageset/1.jpg -------------------------------------------------------------------------------- /UIollectionViewLayout/Assets.xcassets/photos/1.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x", 6 | "filename" : "1.jpg" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /UIollectionViewLayout/Assets.xcassets/photos/10.imageset/10.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lpx0312/UIollectionViewLayout/52772b8a15f4892d1b982ec90818714588bba2b9/UIollectionViewLayout/Assets.xcassets/photos/10.imageset/10.jpg -------------------------------------------------------------------------------- /UIollectionViewLayout/Assets.xcassets/photos/10.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x", 6 | "filename" : "10.jpg" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /UIollectionViewLayout/Assets.xcassets/photos/11.imageset/11.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lpx0312/UIollectionViewLayout/52772b8a15f4892d1b982ec90818714588bba2b9/UIollectionViewLayout/Assets.xcassets/photos/11.imageset/11.jpg -------------------------------------------------------------------------------- /UIollectionViewLayout/Assets.xcassets/photos/11.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x", 6 | "filename" : "11.jpg" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /UIollectionViewLayout/Assets.xcassets/photos/12.imageset/12.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lpx0312/UIollectionViewLayout/52772b8a15f4892d1b982ec90818714588bba2b9/UIollectionViewLayout/Assets.xcassets/photos/12.imageset/12.jpg -------------------------------------------------------------------------------- /UIollectionViewLayout/Assets.xcassets/photos/12.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x", 6 | "filename" : "12.jpg" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /UIollectionViewLayout/Assets.xcassets/photos/13.imageset/13.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lpx0312/UIollectionViewLayout/52772b8a15f4892d1b982ec90818714588bba2b9/UIollectionViewLayout/Assets.xcassets/photos/13.imageset/13.jpg -------------------------------------------------------------------------------- /UIollectionViewLayout/Assets.xcassets/photos/13.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x", 6 | "filename" : "13.jpg" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /UIollectionViewLayout/Assets.xcassets/photos/14.imageset/14.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lpx0312/UIollectionViewLayout/52772b8a15f4892d1b982ec90818714588bba2b9/UIollectionViewLayout/Assets.xcassets/photos/14.imageset/14.jpg -------------------------------------------------------------------------------- /UIollectionViewLayout/Assets.xcassets/photos/14.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x", 6 | "filename" : "14.jpg" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /UIollectionViewLayout/Assets.xcassets/photos/15.imageset/15.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lpx0312/UIollectionViewLayout/52772b8a15f4892d1b982ec90818714588bba2b9/UIollectionViewLayout/Assets.xcassets/photos/15.imageset/15.jpg -------------------------------------------------------------------------------- /UIollectionViewLayout/Assets.xcassets/photos/15.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x", 6 | "filename" : "15.jpg" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /UIollectionViewLayout/Assets.xcassets/photos/16.imageset/16.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lpx0312/UIollectionViewLayout/52772b8a15f4892d1b982ec90818714588bba2b9/UIollectionViewLayout/Assets.xcassets/photos/16.imageset/16.jpg -------------------------------------------------------------------------------- /UIollectionViewLayout/Assets.xcassets/photos/16.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x", 6 | "filename" : "16.jpg" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /UIollectionViewLayout/Assets.xcassets/photos/17.imageset/17.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lpx0312/UIollectionViewLayout/52772b8a15f4892d1b982ec90818714588bba2b9/UIollectionViewLayout/Assets.xcassets/photos/17.imageset/17.jpg -------------------------------------------------------------------------------- /UIollectionViewLayout/Assets.xcassets/photos/17.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x", 6 | "filename" : "17.jpg" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /UIollectionViewLayout/Assets.xcassets/photos/18.imageset/18.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lpx0312/UIollectionViewLayout/52772b8a15f4892d1b982ec90818714588bba2b9/UIollectionViewLayout/Assets.xcassets/photos/18.imageset/18.jpg -------------------------------------------------------------------------------- /UIollectionViewLayout/Assets.xcassets/photos/18.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x", 6 | "filename" : "18.jpg" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /UIollectionViewLayout/Assets.xcassets/photos/19.imageset/19.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lpx0312/UIollectionViewLayout/52772b8a15f4892d1b982ec90818714588bba2b9/UIollectionViewLayout/Assets.xcassets/photos/19.imageset/19.jpg -------------------------------------------------------------------------------- /UIollectionViewLayout/Assets.xcassets/photos/19.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x", 6 | "filename" : "19.jpg" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /UIollectionViewLayout/Assets.xcassets/photos/2.imageset/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lpx0312/UIollectionViewLayout/52772b8a15f4892d1b982ec90818714588bba2b9/UIollectionViewLayout/Assets.xcassets/photos/2.imageset/2.jpg -------------------------------------------------------------------------------- /UIollectionViewLayout/Assets.xcassets/photos/2.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x", 6 | "filename" : "2.jpg" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /UIollectionViewLayout/Assets.xcassets/photos/20.imageset/20.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lpx0312/UIollectionViewLayout/52772b8a15f4892d1b982ec90818714588bba2b9/UIollectionViewLayout/Assets.xcassets/photos/20.imageset/20.jpg -------------------------------------------------------------------------------- /UIollectionViewLayout/Assets.xcassets/photos/20.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x", 6 | "filename" : "20.jpg" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /UIollectionViewLayout/Assets.xcassets/photos/3.imageset/3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lpx0312/UIollectionViewLayout/52772b8a15f4892d1b982ec90818714588bba2b9/UIollectionViewLayout/Assets.xcassets/photos/3.imageset/3.jpg -------------------------------------------------------------------------------- /UIollectionViewLayout/Assets.xcassets/photos/3.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x", 6 | "filename" : "3.jpg" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /UIollectionViewLayout/Assets.xcassets/photos/4.imageset/4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lpx0312/UIollectionViewLayout/52772b8a15f4892d1b982ec90818714588bba2b9/UIollectionViewLayout/Assets.xcassets/photos/4.imageset/4.jpg -------------------------------------------------------------------------------- /UIollectionViewLayout/Assets.xcassets/photos/4.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x", 6 | "filename" : "4.jpg" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /UIollectionViewLayout/Assets.xcassets/photos/5.imageset/5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lpx0312/UIollectionViewLayout/52772b8a15f4892d1b982ec90818714588bba2b9/UIollectionViewLayout/Assets.xcassets/photos/5.imageset/5.jpg -------------------------------------------------------------------------------- /UIollectionViewLayout/Assets.xcassets/photos/5.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x", 6 | "filename" : "5.jpg" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /UIollectionViewLayout/Assets.xcassets/photos/6.imageset/6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lpx0312/UIollectionViewLayout/52772b8a15f4892d1b982ec90818714588bba2b9/UIollectionViewLayout/Assets.xcassets/photos/6.imageset/6.jpg -------------------------------------------------------------------------------- /UIollectionViewLayout/Assets.xcassets/photos/6.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x", 6 | "filename" : "6.jpg" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /UIollectionViewLayout/Assets.xcassets/photos/7.imageset/7.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lpx0312/UIollectionViewLayout/52772b8a15f4892d1b982ec90818714588bba2b9/UIollectionViewLayout/Assets.xcassets/photos/7.imageset/7.jpg -------------------------------------------------------------------------------- /UIollectionViewLayout/Assets.xcassets/photos/7.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x", 6 | "filename" : "7.jpg" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /UIollectionViewLayout/Assets.xcassets/photos/8.imageset/8.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lpx0312/UIollectionViewLayout/52772b8a15f4892d1b982ec90818714588bba2b9/UIollectionViewLayout/Assets.xcassets/photos/8.imageset/8.jpg -------------------------------------------------------------------------------- /UIollectionViewLayout/Assets.xcassets/photos/8.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x", 6 | "filename" : "8.jpg" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /UIollectionViewLayout/Assets.xcassets/photos/9.imageset/9.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lpx0312/UIollectionViewLayout/52772b8a15f4892d1b982ec90818714588bba2b9/UIollectionViewLayout/Assets.xcassets/photos/9.imageset/9.jpg -------------------------------------------------------------------------------- /UIollectionViewLayout/Assets.xcassets/photos/9.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x", 6 | "filename" : "9.jpg" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /UIollectionViewLayout/Assets.xcassets/sub_add.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "sub_add@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "sub_add@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /UIollectionViewLayout/Assets.xcassets/sub_add.imageset/sub_add@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lpx0312/UIollectionViewLayout/52772b8a15f4892d1b982ec90818714588bba2b9/UIollectionViewLayout/Assets.xcassets/sub_add.imageset/sub_add@2x.png -------------------------------------------------------------------------------- /UIollectionViewLayout/Assets.xcassets/sub_add.imageset/sub_add@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lpx0312/UIollectionViewLayout/52772b8a15f4892d1b982ec90818714588bba2b9/UIollectionViewLayout/Assets.xcassets/sub_add.imageset/sub_add@3x.png -------------------------------------------------------------------------------- /UIollectionViewLayout/Assets.xcassets/sub_add_h.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "sub_add_h.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "sub_add_h@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "sub_add_h@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /UIollectionViewLayout/Assets.xcassets/sub_add_h.imageset/sub_add_h.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lpx0312/UIollectionViewLayout/52772b8a15f4892d1b982ec90818714588bba2b9/UIollectionViewLayout/Assets.xcassets/sub_add_h.imageset/sub_add_h.png -------------------------------------------------------------------------------- /UIollectionViewLayout/Assets.xcassets/sub_add_h.imageset/sub_add_h@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lpx0312/UIollectionViewLayout/52772b8a15f4892d1b982ec90818714588bba2b9/UIollectionViewLayout/Assets.xcassets/sub_add_h.imageset/sub_add_h@2x.png -------------------------------------------------------------------------------- /UIollectionViewLayout/Assets.xcassets/sub_add_h.imageset/sub_add_h@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lpx0312/UIollectionViewLayout/52772b8a15f4892d1b982ec90818714588bba2b9/UIollectionViewLayout/Assets.xcassets/sub_add_h.imageset/sub_add_h@3x.png -------------------------------------------------------------------------------- /UIollectionViewLayout/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /UIollectionViewLayout/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 | -------------------------------------------------------------------------------- /UIollectionViewLayout/Cell/PhotoCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // PhotoCell.h 3 | // UIollectionViewLayout 4 | // 5 | // Created by 李攀祥 on 16/3/12. 6 | // Copyright © 2016年 李攀祥. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface PhotoCell : UICollectionViewCell 12 | /** 图片名字 */ 13 | @property (nonatomic,strong)NSString * imageName; 14 | @end 15 | -------------------------------------------------------------------------------- /UIollectionViewLayout/Cell/PhotoCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // PhotoCell.m 3 | // UIollectionViewLayout 4 | // 5 | // Created by 李攀祥 on 16/3/12. 6 | // Copyright © 2016年 李攀祥. All rights reserved. 7 | // 8 | 9 | #import "PhotoCell.h" 10 | 11 | @interface PhotoCell() 12 | @property (weak, nonatomic) IBOutlet UIImageView *imageView; 13 | @end 14 | 15 | @implementation PhotoCell 16 | - (void)awakeFromNib { 17 | self.imageView.layer.borderColor = [UIColor whiteColor].CGColor; 18 | self.imageView.layer.borderWidth = 10; 19 | } 20 | 21 | - (void)setImageName:(NSString *)imageName 22 | { 23 | _imageName = [imageName copy]; 24 | 25 | self.imageView.image = [UIImage imageNamed:imageName]; 26 | } 27 | @end 28 | -------------------------------------------------------------------------------- /UIollectionViewLayout/Cell/PhotoCell.xib: -------------------------------------------------------------------------------- 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 | -------------------------------------------------------------------------------- /UIollectionViewLayout/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 | UIInterfaceOrientationLandscapeRight 38 | 39 | UISupportedInterfaceOrientations~ipad 40 | 41 | UIInterfaceOrientationPortrait 42 | UIInterfaceOrientationPortraitUpsideDown 43 | UIInterfaceOrientationLandscapeLeft 44 | UIInterfaceOrientationLandscapeRight 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /UIollectionViewLayout/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // UIollectionViewLayout 4 | // 5 | // Created by 李攀祥 on 16/3/12. 6 | // Copyright © 2016年 李攀祥. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ViewController : UIViewController 12 | 13 | @end 14 | 15 | -------------------------------------------------------------------------------- /UIollectionViewLayout/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // UIollectionViewLayout 4 | // 5 | // Created by 李攀祥 on 16/3/12. 6 | // Copyright © 2016年 李攀祥. All rights reserved. 7 | // 8 | 9 | #import "ViewController.h" 10 | #import "PhotoCell.h" 11 | 12 | #import "CustomFlowLayout.h" 13 | #import "CircleLayout.h" 14 | #import "SquareLayout.h" 15 | @interface ViewController () 16 | @property(nonatomic,strong)UICollectionView * myCollectionView; 17 | /** 数据源 */ 18 | @property (nonatomic,strong)NSMutableArray * dataArr; 19 | /** CollectionView的自带的流水布局 */ 20 | @property (nonatomic,strong)UICollectionViewFlowLayout * defauleLayout; 21 | /** 自定义的CollectionView的流水布局 */ 22 | @property (nonatomic,strong)CustomFlowLayout * layout; 23 | /** 自定义的圆形布局 */ 24 | @property (nonatomic,strong)CircleLayout* cirLayout; 25 | /** 自定义方形布局 */ 26 | @property (nonatomic,strong)SquareLayout * squareLayout; 27 | @end 28 | 29 | static NSString * const PhotoCellId = @"photo"; 30 | 31 | @implementation ViewController 32 | 33 | - (void)viewDidLoad { 34 | [super viewDidLoad]; 35 | [self.view addSubview:self.myCollectionView]; 36 | // [self addChangedBtn]; 37 | } 38 | #pragma mark ---- 添加 改变布局的按钮 39 | -(void)addChangedBtn 40 | { 41 | //1.创建btn 42 | UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom]; 43 | //btn.center=CGPointMake([UIScreen mainScreen].bounds.size.width/2, [UIScreen mainScreen].bounds.size.height-80); 44 | btn.frame=CGRectMake(200,300, 80, 80); 45 | // 2.设置按钮的图片 46 | [btn setBackgroundImage:[UIImage imageNamed:@"sub_add"] forState:UIControlStateNormal]; 47 | [btn setBackgroundImage:[UIImage imageNamed:@"sub_add_h"] forState:UIControlStateHighlighted]; 48 | [btn addTarget:self action:@selector(changedLayout) forControlEvents:UIControlEventTouchUpInside]; 49 | [self.view addSubview:btn]; 50 | } 51 | #pragma mark ---- 切换布局 52 | -(void)changedLayout 53 | { 54 | if ([self.myCollectionView.collectionViewLayout isKindOfClass:[CircleLayout class]]){ 55 | [self.myCollectionView setCollectionViewLayout:self.layout animated:YES]; 56 | }else if([self.myCollectionView.collectionViewLayout isKindOfClass:[CustomFlowLayout class]]){ 57 | [self.myCollectionView setCollectionViewLayout:self.squareLayout animated:YES]; 58 | }else if([self.myCollectionView.collectionViewLayout isKindOfClass:[SquareLayout class]]){ 59 | [self.myCollectionView setCollectionViewLayout:self.defauleLayout animated:YES]; 60 | }else{ 61 | [self.myCollectionView setCollectionViewLayout:self.cirLayout animated:YES]; 62 | } 63 | } 64 | 65 | #pragma mark- 懒加载 66 | -(NSMutableArray *)dataArr 67 | { 68 | if(!_dataArr){ 69 | _dataArr=[[NSMutableArray alloc] init]; 70 | for (int i=0; i<16; i++) { 71 | [_dataArr addObject:[NSString stringWithFormat:@"%d",i+1]]; 72 | } 73 | } 74 | return _dataArr; 75 | } 76 | 77 | -(UICollectionView *)myCollectionView 78 | { 79 | if(!_myCollectionView){ 80 | /** 81 | 注意:初始化collectionView 通过frame和layout 一定要传进去一个layout 82 | */ 83 | _myCollectionView=[[UICollectionView alloc] initWithFrame:self.view.bounds collectionViewLayout:self.squareLayout]; 84 | _myCollectionView.delegate = self; 85 | _myCollectionView.dataSource = self; 86 | _myCollectionView.showsVerticalScrollIndicator=NO; 87 | _myCollectionView.showsHorizontalScrollIndicator=NO; 88 | //注册cell 89 | [_myCollectionView registerNib:[UINib nibWithNibName:NSStringFromClass([PhotoCell class]) bundle:nil] forCellWithReuseIdentifier:PhotoCellId]; 90 | } 91 | return _myCollectionView; 92 | } 93 | 94 | -(CustomFlowLayout *)layout 95 | { 96 | if(!_layout){ 97 | _layout=[[CustomFlowLayout alloc] init]; 98 | _layout.itemSize=CGSizeMake(150, 150); 99 | } 100 | return _layout; 101 | } 102 | 103 | -(CircleLayout *)cirLayout 104 | { 105 | if(!_cirLayout){ 106 | _cirLayout=[[CircleLayout alloc] init]; 107 | } 108 | return _cirLayout; 109 | } 110 | 111 | -(SquareLayout *)squareLayout 112 | { 113 | if(!_squareLayout){ 114 | _squareLayout=[[SquareLayout alloc] init]; 115 | } 116 | return _squareLayout; 117 | } 118 | //这里是系统自带的流水布局 119 | -(UICollectionViewFlowLayout *)defauleLayout 120 | { 121 | /** 122 | UICollectionViewFlowLayout:是系统自带的唯一的布局 流水布局 123 | 如果我们要自定义布局的话有2中方式 124 | 1--》继承于UICollectionViewLayout(比较底层不是流水布局 没有itemSize,scrollDirection等属性) 125 | 2--》继承于UICollectionViewFlowLayout(这个是继承与上一个的有scrollDirection等属性) 126 | */ 127 | if(!_defauleLayout){ 128 | _defauleLayout=[[UICollectionViewFlowLayout alloc] init]; 129 | _defauleLayout.itemSize=CGSizeMake(150, 130); 130 | _defauleLayout.scrollDirection = UICollectionViewScrollDirectionVertical;//这2个都是流水布局的属性UICollectionViewFlowLayout 131 | } 132 | return _defauleLayout; 133 | } 134 | 135 | #pragma mark - CollectionView的Delegate 136 | -(NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView 137 | { 138 | return 1; 139 | } 140 | 141 | -(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section 142 | { 143 | return self.dataArr.count; 144 | } 145 | 146 | -(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath 147 | { 148 | PhotoCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:PhotoCellId forIndexPath:indexPath]; 149 | cell.imageName = self.dataArr[indexPath.item]; 150 | return cell; 151 | } 152 | 153 | #pragma mark ---- 点击item的方法 154 | -(void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath 155 | { 156 | [self.dataArr removeObjectAtIndex:indexPath.item]; 157 | //TODO: 这个方法 特别注意 删除item的方法 158 | [self.myCollectionView deleteItemsAtIndexPaths:@[indexPath]]; 159 | } 160 | @end 161 | -------------------------------------------------------------------------------- /UIollectionViewLayout/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // UIollectionViewLayout 4 | // 5 | // Created by 李攀祥 on 16/3/12. 6 | // Copyright © 2016年 李攀祥. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "AppDelegate.h" 11 | 12 | int main(int argc, char * argv[]) { 13 | @autoreleasepool { 14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /UIollectionViewLayout/流水布局/CustomFlowLayout.h: -------------------------------------------------------------------------------- 1 | // 2 | // CustomFlowLayout.h 3 | // UIollectionViewLayout 4 | // 5 | // Created by 李攀祥 on 16/3/12. 6 | // Copyright © 2016年 李攀祥. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface CustomFlowLayout : UICollectionViewFlowLayout 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /UIollectionViewLayout/流水布局/CustomFlowLayout.m: -------------------------------------------------------------------------------- 1 | // 2 | // CustomFlowLayout.m 3 | // UIollectionViewLayout 4 | // 5 | // Created by 李攀祥 on 16/3/12. 6 | // Copyright © 2016年 李攀祥. All rights reserved. 7 | // 8 | 9 | #import "CustomFlowLayout.h" 10 | 11 | @implementation CustomFlowLayout 12 | /** 13 | 1.cell的放大和缩小 14 | 2.停止滚动时:cell居中 15 | */ 16 | 17 | #pragma mark- 布局的初始化操作 18 | //TODO: 特别注意 布局的初始化操作 不要在init方法中 做布局的初始化操作 19 | -(void)prepareLayout{ 20 | [super prepareLayout]; 21 | /** 22 | 1.一个cell对应一个UICollectionViewLayoutAttributes对象 23 | 2.UICollectionViewLayoutAttributes对象决定了cell的摆设位置(frame) 24 | */ 25 | //默认水平 排布 26 | self.scrollDirection = UICollectionViewScrollDirectionHorizontal; 27 | //设置内边距 28 | CGFloat insert =(self.collectionView.frame.size.width-self.itemSize.width)/2; 29 | self.sectionInset =UIEdgeInsetsMake(0, insert, 0, insert); 30 | } 31 | 32 | /** 33 | * 这个方法的返回值是一个数组(数组里存放在rect范围内所有元素的布局属性) 34 | * 这个方法的返回值 决定了rect范围内所有元素的排布(frame) 35 | */ 36 | -(NSArray *)layoutAttributesForElementsInRect:(CGRect)rect 37 | { 38 | 39 | //获得super已经计算好的布局属性 只有线性布局才能使用 40 | NSArray * array = [super layoutAttributesForElementsInRect:rect]; 41 | //计算CollectionView最中心的x值 42 | #warning 特别注意: 43 | CGFloat centetX = self.collectionView.contentOffset.x + self.collectionView.frame.size.width/2; 44 | for (UICollectionViewLayoutAttributes * attrs in array) { 45 | //CGFloat scale = arc4random_uniform(100)/100.0; 46 | //attrs.indexPath.item 表示 这个attrs对应的cell的位置 47 | NSLog(@" 第%zdcell--距离:%.1f",attrs.indexPath.item ,attrs.center.x - centetX); 48 | //cell的中心点x 和CollectionView最中心点的x值 49 | CGFloat delta = ABS(attrs.center.x - centetX); 50 | //根据间距值 计算cell的缩放的比例 51 | //这里scale 必须要 小于1 52 | CGFloat scale = 1 - delta/self.collectionView.frame.size.width; 53 | //设置缩放比例 54 | attrs.transform=CGAffineTransformMakeScale(scale, scale); 55 | } 56 | return array; 57 | } 58 | 59 | /*! 60 | * 多次调用 只要滑出范围就会 调用 61 | * 当CollectionView的显示范围发生改变的时候,是否重新发生布局 62 | * 一旦重新刷新 布局,就会重新调用 63 | * 1.layoutAttributesForElementsInRect:方法 64 | * 2.preparelayout方法 65 | */ 66 | -(BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds 67 | { 68 | return YES; 69 | } 70 | 71 | /** 72 | * 只要手一松开就会调用 73 | * 这个方法的返回值,就决定了CollectionView停止滚动时的偏移量 74 | * proposedContentOffset这个是最终的 偏移量的值 但是实际的情况还是要根据返回值来定 75 | * velocity 是滚动速率 有个x和y 如果x有值 说明x上有速度 76 | * 如果y有值 说明y上又速度 还可以通过x或者y的正负来判断是左还是右(上还是下滑动) 有时候会有用 77 | */ 78 | -(CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset withScrollingVelocity:(CGPoint)velocity 79 | { 80 | //计算出 最终显示的矩形框 81 | CGRect rect; 82 | rect.origin.x =proposedContentOffset.x; 83 | rect.origin.y=0; 84 | rect.size=self.collectionView.frame.size; 85 | 86 | NSArray * array = [super layoutAttributesForElementsInRect:rect]; 87 | //TODO: 这里的计算和上面的计算不一样的 88 | // 计算CollectionView最中心点的x值 这里要求 最终的 要考虑惯性 89 | CGFloat centerX = self.collectionView.frame.size.width /2+ proposedContentOffset.x; 90 | //存放的最小间距 91 | //TODO: 注意研究一下: 92 | CGFloat minDelta = MAXFLOAT; 93 | for (UICollectionViewLayoutAttributes * attrs in array) { 94 | if (ABS(minDelta)>ABS(attrs.center.x-centerX)) { 95 | minDelta=attrs.center.x-centerX; 96 | } 97 | } 98 | // 修改原有的偏移量 99 | proposedContentOffset.x+=minDelta; 100 | //如果返回的时zero 那个滑动停止后 就会立刻回到原地 101 | return proposedContentOffset; 102 | } 103 | 104 | @end 105 | -------------------------------------------------------------------------------- /UIollectionViewLayout/自定义布局/CircleLayout.h: -------------------------------------------------------------------------------- 1 | // 2 | // CircleLayout.h 3 | // 01-百思不得其姐 4 | // 5 | // Created by 李攀祥 on 16/3/8. 6 | // Copyright © 2016年 李攀祥. All rights reserved. 7 | // 8 | 9 | #import 10 | @interface CircleLayout : UICollectionViewLayout 11 | @end 12 | -------------------------------------------------------------------------------- /UIollectionViewLayout/自定义布局/CircleLayout.m: -------------------------------------------------------------------------------- 1 | // 2 | // CircleLayout.m 3 | // 01-百思不得其姐 4 | // 5 | // Created by 李攀祥 on 16/3/8. 6 | // Copyright © 2016年 李攀祥. All rights reserved. 7 | 8 | 9 | 10 | 11 | #import "CircleLayout.h" 12 | @interface CircleLayout () 13 | @property(nonatomic,strong)NSMutableArray * attrsArr; 14 | @end 15 | 16 | @implementation CircleLayout 17 | #pragma mark ---- 懒加载 18 | 19 | -(NSMutableArray *)attrsArr 20 | { 21 | if(!_attrsArr){ 22 | _attrsArr=[[NSMutableArray alloc] init]; 23 | } 24 | return _attrsArr; 25 | } 26 | 27 | -(void)prepareLayout 28 | { 29 | [super prepareLayout]; 30 | [self.attrsArr removeAllObjects]; 31 | [self creatAttrs]; 32 | } 33 | -(void)creatAttrs{ 34 | //计算出每组有多少个 35 | NSInteger count=[self.collectionView numberOfItemsInSection:0]; 36 | /** 37 | * 因为不是继承流水布局 UICollectionViewFlowLayout 38 | * 所以我们需要自己创建 UICollectionViewLayoutAttributes 39 | */ 40 | //如果是多组的话 需要2层循环 41 | for (int i=0; i *)layoutAttributesForElementsInRect:(CGRect)rect 51 | { 52 | //TODO: 特别注意 在这个方法里 可以边滑动边刷新(添加) attrs 一劳永逸 如果只需要添加一次的话 可以把这些 prepareLayout方法中去 53 | return self.attrsArr; 54 | } 55 | 56 | #pragma mark ---- 这个方法需要返回indexPath位置对应cell的布局属性 57 | /** 58 | * //TODO: 这个方法主要用于 切换布局的时候 如果不适用该方法 就不会切换布局的时候会报错 59 | * reason: 'no UICollectionViewLayoutAttributes instance for -layoutAttributesForItemAtIndexPath: {length = 2, path = 0 - 2}' 60 | */ 61 | -(UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath 62 | { 63 | //TODO: 主要是返回每个indexPath的attrs 64 | 65 | //创建UICollectionViewLayoutAttributes 66 | //这里需要 告诉 UICollectionViewLayoutAttributes 是哪里的attrs 67 | //计算出每组有多少个 68 | NSInteger count=[self.collectionView numberOfItemsInSection:0]; 69 | //角度 70 | CGFloat angle = 2* M_PI /count *indexPath.item; 71 | //设置半径 72 | CGFloat radius=100; 73 | //CollectionView的圆心的位置 74 | CGFloat Ox = self.collectionView.frame.size.width/2; 75 | CGFloat Oy = self.collectionView.frame.size.height/2; 76 | UICollectionViewLayoutAttributes * attrs=[UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath]; 77 | attrs.center = CGPointMake(Ox+radius*sin(angle), Oy+radius*cos(angle)); 78 | if (count==1) { 79 | attrs.size=CGSizeMake(200, 200); 80 | }else{ 81 | attrs.size=CGSizeMake(50, 50); 82 | } 83 | return attrs; 84 | } 85 | @end 86 | -------------------------------------------------------------------------------- /UIollectionViewLayout/自定义布局/SquareLayout.h: -------------------------------------------------------------------------------- 1 | // 2 | // 3 | // Created by 李攀祥 on 16/3/8. 4 | // Copyright © 2016年 李攀祥. All rights reserved. 5 | 6 | #import 7 | 8 | @interface SquareLayout : UICollectionViewLayout 9 | 10 | @end 11 | -------------------------------------------------------------------------------- /UIollectionViewLayout/自定义布局/SquareLayout.m: -------------------------------------------------------------------------------- 1 | // 2 | // SquareLayout.m 3 | // 01-百思不得其姐 4 | // 5 | // Created by 李攀祥 on 16/3/8. 6 | // Copyright © 2016年 李攀祥. All rights reserved. 7 | // 8 | 9 | #import "SquareLayout.h" 10 | 11 | @interface SquareLayout () 12 | /** attrs的数组 */ 13 | @property(nonatomic,strong)NSMutableArray * attrsArr; 14 | @end 15 | @implementation SquareLayout 16 | 17 | -(NSMutableArray *)attrsArr 18 | { 19 | if(!_attrsArr){ 20 | _attrsArr=[[NSMutableArray alloc] init]; 21 | } 22 | return _attrsArr; 23 | } 24 | 25 | -(void)prepareLayout 26 | { 27 | [super prepareLayout]; 28 | [self.attrsArr removeAllObjects]; 29 | NSInteger count =[self.collectionView numberOfItemsInSection:0]; 30 | for (int i=0; i *)layoutAttributesForElementsInRect:(CGRect)rect 38 | { 39 | return self.attrsArr; 40 | } 41 | 42 | #pragma mark ---- 返回CollectionView的内容大小 43 | /*! 44 | * 如果不设置这个的话 CollectionView就不能滑动 45 | */ 46 | -(CGSize)collectionViewContentSize 47 | { 48 | int count =(int)[self.collectionView numberOfItemsInSection:0]; 49 | int rows=(count +3 -1)/3; 50 | CGFloat rowH = self.collectionView.frame.size.width/2; 51 | if ((count)%6==2|(count)%6==4) { 52 | return CGSizeMake(0, rows * rowH-rowH/2); 53 | }else{ 54 | return CGSizeMake(0, rows*rowH); 55 | } 56 | } 57 | 58 | 59 | 60 | -(UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath 61 | { 62 | CGFloat width =self.collectionView.frame.size.width*0.5; 63 | UICollectionViewLayoutAttributes * attrs=[UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath]; 64 | CGFloat height =width; 65 | NSInteger i=indexPath.item; 66 | if (i==0) { 67 | attrs.frame = CGRectMake(0, 0, width, height); 68 | }else if (i==1){ 69 | attrs.frame = CGRectMake(width, 0, width, height/2); 70 | }else if (i==2){ 71 | attrs.frame = CGRectMake(width, height/2, width, height/2); 72 | }else if (i==3){ 73 | attrs.frame = CGRectMake(0, height, width, height/2); 74 | }else if (i==4){ 75 | attrs.frame = CGRectMake(0, height+height/2, width, height/2); 76 | }else if (i==5){ 77 | attrs.frame = CGRectMake(width, height, width, height); 78 | }else{ 79 | UICollectionViewLayoutAttributes *lastAttrs = self.attrsArr[i-6]; 80 | CGRect frame = lastAttrs.frame; 81 | frame.origin.y+=2 * height; 82 | attrs.frame=frame; 83 | } 84 | /* 85 | if ((i+1)%6==1|(i+1)%6==0) { 86 | int k; 87 | //TODO:floor()这个是向上取整 88 | if ((i+1)%6==1) { 89 | k = floor((i+1)/6+1)*2-2; 90 | }else{ 91 | k = floor((i+1)/6)*2-1; 92 | } 93 | CGFloat height = width; 94 | CGFloat x = (i+1)%6==0 ?width:0; 95 | attrs.frame = CGRectMake(x,k*height , width,height); 96 | }else{ 97 | int j; 98 | if ((i+1)%6==2) { 99 | j = floor((i+1)/6+1)*4-4; 100 | }else if((i+1)%6==3){ 101 | j = floor((i+1)/6+1)*4-3; 102 | }else if ((i+1)%6==4){ 103 | j = floor((i+1)/6+1)*4-2; 104 | }else{ 105 | j = floor((i+1)/6+1)*4-1; 106 | } 107 | CGFloat height = width/2; 108 | CGFloat x = (i+1)%6==3|(i+1)%6==2?width:0; 109 | attrs.frame = CGRectMake(x, j*height, width, height); 110 | } 111 | */ 112 | return attrs; 113 | } 114 | 115 | @end 116 | -------------------------------------------------------------------------------- /UIollectionViewLayoutTests/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 | -------------------------------------------------------------------------------- /UIollectionViewLayoutTests/UIollectionViewLayoutTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIollectionViewLayoutTests.m 3 | // UIollectionViewLayoutTests 4 | // 5 | // Created by 李攀祥 on 16/3/12. 6 | // Copyright © 2016年 李攀祥. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface UIollectionViewLayoutTests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation UIollectionViewLayoutTests 16 | 17 | - (void)setUp { 18 | [super setUp]; 19 | // Put setup code here. This method is called before the invocation of each test method in the class. 20 | } 21 | 22 | - (void)tearDown { 23 | // Put teardown code here. This method is called after the invocation of each test method in the class. 24 | [super tearDown]; 25 | } 26 | 27 | - (void)testExample { 28 | // This is an example of a functional test case. 29 | // Use XCTAssert and related functions to verify your tests produce the correct results. 30 | } 31 | 32 | - (void)testPerformanceExample { 33 | // This is an example of a performance test case. 34 | [self measureBlock:^{ 35 | // Put the code you want to measure the time of here. 36 | }]; 37 | } 38 | 39 | @end 40 | -------------------------------------------------------------------------------- /UIollectionViewLayoutUITests/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 | -------------------------------------------------------------------------------- /UIollectionViewLayoutUITests/UIollectionViewLayoutUITests.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIollectionViewLayoutUITests.m 3 | // UIollectionViewLayoutUITests 4 | // 5 | // Created by 李攀祥 on 16/3/12. 6 | // Copyright © 2016年 李攀祥. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface UIollectionViewLayoutUITests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation UIollectionViewLayoutUITests 16 | 17 | - (void)setUp { 18 | [super setUp]; 19 | 20 | // Put setup code here. This method is called before the invocation of each test method in the class. 21 | 22 | // In UI tests it is usually best to stop immediately when a failure occurs. 23 | self.continueAfterFailure = NO; 24 | // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method. 25 | [[[XCUIApplication alloc] init] launch]; 26 | 27 | // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this. 28 | } 29 | 30 | - (void)tearDown { 31 | // Put teardown code here. This method is called after the invocation of each test method in the class. 32 | [super tearDown]; 33 | } 34 | 35 | - (void)testExample { 36 | // Use recording to get started writing UI tests. 37 | // Use XCTAssert and related functions to verify your tests produce the correct results. 38 | } 39 | 40 | @end 41 | --------------------------------------------------------------------------------