├── .gitignore ├── IGListKitDemo.xcodeproj ├── project.pbxproj └── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ └── IDEWorkspaceChecks.plist ├── IGListKitDemo.xcworkspace ├── contents.xcworkspacedata └── xcshareddata │ └── IDEWorkspaceChecks.plist ├── IGListKitDemo ├── AppDelegate.h ├── AppDelegate.m ├── Assets.xcassets │ ├── AppIcon.appiconset │ │ └── Contents.json │ ├── Contents.json │ ├── arrow_down.imageset │ │ ├── Contents.json │ │ └── arrow_down@2x.png │ ├── comment.imageset │ │ ├── Contents.json │ │ └── comment.png │ ├── praise.imageset │ │ ├── Contents.json │ │ └── praise.png │ └── praise_selected.imageset │ │ ├── Contents.json │ │ └── praise_selected.png ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard ├── CellModels │ ├── CommentCollectionCellModel.h │ ├── CommentCollectionCellModel.m │ ├── FavorCollectionCellModel.h │ ├── FavorCollectionCellModel.m │ ├── ImagesCollectionCellModel.h │ ├── ImagesCollectionCellModel.m │ ├── UserInfoCellModel.h │ └── UserInfoCellModel.m ├── CollectionViewController │ ├── BaseCollectionViewController.h │ ├── BaseCollectionViewController.m │ ├── FifthViewController.h │ ├── FifthViewController.m │ ├── ForthViewController.h │ ├── ForthViewController.m │ ├── OneCollectionViewController.h │ ├── OneCollectionViewController.m │ ├── SecondCollectionViewController.h │ ├── SecondCollectionViewController.m │ ├── SixthViewController.h │ ├── SixthViewController.m │ ├── ThirdViewController.h │ └── ThirdViewController.m ├── Info.plist ├── JsonTool │ ├── JsonTool.h │ └── JsonTool.m ├── Models │ ├── ADModel.h │ ├── ADModel.m │ ├── Comment.h │ ├── Comment.m │ ├── FeedModel.h │ └── FeedModel.m ├── NSArray+FP │ ├── NSArray+FP.h │ └── NSArray+FP.m ├── SectionController │ ├── AdSectionController.h │ ├── AdSectionController.m │ ├── CommentSectionController.h │ ├── CommentSectionController.m │ ├── ContentSectionController.h │ ├── ContentSectionController.m │ ├── FavorSectionController.h │ ├── FavorSectionController.m │ ├── FeedBindingSectionController.h │ ├── FeedBindingSectionController.m │ ├── FeedSectionController.h │ ├── FeedSectionController.m │ ├── ImageSectionController.h │ ├── ImageSectionController.m │ ├── UserInfoSectionController.h │ └── UserInfoSectionController.m ├── UIImage+Extension │ ├── UIImage+Extension.h │ └── UIImage+Extension.m ├── ViewController.h ├── ViewController.m ├── Views │ ├── AdCollectionCell.h │ ├── AdCollectionCell.m │ ├── AdCollectionCell.xib │ ├── CommentCollectionCell.h │ ├── CommentCollectionCell.m │ ├── CommentCollectionCell.xib │ ├── ContentCollectionCell.h │ ├── ContentCollectionCell.m │ ├── ContentCollectionCell.xib │ ├── FavorCollectionCell.h │ ├── FavorCollectionCell.m │ ├── FavorCollectionCell.xib │ ├── ImageCell.h │ ├── ImageCell.m │ ├── ImageCell.xib │ ├── ImagesCollectionCell.h │ ├── ImagesCollectionCell.m │ ├── ImagesCollectionCell.xib │ ├── UserInfoCell.h │ ├── UserInfoCell.m │ └── UserInfoCell.xib ├── data1.json ├── data2.json ├── data3.json ├── data4.json ├── data5.json └── main.m ├── Podfile └── Podfile.lock /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 4 | 5 | ## Build generated 6 | build/ 7 | DerivedData/ 8 | 9 | ## Various settings 10 | *.pbxuser 11 | !default.pbxuser 12 | *.mode1v3 13 | !default.mode1v3 14 | *.mode2v3 15 | !default.mode2v3 16 | *.perspectivev3 17 | !default.perspectivev3 18 | xcuserdata/ 19 | 20 | ## Other 21 | *.moved-aside 22 | *.xccheckout 23 | *.xcscmblueprint 24 | 25 | ## Obj-C/Swift specific 26 | *.hmap 27 | *.ipa 28 | *.dSYM.zip 29 | *.dSYM 30 | 31 | # CocoaPods 32 | # 33 | # We recommend against adding the Pods directory to your .gitignore. However 34 | # you should judge for yourself, the pros and cons are mentioned at: 35 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 36 | # 37 | Pods/ 38 | 39 | # Carthage 40 | # 41 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 42 | # Carthage/Checkouts 43 | 44 | Carthage/Build 45 | 46 | # fastlane 47 | # 48 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 49 | # screenshots whenever they are needed. 50 | # For more information about the recommended setup visit: 51 | # https://docs.fastlane.tools/best-practices/source-control/#source-control 52 | 53 | fastlane/report.xml 54 | fastlane/Preview.html 55 | fastlane/screenshots/**/*.png 56 | fastlane/test_output 57 | 58 | # Code Injection 59 | # 60 | # After new code Injection tools there's a generated folder /iOSInjectionProject 61 | # https://github.com/johnno1962/injectionforxcode 62 | 63 | iOSInjectionProject 64 | -------------------------------------------------------------------------------- /IGListKitDemo.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 50; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 48AF787781767D58C6447313 /* libPods-IGListKitDemo.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 47408D0E5DA74955BA895E4B /* libPods-IGListKitDemo.a */; }; 11 | 8407BB6A20C8271400AB6C0C /* data4.json in Resources */ = {isa = PBXBuildFile; fileRef = 8407BB6920C8271400AB6C0C /* data4.json */; }; 12 | 8407BB6D20C828A800AB6C0C /* Comment.m in Sources */ = {isa = PBXBuildFile; fileRef = 8407BB6C20C828A800AB6C0C /* Comment.m */; }; 13 | 8407BB7020C82AA700AB6C0C /* ForthViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8407BB6F20C82AA700AB6C0C /* ForthViewController.m */; }; 14 | 8407BB7320C82AEE00AB6C0C /* FeedSectionController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8407BB7220C82AEE00AB6C0C /* FeedSectionController.m */; }; 15 | 8407BB7720C8308700AB6C0C /* CommentCollectionCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 8407BB7520C8308700AB6C0C /* CommentCollectionCell.m */; }; 16 | 8407BB7820C8308700AB6C0C /* CommentCollectionCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 8407BB7620C8308700AB6C0C /* CommentCollectionCell.xib */; }; 17 | 8407BB7B20C8334F00AB6C0C /* CommentCollectionCellModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 8407BB7A20C8334F00AB6C0C /* CommentCollectionCellModel.m */; }; 18 | 8415066421A99A5100348E27 /* FeedBindingSectionController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8415066321A99A5100348E27 /* FeedBindingSectionController.m */; }; 19 | 8415066721A99E3100348E27 /* SixthViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8415066621A99E3100348E27 /* SixthViewController.m */; }; 20 | 8437161520C3902E00AC5BDF /* data3.json in Resources */ = {isa = PBXBuildFile; fileRef = 8437161420C3902E00AC5BDF /* data3.json */; }; 21 | 8437161820C4364300AC5BDF /* ThirdViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8437161720C4364300AC5BDF /* ThirdViewController.m */; }; 22 | 8437161B20C4379B00AC5BDF /* FavorSectionController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8437161A20C4379B00AC5BDF /* FavorSectionController.m */; }; 23 | 8437161F20C437B500AC5BDF /* FavorCollectionCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 8437161D20C437B500AC5BDF /* FavorCollectionCell.m */; }; 24 | 8437162020C437B500AC5BDF /* FavorCollectionCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 8437161E20C437B500AC5BDF /* FavorCollectionCell.xib */; }; 25 | 8437162320C4390300AC5BDF /* FavorCollectionCellModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 8437162220C4390300AC5BDF /* FavorCollectionCellModel.m */; }; 26 | 84446EE220BC3BDB0068BC6D /* FeedModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 84446EE120BC3BDB0068BC6D /* FeedModel.m */; }; 27 | 84446EF120BC3EF50068BC6D /* JsonTool.m in Sources */ = {isa = PBXBuildFile; fileRef = 84446EEF20BC3EF50068BC6D /* JsonTool.m */; }; 28 | 84446EF520BC42320068BC6D /* UserInfoCellModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 84446EF420BC42320068BC6D /* UserInfoCellModel.m */; }; 29 | 84446EF820BC465C0068BC6D /* ContentSectionController.m in Sources */ = {isa = PBXBuildFile; fileRef = 84446EF720BC465C0068BC6D /* ContentSectionController.m */; }; 30 | 84446EFC20BC469F0068BC6D /* ContentCollectionCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 84446EFA20BC469F0068BC6D /* ContentCollectionCell.m */; }; 31 | 84446EFD20BC469F0068BC6D /* ContentCollectionCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 84446EFB20BC469F0068BC6D /* ContentCollectionCell.xib */; }; 32 | 84A0136120B056A800204A8D /* data2.json in Resources */ = {isa = PBXBuildFile; fileRef = 84A0136020B056A800204A8D /* data2.json */; }; 33 | 84A5DEF120B7008D000A33CB /* OneCollectionViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 84A5DEF020B7008D000A33CB /* OneCollectionViewController.m */; }; 34 | 84A5DEF420B700C3000A33CB /* BaseCollectionViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 84A5DEF320B700C3000A33CB /* BaseCollectionViewController.m */; }; 35 | 84A5DEF720B705F2000A33CB /* UserInfoSectionController.m in Sources */ = {isa = PBXBuildFile; fileRef = 84A5DEF620B705F2000A33CB /* UserInfoSectionController.m */; }; 36 | 84A5DEFC20B70625000A33CB /* UserInfoCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 84A5DEFA20B70625000A33CB /* UserInfoCell.m */; }; 37 | 84A5DEFD20B70625000A33CB /* UserInfoCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 84A5DEFB20B70625000A33CB /* UserInfoCell.xib */; }; 38 | 84BB8DCC20C6E61C00A07B47 /* CommentSectionController.m in Sources */ = {isa = PBXBuildFile; fileRef = 84BB8DCB20C6E61C00A07B47 /* CommentSectionController.m */; }; 39 | 84D1204320ADC25B00AF1894 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 84D1204220ADC25B00AF1894 /* AppDelegate.m */; }; 40 | 84D1204620ADC25B00AF1894 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 84D1204520ADC25B00AF1894 /* ViewController.m */; }; 41 | 84D1204920ADC25B00AF1894 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 84D1204720ADC25B00AF1894 /* Main.storyboard */; }; 42 | 84D1204B20ADC25C00AF1894 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 84D1204A20ADC25C00AF1894 /* Assets.xcassets */; }; 43 | 84D1204E20ADC25C00AF1894 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 84D1204C20ADC25C00AF1894 /* LaunchScreen.storyboard */; }; 44 | 84D1205120ADC25C00AF1894 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 84D1205020ADC25C00AF1894 /* main.m */; }; 45 | 84D1205820ADC85B00AF1894 /* data1.json in Resources */ = {isa = PBXBuildFile; fileRef = 84D1205720ADC85B00AF1894 /* data1.json */; }; 46 | 84E1099D20BEE7EF00CB590E /* SecondCollectionViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 84E1099C20BEE7EF00CB590E /* SecondCollectionViewController.m */; }; 47 | 84E109A120BEE9A000CB590E /* ImagesCollectionCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 84E1099F20BEE9A000CB590E /* ImagesCollectionCell.m */; }; 48 | 84E109A220BEE9A000CB590E /* ImagesCollectionCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 84E109A020BEE9A000CB590E /* ImagesCollectionCell.xib */; }; 49 | 84E109A620BEEA5C00CB590E /* ImageCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 84E109A420BEEA5C00CB590E /* ImageCell.m */; }; 50 | 84E109A720BEEA5C00CB590E /* ImageCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 84E109A520BEEA5C00CB590E /* ImageCell.xib */; }; 51 | 84E109AA20BEEC6000CB590E /* ImagesCollectionCellModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 84E109A920BEEC6000CB590E /* ImagesCollectionCellModel.m */; }; 52 | 84E109B320BEED4C00CB590E /* UIImage+Extension.m in Sources */ = {isa = PBXBuildFile; fileRef = 84E109AC20BEED4B00CB590E /* UIImage+Extension.m */; }; 53 | 84E109B520BEED4C00CB590E /* NSArray+FP.m in Sources */ = {isa = PBXBuildFile; fileRef = 84E109B020BEED4B00CB590E /* NSArray+FP.m */; }; 54 | 84E109B820BEF00C00CB590E /* ImageSectionController.m in Sources */ = {isa = PBXBuildFile; fileRef = 84E109B720BEF00C00CB590E /* ImageSectionController.m */; }; 55 | 84E16F4020E127D1002A3BED /* data5.json in Resources */ = {isa = PBXBuildFile; fileRef = 84E16F3F20E127D1002A3BED /* data5.json */; }; 56 | 84E16F4320E128F7002A3BED /* ADModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 84E16F4220E128F7002A3BED /* ADModel.m */; }; 57 | 84E16F4620E129A2002A3BED /* FifthViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 84E16F4520E129A2002A3BED /* FifthViewController.m */; }; 58 | 84E16F4C20E12EB6002A3BED /* AdSectionController.m in Sources */ = {isa = PBXBuildFile; fileRef = 84E16F4B20E12EB6002A3BED /* AdSectionController.m */; }; 59 | 84E16F5520E144ED002A3BED /* AdCollectionCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 84E16F5320E144ED002A3BED /* AdCollectionCell.m */; }; 60 | 84E16F5620E144ED002A3BED /* AdCollectionCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 84E16F5420E144ED002A3BED /* AdCollectionCell.xib */; }; 61 | /* End PBXBuildFile section */ 62 | 63 | /* Begin PBXFileReference section */ 64 | 47408D0E5DA74955BA895E4B /* libPods-IGListKitDemo.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-IGListKitDemo.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 65 | 8407BB6920C8271400AB6C0C /* data4.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = data4.json; sourceTree = ""; }; 66 | 8407BB6B20C828A800AB6C0C /* Comment.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Comment.h; sourceTree = ""; }; 67 | 8407BB6C20C828A800AB6C0C /* Comment.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = Comment.m; sourceTree = ""; }; 68 | 8407BB6E20C82AA700AB6C0C /* ForthViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ForthViewController.h; sourceTree = ""; }; 69 | 8407BB6F20C82AA700AB6C0C /* ForthViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ForthViewController.m; sourceTree = ""; }; 70 | 8407BB7120C82AEE00AB6C0C /* FeedSectionController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FeedSectionController.h; sourceTree = ""; }; 71 | 8407BB7220C82AEE00AB6C0C /* FeedSectionController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FeedSectionController.m; sourceTree = ""; }; 72 | 8407BB7420C8308700AB6C0C /* CommentCollectionCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CommentCollectionCell.h; sourceTree = ""; }; 73 | 8407BB7520C8308700AB6C0C /* CommentCollectionCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CommentCollectionCell.m; sourceTree = ""; }; 74 | 8407BB7620C8308700AB6C0C /* CommentCollectionCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = CommentCollectionCell.xib; sourceTree = ""; }; 75 | 8407BB7920C8334F00AB6C0C /* CommentCollectionCellModel.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CommentCollectionCellModel.h; sourceTree = ""; }; 76 | 8407BB7A20C8334F00AB6C0C /* CommentCollectionCellModel.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CommentCollectionCellModel.m; sourceTree = ""; }; 77 | 8415066221A99A5100348E27 /* FeedBindingSectionController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FeedBindingSectionController.h; sourceTree = ""; }; 78 | 8415066321A99A5100348E27 /* FeedBindingSectionController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FeedBindingSectionController.m; sourceTree = ""; }; 79 | 8415066521A99E3100348E27 /* SixthViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SixthViewController.h; sourceTree = ""; }; 80 | 8415066621A99E3100348E27 /* SixthViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SixthViewController.m; sourceTree = ""; }; 81 | 8437161420C3902E00AC5BDF /* data3.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = data3.json; sourceTree = ""; }; 82 | 8437161620C4364300AC5BDF /* ThirdViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ThirdViewController.h; sourceTree = ""; }; 83 | 8437161720C4364300AC5BDF /* ThirdViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ThirdViewController.m; sourceTree = ""; }; 84 | 8437161920C4379B00AC5BDF /* FavorSectionController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FavorSectionController.h; sourceTree = ""; }; 85 | 8437161A20C4379B00AC5BDF /* FavorSectionController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FavorSectionController.m; sourceTree = ""; }; 86 | 8437161C20C437B500AC5BDF /* FavorCollectionCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FavorCollectionCell.h; sourceTree = ""; }; 87 | 8437161D20C437B500AC5BDF /* FavorCollectionCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FavorCollectionCell.m; sourceTree = ""; }; 88 | 8437161E20C437B500AC5BDF /* FavorCollectionCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = FavorCollectionCell.xib; sourceTree = ""; }; 89 | 8437162120C4390300AC5BDF /* FavorCollectionCellModel.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FavorCollectionCellModel.h; sourceTree = ""; }; 90 | 8437162220C4390300AC5BDF /* FavorCollectionCellModel.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FavorCollectionCellModel.m; sourceTree = ""; }; 91 | 84446EE020BC3BDB0068BC6D /* FeedModel.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FeedModel.h; sourceTree = ""; }; 92 | 84446EE120BC3BDB0068BC6D /* FeedModel.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FeedModel.m; sourceTree = ""; }; 93 | 84446EEF20BC3EF50068BC6D /* JsonTool.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = JsonTool.m; sourceTree = ""; }; 94 | 84446EF020BC3EF50068BC6D /* JsonTool.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JsonTool.h; sourceTree = ""; }; 95 | 84446EF320BC42320068BC6D /* UserInfoCellModel.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = UserInfoCellModel.h; sourceTree = ""; }; 96 | 84446EF420BC42320068BC6D /* UserInfoCellModel.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = UserInfoCellModel.m; sourceTree = ""; }; 97 | 84446EF620BC465C0068BC6D /* ContentSectionController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ContentSectionController.h; sourceTree = ""; }; 98 | 84446EF720BC465C0068BC6D /* ContentSectionController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ContentSectionController.m; sourceTree = ""; }; 99 | 84446EF920BC469F0068BC6D /* ContentCollectionCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ContentCollectionCell.h; sourceTree = ""; }; 100 | 84446EFA20BC469F0068BC6D /* ContentCollectionCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ContentCollectionCell.m; sourceTree = ""; }; 101 | 84446EFB20BC469F0068BC6D /* ContentCollectionCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = ContentCollectionCell.xib; sourceTree = ""; }; 102 | 84A0136020B056A800204A8D /* data2.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = data2.json; sourceTree = ""; }; 103 | 84A5DEEF20B7008D000A33CB /* OneCollectionViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OneCollectionViewController.h; sourceTree = ""; }; 104 | 84A5DEF020B7008D000A33CB /* OneCollectionViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = OneCollectionViewController.m; sourceTree = ""; }; 105 | 84A5DEF220B700C3000A33CB /* BaseCollectionViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = BaseCollectionViewController.h; sourceTree = ""; }; 106 | 84A5DEF320B700C3000A33CB /* BaseCollectionViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = BaseCollectionViewController.m; sourceTree = ""; }; 107 | 84A5DEF520B705F2000A33CB /* UserInfoSectionController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = UserInfoSectionController.h; sourceTree = ""; }; 108 | 84A5DEF620B705F2000A33CB /* UserInfoSectionController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = UserInfoSectionController.m; sourceTree = ""; }; 109 | 84A5DEF920B70625000A33CB /* UserInfoCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = UserInfoCell.h; sourceTree = ""; }; 110 | 84A5DEFA20B70625000A33CB /* UserInfoCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = UserInfoCell.m; sourceTree = ""; }; 111 | 84A5DEFB20B70625000A33CB /* UserInfoCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = UserInfoCell.xib; sourceTree = ""; }; 112 | 84BB8DCA20C6E61C00A07B47 /* CommentSectionController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CommentSectionController.h; sourceTree = ""; }; 113 | 84BB8DCB20C6E61C00A07B47 /* CommentSectionController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CommentSectionController.m; sourceTree = ""; }; 114 | 84D1203E20ADC25B00AF1894 /* IGListKitDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = IGListKitDemo.app; sourceTree = BUILT_PRODUCTS_DIR; }; 115 | 84D1204120ADC25B00AF1894 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 116 | 84D1204220ADC25B00AF1894 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 117 | 84D1204420ADC25B00AF1894 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; 118 | 84D1204520ADC25B00AF1894 /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; 119 | 84D1204820ADC25B00AF1894 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 120 | 84D1204A20ADC25C00AF1894 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 121 | 84D1204D20ADC25C00AF1894 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 122 | 84D1204F20ADC25C00AF1894 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 123 | 84D1205020ADC25C00AF1894 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 124 | 84D1205720ADC85B00AF1894 /* data1.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = data1.json; sourceTree = ""; }; 125 | 84E1099B20BEE7EF00CB590E /* SecondCollectionViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SecondCollectionViewController.h; sourceTree = ""; }; 126 | 84E1099C20BEE7EF00CB590E /* SecondCollectionViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SecondCollectionViewController.m; sourceTree = ""; }; 127 | 84E1099E20BEE9A000CB590E /* ImagesCollectionCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ImagesCollectionCell.h; sourceTree = ""; }; 128 | 84E1099F20BEE9A000CB590E /* ImagesCollectionCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ImagesCollectionCell.m; sourceTree = ""; }; 129 | 84E109A020BEE9A000CB590E /* ImagesCollectionCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = ImagesCollectionCell.xib; sourceTree = ""; }; 130 | 84E109A320BEEA5C00CB590E /* ImageCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ImageCell.h; sourceTree = ""; }; 131 | 84E109A420BEEA5C00CB590E /* ImageCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ImageCell.m; sourceTree = ""; }; 132 | 84E109A520BEEA5C00CB590E /* ImageCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = ImageCell.xib; sourceTree = ""; }; 133 | 84E109A820BEEC6000CB590E /* ImagesCollectionCellModel.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ImagesCollectionCellModel.h; sourceTree = ""; }; 134 | 84E109A920BEEC6000CB590E /* ImagesCollectionCellModel.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ImagesCollectionCellModel.m; sourceTree = ""; }; 135 | 84E109AC20BEED4B00CB590E /* UIImage+Extension.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIImage+Extension.m"; sourceTree = ""; }; 136 | 84E109AD20BEED4B00CB590E /* UIImage+Extension.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIImage+Extension.h"; sourceTree = ""; }; 137 | 84E109B020BEED4B00CB590E /* NSArray+FP.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSArray+FP.m"; sourceTree = ""; }; 138 | 84E109B120BEED4B00CB590E /* NSArray+FP.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSArray+FP.h"; sourceTree = ""; }; 139 | 84E109B620BEF00C00CB590E /* ImageSectionController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ImageSectionController.h; sourceTree = ""; }; 140 | 84E109B720BEF00C00CB590E /* ImageSectionController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ImageSectionController.m; sourceTree = ""; }; 141 | 84E16F3F20E127D1002A3BED /* data5.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = data5.json; sourceTree = ""; }; 142 | 84E16F4120E128F7002A3BED /* ADModel.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ADModel.h; sourceTree = ""; }; 143 | 84E16F4220E128F7002A3BED /* ADModel.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ADModel.m; sourceTree = ""; }; 144 | 84E16F4420E129A2002A3BED /* FifthViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FifthViewController.h; sourceTree = ""; }; 145 | 84E16F4520E129A2002A3BED /* FifthViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FifthViewController.m; sourceTree = ""; }; 146 | 84E16F4A20E12EB6002A3BED /* AdSectionController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AdSectionController.h; sourceTree = ""; }; 147 | 84E16F4B20E12EB6002A3BED /* AdSectionController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AdSectionController.m; sourceTree = ""; }; 148 | 84E16F5220E144ED002A3BED /* AdCollectionCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AdCollectionCell.h; sourceTree = ""; }; 149 | 84E16F5320E144ED002A3BED /* AdCollectionCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AdCollectionCell.m; sourceTree = ""; }; 150 | 84E16F5420E144ED002A3BED /* AdCollectionCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = AdCollectionCell.xib; sourceTree = ""; }; 151 | 8D2F230AA8CAD5D5BCCA81A0 /* Pods-IGListKitDemo.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-IGListKitDemo.release.xcconfig"; path = "Pods/Target Support Files/Pods-IGListKitDemo/Pods-IGListKitDemo.release.xcconfig"; sourceTree = ""; }; 152 | E7F92F691F6620D0D1F62EE6 /* Pods-IGListKitDemo.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-IGListKitDemo.debug.xcconfig"; path = "Pods/Target Support Files/Pods-IGListKitDemo/Pods-IGListKitDemo.debug.xcconfig"; sourceTree = ""; }; 153 | /* End PBXFileReference section */ 154 | 155 | /* Begin PBXFrameworksBuildPhase section */ 156 | 84D1203B20ADC25B00AF1894 /* Frameworks */ = { 157 | isa = PBXFrameworksBuildPhase; 158 | buildActionMask = 2147483647; 159 | files = ( 160 | 48AF787781767D58C6447313 /* libPods-IGListKitDemo.a in Frameworks */, 161 | ); 162 | runOnlyForDeploymentPostprocessing = 0; 163 | }; 164 | /* End PBXFrameworksBuildPhase section */ 165 | 166 | /* Begin PBXGroup section */ 167 | 1CA05C7301F2FBBFA755EF03 /* Pods */ = { 168 | isa = PBXGroup; 169 | children = ( 170 | E7F92F691F6620D0D1F62EE6 /* Pods-IGListKitDemo.debug.xcconfig */, 171 | 8D2F230AA8CAD5D5BCCA81A0 /* Pods-IGListKitDemo.release.xcconfig */, 172 | ); 173 | name = Pods; 174 | sourceTree = ""; 175 | }; 176 | 3E1AFDE61F0F1E0FFFA2360B /* Frameworks */ = { 177 | isa = PBXGroup; 178 | children = ( 179 | 47408D0E5DA74955BA895E4B /* libPods-IGListKitDemo.a */, 180 | ); 181 | name = Frameworks; 182 | sourceTree = ""; 183 | }; 184 | 84446EDF20BC38EC0068BC6D /* Models */ = { 185 | isa = PBXGroup; 186 | children = ( 187 | 84446EE020BC3BDB0068BC6D /* FeedModel.h */, 188 | 84446EE120BC3BDB0068BC6D /* FeedModel.m */, 189 | 8407BB6B20C828A800AB6C0C /* Comment.h */, 190 | 8407BB6C20C828A800AB6C0C /* Comment.m */, 191 | 84E16F4120E128F7002A3BED /* ADModel.h */, 192 | 84E16F4220E128F7002A3BED /* ADModel.m */, 193 | ); 194 | path = Models; 195 | sourceTree = ""; 196 | }; 197 | 84446EEE20BC3EF50068BC6D /* JsonTool */ = { 198 | isa = PBXGroup; 199 | children = ( 200 | 84446EF020BC3EF50068BC6D /* JsonTool.h */, 201 | 84446EEF20BC3EF50068BC6D /* JsonTool.m */, 202 | ); 203 | path = JsonTool; 204 | sourceTree = ""; 205 | }; 206 | 84446EF220BC42160068BC6D /* CellModels */ = { 207 | isa = PBXGroup; 208 | children = ( 209 | 84446EF320BC42320068BC6D /* UserInfoCellModel.h */, 210 | 84446EF420BC42320068BC6D /* UserInfoCellModel.m */, 211 | 84E109A820BEEC6000CB590E /* ImagesCollectionCellModel.h */, 212 | 84E109A920BEEC6000CB590E /* ImagesCollectionCellModel.m */, 213 | 8437162120C4390300AC5BDF /* FavorCollectionCellModel.h */, 214 | 8437162220C4390300AC5BDF /* FavorCollectionCellModel.m */, 215 | 8407BB7920C8334F00AB6C0C /* CommentCollectionCellModel.h */, 216 | 8407BB7A20C8334F00AB6C0C /* CommentCollectionCellModel.m */, 217 | ); 218 | path = CellModels; 219 | sourceTree = ""; 220 | }; 221 | 84A5DEEA20B6FF54000A33CB /* CollectionViewController */ = { 222 | isa = PBXGroup; 223 | children = ( 224 | 84A5DEF220B700C3000A33CB /* BaseCollectionViewController.h */, 225 | 84A5DEF320B700C3000A33CB /* BaseCollectionViewController.m */, 226 | 84A5DEEF20B7008D000A33CB /* OneCollectionViewController.h */, 227 | 84A5DEF020B7008D000A33CB /* OneCollectionViewController.m */, 228 | 84E1099B20BEE7EF00CB590E /* SecondCollectionViewController.h */, 229 | 84E1099C20BEE7EF00CB590E /* SecondCollectionViewController.m */, 230 | 8437161620C4364300AC5BDF /* ThirdViewController.h */, 231 | 8437161720C4364300AC5BDF /* ThirdViewController.m */, 232 | 8407BB6E20C82AA700AB6C0C /* ForthViewController.h */, 233 | 8407BB6F20C82AA700AB6C0C /* ForthViewController.m */, 234 | 84E16F4420E129A2002A3BED /* FifthViewController.h */, 235 | 84E16F4520E129A2002A3BED /* FifthViewController.m */, 236 | 8415066521A99E3100348E27 /* SixthViewController.h */, 237 | 8415066621A99E3100348E27 /* SixthViewController.m */, 238 | ); 239 | path = CollectionViewController; 240 | sourceTree = ""; 241 | }; 242 | 84A5DEEB20B6FF78000A33CB /* SectionController */ = { 243 | isa = PBXGroup; 244 | children = ( 245 | 84A5DEF520B705F2000A33CB /* UserInfoSectionController.h */, 246 | 84A5DEF620B705F2000A33CB /* UserInfoSectionController.m */, 247 | 84446EF620BC465C0068BC6D /* ContentSectionController.h */, 248 | 84446EF720BC465C0068BC6D /* ContentSectionController.m */, 249 | 84E109B620BEF00C00CB590E /* ImageSectionController.h */, 250 | 84E109B720BEF00C00CB590E /* ImageSectionController.m */, 251 | 8437161920C4379B00AC5BDF /* FavorSectionController.h */, 252 | 8437161A20C4379B00AC5BDF /* FavorSectionController.m */, 253 | 84BB8DCA20C6E61C00A07B47 /* CommentSectionController.h */, 254 | 84BB8DCB20C6E61C00A07B47 /* CommentSectionController.m */, 255 | 8407BB7120C82AEE00AB6C0C /* FeedSectionController.h */, 256 | 8407BB7220C82AEE00AB6C0C /* FeedSectionController.m */, 257 | 84E16F4A20E12EB6002A3BED /* AdSectionController.h */, 258 | 84E16F4B20E12EB6002A3BED /* AdSectionController.m */, 259 | 8415066221A99A5100348E27 /* FeedBindingSectionController.h */, 260 | 8415066321A99A5100348E27 /* FeedBindingSectionController.m */, 261 | ); 262 | path = SectionController; 263 | sourceTree = ""; 264 | }; 265 | 84A5DEF820B705F6000A33CB /* Views */ = { 266 | isa = PBXGroup; 267 | children = ( 268 | 84A5DEF920B70625000A33CB /* UserInfoCell.h */, 269 | 84A5DEFA20B70625000A33CB /* UserInfoCell.m */, 270 | 84A5DEFB20B70625000A33CB /* UserInfoCell.xib */, 271 | 84446EF920BC469F0068BC6D /* ContentCollectionCell.h */, 272 | 84446EFA20BC469F0068BC6D /* ContentCollectionCell.m */, 273 | 84446EFB20BC469F0068BC6D /* ContentCollectionCell.xib */, 274 | 84E1099E20BEE9A000CB590E /* ImagesCollectionCell.h */, 275 | 84E1099F20BEE9A000CB590E /* ImagesCollectionCell.m */, 276 | 84E109A020BEE9A000CB590E /* ImagesCollectionCell.xib */, 277 | 84E109A320BEEA5C00CB590E /* ImageCell.h */, 278 | 84E109A420BEEA5C00CB590E /* ImageCell.m */, 279 | 84E109A520BEEA5C00CB590E /* ImageCell.xib */, 280 | 8437161C20C437B500AC5BDF /* FavorCollectionCell.h */, 281 | 8437161D20C437B500AC5BDF /* FavorCollectionCell.m */, 282 | 8437161E20C437B500AC5BDF /* FavorCollectionCell.xib */, 283 | 8407BB7420C8308700AB6C0C /* CommentCollectionCell.h */, 284 | 8407BB7520C8308700AB6C0C /* CommentCollectionCell.m */, 285 | 8407BB7620C8308700AB6C0C /* CommentCollectionCell.xib */, 286 | 84E16F5220E144ED002A3BED /* AdCollectionCell.h */, 287 | 84E16F5320E144ED002A3BED /* AdCollectionCell.m */, 288 | 84E16F5420E144ED002A3BED /* AdCollectionCell.xib */, 289 | ); 290 | path = Views; 291 | sourceTree = ""; 292 | }; 293 | 84D1203520ADC25B00AF1894 = { 294 | isa = PBXGroup; 295 | children = ( 296 | 84D1204020ADC25B00AF1894 /* IGListKitDemo */, 297 | 84D1203F20ADC25B00AF1894 /* Products */, 298 | 1CA05C7301F2FBBFA755EF03 /* Pods */, 299 | 3E1AFDE61F0F1E0FFFA2360B /* Frameworks */, 300 | ); 301 | sourceTree = ""; 302 | }; 303 | 84D1203F20ADC25B00AF1894 /* Products */ = { 304 | isa = PBXGroup; 305 | children = ( 306 | 84D1203E20ADC25B00AF1894 /* IGListKitDemo.app */, 307 | ); 308 | name = Products; 309 | sourceTree = ""; 310 | }; 311 | 84D1204020ADC25B00AF1894 /* IGListKitDemo */ = { 312 | isa = PBXGroup; 313 | children = ( 314 | 84E109AE20BEED4B00CB590E /* NSArray+FP */, 315 | 84E109AB20BEED4B00CB590E /* UIImage+Extension */, 316 | 84446EEE20BC3EF50068BC6D /* JsonTool */, 317 | 84446EDF20BC38EC0068BC6D /* Models */, 318 | 84446EF220BC42160068BC6D /* CellModels */, 319 | 84A5DEF820B705F6000A33CB /* Views */, 320 | 84A5DEEB20B6FF78000A33CB /* SectionController */, 321 | 84A5DEEA20B6FF54000A33CB /* CollectionViewController */, 322 | 84D1204120ADC25B00AF1894 /* AppDelegate.h */, 323 | 84D1204220ADC25B00AF1894 /* AppDelegate.m */, 324 | 84D1204420ADC25B00AF1894 /* ViewController.h */, 325 | 84D1204520ADC25B00AF1894 /* ViewController.m */, 326 | 84D1204720ADC25B00AF1894 /* Main.storyboard */, 327 | 84D1204A20ADC25C00AF1894 /* Assets.xcassets */, 328 | 84D1204C20ADC25C00AF1894 /* LaunchScreen.storyboard */, 329 | 84D1204F20ADC25C00AF1894 /* Info.plist */, 330 | 84D1205020ADC25C00AF1894 /* main.m */, 331 | 84D1205720ADC85B00AF1894 /* data1.json */, 332 | 84A0136020B056A800204A8D /* data2.json */, 333 | 8437161420C3902E00AC5BDF /* data3.json */, 334 | 8407BB6920C8271400AB6C0C /* data4.json */, 335 | 84E16F3F20E127D1002A3BED /* data5.json */, 336 | ); 337 | path = IGListKitDemo; 338 | sourceTree = ""; 339 | }; 340 | 84E109AB20BEED4B00CB590E /* UIImage+Extension */ = { 341 | isa = PBXGroup; 342 | children = ( 343 | 84E109AD20BEED4B00CB590E /* UIImage+Extension.h */, 344 | 84E109AC20BEED4B00CB590E /* UIImage+Extension.m */, 345 | ); 346 | path = "UIImage+Extension"; 347 | sourceTree = ""; 348 | }; 349 | 84E109AE20BEED4B00CB590E /* NSArray+FP */ = { 350 | isa = PBXGroup; 351 | children = ( 352 | 84E109B120BEED4B00CB590E /* NSArray+FP.h */, 353 | 84E109B020BEED4B00CB590E /* NSArray+FP.m */, 354 | ); 355 | path = "NSArray+FP"; 356 | sourceTree = ""; 357 | }; 358 | /* End PBXGroup section */ 359 | 360 | /* Begin PBXNativeTarget section */ 361 | 84D1203D20ADC25B00AF1894 /* IGListKitDemo */ = { 362 | isa = PBXNativeTarget; 363 | buildConfigurationList = 84D1205420ADC25C00AF1894 /* Build configuration list for PBXNativeTarget "IGListKitDemo" */; 364 | buildPhases = ( 365 | 01B2D50C72119C05EA6112B5 /* [CP] Check Pods Manifest.lock */, 366 | 84D1203A20ADC25B00AF1894 /* Sources */, 367 | 84D1203B20ADC25B00AF1894 /* Frameworks */, 368 | 84D1203C20ADC25B00AF1894 /* Resources */, 369 | B35B24CE302DDBA5A7DC8946 /* [CP] Embed Pods Frameworks */, 370 | 7534290F586C34133C69F82D /* [CP] Copy Pods Resources */, 371 | ); 372 | buildRules = ( 373 | ); 374 | dependencies = ( 375 | ); 376 | name = IGListKitDemo; 377 | productName = IGListKitDemo; 378 | productReference = 84D1203E20ADC25B00AF1894 /* IGListKitDemo.app */; 379 | productType = "com.apple.product-type.application"; 380 | }; 381 | /* End PBXNativeTarget section */ 382 | 383 | /* Begin PBXProject section */ 384 | 84D1203620ADC25B00AF1894 /* Project object */ = { 385 | isa = PBXProject; 386 | attributes = { 387 | LastUpgradeCheck = 0930; 388 | ORGANIZATIONNAME = gxy; 389 | TargetAttributes = { 390 | 84D1203D20ADC25B00AF1894 = { 391 | CreatedOnToolsVersion = 9.3.1; 392 | }; 393 | }; 394 | }; 395 | buildConfigurationList = 84D1203920ADC25B00AF1894 /* Build configuration list for PBXProject "IGListKitDemo" */; 396 | compatibilityVersion = "Xcode 9.3"; 397 | developmentRegion = en; 398 | hasScannedForEncodings = 0; 399 | knownRegions = ( 400 | en, 401 | Base, 402 | ); 403 | mainGroup = 84D1203520ADC25B00AF1894; 404 | productRefGroup = 84D1203F20ADC25B00AF1894 /* Products */; 405 | projectDirPath = ""; 406 | projectRoot = ""; 407 | targets = ( 408 | 84D1203D20ADC25B00AF1894 /* IGListKitDemo */, 409 | ); 410 | }; 411 | /* End PBXProject section */ 412 | 413 | /* Begin PBXResourcesBuildPhase section */ 414 | 84D1203C20ADC25B00AF1894 /* Resources */ = { 415 | isa = PBXResourcesBuildPhase; 416 | buildActionMask = 2147483647; 417 | files = ( 418 | 84D1204E20ADC25C00AF1894 /* LaunchScreen.storyboard in Resources */, 419 | 84D1204B20ADC25C00AF1894 /* Assets.xcassets in Resources */, 420 | 84446EFD20BC469F0068BC6D /* ContentCollectionCell.xib in Resources */, 421 | 8437161520C3902E00AC5BDF /* data3.json in Resources */, 422 | 8437162020C437B500AC5BDF /* FavorCollectionCell.xib in Resources */, 423 | 84E109A220BEE9A000CB590E /* ImagesCollectionCell.xib in Resources */, 424 | 84A5DEFD20B70625000A33CB /* UserInfoCell.xib in Resources */, 425 | 84E16F4020E127D1002A3BED /* data5.json in Resources */, 426 | 84D1204920ADC25B00AF1894 /* Main.storyboard in Resources */, 427 | 8407BB6A20C8271400AB6C0C /* data4.json in Resources */, 428 | 84E109A720BEEA5C00CB590E /* ImageCell.xib in Resources */, 429 | 8407BB7820C8308700AB6C0C /* CommentCollectionCell.xib in Resources */, 430 | 84E16F5620E144ED002A3BED /* AdCollectionCell.xib in Resources */, 431 | 84A0136120B056A800204A8D /* data2.json in Resources */, 432 | 84D1205820ADC85B00AF1894 /* data1.json in Resources */, 433 | ); 434 | runOnlyForDeploymentPostprocessing = 0; 435 | }; 436 | /* End PBXResourcesBuildPhase section */ 437 | 438 | /* Begin PBXShellScriptBuildPhase section */ 439 | 01B2D50C72119C05EA6112B5 /* [CP] Check Pods Manifest.lock */ = { 440 | isa = PBXShellScriptBuildPhase; 441 | buildActionMask = 2147483647; 442 | files = ( 443 | ); 444 | inputPaths = ( 445 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 446 | "${PODS_ROOT}/Manifest.lock", 447 | ); 448 | name = "[CP] Check Pods Manifest.lock"; 449 | outputPaths = ( 450 | "$(DERIVED_FILE_DIR)/Pods-IGListKitDemo-checkManifestLockResult.txt", 451 | ); 452 | runOnlyForDeploymentPostprocessing = 0; 453 | shellPath = /bin/sh; 454 | 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"; 455 | showEnvVarsInLog = 0; 456 | }; 457 | 7534290F586C34133C69F82D /* [CP] Copy Pods Resources */ = { 458 | isa = PBXShellScriptBuildPhase; 459 | buildActionMask = 2147483647; 460 | files = ( 461 | ); 462 | inputPaths = ( 463 | ); 464 | name = "[CP] Copy Pods Resources"; 465 | outputPaths = ( 466 | ); 467 | runOnlyForDeploymentPostprocessing = 0; 468 | shellPath = /bin/sh; 469 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-IGListKitDemo/Pods-IGListKitDemo-resources.sh\"\n"; 470 | showEnvVarsInLog = 0; 471 | }; 472 | B35B24CE302DDBA5A7DC8946 /* [CP] Embed Pods Frameworks */ = { 473 | isa = PBXShellScriptBuildPhase; 474 | buildActionMask = 2147483647; 475 | files = ( 476 | ); 477 | inputPaths = ( 478 | ); 479 | name = "[CP] Embed Pods Frameworks"; 480 | outputPaths = ( 481 | ); 482 | runOnlyForDeploymentPostprocessing = 0; 483 | shellPath = /bin/sh; 484 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-IGListKitDemo/Pods-IGListKitDemo-frameworks.sh\"\n"; 485 | showEnvVarsInLog = 0; 486 | }; 487 | /* End PBXShellScriptBuildPhase section */ 488 | 489 | /* Begin PBXSourcesBuildPhase section */ 490 | 84D1203A20ADC25B00AF1894 /* Sources */ = { 491 | isa = PBXSourcesBuildPhase; 492 | buildActionMask = 2147483647; 493 | files = ( 494 | 8437162320C4390300AC5BDF /* FavorCollectionCellModel.m in Sources */, 495 | 84BB8DCC20C6E61C00A07B47 /* CommentSectionController.m in Sources */, 496 | 84446EF120BC3EF50068BC6D /* JsonTool.m in Sources */, 497 | 84E109A620BEEA5C00CB590E /* ImageCell.m in Sources */, 498 | 84E109B320BEED4C00CB590E /* UIImage+Extension.m in Sources */, 499 | 8407BB7B20C8334F00AB6C0C /* CommentCollectionCellModel.m in Sources */, 500 | 84E16F4620E129A2002A3BED /* FifthViewController.m in Sources */, 501 | 8407BB7720C8308700AB6C0C /* CommentCollectionCell.m in Sources */, 502 | 84D1204620ADC25B00AF1894 /* ViewController.m in Sources */, 503 | 84A5DEFC20B70625000A33CB /* UserInfoCell.m in Sources */, 504 | 84446EF820BC465C0068BC6D /* ContentSectionController.m in Sources */, 505 | 8437161B20C4379B00AC5BDF /* FavorSectionController.m in Sources */, 506 | 8437161820C4364300AC5BDF /* ThirdViewController.m in Sources */, 507 | 8415066421A99A5100348E27 /* FeedBindingSectionController.m in Sources */, 508 | 84A5DEF120B7008D000A33CB /* OneCollectionViewController.m in Sources */, 509 | 84E109B820BEF00C00CB590E /* ImageSectionController.m in Sources */, 510 | 84E16F5520E144ED002A3BED /* AdCollectionCell.m in Sources */, 511 | 84E16F4C20E12EB6002A3BED /* AdSectionController.m in Sources */, 512 | 8437161F20C437B500AC5BDF /* FavorCollectionCell.m in Sources */, 513 | 8407BB6D20C828A800AB6C0C /* Comment.m in Sources */, 514 | 84E16F4320E128F7002A3BED /* ADModel.m in Sources */, 515 | 8407BB7020C82AA700AB6C0C /* ForthViewController.m in Sources */, 516 | 84E109A120BEE9A000CB590E /* ImagesCollectionCell.m in Sources */, 517 | 84E1099D20BEE7EF00CB590E /* SecondCollectionViewController.m in Sources */, 518 | 8407BB7320C82AEE00AB6C0C /* FeedSectionController.m in Sources */, 519 | 84446EE220BC3BDB0068BC6D /* FeedModel.m in Sources */, 520 | 84E109AA20BEEC6000CB590E /* ImagesCollectionCellModel.m in Sources */, 521 | 84A5DEF720B705F2000A33CB /* UserInfoSectionController.m in Sources */, 522 | 84446EF520BC42320068BC6D /* UserInfoCellModel.m in Sources */, 523 | 84D1205120ADC25C00AF1894 /* main.m in Sources */, 524 | 84E109B520BEED4C00CB590E /* NSArray+FP.m in Sources */, 525 | 84446EFC20BC469F0068BC6D /* ContentCollectionCell.m in Sources */, 526 | 84A5DEF420B700C3000A33CB /* BaseCollectionViewController.m in Sources */, 527 | 84D1204320ADC25B00AF1894 /* AppDelegate.m in Sources */, 528 | 8415066721A99E3100348E27 /* SixthViewController.m in Sources */, 529 | ); 530 | runOnlyForDeploymentPostprocessing = 0; 531 | }; 532 | /* End PBXSourcesBuildPhase section */ 533 | 534 | /* Begin PBXVariantGroup section */ 535 | 84D1204720ADC25B00AF1894 /* Main.storyboard */ = { 536 | isa = PBXVariantGroup; 537 | children = ( 538 | 84D1204820ADC25B00AF1894 /* Base */, 539 | ); 540 | name = Main.storyboard; 541 | sourceTree = ""; 542 | }; 543 | 84D1204C20ADC25C00AF1894 /* LaunchScreen.storyboard */ = { 544 | isa = PBXVariantGroup; 545 | children = ( 546 | 84D1204D20ADC25C00AF1894 /* Base */, 547 | ); 548 | name = LaunchScreen.storyboard; 549 | sourceTree = ""; 550 | }; 551 | /* End PBXVariantGroup section */ 552 | 553 | /* Begin XCBuildConfiguration section */ 554 | 84D1205220ADC25C00AF1894 /* Debug */ = { 555 | isa = XCBuildConfiguration; 556 | buildSettings = { 557 | ALWAYS_SEARCH_USER_PATHS = NO; 558 | CLANG_ANALYZER_NONNULL = YES; 559 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 560 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 561 | CLANG_CXX_LIBRARY = "libc++"; 562 | CLANG_ENABLE_MODULES = YES; 563 | CLANG_ENABLE_OBJC_ARC = YES; 564 | CLANG_ENABLE_OBJC_WEAK = YES; 565 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 566 | CLANG_WARN_BOOL_CONVERSION = YES; 567 | CLANG_WARN_COMMA = YES; 568 | CLANG_WARN_CONSTANT_CONVERSION = YES; 569 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 570 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 571 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 572 | CLANG_WARN_EMPTY_BODY = YES; 573 | CLANG_WARN_ENUM_CONVERSION = YES; 574 | CLANG_WARN_INFINITE_RECURSION = YES; 575 | CLANG_WARN_INT_CONVERSION = YES; 576 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 577 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 578 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 579 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 580 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 581 | CLANG_WARN_STRICT_PROTOTYPES = YES; 582 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 583 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 584 | CLANG_WARN_UNREACHABLE_CODE = YES; 585 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 586 | CODE_SIGN_IDENTITY = "iPhone Developer"; 587 | COPY_PHASE_STRIP = NO; 588 | DEBUG_INFORMATION_FORMAT = dwarf; 589 | ENABLE_STRICT_OBJC_MSGSEND = YES; 590 | ENABLE_TESTABILITY = YES; 591 | GCC_C_LANGUAGE_STANDARD = gnu11; 592 | GCC_DYNAMIC_NO_PIC = NO; 593 | GCC_NO_COMMON_BLOCKS = YES; 594 | GCC_OPTIMIZATION_LEVEL = 0; 595 | GCC_PREPROCESSOR_DEFINITIONS = ( 596 | "DEBUG=1", 597 | "$(inherited)", 598 | ); 599 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 600 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 601 | GCC_WARN_UNDECLARED_SELECTOR = YES; 602 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 603 | GCC_WARN_UNUSED_FUNCTION = YES; 604 | GCC_WARN_UNUSED_VARIABLE = YES; 605 | IPHONEOS_DEPLOYMENT_TARGET = 11.3; 606 | MTL_ENABLE_DEBUG_INFO = YES; 607 | ONLY_ACTIVE_ARCH = YES; 608 | SDKROOT = iphoneos; 609 | }; 610 | name = Debug; 611 | }; 612 | 84D1205320ADC25C00AF1894 /* Release */ = { 613 | isa = XCBuildConfiguration; 614 | buildSettings = { 615 | ALWAYS_SEARCH_USER_PATHS = NO; 616 | CLANG_ANALYZER_NONNULL = YES; 617 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 618 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 619 | CLANG_CXX_LIBRARY = "libc++"; 620 | CLANG_ENABLE_MODULES = YES; 621 | CLANG_ENABLE_OBJC_ARC = YES; 622 | CLANG_ENABLE_OBJC_WEAK = YES; 623 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 624 | CLANG_WARN_BOOL_CONVERSION = YES; 625 | CLANG_WARN_COMMA = YES; 626 | CLANG_WARN_CONSTANT_CONVERSION = YES; 627 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 628 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 629 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 630 | CLANG_WARN_EMPTY_BODY = YES; 631 | CLANG_WARN_ENUM_CONVERSION = YES; 632 | CLANG_WARN_INFINITE_RECURSION = YES; 633 | CLANG_WARN_INT_CONVERSION = YES; 634 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 635 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 636 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 637 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 638 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 639 | CLANG_WARN_STRICT_PROTOTYPES = YES; 640 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 641 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 642 | CLANG_WARN_UNREACHABLE_CODE = YES; 643 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 644 | CODE_SIGN_IDENTITY = "iPhone Developer"; 645 | COPY_PHASE_STRIP = NO; 646 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 647 | ENABLE_NS_ASSERTIONS = NO; 648 | ENABLE_STRICT_OBJC_MSGSEND = YES; 649 | GCC_C_LANGUAGE_STANDARD = gnu11; 650 | GCC_NO_COMMON_BLOCKS = YES; 651 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 652 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 653 | GCC_WARN_UNDECLARED_SELECTOR = YES; 654 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 655 | GCC_WARN_UNUSED_FUNCTION = YES; 656 | GCC_WARN_UNUSED_VARIABLE = YES; 657 | IPHONEOS_DEPLOYMENT_TARGET = 11.3; 658 | MTL_ENABLE_DEBUG_INFO = NO; 659 | SDKROOT = iphoneos; 660 | VALIDATE_PRODUCT = YES; 661 | }; 662 | name = Release; 663 | }; 664 | 84D1205520ADC25C00AF1894 /* Debug */ = { 665 | isa = XCBuildConfiguration; 666 | baseConfigurationReference = E7F92F691F6620D0D1F62EE6 /* Pods-IGListKitDemo.debug.xcconfig */; 667 | buildSettings = { 668 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 669 | CODE_SIGN_STYLE = Automatic; 670 | DEVELOPMENT_TEAM = NS27ZB8WPD; 671 | INFOPLIST_FILE = IGListKitDemo/Info.plist; 672 | LD_RUNPATH_SEARCH_PATHS = ( 673 | "$(inherited)", 674 | "@executable_path/Frameworks", 675 | ); 676 | PRODUCT_BUNDLE_IDENTIFIER = bruce.IGListKitDemo; 677 | PRODUCT_NAME = "$(TARGET_NAME)"; 678 | TARGETED_DEVICE_FAMILY = "1,2"; 679 | }; 680 | name = Debug; 681 | }; 682 | 84D1205620ADC25C00AF1894 /* Release */ = { 683 | isa = XCBuildConfiguration; 684 | baseConfigurationReference = 8D2F230AA8CAD5D5BCCA81A0 /* Pods-IGListKitDemo.release.xcconfig */; 685 | buildSettings = { 686 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 687 | CODE_SIGN_STYLE = Automatic; 688 | DEVELOPMENT_TEAM = NS27ZB8WPD; 689 | INFOPLIST_FILE = IGListKitDemo/Info.plist; 690 | LD_RUNPATH_SEARCH_PATHS = ( 691 | "$(inherited)", 692 | "@executable_path/Frameworks", 693 | ); 694 | PRODUCT_BUNDLE_IDENTIFIER = bruce.IGListKitDemo; 695 | PRODUCT_NAME = "$(TARGET_NAME)"; 696 | TARGETED_DEVICE_FAMILY = "1,2"; 697 | }; 698 | name = Release; 699 | }; 700 | /* End XCBuildConfiguration section */ 701 | 702 | /* Begin XCConfigurationList section */ 703 | 84D1203920ADC25B00AF1894 /* Build configuration list for PBXProject "IGListKitDemo" */ = { 704 | isa = XCConfigurationList; 705 | buildConfigurations = ( 706 | 84D1205220ADC25C00AF1894 /* Debug */, 707 | 84D1205320ADC25C00AF1894 /* Release */, 708 | ); 709 | defaultConfigurationIsVisible = 0; 710 | defaultConfigurationName = Release; 711 | }; 712 | 84D1205420ADC25C00AF1894 /* Build configuration list for PBXNativeTarget "IGListKitDemo" */ = { 713 | isa = XCConfigurationList; 714 | buildConfigurations = ( 715 | 84D1205520ADC25C00AF1894 /* Debug */, 716 | 84D1205620ADC25C00AF1894 /* Release */, 717 | ); 718 | defaultConfigurationIsVisible = 0; 719 | defaultConfigurationName = Release; 720 | }; 721 | /* End XCConfigurationList section */ 722 | }; 723 | rootObject = 84D1203620ADC25B00AF1894 /* Project object */; 724 | } 725 | -------------------------------------------------------------------------------- /IGListKitDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /IGListKitDemo.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /IGListKitDemo.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /IGListKitDemo.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /IGListKitDemo/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // IGListKitDemo 4 | // 5 | // Created by gxy on 2018/5/17. 6 | // Copyright © 2018年 gxy. 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 | -------------------------------------------------------------------------------- /IGListKitDemo/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // IGListKitDemo 4 | // 5 | // Created by gxy on 2018/5/17. 6 | // Copyright © 2018年 gxy. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | 11 | @interface AppDelegate () 12 | 13 | @end 14 | 15 | @implementation AppDelegate 16 | 17 | 18 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 19 | // Override point for customization after application launch. 20 | return YES; 21 | } 22 | 23 | 24 | - (void)applicationWillResignActive:(UIApplication *)application { 25 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 26 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. 27 | } 28 | 29 | 30 | - (void)applicationDidEnterBackground:(UIApplication *)application { 31 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 32 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 33 | } 34 | 35 | 36 | - (void)applicationWillEnterForeground:(UIApplication *)application { 37 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. 38 | } 39 | 40 | 41 | - (void)applicationDidBecomeActive:(UIApplication *)application { 42 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 43 | } 44 | 45 | 46 | - (void)applicationWillTerminate:(UIApplication *)application { 47 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 48 | } 49 | 50 | 51 | @end 52 | -------------------------------------------------------------------------------- /IGListKitDemo/Assets.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" : "ipad", 45 | "size" : "20x20", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "20x20", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "29x29", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "29x29", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "size" : "40x40", 66 | "scale" : "1x" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "size" : "40x40", 71 | "scale" : "2x" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "size" : "76x76", 76 | "scale" : "1x" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "size" : "76x76", 81 | "scale" : "2x" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "size" : "83.5x83.5", 86 | "scale" : "2x" 87 | }, 88 | { 89 | "idiom" : "ios-marketing", 90 | "size" : "1024x1024", 91 | "scale" : "1x" 92 | } 93 | ], 94 | "info" : { 95 | "version" : 1, 96 | "author" : "xcode" 97 | } 98 | } -------------------------------------------------------------------------------- /IGListKitDemo/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /IGListKitDemo/Assets.xcassets/arrow_down.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "arrow_down@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /IGListKitDemo/Assets.xcassets/arrow_down.imageset/arrow_down@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Bruce-pac/IGListKitDemoOC/4b2d5c8deaae3d1ef5b4a54a604cca3d4bc7e981/IGListKitDemo/Assets.xcassets/arrow_down.imageset/arrow_down@2x.png -------------------------------------------------------------------------------- /IGListKitDemo/Assets.xcassets/comment.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "comment.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /IGListKitDemo/Assets.xcassets/comment.imageset/comment.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Bruce-pac/IGListKitDemoOC/4b2d5c8deaae3d1ef5b4a54a604cca3d4bc7e981/IGListKitDemo/Assets.xcassets/comment.imageset/comment.png -------------------------------------------------------------------------------- /IGListKitDemo/Assets.xcassets/praise.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "praise.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /IGListKitDemo/Assets.xcassets/praise.imageset/praise.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Bruce-pac/IGListKitDemoOC/4b2d5c8deaae3d1ef5b4a54a604cca3d4bc7e981/IGListKitDemo/Assets.xcassets/praise.imageset/praise.png -------------------------------------------------------------------------------- /IGListKitDemo/Assets.xcassets/praise_selected.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "praise_selected.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /IGListKitDemo/Assets.xcassets/praise_selected.imageset/praise_selected.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Bruce-pac/IGListKitDemoOC/4b2d5c8deaae3d1ef5b4a54a604cca3d4bc7e981/IGListKitDemo/Assets.xcassets/praise_selected.imageset/praise_selected.png -------------------------------------------------------------------------------- /IGListKitDemo/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 | -------------------------------------------------------------------------------- /IGListKitDemo/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 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | -------------------------------------------------------------------------------- /IGListKitDemo/CellModels/CommentCollectionCellModel.h: -------------------------------------------------------------------------------- 1 | // 2 | // CommentCollectionCellModel.h 3 | // IGListKitDemo 4 | // 5 | // Created by gxy on 2018/6/6. 6 | // Copyright © 2018年 gxy. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | @class Comment; 12 | @interface CommentCollectionCellModel : NSObject 13 | @property (nonatomic,copy) NSString *person; 14 | @property (nonatomic,copy) NSString *comment; 15 | -(instancetype)initWithModel:(Comment *)comment; 16 | @end 17 | -------------------------------------------------------------------------------- /IGListKitDemo/CellModels/CommentCollectionCellModel.m: -------------------------------------------------------------------------------- 1 | // 2 | // CommentCollectionCellModel.m 3 | // IGListKitDemo 4 | // 5 | // Created by gxy on 2018/6/6. 6 | // Copyright © 2018年 gxy. All rights reserved. 7 | // 8 | 9 | #import "CommentCollectionCellModel.h" 10 | #import "Comment.h" 11 | 12 | @implementation CommentCollectionCellModel 13 | -(instancetype)initWithModel:(Comment *)comment{ 14 | self = [super init]; 15 | if (self) { 16 | _person = comment.person; 17 | _comment = [NSString stringWithFormat:@"回复了:%@",comment.comment]; 18 | } 19 | return self; 20 | } 21 | 22 | -(id)diffIdentifier{ 23 | return @(self.person.hash ^ self.comment.hash); 24 | } 25 | 26 | -(BOOL)isEqualToDiffableObject:(NSObject *)object{ 27 | if (object == self) { 28 | return YES; 29 | } else if (![object isKindOfClass:[CommentCollectionCellModel class]]) { 30 | return NO; 31 | } else { 32 | CommentCollectionCellModel *obj = (CommentCollectionCellModel *)object; 33 | return [self.person isEqualToString:obj.person] && [self.comment isEqualToString:obj.comment]; 34 | } 35 | } 36 | @end 37 | -------------------------------------------------------------------------------- /IGListKitDemo/CellModels/FavorCollectionCellModel.h: -------------------------------------------------------------------------------- 1 | // 2 | // FavorCollectionCellModel.h 3 | // IGListKitDemo 4 | // 5 | // Created by gxy on 2018/6/3. 6 | // Copyright © 2018年 gxy. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | @class FeedModel,FavorCollectionCell; 12 | @interface FavorCollectionCellModel : NSObject 13 | @property (nonatomic,assign) BOOL isFavor; 14 | @property (nonatomic,copy) NSString *favorNum; 15 | @property (nonatomic,copy) void (^favorBlock)(BOOL isFavor); 16 | @property(nonatomic,strong,readonly) FeedModel *model; 17 | -(instancetype)initWithModel:(FeedModel *)model; 18 | @end 19 | -------------------------------------------------------------------------------- /IGListKitDemo/CellModels/FavorCollectionCellModel.m: -------------------------------------------------------------------------------- 1 | // 2 | // FavorCollectionCellModel.m 3 | // IGListKitDemo 4 | // 5 | // Created by gxy on 2018/6/3. 6 | // Copyright © 2018年 gxy. All rights reserved. 7 | // 8 | 9 | #import "FavorCollectionCellModel.h" 10 | #import "FeedModel.h" 11 | 12 | #define GBKeyPath(objc, keyPath) @(((void)objc.keyPath, #keyPath)) 13 | 14 | @implementation FavorCollectionCellModel 15 | 16 | -(void)dealloc{ 17 | [self.model removeObserver:self forKeyPath:GBKeyPath(self.model, favor)]; 18 | } 19 | 20 | -(instancetype)initWithModel:(FeedModel *)model{ 21 | self = [super init]; 22 | if (self) { 23 | _model = model; 24 | [model addObserver:self forKeyPath:GBKeyPath(model, favor) options:NSKeyValueObservingOptionNew context:nil]; 25 | _isFavor = model.isFavor; 26 | _favorNum = [NSString stringWithFormat:@"%ld个👍",model.favor.unsignedIntegerValue]; 27 | } 28 | return self; 29 | } 30 | 31 | - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{ 32 | if ([keyPath isEqualToString:GBKeyPath(self.model, favor)]) { 33 | NSNumber *favor = change[NSKeyValueChangeNewKey]; 34 | self.favorNum = [NSString stringWithFormat:@"%ld个👍",favor.unsignedIntegerValue]; 35 | } 36 | } 37 | 38 | -(id)diffIdentifier{ 39 | return self.model.feedId; 40 | } 41 | 42 | -(BOOL)isEqualToDiffableObject:(NSObject *)object{ 43 | if (object == self) { 44 | return YES; 45 | } else if (![object isKindOfClass:[FavorCollectionCellModel class]]) { 46 | return NO; 47 | } else { 48 | FavorCollectionCellModel *obj = (FavorCollectionCellModel *)object; 49 | 50 | return (self.isFavor == obj.isFavor) && [self.favorNum isEqualToString:obj.favorNum]; 51 | } 52 | } 53 | @end 54 | -------------------------------------------------------------------------------- /IGListKitDemo/CellModels/ImagesCollectionCellModel.h: -------------------------------------------------------------------------------- 1 | // 2 | // ImagesCollectionCellModel.h 3 | // IGListKitDemo 4 | // 5 | // Created by gxy on 2018/5/30. 6 | // Copyright © 2018年 gxy. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | #import 12 | 13 | @interface ImagesCollectionCellModel : NSObject 14 | @property (nonatomic,copy) NSArray *images; 15 | -(instancetype)initWithImages:(NSArray *)urls; 16 | @end 17 | -------------------------------------------------------------------------------- /IGListKitDemo/CellModels/ImagesCollectionCellModel.m: -------------------------------------------------------------------------------- 1 | // 2 | // ImagesCollectionCellModel.m 3 | // IGListKitDemo 4 | // 5 | // Created by gxy on 2018/5/30. 6 | // Copyright © 2018年 gxy. All rights reserved. 7 | // 8 | 9 | #import "ImagesCollectionCellModel.h" 10 | #import "NSArray+FP.h" 11 | #import "UIImage+Extension.h" 12 | 13 | @implementation ImagesCollectionCellModel 14 | -(instancetype)initWithImages:(NSArray *)urls{ 15 | self = [super init]; 16 | if (self) { 17 | _images = [urls map:^id(NSString *element) { 18 | if ([element isEqualToString:@"red"]) { 19 | return [UIImage imageWithColor:[UIColor redColor]]; 20 | } 21 | if ([element isEqualToString:@"blue"]) { 22 | return [UIImage imageWithColor:[UIColor blueColor]]; 23 | } 24 | if ([element isEqualToString:@"purple"]) { 25 | return [UIImage imageWithColor:[UIColor purpleColor]]; 26 | } 27 | if ([element isEqualToString:@"orange"]) { 28 | return [UIImage imageWithColor:[UIColor orangeColor]]; 29 | } 30 | if ([element isEqualToString:@"green"]) { 31 | return [UIImage imageWithColor:[UIColor greenColor]]; 32 | } 33 | if ([element isEqualToString:@"yellow"]) { 34 | return [UIImage imageWithColor:[UIColor yellowColor]]; 35 | } 36 | return [UIImage imageWithColor:[UIColor blackColor]]; 37 | }]; 38 | } 39 | return self; 40 | } 41 | 42 | -(id)diffIdentifier{ 43 | return self; 44 | } 45 | 46 | -(BOOL)isEqualToDiffableObject:(NSObject *)object{ 47 | if (object == self) { 48 | return YES; 49 | } else if (![object isKindOfClass:[ImagesCollectionCellModel class]]) { 50 | return NO; 51 | } else { 52 | return [self.images isEqualToArray:((ImagesCollectionCellModel *)object).images]; 53 | } 54 | } 55 | @end 56 | -------------------------------------------------------------------------------- /IGListKitDemo/CellModels/UserInfoCellModel.h: -------------------------------------------------------------------------------- 1 | // 2 | // UserInfoCellModel.h 3 | // IGListKitDemo 4 | // 5 | // Created by gxy on 2018/5/28. 6 | // Copyright © 2018年 gxy. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @interface UserInfoCellModel : NSObject 13 | @property (nonatomic,copy) NSURL *avatar; 14 | @property (nonatomic,copy) NSString *userName; 15 | -(instancetype)initWithUserName:(NSString *)userName; 16 | @end 17 | -------------------------------------------------------------------------------- /IGListKitDemo/CellModels/UserInfoCellModel.m: -------------------------------------------------------------------------------- 1 | // 2 | // UserInfoCellModel.m 3 | // IGListKitDemo 4 | // 5 | // Created by gxy on 2018/5/28. 6 | // Copyright © 2018年 gxy. All rights reserved. 7 | // 8 | 9 | #import "UserInfoCellModel.h" 10 | 11 | @implementation UserInfoCellModel 12 | -(instancetype)initWithUserName:(NSString *)userName{ 13 | self = [super init]; 14 | if (self) { 15 | _userName = userName; 16 | } 17 | return self; 18 | } 19 | 20 | -(id)diffIdentifier{ 21 | return self.userName; 22 | } 23 | 24 | -(BOOL)isEqualToDiffableObject:(NSObject *)object{ 25 | if (object == self) { 26 | return YES; 27 | } else if (![object isKindOfClass:[UserInfoCellModel class]]) { 28 | return NO; 29 | } else { 30 | return [self.userName isEqualToString:((UserInfoCellModel *)object).userName]; 31 | } 32 | } 33 | @end 34 | -------------------------------------------------------------------------------- /IGListKitDemo/CollectionViewController/BaseCollectionViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // BaseCollectionViewController.h 3 | // IGListKitDemo 4 | // 5 | // Created by gxy on 2018/5/24. 6 | // Copyright © 2018年 gxy. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | #import 12 | #import "JsonTool.h" 13 | #import "UserInfoSectionController.h" 14 | #import "ContentSectionController.h" 15 | #import "ImageSectionController.h" 16 | #import "FavorSectionController.h" 17 | #import "FeedModel.h" 18 | 19 | @interface BaseCollectionViewController : UIViewController 20 | @property(nonatomic,strong) UICollectionView *collectionView; 21 | @property(nonatomic,strong) IGListAdapter *adapter; 22 | @property(nonatomic,strong) NSMutableArray *objects; 23 | @end 24 | -------------------------------------------------------------------------------- /IGListKitDemo/CollectionViewController/BaseCollectionViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // BaseCollectionViewController.m 3 | // IGListKitDemo 4 | // 5 | // Created by gxy on 2018/5/24. 6 | // Copyright © 2018年 gxy. All rights reserved. 7 | // 8 | 9 | #import "BaseCollectionViewController.h" 10 | 11 | @interface BaseCollectionViewController () 12 | 13 | @end 14 | 15 | @implementation BaseCollectionViewController 16 | 17 | - (void)viewDidLoad { 18 | [super viewDidLoad]; 19 | } 20 | 21 | -(void)viewDidLayoutSubviews{ 22 | [super viewDidLayoutSubviews]; 23 | self.collectionView.frame = self.view.bounds; 24 | } 25 | 26 | -(UIView *)emptyViewForListAdapter:(IGListAdapter *)listAdapter{ 27 | return nil; 28 | } 29 | 30 | -(NSArray> *)objectsForListAdapter:(IGListAdapter *)listAdapter{ 31 | return self.objects; 32 | } 33 | 34 | -(IGListSectionController *)listAdapter:(IGListAdapter *)listAdapter sectionControllerForObject:(id)object{ 35 | return nil; 36 | } 37 | 38 | -(NSMutableArray *)objects{ 39 | if (!_objects) { 40 | _objects = [NSMutableArray array]; 41 | } 42 | return _objects; 43 | } 44 | 45 | -(UICollectionView *)collectionView{ 46 | if (!_collectionView) { 47 | UICollectionViewFlowLayout *flow = [UICollectionViewFlowLayout new]; 48 | _collectionView = [[UICollectionView alloc] initWithFrame:CGRectZero collectionViewLayout:flow]; 49 | _collectionView.backgroundColor = [UIColor groupTableViewBackgroundColor]; 50 | [self.view addSubview:_collectionView]; 51 | } 52 | return _collectionView; 53 | } 54 | 55 | @end 56 | -------------------------------------------------------------------------------- /IGListKitDemo/CollectionViewController/FifthViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // FifthViewController.h 3 | // IGListKitDemo 4 | // 5 | // Created by gxy on 2018/6/25. 6 | // Copyright © 2018年 gxy. All rights reserved. 7 | // 8 | 9 | #import "BaseCollectionViewController.h" 10 | 11 | @interface FifthViewController : BaseCollectionViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /IGListKitDemo/CollectionViewController/FifthViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // FifthViewController.m 3 | // IGListKitDemo 4 | // 5 | // Created by gxy on 2018/6/25. 6 | // Copyright © 2018年 gxy. All rights reserved. 7 | // 8 | 9 | #import "FifthViewController.h" 10 | #import "NSArray+FP.h" 11 | #import "ADModel.h" 12 | #import "FeedSectionController.h" 13 | #import "AdSectionController.h" 14 | 15 | 16 | @interface FifthViewController () 17 | 18 | @end 19 | 20 | @implementation FifthViewController 21 | 22 | - (void)viewDidLoad { 23 | [super viewDidLoad]; 24 | NSArray *json = [JsonTool arrayWithJson:@"data5"]; 25 | self.objects = [json mutableMap:^id(NSDictionary *element) { 26 | NSInteger type = [element[@"type"] integerValue]; 27 | if (type == 1) { 28 | return [FeedModel mj_objectWithKeyValues:element[@"data"]]; 29 | }else{ 30 | return [ADModel mj_objectWithKeyValues:element[@"data"]]; 31 | } 32 | }]; 33 | self.adapter = [[IGListAdapter alloc] initWithUpdater:[IGListAdapterUpdater new] viewController:self]; 34 | self.adapter.dataSource = self; 35 | self.adapter.collectionView = self.collectionView; 36 | } 37 | 38 | -(IGListSectionController *)listAdapter:(IGListAdapter *)listAdapter sectionControllerForObject:(id)object{ 39 | if ([object isKindOfClass:[FeedModel class]]) { 40 | FeedSectionController *section = [FeedSectionController new]; 41 | section.inset = UIEdgeInsetsMake(5, 0, 0, 0); 42 | return section; 43 | } 44 | if ([object isKindOfClass:[ADModel class]]) { 45 | return [AdSectionController new]; 46 | } 47 | return nil; 48 | } 49 | 50 | @end 51 | -------------------------------------------------------------------------------- /IGListKitDemo/CollectionViewController/ForthViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ForthViewController.h 3 | // IGListKitDemo 4 | // 5 | // Created by gxy on 2018/6/6. 6 | // Copyright © 2018年 gxy. All rights reserved. 7 | // 8 | 9 | #import "BaseCollectionViewController.h" 10 | 11 | @interface ForthViewController : BaseCollectionViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /IGListKitDemo/CollectionViewController/ForthViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ForthViewController.m 3 | // IGListKitDemo 4 | // 5 | // Created by gxy on 2018/6/6. 6 | // Copyright © 2018年 gxy. All rights reserved. 7 | // 8 | 9 | #import "ForthViewController.h" 10 | #import "FeedSectionController.h" 11 | 12 | @interface ForthViewController () 13 | 14 | @end 15 | 16 | @implementation ForthViewController 17 | 18 | - (void)viewDidLoad { 19 | [super viewDidLoad]; 20 | NSArray *json = [JsonTool arrayWithJson:@"data4"]; 21 | [self.objects addObjectsFromArray:[FeedModel mj_objectArrayWithKeyValuesArray:json]]; 22 | self.adapter = [[IGListAdapter alloc] initWithUpdater:[IGListAdapterUpdater new] viewController:self]; 23 | self.adapter.dataSource = self; 24 | self.adapter.collectionView = self.collectionView; 25 | 26 | } 27 | 28 | -(IGListSectionController *)listAdapter:(IGListAdapter *)listAdapter sectionControllerForObject:(id)object{ 29 | FeedSectionController *section = [FeedSectionController new]; 30 | section.inset = UIEdgeInsetsMake(5, 0, 0, 0); 31 | return section; 32 | } 33 | 34 | @end 35 | -------------------------------------------------------------------------------- /IGListKitDemo/CollectionViewController/OneCollectionViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // OneCollectionViewController.h 3 | // IGListKitDemo 4 | // 5 | // Created by gxy on 2018/5/24. 6 | // Copyright © 2018年 gxy. All rights reserved. 7 | // 8 | 9 | #import "BaseCollectionViewController.h" 10 | 11 | @interface OneCollectionViewController : BaseCollectionViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /IGListKitDemo/CollectionViewController/OneCollectionViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // OneCollectionViewController.m 3 | // IGListKitDemo 4 | // 5 | // Created by gxy on 2018/5/24. 6 | // Copyright © 2018年 gxy. All rights reserved. 7 | // 8 | 9 | #import "OneCollectionViewController.h" 10 | 11 | @interface OneCollectionViewController () 12 | 13 | @end 14 | 15 | @implementation OneCollectionViewController 16 | 17 | - (void)viewDidLoad { 18 | [super viewDidLoad]; 19 | NSArray *json = [JsonTool arrayWithJson:@"data1"]; 20 | [self.objects addObjectsFromArray:[FeedModel mj_objectArrayWithKeyValuesArray:json]]; 21 | self.adapter = [[IGListAdapter alloc] initWithUpdater:[IGListAdapterUpdater new] viewController:self]; 22 | self.adapter.dataSource = self; 23 | self.adapter.collectionView = self.collectionView; 24 | [self addNotificationObserver]; 25 | } 26 | 27 | -(IGListSectionController *)listAdapter:(IGListAdapter *)listAdapter sectionControllerForObject:(id)object{ 28 | IGListStackedSectionController *stack = [[IGListStackedSectionController alloc] initWithSectionControllers:@[[UserInfoSectionController new],[ContentSectionController new]]]; 29 | stack.inset = UIEdgeInsetsMake(5, 0, 0, 0); 30 | return stack; 31 | } 32 | 33 | - (void)addNotificationObserver{ 34 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(deleteNoti:) name:kStackSectionDeleteNotification object:nil]; 35 | } 36 | 37 | - (void)deleteNoti:(NSNotification *)noti{ 38 | NSInteger section = [noti.object integerValue]; 39 | [self.objects removeObjectAtIndex:section]; 40 | [self.adapter performUpdatesAnimated:YES completion:nil]; 41 | } 42 | @end 43 | -------------------------------------------------------------------------------- /IGListKitDemo/CollectionViewController/SecondCollectionViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // SecondCollectionViewController.h 3 | // IGListKitDemo 4 | // 5 | // Created by gxy on 2018/5/30. 6 | // Copyright © 2018年 gxy. All rights reserved. 7 | // 8 | 9 | #import "BaseCollectionViewController.h" 10 | 11 | @interface SecondCollectionViewController : BaseCollectionViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /IGListKitDemo/CollectionViewController/SecondCollectionViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // SecondCollectionViewController.m 3 | // IGListKitDemo 4 | // 5 | // Created by gxy on 2018/5/30. 6 | // Copyright © 2018年 gxy. All rights reserved. 7 | // 8 | 9 | #import "SecondCollectionViewController.h" 10 | #import "FeedModel.h" 11 | #import "UserInfoSectionController.h" 12 | #import "ContentSectionController.h" 13 | #import "ImageSectionController.h" 14 | 15 | @interface SecondCollectionViewController () 16 | 17 | @end 18 | 19 | @implementation SecondCollectionViewController 20 | 21 | - (void)viewDidLoad { 22 | [super viewDidLoad]; 23 | NSArray *json = [JsonTool arrayWithJson:@"data2"]; 24 | [self.objects addObjectsFromArray:[FeedModel mj_objectArrayWithKeyValuesArray:json]]; 25 | self.adapter = [[IGListAdapter alloc] initWithUpdater:[IGListAdapterUpdater new] viewController:self]; 26 | self.adapter.dataSource = self; 27 | self.adapter.collectionView = self.collectionView; 28 | [self addNotificationObserver]; 29 | } 30 | 31 | -(IGListSectionController *)listAdapter:(IGListAdapter *)listAdapter sectionControllerForObject:(id)object{ 32 | IGListStackedSectionController *stack = [[IGListStackedSectionController alloc] initWithSectionControllers:@[[UserInfoSectionController new],[ContentSectionController new],[ImageSectionController new]]]; 33 | stack.inset = UIEdgeInsetsMake(5, 0, 0, 0); 34 | return stack; 35 | } 36 | 37 | - (void)addNotificationObserver{ 38 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(deleteNoti:) name:kStackSectionDeleteNotification object:nil]; 39 | } 40 | 41 | - (void)deleteNoti:(NSNotification *)noti{ 42 | NSInteger section = [noti.object integerValue]; 43 | [self.objects removeObjectAtIndex:section]; 44 | [self.adapter performUpdatesAnimated:YES completion:nil]; 45 | } 46 | 47 | @end 48 | -------------------------------------------------------------------------------- /IGListKitDemo/CollectionViewController/SixthViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // SixthViewController.h 3 | // IGListKitDemo 4 | // 5 | // Created by gxy on 2018/11/24. 6 | // Copyright © 2018年 gxy. All rights reserved. 7 | // 8 | 9 | #import "BaseCollectionViewController.h" 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface SixthViewController : BaseCollectionViewController 14 | 15 | @end 16 | 17 | NS_ASSUME_NONNULL_END 18 | -------------------------------------------------------------------------------- /IGListKitDemo/CollectionViewController/SixthViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // SixthViewController.m 3 | // IGListKitDemo 4 | // 5 | // Created by gxy on 2018/11/24. 6 | // Copyright © 2018年 gxy. All rights reserved. 7 | // 8 | 9 | #import "SixthViewController.h" 10 | #import "FeedBindingSectionController.h" 11 | 12 | @interface SixthViewController () 13 | 14 | @end 15 | 16 | @implementation SixthViewController 17 | 18 | - (void)viewDidLoad { 19 | [super viewDidLoad]; 20 | NSArray *json = [JsonTool arrayWithJson:@"data4"]; 21 | [self.objects addObjectsFromArray:[FeedModel mj_objectArrayWithKeyValuesArray:json]]; 22 | self.adapter = [[IGListAdapter alloc] initWithUpdater:[IGListAdapterUpdater new] viewController:self]; 23 | self.adapter.dataSource = self; 24 | self.adapter.collectionView = self.collectionView; 25 | 26 | } 27 | 28 | -(IGListSectionController *)listAdapter:(IGListAdapter *)listAdapter sectionControllerForObject:(id)object{ 29 | FeedBindingSectionController *section = [FeedBindingSectionController new]; 30 | return section; 31 | } 32 | 33 | @end 34 | -------------------------------------------------------------------------------- /IGListKitDemo/CollectionViewController/ThirdViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ThirdViewController.h 3 | // IGListKitDemo 4 | // 5 | // Created by gxy on 2018/6/3. 6 | // Copyright © 2018年 gxy. All rights reserved. 7 | // 8 | 9 | #import "BaseCollectionViewController.h" 10 | 11 | @interface ThirdViewController : BaseCollectionViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /IGListKitDemo/CollectionViewController/ThirdViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ThirdViewController.m 3 | // IGListKitDemo 4 | // 5 | // Created by gxy on 2018/6/3. 6 | // Copyright © 2018年 gxy. All rights reserved. 7 | // 8 | 9 | #import "ThirdViewController.h" 10 | 11 | @interface ThirdViewController () 12 | 13 | @end 14 | 15 | @implementation ThirdViewController 16 | 17 | - (void)viewDidLoad { 18 | [super viewDidLoad]; 19 | NSArray *json = [JsonTool arrayWithJson:@"data3"]; 20 | [self.objects addObjectsFromArray:[FeedModel mj_objectArrayWithKeyValuesArray:json]]; 21 | self.adapter = [[IGListAdapter alloc] initWithUpdater:[IGListAdapterUpdater new] viewController:self]; 22 | self.adapter.dataSource = self; 23 | self.adapter.collectionView = self.collectionView; 24 | [self addNotificationObserver]; 25 | } 26 | 27 | -(IGListSectionController *)listAdapter:(IGListAdapter *)listAdapter sectionControllerForObject:(id)object{ 28 | IGListStackedSectionController *stack = [[IGListStackedSectionController alloc] initWithSectionControllers:@[[UserInfoSectionController new],[ContentSectionController new],[ImageSectionController new],[FavorSectionController new]]]; 29 | stack.inset = UIEdgeInsetsMake(5, 0, 0, 0); 30 | return stack; 31 | } 32 | 33 | - (void)addNotificationObserver{ 34 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(deleteNoti:) name:kStackSectionDeleteNotification object:nil]; 35 | } 36 | 37 | - (void)deleteNoti:(NSNotification *)noti{ 38 | NSInteger section = [noti.object integerValue]; 39 | [self.objects removeObjectAtIndex:section]; 40 | [self.adapter performUpdatesAnimated:YES completion:nil]; 41 | } 42 | 43 | 44 | @end 45 | -------------------------------------------------------------------------------- /IGListKitDemo/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UILaunchStoryboardName 24 | LaunchScreen 25 | UIMainStoryboardFile 26 | Main 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | UISupportedInterfaceOrientations~ipad 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationPortraitUpsideDown 41 | UIInterfaceOrientationLandscapeLeft 42 | UIInterfaceOrientationLandscapeRight 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /IGListKitDemo/JsonTool/JsonTool.h: -------------------------------------------------------------------------------- 1 | // 2 | // JsonTool+Json.h 3 | // 4 | // 5 | // Created by gxy on 16/8/9. 6 | // Copyright © 2016年 gxy. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | 12 | 13 | @interface JsonTool : NSObject 14 | + (nullable NSArray *)arrayWithJson:(nonnull NSString *)jsonPath; 15 | + (nullable NSDictionary *)dicWithJson:(nonnull NSString *)jsonPath; 16 | @end 17 | -------------------------------------------------------------------------------- /IGListKitDemo/JsonTool/JsonTool.m: -------------------------------------------------------------------------------- 1 | // 2 | // DataTool+Json.m 3 | // 4 | // 5 | // Created by gxy on 16/8/9. 6 | // Copyright © 2016年 gxy. All rights reserved. 7 | // 8 | 9 | #import "JsonTool.h" 10 | 11 | 12 | 13 | @implementation JsonTool 14 | + (NSArray *)arrayWithJson:(NSString *)jsonPath { 15 | NSURL *url = [[NSBundle mainBundle] URLForResource:jsonPath withExtension:@"json"]; 16 | NSData *data = [NSData dataWithContentsOfURL:url]; 17 | if (!data) { 18 | return @[]; 19 | } 20 | NSArray *array = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:nil]; 21 | return array; 22 | } 23 | 24 | + (NSDictionary *)dicWithJson:(NSString *)jsonPath { 25 | NSURL *url = [[NSBundle mainBundle] URLForResource:jsonPath withExtension:@"json"]; 26 | NSData *data = [NSData dataWithContentsOfURL:url]; 27 | if (!data) { 28 | return @{}; 29 | } 30 | NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:nil]; 31 | return dic; 32 | } 33 | @end 34 | -------------------------------------------------------------------------------- /IGListKitDemo/Models/ADModel.h: -------------------------------------------------------------------------------- 1 | // 2 | // ADModel.h 3 | // IGListKitDemo 4 | // 5 | // Created by gxy on 2018/6/25. 6 | // Copyright © 2018年 gxy. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @interface ADModel : NSObject 13 | @property (nonatomic,copy) NSString *adTitle; 14 | @property (nonatomic,copy) NSString *adUrl; 15 | @end 16 | -------------------------------------------------------------------------------- /IGListKitDemo/Models/ADModel.m: -------------------------------------------------------------------------------- 1 | // 2 | // ADModel.m 3 | // IGListKitDemo 4 | // 5 | // Created by gxy on 2018/6/25. 6 | // Copyright © 2018年 gxy. All rights reserved. 7 | // 8 | 9 | #import "ADModel.h" 10 | 11 | @implementation ADModel 12 | -(id)diffIdentifier{ 13 | return self; 14 | } 15 | 16 | -(BOOL)isEqualToDiffableObject:(id)object{ 17 | return [self isEqual:object]; 18 | } 19 | @end 20 | -------------------------------------------------------------------------------- /IGListKitDemo/Models/Comment.h: -------------------------------------------------------------------------------- 1 | // 2 | // Comment.h 3 | // IGListKitDemo 4 | // 5 | // Created by gxy on 2018/6/6. 6 | // Copyright © 2018年 gxy. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface Comment : NSObject 12 | @property (nonatomic,copy) NSString *person; 13 | @property (nonatomic,copy) NSString *comment; 14 | @end 15 | -------------------------------------------------------------------------------- /IGListKitDemo/Models/Comment.m: -------------------------------------------------------------------------------- 1 | // 2 | // Comment.m 3 | // IGListKitDemo 4 | // 5 | // Created by gxy on 2018/6/6. 6 | // Copyright © 2018年 gxy. All rights reserved. 7 | // 8 | 9 | #import "Comment.h" 10 | 11 | @implementation Comment 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /IGListKitDemo/Models/FeedModel.h: -------------------------------------------------------------------------------- 1 | // 2 | // FeedModel.h 3 | // IGListKitDemo 4 | // 5 | // Created by gxy on 2018/5/28. 6 | // Copyright © 2018年 gxy. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | #import "Comment.h" 12 | @interface FeedModel : NSObject 13 | @property (nonatomic,copy) NSNumber *feedId; 14 | @property (nonatomic,copy) NSString *avatar; 15 | @property (nonatomic,copy) NSString *userName; 16 | @property (nonatomic,copy) NSString *content; 17 | @property (nonatomic,copy) NSArray *images; 18 | @property (nonatomic,copy) NSNumber *favor; 19 | @property (nonatomic,assign) BOOL isFavor; 20 | @property (nonatomic,copy) NSArray *comments; 21 | @end 22 | -------------------------------------------------------------------------------- /IGListKitDemo/Models/FeedModel.m: -------------------------------------------------------------------------------- 1 | // 2 | // FeedModel.m 3 | // IGListKitDemo 4 | // 5 | // Created by gxy on 2018/5/28. 6 | // Copyright © 2018年 gxy. All rights reserved. 7 | // 8 | 9 | #import "FeedModel.h" 10 | #import 11 | 12 | @implementation FeedModel 13 | 14 | +(NSDictionary *)mj_objectClassInArray{ 15 | return @{ 16 | @"comments":[Comment class] 17 | }; 18 | } 19 | 20 | -(id)diffIdentifier{ 21 | return self; 22 | } 23 | 24 | -(BOOL)isEqualToDiffableObject:(id)object{ 25 | return [self isEqual:object]; 26 | } 27 | @end 28 | -------------------------------------------------------------------------------- /IGListKitDemo/NSArray+FP/NSArray+FP.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSArray+FP.h 3 | // youxueyun 4 | // 5 | // Created by gxy on 16/12/29. 6 | // Copyright © 2016年 gxy. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | //typedef T(^<#name#>)(<#arguments#>); 12 | 13 | 14 | 15 | @interface NSArray (FP) 16 | 17 | - (NSArray *)map : (id(NS_NOESCAPE ^)(ObjectType element))block; 18 | - (NSMutableArray *)mutableMap:(id(NS_NOESCAPE ^)(ObjectType element))block; 19 | 20 | ///数组展开 element的类型是数组元素的元素类型 21 | - (NSArray *)flatMap:(id(NS_NOESCAPE ^)(id element))block; 22 | 23 | - (NSArray *)filter:(BOOL(NS_NOESCAPE ^)(ObjectType element))block; 24 | 25 | ///去除重复元素 26 | - (NSArray *)filterRepeat; 27 | 28 | ///相当于swift的reduce函数 29 | - (id)reduceWithInitialResult:(id)initialResult nextPartialResult:(id (^)(id result, ObjectType element))nextPartialResult; 30 | 31 | - (NSArray *)dropFirst; 32 | @end 33 | -------------------------------------------------------------------------------- /IGListKitDemo/NSArray+FP/NSArray+FP.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSArray+FP.m 3 | // youxueyun 4 | // 5 | // Created by gxy on 16/12/29. 6 | // Copyright © 2016年 gxy. All rights reserved. 7 | // 8 | 9 | #import "NSArray+FP.h" 10 | 11 | 12 | 13 | @implementation NSArray (FP) 14 | 15 | - (NSArray *)filterRepeat { 16 | NSSet * set = [NSSet setWithArray:self]; 17 | NSArray *result = [set allObjects]; 18 | return result; 19 | } 20 | 21 | - (NSArray *)map:(id (^)(id))block { 22 | NSMutableArray *newArray = [NSMutableArray array]; 23 | if (!block) { 24 | return self; 25 | } 26 | for (id element in self) { 27 | [newArray addObject:block(element)]; 28 | } 29 | return newArray; 30 | } 31 | 32 | - (NSMutableArray *)mutableMap:(id (^)(id))block { 33 | NSMutableArray *newArray = [NSMutableArray array]; 34 | if (!block) { 35 | return self.mutableCopy; 36 | } 37 | for (id element in self) { 38 | [newArray addObject:block(element)]; 39 | } 40 | return newArray; 41 | } 42 | 43 | - (NSArray *)flatMap:(id (^)(id))block { 44 | NSMutableArray *newArr = [NSMutableArray array]; 45 | if (!block) { 46 | return self; 47 | } 48 | return [self reduceWithInitialResult:newArr 49 | nextPartialResult:^NSMutableArray *(NSMutableArray *result, id element) { 50 | if ([element isKindOfClass:[NSArray class]]) { 51 | __kindof NSArray *arr = element; 52 | [result addObjectsFromArray:[arr map:^id(id aElement) { 53 | return block(aElement); 54 | }]]; 55 | } else { 56 | [result addObject:block(element)]; 57 | } 58 | return result; 59 | }]; 60 | } 61 | 62 | - (NSArray *)filter:(BOOL (^)(id))block { 63 | NSMutableArray *newArray = [NSMutableArray array]; 64 | if (!block) { 65 | return self; 66 | } 67 | for (id element in self) { 68 | if (block(element)) { 69 | [newArray addObject:element]; 70 | } 71 | } 72 | return newArray; 73 | } 74 | 75 | - (id)reduceWithInitialResult:(id)initialResult nextPartialResult:(id (^)(id, id))nextPartialResult { 76 | id result = initialResult; 77 | for (id element in self) { 78 | result = nextPartialResult(result, element); 79 | } 80 | return result; 81 | } 82 | 83 | - (NSArray *)dropFirst { 84 | if (self.count == 0 || 85 | self.count == 1) { 86 | return @[]; 87 | } 88 | return [self subarrayWithRange:NSMakeRange(1, self.count - 1)]; 89 | } 90 | @end 91 | -------------------------------------------------------------------------------- /IGListKitDemo/SectionController/AdSectionController.h: -------------------------------------------------------------------------------- 1 | // 2 | // AdSectionController.h 3 | // IGListKitDemo 4 | // 5 | // Created by gxy on 2018/6/25. 6 | // Copyright © 2018年 gxy. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AdSectionController : IGListSectionController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /IGListKitDemo/SectionController/AdSectionController.m: -------------------------------------------------------------------------------- 1 | // 2 | // AdSectionController.m 3 | // IGListKitDemo 4 | // 5 | // Created by gxy on 2018/6/25. 6 | // Copyright © 2018年 gxy. All rights reserved. 7 | // 8 | 9 | #import "AdSectionController.h" 10 | #import "AdCollectionCell.h" 11 | 12 | @interface AdSectionController () 13 | @property(nonatomic,strong) ADModel *object; 14 | @end 15 | 16 | @implementation AdSectionController 17 | -(NSInteger)numberOfItems{ 18 | return 1; 19 | } 20 | 21 | -(CGSize)sizeForItemAtIndex:(NSInteger)index{ 22 | return CGSizeMake(self.collectionContext.containerSize.width, 100); 23 | } 24 | 25 | -(UICollectionViewCell *)cellForItemAtIndex:(NSInteger)index{ 26 | AdCollectionCell *cell = [self.collectionContext dequeueReusableCellWithNibName:@"AdCollectionCell" bundle:nil forSectionController:self atIndex:index]; 27 | [cell bindViewModel:_object]; 28 | return cell; 29 | } 30 | 31 | -(void)didUpdateToObject:(id)object{ 32 | _object = object; 33 | self.inset = UIEdgeInsetsMake(5, 0, 0, 0); 34 | } 35 | 36 | @end 37 | -------------------------------------------------------------------------------- /IGListKitDemo/SectionController/CommentSectionController.h: -------------------------------------------------------------------------------- 1 | // 2 | // CommentSectionController.h 3 | // IGListKitDemo 4 | // 5 | // Created by gxy on 2018/6/5. 6 | // Copyright © 2018年 gxy. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface CommentSectionController : IGListSectionController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /IGListKitDemo/SectionController/CommentSectionController.m: -------------------------------------------------------------------------------- 1 | // 2 | // CommentSectionController.m 3 | // IGListKitDemo 4 | // 5 | // Created by gxy on 2018/6/5. 6 | // Copyright © 2018年 gxy. All rights reserved. 7 | // 8 | 9 | #import "CommentSectionController.h" 10 | 11 | @implementation CommentSectionController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /IGListKitDemo/SectionController/ContentSectionController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ContentSectionController.h 3 | // IGListKitDemo 4 | // 5 | // Created by gxy on 2018/5/28. 6 | // Copyright © 2018年 gxy. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ContentSectionController : IGListSectionController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /IGListKitDemo/SectionController/ContentSectionController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ContentSectionController.m 3 | // IGListKitDemo 4 | // 5 | // Created by gxy on 2018/5/28. 6 | // Copyright © 2018年 gxy. All rights reserved. 7 | // 8 | 9 | #import "ContentSectionController.h" 10 | #import "FeedModel.h" 11 | #import "ContentCollectionCell.h" 12 | @interface ContentSectionController () 13 | @property(nonatomic,strong) FeedModel *object; 14 | @property (nonatomic) BOOL expanded; 15 | @end 16 | 17 | @implementation ContentSectionController 18 | 19 | -(NSInteger)numberOfItems{ 20 | if (!self.object.content) { 21 | return 0; 22 | } 23 | return 1; 24 | } 25 | 26 | -(CGSize)sizeForItemAtIndex:(NSInteger)index{ 27 | CGFloat width = self.collectionContext.containerSize.width; 28 | CGFloat height = _expanded ? [ContentCollectionCell heightWithText:self.object.content width:width] : [ContentCollectionCell lineHeight]; 29 | return CGSizeMake(width, height); 30 | } 31 | 32 | -(UICollectionViewCell *)cellForItemAtIndex:(NSInteger)index{ 33 | ContentCollectionCell *cell = [self.collectionContext dequeueReusableCellWithNibName:@"ContentCollectionCell" bundle:nil forSectionController:self atIndex:index]; 34 | [cell bindViewModel:self.object.content]; 35 | return cell; 36 | } 37 | 38 | -(void)didUpdateToObject:(id)object{ 39 | _object = object; 40 | } 41 | 42 | -(void)didSelectItemAtIndex:(NSInteger)index{ 43 | _expanded = !_expanded; 44 | [UIView animateWithDuration:0.5 delay:0 usingSpringWithDamping:0.4 initialSpringVelocity:0.6 options:0 animations:^{ 45 | [self.collectionContext invalidateLayoutForSectionController:self completion:nil]; 46 | } completion:nil]; 47 | } 48 | @end 49 | -------------------------------------------------------------------------------- /IGListKitDemo/SectionController/FavorSectionController.h: -------------------------------------------------------------------------------- 1 | // 2 | // FavorSectionController.h 3 | // IGListKitDemo 4 | // 5 | // Created by gxy on 2018/6/3. 6 | // Copyright © 2018年 gxy. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface FavorSectionController : IGListSectionController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /IGListKitDemo/SectionController/FavorSectionController.m: -------------------------------------------------------------------------------- 1 | // 2 | // FavorSectionController.m 3 | // IGListKitDemo 4 | // 5 | // Created by gxy on 2018/6/3. 6 | // Copyright © 2018年 gxy. All rights reserved. 7 | // 8 | 9 | #import "FavorSectionController.h" 10 | #import "FavorCollectionCell.h" 11 | #import "FeedModel.h" 12 | #import "FavorCollectionCellModel.h" 13 | @interface FavorSectionController () 14 | @property(nonatomic,strong) FeedModel *object; 15 | @property(nonatomic,strong) FavorCollectionCellModel *viewModel; 16 | @end 17 | 18 | @implementation FavorSectionController 19 | -(NSInteger)numberOfItems{ 20 | return 1; 21 | } 22 | 23 | -(CGSize)sizeForItemAtIndex:(NSInteger)index{ 24 | return CGSizeMake(self.collectionContext.containerSize.width, 65); 25 | } 26 | 27 | -(UICollectionViewCell *)cellForItemAtIndex:(NSInteger)index{ 28 | FavorCollectionCell *cell = [self.collectionContext dequeueReusableCellWithNibName:@"FavorCollectionCell" bundle:nil forSectionController:self atIndex:index]; 29 | [cell bindViewModel:self.viewModel]; 30 | return cell; 31 | } 32 | 33 | -(void)didUpdateToObject:(id)object{ 34 | _object = object; 35 | self.viewModel = [[FavorCollectionCellModel alloc] initWithModel:_object]; 36 | __weak typeof(self) weakSelf = self; 37 | self.viewModel.favorBlock = ^(BOOL isFavor) { 38 | __strong typeof(self) self = weakSelf; 39 | NSInteger favor = self.object.favor.integerValue; 40 | self.object.favor = isFavor ? @(favor + 1) : @(favor - 1); 41 | }; 42 | } 43 | @end 44 | -------------------------------------------------------------------------------- /IGListKitDemo/SectionController/FeedBindingSectionController.h: -------------------------------------------------------------------------------- 1 | // 2 | // FeedBindingSectionController.h 3 | // IGListKitDemo 4 | // 5 | // Created by gxy on 2018/11/24. 6 | // Copyright © 2018年 gxy. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface FeedBindingSectionController : IGListBindingSectionController 14 | 15 | @end 16 | 17 | NS_ASSUME_NONNULL_END 18 | -------------------------------------------------------------------------------- /IGListKitDemo/SectionController/FeedBindingSectionController.m: -------------------------------------------------------------------------------- 1 | // 2 | // FeedBindingSectionController.m 3 | // IGListKitDemo 4 | // 5 | // Created by gxy on 2018/11/24. 6 | // Copyright © 2018年 gxy. All rights reserved. 7 | // 8 | 9 | #import "FeedBindingSectionController.h" 10 | #import "FeedModel.h" 11 | #import "UserInfoCell.h" 12 | #import "ContentCollectionCell.h" 13 | #import "ImagesCollectionCell.h" 14 | #import "FavorCollectionCell.h" 15 | #import "CommentCollectionCell.h" 16 | #import "ImagesCollectionCellModel.h" 17 | #import "FavorCollectionCellModel.h" 18 | #import "CommentCollectionCellModel.h" 19 | #import "NSArray+FP.h" 20 | 21 | #define KInsetLeft 10 22 | 23 | @interface FeedBindingSectionController () 24 | @property(nonatomic,strong,readonly) FeedModel *dataObject; 25 | @property (nonatomic) BOOL expanded; 26 | @end 27 | 28 | @implementation FeedBindingSectionController 29 | 30 | - (instancetype)init 31 | { 32 | self = [super init]; 33 | if (self) { 34 | self.dataSource = self; 35 | self.selectionDelegate = self; 36 | self.inset = UIEdgeInsetsMake(5, 0, 0, 0); 37 | } 38 | return self; 39 | } 40 | 41 | - (nonnull UICollectionViewCell *)sectionController:(nonnull IGListBindingSectionController *)sectionController cellForViewModel:(nonnull id)viewModel atIndex:(NSInteger)index { 42 | if ([viewModel isKindOfClass:[UserInfoCellModel class]]) { 43 | UserInfoCell *cell = [self.collectionContext dequeueReusableCellWithNibName:@"UserInfoCell" bundle:nil forSectionController:self atIndex:index]; 44 | cell.delegate = self; 45 | return cell; 46 | } 47 | if ([viewModel isKindOfClass:[NSString class]]) { 48 | ContentCollectionCell *cell = [self.collectionContext dequeueReusableCellWithNibName:@"ContentCollectionCell" bundle:nil forSectionController:self atIndex:index]; 49 | return cell; 50 | } 51 | if ([viewModel isKindOfClass:[ImagesCollectionCellModel class]]) { 52 | ImagesCollectionCell *cell = [self.collectionContext dequeueReusableCellWithNibName:@"ImagesCollectionCell" bundle:nil forSectionController:self atIndex:index]; 53 | return cell; 54 | } 55 | if ([viewModel isKindOfClass:[FavorCollectionCellModel class]]) { 56 | FavorCollectionCell *cell = [self.collectionContext dequeueReusableCellWithNibName:@"FavorCollectionCell" bundle:nil forSectionController:self atIndex:index]; 57 | return cell; 58 | } 59 | if ([viewModel isKindOfClass:[CommentCollectionCellModel class]]) { 60 | CommentCollectionCell *cell = [self.collectionContext dequeueReusableCellWithNibName:@"CommentCollectionCell" bundle:nil forSectionController:self atIndex:index]; 61 | return cell; 62 | } 63 | return [UICollectionViewCell new]; 64 | } 65 | 66 | - (CGSize)sectionController:(nonnull IGListBindingSectionController *)sectionController sizeForViewModel:(nonnull id)viewModel atIndex:(NSInteger)index { 67 | CGFloat width = self.collectionContext.containerSize.width; 68 | if ([viewModel isKindOfClass:[UserInfoCellModel class]]) { 69 | return CGSizeMake(width, 25); 70 | } 71 | if ([viewModel isKindOfClass:[NSString class]]) { 72 | CGFloat height = _expanded ? [ContentCollectionCell heightWithText:self.dataObject.content width:width] : [ContentCollectionCell lineHeight]; 73 | return CGSizeMake(width, height); 74 | } 75 | if ([viewModel isKindOfClass:[ImagesCollectionCellModel class]]) { 76 | CGFloat mwidth = (width - KInsetLeft * 4.f) / 3.f; 77 | CGFloat height = (self.dataObject.images.count - 1) / 3 *(mwidth + KInsetLeft) + mwidth; 78 | return CGSizeMake(width, height); 79 | } 80 | if ([viewModel isKindOfClass:[FavorCollectionCellModel class]]) { 81 | return CGSizeMake(width, 65); 82 | } 83 | if ([viewModel isKindOfClass:[CommentCollectionCellModel class]]) { 84 | return CGSizeMake(width, 50); 85 | } 86 | return CGSizeZero; 87 | } 88 | 89 | - (nonnull NSArray> *)sectionController:(nonnull IGListBindingSectionController *)sectionController viewModelsForObject:(nonnull FeedModel *)object { 90 | NSMutableArray *viewModels = [NSMutableArray array]; 91 | UserInfoCellModel *vm1 = [[UserInfoCellModel alloc] initWithUserName:object.userName]; 92 | [viewModels addObject:vm1]; 93 | if (object.content) { 94 | [viewModels addObject:object.content]; 95 | } 96 | 97 | if (object.images.count > 0) { 98 | [viewModels addObject:[[ImagesCollectionCellModel alloc] initWithImages:object.images]]; 99 | } 100 | FavorCollectionCellModel *vm2 = [[FavorCollectionCellModel alloc] initWithModel:object]; 101 | __weak typeof(self) weakSelf = self; 102 | vm2.favorBlock = ^(BOOL isFavor) { 103 | __strong typeof(self) self = weakSelf; 104 | NSInteger favor = self.dataObject.favor.integerValue; 105 | self.dataObject.favor = isFavor ? @(favor + 1) : @(favor - 1); 106 | }; 107 | [viewModels addObject:vm2]; 108 | 109 | NSArray *comments = [object.comments map:^id(Comment *element) { 110 | return [[CommentCollectionCellModel alloc] initWithModel:element]; 111 | }]; 112 | [viewModels addObjectsFromArray:comments]; 113 | return viewModels; 114 | } 115 | 116 | -(void)sectionController:(IGListBindingSectionController *)sectionController didSelectItemAtIndex:(NSInteger)index viewModel:(id)viewModel{ 117 | if ([viewModel isKindOfClass:[NSString class]]) { 118 | _expanded = !_expanded; 119 | [UIView animateWithDuration:0.5 delay:0 usingSpringWithDamping:0.4 initialSpringVelocity:0.6 options:0 animations:^{ 120 | [self.collectionContext invalidateLayoutForSectionController:self completion:nil]; 121 | } completion:nil]; 122 | } 123 | } 124 | 125 | -(void)cellDidClickMore:(UserInfoCell *)cell{ 126 | 127 | } 128 | 129 | -(FeedModel *)dataObject{ 130 | return self.object; 131 | } 132 | 133 | @end 134 | -------------------------------------------------------------------------------- /IGListKitDemo/SectionController/FeedSectionController.h: -------------------------------------------------------------------------------- 1 | // 2 | // FeedSectionController.h 3 | // IGListKitDemo 4 | // 5 | // Created by gxy on 2018/6/6. 6 | // Copyright © 2018年 gxy. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface FeedSectionController : IGListSectionController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /IGListKitDemo/SectionController/FeedSectionController.m: -------------------------------------------------------------------------------- 1 | // 2 | // FeedSectionController.m 3 | // IGListKitDemo 4 | // 5 | // Created by gxy on 2018/6/6. 6 | // Copyright © 2018年 gxy. All rights reserved. 7 | // 8 | 9 | #import "FeedSectionController.h" 10 | #import "FeedModel.h" 11 | #import "UserInfoCell.h" 12 | #import "ContentCollectionCell.h" 13 | #import "ImagesCollectionCell.h" 14 | #import "FavorCollectionCell.h" 15 | #import "CommentCollectionCell.h" 16 | #import "ImagesCollectionCellModel.h" 17 | #import "FavorCollectionCellModel.h" 18 | #import "CommentCollectionCellModel.h" 19 | #import "NSArray+FP.h" 20 | 21 | #define KInsetLeft 10 22 | 23 | @interface FeedSectionController () 24 | @property(nonatomic,strong) FeedModel *object; 25 | @property(nonatomic,strong) NSMutableArray *viewModels; 26 | @property (nonatomic) BOOL expanded; 27 | @property (nonatomic) BOOL hasContent; 28 | @property (nonatomic) BOOL hasImages; 29 | @end 30 | 31 | @implementation FeedSectionController 32 | 33 | -(NSInteger)numberOfItems{ 34 | return self.viewModels.count; 35 | } 36 | 37 | -(CGSize)sizeForItemAtIndex:(NSInteger)index{ 38 | switch (index) { 39 | case 0: 40 | return CGSizeMake(self.collectionContext.containerSize.width, 25); 41 | break; 42 | case 1:{ 43 | if (_hasContent) { 44 | CGFloat width = self.collectionContext.containerSize.width; 45 | CGFloat height = _expanded ? [ContentCollectionCell heightWithText:self.object.content width:width] : [ContentCollectionCell lineHeight]; 46 | return CGSizeMake(width, height); 47 | } 48 | return [self imageCellSize]; 49 | }break; 50 | case 2:{ 51 | if (_hasContent && _hasImages) { 52 | return [self imageCellSize]; 53 | } 54 | return CGSizeMake(self.collectionContext.containerSize.width, 65); 55 | }break; 56 | case 3:{ 57 | if (_hasContent && _hasImages) { 58 | return CGSizeMake(self.collectionContext.containerSize.width, 65); 59 | } 60 | return CGSizeMake(self.collectionContext.containerSize.width, 50); 61 | }break; 62 | default:{ 63 | return CGSizeMake(self.collectionContext.containerSize.width, 50); 64 | } 65 | break; 66 | } 67 | } 68 | 69 | -(UICollectionViewCell *)cellForItemAtIndex:(NSInteger)index{ 70 | switch (index) { 71 | case 0:{ 72 | UserInfoCell *cell = [self.collectionContext dequeueReusableCellWithNibName:@"UserInfoCell" bundle:nil forSectionController:self atIndex:index]; 73 | cell.delegate = self; 74 | [cell bindViewModel:self.viewModels[index]]; 75 | return cell; 76 | } 77 | break; 78 | case 1:{ 79 | if (_hasContent) { 80 | ContentCollectionCell *cell = [self.collectionContext dequeueReusableCellWithNibName:@"ContentCollectionCell" bundle:nil forSectionController:self atIndex:index]; 81 | [cell bindViewModel:self.viewModels[index]]; 82 | return cell; 83 | } 84 | return [self cellWithIndex:index]; 85 | }break; 86 | case 2:{ 87 | if (_hasContent && _hasImages) { 88 | return [self cellWithIndex:index]; 89 | } 90 | FavorCollectionCell *cell = [self.collectionContext dequeueReusableCellWithNibName:@"FavorCollectionCell" bundle:nil forSectionController:self atIndex:index]; 91 | [cell bindViewModel:self.viewModels[index]]; 92 | return cell; 93 | }break; 94 | case 3:{ 95 | if (_hasContent && _hasImages) { 96 | FavorCollectionCell *cell = [self.collectionContext dequeueReusableCellWithNibName:@"FavorCollectionCell" bundle:nil forSectionController:self atIndex:index]; 97 | [cell bindViewModel:self.viewModels[index]]; 98 | return cell; 99 | } 100 | CommentCollectionCell *cell = [self.collectionContext dequeueReusableCellWithNibName:@"CommentCollectionCell" bundle:nil forSectionController:self atIndex:index]; 101 | [cell bindViewModel:self.viewModels[index]]; 102 | return cell; 103 | }break; 104 | default:{ 105 | CommentCollectionCell *cell = [self.collectionContext dequeueReusableCellWithNibName:@"CommentCollectionCell" bundle:nil forSectionController:self atIndex:index]; 106 | [cell bindViewModel:self.viewModels[index]]; 107 | return cell; 108 | } 109 | break; 110 | } 111 | } 112 | 113 | -(void)didUpdateToObject:(FeedModel *)object{ 114 | _object = object; 115 | UserInfoCellModel *vm1 = [[UserInfoCellModel alloc] initWithUserName:object.userName]; 116 | [self.viewModels addObject:vm1]; 117 | if (object.content) { 118 | _hasContent = YES; 119 | [self.viewModels addObject:object.content]; 120 | } 121 | 122 | if (object.images.count > 0) { 123 | _hasImages = YES; 124 | [self.viewModels addObject:[[ImagesCollectionCellModel alloc] initWithImages:object.images]]; 125 | } 126 | FavorCollectionCellModel *vm2 = [[FavorCollectionCellModel alloc] initWithModel:_object]; 127 | __weak typeof(self) weakSelf = self; 128 | vm2.favorBlock = ^(BOOL isFavor) { 129 | __strong typeof(self) self = weakSelf; 130 | NSInteger favor = self.object.favor.integerValue; 131 | self.object.favor = isFavor ? @(favor + 1) : @(favor - 1); 132 | }; 133 | [self.viewModels addObject:vm2]; 134 | 135 | NSArray *comments = [object.comments map:^id(Comment *element) { 136 | return [[CommentCollectionCellModel alloc] initWithModel:element]; 137 | }]; 138 | [self.viewModels addObjectsFromArray:comments]; 139 | } 140 | 141 | -(void)didSelectItemAtIndex:(NSInteger)index{ 142 | if (_hasContent && index == 1) { 143 | _expanded = !_expanded; 144 | [UIView animateWithDuration:0.5 delay:0 usingSpringWithDamping:0.4 initialSpringVelocity:0.6 options:0 animations:^{ 145 | [self.collectionContext invalidateLayoutForSectionController:self completion:nil]; 146 | } completion:nil]; 147 | } 148 | } 149 | 150 | - (CGSize)imageCellSize{ 151 | CGFloat width = (self.collectionContext.containerSize.width - KInsetLeft * 4.f) / 3.f; 152 | CGFloat height = (_object.images.count - 1) / 3 *(width + KInsetLeft) + width; 153 | return CGSizeMake(self.collectionContext.containerSize.width, height); 154 | } 155 | 156 | - (ImagesCollectionCell *)cellWithIndex:(NSInteger)index{ 157 | ImagesCollectionCell *cell = [self.collectionContext dequeueReusableCellWithNibName:@"ImagesCollectionCell" bundle:nil forSectionController:self atIndex:index]; 158 | [cell bindViewModel:self.viewModels[index]]; 159 | return cell; 160 | } 161 | 162 | -(void)cellDidClickMore:(UserInfoCell *)cell{ 163 | UIAlertController *actionSheet = [UIAlertController alertControllerWithTitle:nil message:nil preferredStyle:UIAlertControllerStyleActionSheet]; 164 | [actionSheet addAction:[UIAlertAction actionWithTitle:@"share" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) { 165 | }]]; 166 | [actionSheet addAction:[UIAlertAction actionWithTitle:@"delete" style:UIAlertActionStyleDestructive handler:^(UIAlertAction * _Nonnull action) { 167 | [self.collectionContext performBatchAnimated:YES updates:^(id _Nonnull batchContext) { 168 | NSIndexSet *set = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, self.viewModels.count)]; 169 | [self.viewModels removeAllObjects]; 170 | [batchContext deleteInSectionController:self atIndexes:set]; 171 | } completion:^(BOOL finished) { 172 | 173 | }]; 174 | }]]; 175 | [actionSheet addAction:[UIAlertAction actionWithTitle:@"cancel" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) { 176 | }]]; 177 | [self.viewController presentViewController:actionSheet animated:YES completion:nil]; 178 | } 179 | 180 | -(NSMutableArray *)viewModels{ 181 | if (!_viewModels) { 182 | _viewModels = [NSMutableArray array]; 183 | } 184 | return _viewModels; 185 | } 186 | @end 187 | -------------------------------------------------------------------------------- /IGListKitDemo/SectionController/ImageSectionController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ImageSectionController.h 3 | // IGListKitDemo 4 | // 5 | // Created by gxy on 2018/5/30. 6 | // Copyright © 2018年 gxy. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ImageSectionController : IGListSectionController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /IGListKitDemo/SectionController/ImageSectionController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ImageSectionController.m 3 | // IGListKitDemo 4 | // 5 | // Created by gxy on 2018/5/30. 6 | // Copyright © 2018年 gxy. All rights reserved. 7 | // 8 | 9 | #import "ImageSectionController.h" 10 | #import "FeedModel.h" 11 | #import "ImageCell.h" 12 | #import "ImagesCollectionCell.h" 13 | #import "ImagesCollectionCellModel.h" 14 | 15 | #define KInsetLeft 10 16 | 17 | @interface ImageSectionController () 18 | @property(nonatomic,strong) FeedModel *object; 19 | @property(nonatomic,strong) ImagesCollectionCellModel *model; 20 | @end 21 | 22 | @implementation ImageSectionController 23 | 24 | -(NSInteger)numberOfItems{ 25 | if (!_object.images || _object.images.count == 0) { 26 | return 0; 27 | } 28 | return 1; 29 | } 30 | 31 | -(CGSize)sizeForItemAtIndex:(NSInteger)index{ 32 | CGFloat width = (self.collectionContext.containerSize.width - KInsetLeft * 4.f) / 3.f; 33 | CGFloat height = (_object.images.count - 1) / 3 *(width + KInsetLeft) + width; 34 | return CGSizeMake(self.collectionContext.containerSize.width, height); 35 | } 36 | 37 | -(UICollectionViewCell *)cellForItemAtIndex:(NSInteger)index{ 38 | ImagesCollectionCell *cell = [self.collectionContext dequeueReusableCellWithNibName:@"ImagesCollectionCell" bundle:nil forSectionController:self atIndex:index]; 39 | [cell bindViewModel:_model]; 40 | return cell; 41 | } 42 | 43 | -(void)didUpdateToObject:(id)object{ 44 | _object = object; 45 | _model = [[ImagesCollectionCellModel alloc] initWithImages:_object.images]; 46 | } 47 | @end 48 | -------------------------------------------------------------------------------- /IGListKitDemo/SectionController/UserInfoSectionController.h: -------------------------------------------------------------------------------- 1 | // 2 | // UserInfoSectionController.h 3 | // IGListKitDemo 4 | // 5 | // Created by gxy on 2018/5/24. 6 | // Copyright © 2018年 gxy. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | extern NSString *const kStackSectionDeleteNotification; 12 | 13 | @interface UserInfoSectionController : IGListSectionController 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /IGListKitDemo/SectionController/UserInfoSectionController.m: -------------------------------------------------------------------------------- 1 | // 2 | // UserInfoSectionController.m 3 | // IGListKitDemo 4 | // 5 | // Created by gxy on 2018/5/24. 6 | // Copyright © 2018年 gxy. All rights reserved. 7 | // 8 | 9 | #import "UserInfoSectionController.h" 10 | #import "UserInfoCell.h" 11 | #import "FeedModel.h" 12 | 13 | NSString *const kStackSectionDeleteNotification = @"kStackSectionDeleteNotification"; 14 | 15 | @interface UserInfoSectionController () 16 | @property(nonatomic,strong) FeedModel *object; 17 | @end 18 | 19 | @implementation UserInfoSectionController 20 | -(NSInteger)numberOfItems{ 21 | return 1; 22 | } 23 | 24 | -(CGSize)sizeForItemAtIndex:(NSInteger)index{ 25 | return CGSizeMake(self.collectionContext.containerSize.width, 25); 26 | } 27 | 28 | -(UICollectionViewCell *)cellForItemAtIndex:(NSInteger)index{ 29 | UserInfoCell *cell = [self.collectionContext dequeueReusableCellWithNibName:@"UserInfoCell" bundle:nil forSectionController:self atIndex:index]; 30 | cell.delegate = self; 31 | [cell bindViewModel:[[UserInfoCellModel alloc]initWithUserName:_object.userName]]; 32 | return cell; 33 | } 34 | 35 | -(void)didUpdateToObject:(id)object{ 36 | _object = object; 37 | } 38 | 39 | -(void)cellDidClickMore:(UserInfoCell *)cell{ 40 | UIAlertController *actionSheet = [UIAlertController alertControllerWithTitle:nil message:nil preferredStyle:UIAlertControllerStyleActionSheet]; 41 | [actionSheet addAction:[UIAlertAction actionWithTitle:@"share" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) { 42 | }]]; 43 | [actionSheet addAction:[UIAlertAction actionWithTitle:@"delete" style:UIAlertActionStyleDestructive handler:^(UIAlertAction * _Nonnull action) { 44 | IGListStackedSectionController *stack = self.collectionContext; 45 | [[NSNotificationCenter defaultCenter] postNotificationName:kStackSectionDeleteNotification object:@(stack.section)]; 46 | }]]; 47 | [actionSheet addAction:[UIAlertAction actionWithTitle:@"cancel" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) { 48 | }]]; 49 | [self.viewController presentViewController:actionSheet animated:YES completion:nil]; 50 | } 51 | @end 52 | -------------------------------------------------------------------------------- /IGListKitDemo/UIImage+Extension/UIImage+Extension.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIImage+color.h 3 | // firstAppPageV1 4 | // 5 | // Created by gxy on 16/10/15. 6 | // Copyright © 2016年 gxy. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | 12 | 13 | @interface UIImage (Extension) 14 | 15 | + (UIImage *)imageWithColor:(UIColor *)color; 16 | @end 17 | -------------------------------------------------------------------------------- /IGListKitDemo/UIImage+Extension/UIImage+Extension.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIImage+color.m 3 | // firstAppPageV1 4 | // 5 | // Created by gxy on 16/10/15. 6 | // Copyright © 2016年 gxy. All rights reserved. 7 | // 8 | 9 | #import "UIImage+Extension.h" 10 | 11 | 12 | 13 | @implementation UIImage (Extension) 14 | + (UIImage *)imageWithColor:(UIColor *)color { 15 | return [UIImage imageWithColor:color size:CGSizeMake(1.0f, 1.0f)]; 16 | } 17 | 18 | + (UIImage *)imageWithColor:(UIColor *)color size:(CGSize)size { 19 | CGRect rect = CGRectMake(0.0f, 0.0f, size.width, size.height); 20 | UIGraphicsBeginImageContext(size); 21 | CGContextRef context = UIGraphicsGetCurrentContext(); 22 | 23 | CGContextSetFillColorWithColor(context, [color CGColor]); 24 | CGContextFillRect(context, rect); 25 | 26 | UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); 27 | UIGraphicsEndImageContext(); 28 | 29 | return image; 30 | } 31 | @end 32 | -------------------------------------------------------------------------------- /IGListKitDemo/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // IGListKitDemo 4 | // 5 | // Created by gxy on 2018/5/17. 6 | // Copyright © 2018年 gxy. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ViewController : UITableViewController 12 | 13 | 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /IGListKitDemo/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // IGListKitDemo 4 | // 5 | // Created by gxy on 2018/5/17. 6 | // Copyright © 2018年 gxy. All rights reserved. 7 | // 8 | 9 | #import "ViewController.h" 10 | #import "OneCollectionViewController.h" 11 | #import "SecondCollectionViewController.h" 12 | #import "ThirdViewController.h" 13 | #import "ForthViewController.h" 14 | #import "FifthViewController.h" 15 | #import "SixthViewController.h" 16 | @interface ViewController () 17 | 18 | @end 19 | 20 | @implementation ViewController 21 | 22 | - (void)viewDidLoad { 23 | [super viewDidLoad]; 24 | // Do any additional setup after loading the view, typically from a nib. 25 | } 26 | 27 | -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ 28 | switch (indexPath.row) { 29 | case 0:{ 30 | [self.navigationController pushViewController:[OneCollectionViewController new] animated:YES]; 31 | } 32 | break; 33 | case 1:{ 34 | [self.navigationController pushViewController:[SecondCollectionViewController new] animated:YES]; 35 | } 36 | break; 37 | case 2: 38 | [self.navigationController pushViewController:[ThirdViewController new] animated:YES]; 39 | break; 40 | case 3: 41 | [self.navigationController pushViewController:[ForthViewController new] animated:YES]; 42 | break; 43 | case 4: 44 | [self.navigationController pushViewController:[FifthViewController new] animated:YES]; 45 | break; 46 | case 5: 47 | [self.navigationController pushViewController:[SixthViewController new] animated:YES]; 48 | default: 49 | break; 50 | } 51 | } 52 | 53 | 54 | @end 55 | -------------------------------------------------------------------------------- /IGListKitDemo/Views/AdCollectionCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // AdCollectionCell.h 3 | // IGListKitDemo 4 | // 5 | // Created by gxy on 2018/6/25. 6 | // Copyright © 2018年 gxy. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @class ADModel; 13 | @interface AdCollectionCell : UICollectionViewCell 14 | -(void)bindViewModel:(id)viewModel; 15 | @end 16 | -------------------------------------------------------------------------------- /IGListKitDemo/Views/AdCollectionCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // AdCollectionCell.m 3 | // IGListKitDemo 4 | // 5 | // Created by gxy on 2018/6/25. 6 | // Copyright © 2018年 gxy. All rights reserved. 7 | // 8 | 9 | #import "AdCollectionCell.h" 10 | #import "ADModel.h" 11 | 12 | @interface AdCollectionCell () 13 | @property (weak, nonatomic) IBOutlet UIView *box; 14 | @property (weak, nonatomic) IBOutlet UIImageView *imageView; 15 | @property (weak, nonatomic) IBOutlet UILabel *titleLabel; 16 | @property(nonatomic,strong) UIPanGestureRecognizer *swipeGesture; 17 | @end 18 | 19 | @implementation AdCollectionCell 20 | 21 | - (void)awakeFromNib { 22 | [super awakeFromNib]; 23 | } 24 | 25 | -(void)bindViewModel:(ADModel *)viewModel{ 26 | // [self.imageview sd_setUrl:viewModel.adUrl]; 27 | self.titleLabel.text = viewModel.adTitle; 28 | } 29 | 30 | @end 31 | -------------------------------------------------------------------------------- /IGListKitDemo/Views/AdCollectionCell.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 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /IGListKitDemo/Views/CommentCollectionCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // CommentCollectionCell.h 3 | // IGListKitDemo 4 | // 5 | // Created by gxy on 2018/6/6. 6 | // Copyright © 2018年 gxy. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | @class CommentCollectionCellModel; 12 | @interface CommentCollectionCell : UICollectionViewCell 13 | -(void)bindViewModel:(CommentCollectionCellModel *)viewModel; 14 | @end 15 | -------------------------------------------------------------------------------- /IGListKitDemo/Views/CommentCollectionCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // CommentCollectionCell.m 3 | // IGListKitDemo 4 | // 5 | // Created by gxy on 2018/6/6. 6 | // Copyright © 2018年 gxy. All rights reserved. 7 | // 8 | 9 | #import "CommentCollectionCell.h" 10 | #import "CommentCollectionCellModel.h" 11 | @interface CommentCollectionCell () 12 | @property (weak, nonatomic) IBOutlet UILabel *leftlabel; 13 | @property (weak, nonatomic) IBOutlet UILabel *rightLabel; 14 | 15 | @end 16 | 17 | @implementation CommentCollectionCell 18 | 19 | - (void)awakeFromNib { 20 | [super awakeFromNib]; 21 | // Initialization code 22 | } 23 | 24 | -(void)bindViewModel:(CommentCollectionCellModel *)viewModel{ 25 | self.leftlabel.text = viewModel.person; 26 | self.rightLabel.text = viewModel.comment; 27 | } 28 | @end 29 | -------------------------------------------------------------------------------- /IGListKitDemo/Views/CommentCollectionCell.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 28 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /IGListKitDemo/Views/ContentCollectionCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // ContentCollectionCell.h 3 | // IGListKitDemo 4 | // 5 | // Created by gxy on 2018/5/28. 6 | // Copyright © 2018年 gxy. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | @interface ContentCollectionCell : UICollectionViewCell 12 | -(void)bindViewModel:(NSString *)viewModel; 13 | + (CGFloat)lineHeight; 14 | + (CGFloat)heightWithText:(NSString *)text width:(CGFloat)width; 15 | @end 16 | -------------------------------------------------------------------------------- /IGListKitDemo/Views/ContentCollectionCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // ContentCollectionCell.m 3 | // IGListKitDemo 4 | // 5 | // Created by gxy on 2018/5/28. 6 | // Copyright © 2018年 gxy. All rights reserved. 7 | // 8 | 9 | #import "ContentCollectionCell.h" 10 | 11 | @interface ContentCollectionCell () 12 | @property (weak, nonatomic) IBOutlet UILabel *textLabel; 13 | 14 | @end 15 | 16 | @implementation ContentCollectionCell 17 | 18 | - (void)awakeFromNib { 19 | [super awakeFromNib]; 20 | // Initialization code 21 | } 22 | 23 | -(void)bindViewModel:(NSString *)viewModel{ 24 | self.textLabel.text = viewModel; 25 | } 26 | 27 | +(CGFloat)lineHeight{ 28 | UIFont *font = [UIFont systemFontOfSize:16]; 29 | return font.lineHeight + font.ascender + font.descender; 30 | } 31 | 32 | +(CGFloat)heightWithText:(NSString *)text width:(CGFloat)width{ 33 | UIFont *font = [UIFont systemFontOfSize:16]; 34 | CGSize size = CGSizeMake(width - 20, CGFLOAT_MAX); 35 | CGRect rect = [text boundingRectWithSize:size options:NSStringDrawingUsesFontLeading |NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName:font} context:nil]; 36 | return ceil(rect.size.height) + font.ascender + font.descender; 37 | } 38 | @end 39 | -------------------------------------------------------------------------------- /IGListKitDemo/Views/ContentCollectionCell.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /IGListKitDemo/Views/FavorCollectionCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // FavorCollectionCell.h 3 | // IGListKitDemo 4 | // 5 | // Created by gxy on 2018/6/3. 6 | // Copyright © 2018年 gxy. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @class FavorCollectionCellModel; 13 | @interface FavorCollectionCell : UICollectionViewCell 14 | -(void)bindViewModel:(FavorCollectionCellModel *)viewModel; 15 | @end 16 | -------------------------------------------------------------------------------- /IGListKitDemo/Views/FavorCollectionCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // FavorCollectionCell.m 3 | // IGListKitDemo 4 | // 5 | // Created by gxy on 2018/6/3. 6 | // Copyright © 2018年 gxy. All rights reserved. 7 | // 8 | 9 | #import "FavorCollectionCell.h" 10 | #import "FavorCollectionCellModel.h" 11 | 12 | #define GBKeyPath(objc, keyPath) @(((void)objc.keyPath, #keyPath)) 13 | 14 | @interface FavorCollectionCell () 15 | @property (weak, nonatomic) IBOutlet UIButton *favorBtn; 16 | @property (weak, nonatomic) IBOutlet UILabel *nameLabel; 17 | @property(nonatomic,strong) FavorCollectionCellModel *viewModel; 18 | @end 19 | 20 | @implementation FavorCollectionCell 21 | 22 | -(void)dealloc{ 23 | [self.viewModel removeObserver:self forKeyPath:GBKeyPath(self.viewModel, favorNum)]; 24 | } 25 | 26 | - (void)awakeFromNib { 27 | [super awakeFromNib]; 28 | } 29 | 30 | -(void)bindViewModel:(FavorCollectionCellModel *)viewModel{ 31 | self.viewModel = viewModel; 32 | [self.viewModel addObserver:self forKeyPath:GBKeyPath(self.viewModel, favorNum) options:NSKeyValueObservingOptionNew context:nil]; 33 | self.favorBtn.selected = viewModel.isFavor; 34 | self.nameLabel.text = viewModel.favorNum; 35 | } 36 | 37 | - (IBAction)btnDidClick:(UIButton *)sender { 38 | self.favorBtn.selected = !sender.isSelected; 39 | self.viewModel.isFavor = self.favorBtn.selected; 40 | if (self.viewModel.favorBlock) { 41 | self.viewModel.favorBlock(self.viewModel.isFavor); 42 | } 43 | } 44 | 45 | -(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{ 46 | if ([keyPath isEqualToString:GBKeyPath(self.viewModel, favorNum)]) { 47 | NSString *favorNum = change[NSKeyValueChangeNewKey]; 48 | self.nameLabel.text = favorNum; 49 | } 50 | } 51 | 52 | @end 53 | -------------------------------------------------------------------------------- /IGListKitDemo/Views/FavorCollectionCell.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 30 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /IGListKitDemo/Views/ImageCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // ImageCell.h 3 | // IGListKitDemo 4 | // 5 | // Created by gxy on 2018/5/30. 6 | // Copyright © 2018年 gxy. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ImageCell : UICollectionViewCell 12 | - (void)bindViewModel:(UIImage *)image; 13 | @end 14 | -------------------------------------------------------------------------------- /IGListKitDemo/Views/ImageCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // ImageCell.m 3 | // IGListKitDemo 4 | // 5 | // Created by gxy on 2018/5/30. 6 | // Copyright © 2018年 gxy. All rights reserved. 7 | // 8 | 9 | #import "ImageCell.h" 10 | 11 | @interface ImageCell () 12 | @property (weak, nonatomic) IBOutlet UIImageView *imageView; 13 | 14 | @end 15 | 16 | @implementation ImageCell 17 | 18 | - (void)awakeFromNib { 19 | [super awakeFromNib]; 20 | // Initialization code 21 | } 22 | 23 | -(void)bindViewModel:(UIImage *)image{ 24 | self.imageView.image = image; 25 | } 26 | 27 | @end 28 | -------------------------------------------------------------------------------- /IGListKitDemo/Views/ImageCell.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 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /IGListKitDemo/Views/ImagesCollectionCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // ImagesCollectionCell.h 3 | // IGListKitDemo 4 | // 5 | // Created by gxy on 2018/5/30. 6 | // Copyright © 2018年 gxy. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | @class ImagesCollectionCellModel; 12 | @interface ImagesCollectionCell : UICollectionViewCell 13 | -(void)bindViewModel:(ImagesCollectionCellModel *)viewModel; 14 | @end 15 | -------------------------------------------------------------------------------- /IGListKitDemo/Views/ImagesCollectionCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // ImagesCollectionCell.m 3 | // IGListKitDemo 4 | // 5 | // Created by gxy on 2018/5/30. 6 | // Copyright © 2018年 gxy. All rights reserved. 7 | // 8 | 9 | #import "ImagesCollectionCell.h" 10 | #import "ImageCell.h" 11 | #import "ImagesCollectionCellModel.h" 12 | @interface ImagesCollectionCell () 13 | @property (weak, nonatomic) IBOutlet UICollectionView *collectionView; 14 | @property(nonatomic,strong) ImagesCollectionCellModel *viewModel; 15 | @end 16 | 17 | @implementation ImagesCollectionCell 18 | 19 | - (void)awakeFromNib { 20 | [super awakeFromNib]; 21 | [self.collectionView registerNib:[UINib nibWithNibName:@"ImageCell" bundle:nil] forCellWithReuseIdentifier:@"ImageCell"]; 22 | } 23 | 24 | -(void)bindViewModel:(ImagesCollectionCellModel *)viewModel{ 25 | self.viewModel = viewModel; 26 | [self.collectionView reloadData]; 27 | } 28 | 29 | - (nonnull __kindof UICollectionViewCell *)collectionView:(nonnull UICollectionView *)collectionView cellForItemAtIndexPath:(nonnull NSIndexPath *)indexPath { 30 | ImageCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"ImageCell" forIndexPath:indexPath]; 31 | [cell bindViewModel:self.viewModel.images[indexPath.row]]; 32 | return cell; 33 | } 34 | 35 | - (NSInteger)collectionView:(nonnull UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section { 36 | return self.viewModel.images.count; 37 | } 38 | 39 | -(CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath{ 40 | CGFloat width = (collectionView.bounds.size.width - 40) / 3.f; 41 | return CGSizeMake(width, width); 42 | } 43 | @end 44 | -------------------------------------------------------------------------------- /IGListKitDemo/Views/ImagesCollectionCell.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 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /IGListKitDemo/Views/UserInfoCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // UserInfoCell.h 3 | // IGListKitDemo 4 | // 5 | // Created by gxy on 2018/5/24. 6 | // Copyright © 2018年 gxy. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | #import "UserInfoCellModel.h" 12 | 13 | @class UserInfoCell; 14 | @protocol UserInfoCellDelegate 15 | 16 | - (void)cellDidClickMore:(UserInfoCell *)cell; 17 | 18 | @end 19 | 20 | @interface UserInfoCell : UICollectionViewCell 21 | @property(nonatomic,weak) id delegate; 22 | -(void)bindViewModel:(UserInfoCellModel *)viewModel; 23 | @end 24 | -------------------------------------------------------------------------------- /IGListKitDemo/Views/UserInfoCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // UserInfoCell.m 3 | // IGListKitDemo 4 | // 5 | // Created by gxy on 2018/5/24. 6 | // Copyright © 2018年 gxy. All rights reserved. 7 | // 8 | 9 | #import "UserInfoCell.h" 10 | 11 | @interface UserInfoCell () 12 | @property (weak, nonatomic) IBOutlet UIImageView *avatarView; 13 | @property (weak, nonatomic) IBOutlet UILabel *nameLabel; 14 | 15 | @end 16 | 17 | @implementation UserInfoCell 18 | 19 | - (void)awakeFromNib { 20 | [super awakeFromNib]; 21 | self.avatarView.layer.cornerRadius = 12; 22 | } 23 | 24 | -(void)bindViewModel:(UserInfoCellModel *)viewModel{ 25 | self.avatarView.backgroundColor = [UIColor purpleColor]; 26 | self.nameLabel.text = viewModel.userName; 27 | } 28 | 29 | - (IBAction)clickMore:(id)sender { 30 | if ([self.delegate respondsToSelector:@selector(cellDidClickMore:)]) { 31 | [self.delegate cellDidClickMore:self]; 32 | } 33 | } 34 | @end 35 | -------------------------------------------------------------------------------- /IGListKitDemo/Views/UserInfoCell.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 | 36 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | -------------------------------------------------------------------------------- /IGListKitDemo/data1.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "feedId":1, 4 | "avatar":"http://tse4.mm.bing.net/th?id=OIP.pYkSDAPsbJdgrdN_Oub2QgAAAA&w=196&h=196&c=7&o=5&dpr=2&pid=1.7", 5 | "userName":"Bruce", 6 | "content":"this is a content" 7 | }, 8 | { 9 | "feedId":2, 10 | "avatar":"http://tse4.mm.bing.net/th?id=OIP.pYkSDAPsbJdgrdN_Oub2QgAAAA&w=196&h=196&c=7&o=5&dpr=2&pid=1.7", 11 | "userName":"Bruce", 12 | "content":"11" 13 | },{ 14 | "feedId":3, 15 | "avatar":"http://tse4.mm.bing.net/th?id=OIP.pYkSDAPsbJdgrdN_Oub2QgAAAA&w=196&h=196&c=7&o=5&dpr=2&pid=1.7", 16 | "userName":"Bruce", 17 | "content":"this is a long long long long long long long long long long long long long long long content" 18 | },{ 19 | "feedId":4, 20 | "avatar":"http://tse4.mm.bing.net/th?id=OIP.pYkSDAPsbJdgrdN_Oub2QgAAAA&w=196&h=196&c=7&o=5&dpr=2&pid=1.7", 21 | "userName":"Bruce", 22 | "content":"11" 23 | },{ 24 | "feedId":5, 25 | "avatar":"http://tse4.mm.bing.net/th?id=OIP.pYkSDAPsbJdgrdN_Oub2QgAAAA&w=196&h=196&c=7&o=5&dpr=2&pid=1.7", 26 | "userName":"Bruce", 27 | "content":"11" 28 | } 29 | ] 30 | -------------------------------------------------------------------------------- /IGListKitDemo/data2.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "feedId":1, 4 | "avatar":"http://tse4.mm.bing.net/th?id=OIP.pYkSDAPsbJdgrdN_Oub2QgAAAA&w=196&h=196&c=7&o=5&dpr=2&pid=1.7", 5 | "userName":"Bruce", 6 | "content":"this is a content", 7 | "images":["red","blue"] 8 | }, 9 | { 10 | "feedId":2, 11 | "avatar":"http://tse4.mm.bing.net/th?id=OIP.pYkSDAPsbJdgrdN_Oub2QgAAAA&w=196&h=196&c=7&o=5&dpr=2&pid=1.7", 12 | "userName":"Bruce", 13 | "content":"11", 14 | "images":[] 15 | },{ 16 | "feedId":3, 17 | "avatar":"http://tse4.mm.bing.net/th?id=OIP.pYkSDAPsbJdgrdN_Oub2QgAAAA&w=196&h=196&c=7&o=5&dpr=2&pid=1.7", 18 | "userName":"Bruce", 19 | "content":"this is a long long long long long long long long long long long long long long long content", 20 | "images":["red","blue","yellow"] 21 | },{ 22 | "feedId":4, 23 | "avatar":"http://tse4.mm.bing.net/th?id=OIP.pYkSDAPsbJdgrdN_Oub2QgAAAA&w=196&h=196&c=7&o=5&dpr=2&pid=1.7", 24 | "userName":"Bruce", 25 | "content":"11", 26 | "images":["red","blue","yellow","green"] 27 | },{ 28 | "feedId":5, 29 | "avatar":"http://tse4.mm.bing.net/th?id=OIP.pYkSDAPsbJdgrdN_Oub2QgAAAA&w=196&h=196&c=7&o=5&dpr=2&pid=1.7", 30 | "userName":"Bruce", 31 | "content":null, 32 | "images":["red"] 33 | } 34 | ] 35 | -------------------------------------------------------------------------------- /IGListKitDemo/data3.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "feedId":1, 4 | "avatar":"http://tse4.mm.bing.net/th?id=OIP.pYkSDAPsbJdgrdN_Oub2QgAAAA&w=196&h=196&c=7&o=5&dpr=2&pid=1.7", 5 | "userName":"Bruce", 6 | "content":"this is a content", 7 | "images":["red","blue"], 8 | "isFavor":true, 9 | "favor":10 10 | }, 11 | { 12 | "feedId":2, 13 | "avatar":"http://tse4.mm.bing.net/th?id=OIP.pYkSDAPsbJdgrdN_Oub2QgAAAA&w=196&h=196&c=7&o=5&dpr=2&pid=1.7", 14 | "userName":"Bruce", 15 | "content":"11", 16 | "images":[], 17 | "isFavor":false, 18 | "favor":10 19 | },{ 20 | "feedId":3, 21 | "avatar":"http://tse4.mm.bing.net/th?id=OIP.pYkSDAPsbJdgrdN_Oub2QgAAAA&w=196&h=196&c=7&o=5&dpr=2&pid=1.7", 22 | "userName":"Bruce", 23 | "content":"this is a long long long long long long long long long long long long long long long content", 24 | "images":["red","blue","yellow"], 25 | "isFavor":false, 26 | "favor":10 27 | },{ 28 | "feedId":4, 29 | "avatar":"http://tse4.mm.bing.net/th?id=OIP.pYkSDAPsbJdgrdN_Oub2QgAAAA&w=196&h=196&c=7&o=5&dpr=2&pid=1.7", 30 | "userName":"Bruce", 31 | "content":"11", 32 | "images":["red","blue","yellow","green"], 33 | "isFavor":true, 34 | "favor":10 35 | },{ 36 | "feedId":5, 37 | "avatar":"http://tse4.mm.bing.net/th?id=OIP.pYkSDAPsbJdgrdN_Oub2QgAAAA&w=196&h=196&c=7&o=5&dpr=2&pid=1.7", 38 | "userName":"Bruce", 39 | "content":null, 40 | "images":["red"], 41 | "isFavor":true, 42 | "favor":10 43 | } 44 | ] 45 | 46 | -------------------------------------------------------------------------------- /IGListKitDemo/data4.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "feedId":1, 4 | "avatar":"http://tse4.mm.bing.net/th?id=OIP.pYkSDAPsbJdgrdN_Oub2QgAAAA&w=196&h=196&c=7&o=5&dpr=2&pid=1.7", 5 | "userName":"Bruce", 6 | "content":"this is a content", 7 | "images":["red","blue"], 8 | "isFavor":true, 9 | "favor":10, 10 | "comments":[{ 11 | "comment":"comment 1", 12 | "person":"jack" 13 | }] 14 | }, 15 | { 16 | "feedId":2, 17 | "avatar":"http://tse4.mm.bing.net/th?id=OIP.pYkSDAPsbJdgrdN_Oub2QgAAAA&w=196&h=196&c=7&o=5&dpr=2&pid=1.7", 18 | "userName":"Bruce", 19 | "content":"11", 20 | "images":[], 21 | "isFavor":false, 22 | "favor":10, 23 | "comments":[] 24 | },{ 25 | "feedId":3, 26 | "avatar":"http://tse4.mm.bing.net/th?id=OIP.pYkSDAPsbJdgrdN_Oub2QgAAAA&w=196&h=196&c=7&o=5&dpr=2&pid=1.7", 27 | "userName":"Bruce", 28 | "content":"this is a long long long long long long long long long long long long long long long content", 29 | "images":["red","blue","yellow"], 30 | "isFavor":false, 31 | "favor":10, 32 | "comments":[{ 33 | "comment":"comment 3", 34 | "person":"jane" 35 | }] 36 | },{ 37 | "feedId":4, 38 | "avatar":"http://tse4.mm.bing.net/th?id=OIP.pYkSDAPsbJdgrdN_Oub2QgAAAA&w=196&h=196&c=7&o=5&dpr=2&pid=1.7", 39 | "userName":"Bruce", 40 | "content":"11", 41 | "images":["red","blue","yellow","green"], 42 | "isFavor":true, 43 | "favor":10, 44 | "comments":[{ 45 | "comment":"cav", 46 | "person":"james" 47 | }, 48 | { 49 | "comment":"boston", 50 | "person":"irving" 51 | }, 52 | { 53 | "comment":"cav", 54 | "person":"love" 55 | }] 56 | },{ 57 | "feedId":5, 58 | "avatar":"http://tse4.mm.bing.net/th?id=OIP.pYkSDAPsbJdgrdN_Oub2QgAAAA&w=196&h=196&c=7&o=5&dpr=2&pid=1.7", 59 | "userName":"Bruce", 60 | "content":null, 61 | "images":["red"], 62 | "isFavor":true, 63 | "favor":10, 64 | "comments":[{ 65 | "comment":"comment 1", 66 | "person":"jack" 67 | }] 68 | } 69 | ] 70 | 71 | -------------------------------------------------------------------------------- /IGListKitDemo/data5.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "type": 1, 4 | "data": { 5 | "avatar": "http://tse4.mm.bing.net/th?id=OIP.pYkSDAPsbJdgrdN_Oub2QgAAAA&w=196&h=196&c=7&o=5&dpr=2&pid=1.7", 6 | "userName": "Bruce", 7 | "content": "this is a content", 8 | "images": [ 9 | "red", 10 | "blue" 11 | ], 12 | "isFavor": true, 13 | "favor": 10, 14 | "comments": [ 15 | { 16 | "comment": "comment 1", 17 | "person": "jack" 18 | } 19 | ] 20 | } 21 | }, 22 | { 23 | "type": 2, 24 | "data": { 25 | "adTitle": "这是广告", 26 | "adUrl": "" 27 | } 28 | }, 29 | { 30 | "type": 1, 31 | "data": { 32 | "avatar": "http://tse4.mm.bing.net/th?id=OIP.pYkSDAPsbJdgrdN_Oub2QgAAAA&w=196&h=196&c=7&o=5&dpr=2&pid=1.7", 33 | "userName": "Bruce", 34 | "content": "11", 35 | "images": [], 36 | "isFavor": false, 37 | "favor": 10, 38 | "comments": [] 39 | } 40 | }, 41 | { 42 | "type": 1, 43 | "data": { 44 | "avatar": "http://tse4.mm.bing.net/th?id=OIP.pYkSDAPsbJdgrdN_Oub2QgAAAA&w=196&h=196&c=7&o=5&dpr=2&pid=1.7", 45 | "userName": "Bruce", 46 | "content": "this is a long long long long long long long long long long long long long long long content", 47 | "images": [ 48 | "red", 49 | "blue", 50 | "yellow" 51 | ], 52 | "isFavor": false, 53 | "favor": 10, 54 | "comments": [ 55 | { 56 | "comment": "comment 3", 57 | "person": "jane" 58 | } 59 | ] 60 | } 61 | }, 62 | { 63 | "type": 1, 64 | "data": { 65 | "avatar": "http://tse4.mm.bing.net/th?id=OIP.pYkSDAPsbJdgrdN_Oub2QgAAAA&w=196&h=196&c=7&o=5&dpr=2&pid=1.7", 66 | "userName": "Bruce", 67 | "content": "11", 68 | "images": [ 69 | "red", 70 | "blue", 71 | "yellow", 72 | "green" 73 | ], 74 | "isFavor": true, 75 | "favor": 10, 76 | "comments": [ 77 | { 78 | "comment": "cav", 79 | "person": "james" 80 | }, 81 | { 82 | "comment": "boston", 83 | "person": "irving" 84 | }, 85 | { 86 | "comment": "cav", 87 | "person": "love" 88 | } 89 | ] 90 | } 91 | }, 92 | { 93 | "type": 2, 94 | "data": { 95 | "adTitle": "这是广告", 96 | "adUrl": "" 97 | } 98 | } 99 | ] 100 | -------------------------------------------------------------------------------- /IGListKitDemo/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // IGListKitDemo 4 | // 5 | // Created by gxy on 2018/5/17. 6 | // Copyright © 2018年 gxy. 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 | -------------------------------------------------------------------------------- /Podfile: -------------------------------------------------------------------------------- 1 | platform:ios,'8.0' 2 | inhibit_all_warnings! 3 | 4 | target 'IGListKitDemo' do 5 | pod 'IGListKit' 6 | pod 'MJExtension' 7 | end 8 | -------------------------------------------------------------------------------- /Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - IGListKit (3.4.0): 3 | - IGListKit/Default (= 3.4.0) 4 | - IGListKit/Default (3.4.0): 5 | - IGListKit/Diffing 6 | - IGListKit/Diffing (3.4.0) 7 | - MJExtension (3.0.13) 8 | 9 | DEPENDENCIES: 10 | - IGListKit 11 | - MJExtension 12 | 13 | SPEC CHECKSUMS: 14 | IGListKit: 7a5d788e9fb746bcd402baa8e8b24bc3bd2a5a07 15 | MJExtension: 5932755f451458eefa24239358817f8d291240c7 16 | 17 | PODFILE CHECKSUM: cee3afcc89f0a59613b1a5dab030e058dadcb9c3 18 | 19 | COCOAPODS: 1.3.1 20 | --------------------------------------------------------------------------------