├── .gitignore ├── Podfile ├── README.md ├── bizhi.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ └── contents.xcworkspacedata └── xcuserdata │ └── limboy.xcuserdatad │ └── xcschemes │ ├── bizhi.xcscheme │ └── xcschememanagement.plist ├── bizhi.xcworkspace └── contents.xcworkspacedata ├── bizhi ├── BZAPIManager.h ├── BZAPIManager.m ├── BZAppDelegate.h ├── BZAppDelegate.m ├── BZDetailModule.h ├── BZDetailModule.m ├── BZDetailViewCell.h ├── BZDetailViewCell.m ├── BZDetailViewController.h ├── BZDetailViewController.m ├── BZPinModel.h ├── BZPinModel.m ├── BZSettingsModule.h ├── BZSettingsModule.m ├── BZSettingsViewController.h ├── BZSettingsViewController.m ├── BZTagModel.h ├── BZTagModel.m ├── BZTagsModule.h ├── BZTagsModule.m ├── BZTagsViewController.h ├── BZTagsViewController.m ├── BZWaterfallModule.h ├── BZWaterfallModule.m ├── BZWaterfallViewCell.h ├── BZWaterfallViewCell.m ├── BZWaterfallViewCellModel.h ├── BZWaterfallViewCellModel.m ├── BZWaterfallViewController.h ├── BZWaterfallViewController.m ├── BZWaterfallViewModel.h ├── BZWaterfallViewModel.m ├── Images.xcassets │ ├── AppIcon.appiconset │ │ ├── Contents.json │ │ └── icon.png │ ├── LaunchImage.launchimage │ │ ├── Contents.json │ │ └── launch.png │ ├── button_download.imageset │ │ ├── Contents.json │ │ └── button_download@2x.png │ ├── button_share.imageset │ │ ├── Contents.json │ │ └── button_share@2x.png │ ├── categories.imageset │ │ ├── Contents.json │ │ └── categories@2x.png │ ├── latest.imageset │ │ ├── Contents.json │ │ └── latest@2x.png │ ├── settings.imageset │ │ ├── Contents.json │ │ └── settings@2x.png │ └── trash.imageset │ │ ├── Contents.json │ │ └── trash@2x.png ├── Protocols.h ├── UICollectionView+FixRefreshControlJump.h ├── UICollectionView+FixRefreshControlJump.m ├── UIColor+LightRandom.h ├── UIColor+LightRandom.m ├── UIView+Layout.h ├── UIView+Layout.m ├── UIView+SuperView.h ├── UIView+SuperView.m ├── UtilsMacro.h ├── bizhi-Info.plist ├── bizhi-Prefix.pch ├── en.lproj │ └── InfoPlist.strings └── main.m ├── bizhiTests ├── bizhiTests-Info.plist ├── bizhiTests.m └── en.lproj │ └── InfoPlist.strings └── screenshot.jpg /.gitignore: -------------------------------------------------------------------------------- 1 | # OS X 2 | .DS_Store 3 | 4 | # Xcode 5 | build/ 6 | *.pbxuser 7 | !default.pbxuser 8 | *.mode1v3 9 | !default.mode1v3 10 | *.mode2v3 11 | !default.mode2v3 12 | *.perspectivev3 13 | !default.perspectivev3 14 | xcuserdata 15 | *.xccheckout 16 | profile 17 | *.moved-aside 18 | DerivedData 19 | *.hmap 20 | *.ipa 21 | 22 | # CocoaPods 23 | # Pods 24 | Pods 25 | Podfile.lock 26 | -------------------------------------------------------------------------------- /Podfile: -------------------------------------------------------------------------------- 1 | platform :ios, '6.1' 2 | inhibit_all_warnings! 3 | 4 | pod 'AFNetworking', '~>2.2' 5 | pod 'SDWebImage', '~>3.6' 6 | pod 'ReactiveCocoa', '~>2.3' 7 | pod 'SVProgressHUD', '~>1.0' 8 | pod 'SVPullToRefresh', '~>0.4' 9 | pod 'ReactiveViewModel', '~>0.1' 10 | pod 'CHTCollectionViewWaterfallLayout', '~>0.4' 11 | pod 'JSONModel', '~>0.13' 12 | pod 'AFNetworking-RACExtensions', '~>0.1' 13 | pod 'Objection', '~> 0.9' 14 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ### Introduction 2 | 3 | A simple Wallpaper App to demonstrate the use of [ReactiveCocoa2](https://github.com/ReactiveCocoa/ReactiveCocoa), [MVVM](https://github.com/ReactiveCocoa/ReactiveViewModel) and [objection](https://github.com/atomicobject/objection) 4 | 5 | ### ScreenShots 6 | 7 | ![Screenshot](https://raw.githubusercontent.com/lzyy/bizhi/master/screenshot.jpg) 8 | 9 | ### Install 10 | 11 | after cloned to local, run `pod install` 12 | -------------------------------------------------------------------------------- /bizhi.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 6A1D3949190E71DE00F1EA81 /* BZTagModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 6A1D3948190E71DE00F1EA81 /* BZTagModel.m */; }; 11 | 6A1D3952190E73C600F1EA81 /* UICollectionView+FixRefreshControlJump.m in Sources */ = {isa = PBXBuildFile; fileRef = 6A1D394F190E73C600F1EA81 /* UICollectionView+FixRefreshControlJump.m */; }; 12 | 6A1D3953190E73C600F1EA81 /* UIColor+LightRandom.m in Sources */ = {isa = PBXBuildFile; fileRef = 6A1D3951190E73C600F1EA81 /* UIColor+LightRandom.m */; }; 13 | 6A1D3959190E73F400F1EA81 /* BZSettingsModule.m in Sources */ = {isa = PBXBuildFile; fileRef = 6A1D3956190E73F400F1EA81 /* BZSettingsModule.m */; }; 14 | 6A1D395A190E73F400F1EA81 /* BZSettingsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6A1D3958190E73F400F1EA81 /* BZSettingsViewController.m */; }; 15 | 6A1D3963190E742800F1EA81 /* BZTagsModule.m in Sources */ = {isa = PBXBuildFile; fileRef = 6A1D3960190E742800F1EA81 /* BZTagsModule.m */; }; 16 | 6A1D3964190E742800F1EA81 /* BZTagsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6A1D3962190E742800F1EA81 /* BZTagsViewController.m */; }; 17 | 6A1D396B190E743A00F1EA81 /* BZDetailModule.m in Sources */ = {isa = PBXBuildFile; fileRef = 6A1D3966190E743A00F1EA81 /* BZDetailModule.m */; }; 18 | 6A1D396C190E743A00F1EA81 /* BZDetailViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 6A1D3968190E743A00F1EA81 /* BZDetailViewCell.m */; }; 19 | 6A1D396D190E743A00F1EA81 /* BZDetailViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6A1D396A190E743A00F1EA81 /* BZDetailViewController.m */; }; 20 | 6A1D3978190E744500F1EA81 /* BZWaterfallModule.m in Sources */ = {isa = PBXBuildFile; fileRef = 6A1D396F190E744500F1EA81 /* BZWaterfallModule.m */; }; 21 | 6A1D3979190E744500F1EA81 /* BZWaterfallViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 6A1D3971190E744500F1EA81 /* BZWaterfallViewCell.m */; }; 22 | 6A1D397A190E744500F1EA81 /* BZWaterfallViewCellModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 6A1D3973190E744500F1EA81 /* BZWaterfallViewCellModel.m */; }; 23 | 6A1D397B190E744500F1EA81 /* BZWaterfallViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6A1D3975190E744500F1EA81 /* BZWaterfallViewController.m */; }; 24 | 6A1D397C190E744500F1EA81 /* BZWaterfallViewModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 6A1D3977190E744500F1EA81 /* BZWaterfallViewModel.m */; }; 25 | 6A1D397F190E792800F1EA81 /* UIView+SuperView.m in Sources */ = {isa = PBXBuildFile; fileRef = 6A1D397E190E792800F1EA81 /* UIView+SuperView.m */; }; 26 | 6A1D3982190E797E00F1EA81 /* UIView+Layout.m in Sources */ = {isa = PBXBuildFile; fileRef = 6A1D3981190E797E00F1EA81 /* UIView+Layout.m */; }; 27 | 6A33AC14190E555D007A121D /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6A33AC13190E555D007A121D /* Foundation.framework */; }; 28 | 6A33AC16190E555D007A121D /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6A33AC15190E555D007A121D /* CoreGraphics.framework */; }; 29 | 6A33AC18190E555D007A121D /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6A33AC17190E555D007A121D /* UIKit.framework */; }; 30 | 6A33AC1E190E555D007A121D /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 6A33AC1C190E555D007A121D /* InfoPlist.strings */; }; 31 | 6A33AC20190E555D007A121D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 6A33AC1F190E555D007A121D /* main.m */; }; 32 | 6A33AC24190E555D007A121D /* BZAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 6A33AC23190E555D007A121D /* BZAppDelegate.m */; }; 33 | 6A33AC26190E555D007A121D /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6A33AC25190E555D007A121D /* Images.xcassets */; }; 34 | 6A33AC2D190E555D007A121D /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6A33AC2C190E555D007A121D /* XCTest.framework */; }; 35 | 6A33AC2E190E555D007A121D /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6A33AC13190E555D007A121D /* Foundation.framework */; }; 36 | 6A33AC2F190E555D007A121D /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6A33AC17190E555D007A121D /* UIKit.framework */; }; 37 | 6A33AC37190E555D007A121D /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 6A33AC35190E555D007A121D /* InfoPlist.strings */; }; 38 | 6A33AC39190E555D007A121D /* bizhiTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 6A33AC38190E555D007A121D /* bizhiTests.m */; }; 39 | 6A33AC46190E5899007A121D /* BZPinModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 6A33AC45190E5899007A121D /* BZPinModel.m */; }; 40 | 6A33AC49190E5B29007A121D /* BZAPIManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 6A33AC48190E5B29007A121D /* BZAPIManager.m */; }; 41 | F0F70AFBB7FF42679A7237C3 /* libPods.a in Frameworks */ = {isa = PBXBuildFile; fileRef = A0D08661F7C4427985F32208 /* libPods.a */; }; 42 | /* End PBXBuildFile section */ 43 | 44 | /* Begin PBXContainerItemProxy section */ 45 | 6A33AC30190E555D007A121D /* PBXContainerItemProxy */ = { 46 | isa = PBXContainerItemProxy; 47 | containerPortal = 6A33AC08190E555D007A121D /* Project object */; 48 | proxyType = 1; 49 | remoteGlobalIDString = 6A33AC0F190E555D007A121D; 50 | remoteInfo = bizhi; 51 | }; 52 | /* End PBXContainerItemProxy section */ 53 | 54 | /* Begin PBXFileReference section */ 55 | 6A1D3947190E71DE00F1EA81 /* BZTagModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BZTagModel.h; sourceTree = ""; }; 56 | 6A1D3948190E71DE00F1EA81 /* BZTagModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BZTagModel.m; sourceTree = ""; }; 57 | 6A1D394E190E73C600F1EA81 /* UICollectionView+FixRefreshControlJump.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UICollectionView+FixRefreshControlJump.h"; sourceTree = ""; }; 58 | 6A1D394F190E73C600F1EA81 /* UICollectionView+FixRefreshControlJump.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UICollectionView+FixRefreshControlJump.m"; sourceTree = ""; }; 59 | 6A1D3950190E73C600F1EA81 /* UIColor+LightRandom.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIColor+LightRandom.h"; sourceTree = ""; }; 60 | 6A1D3951190E73C600F1EA81 /* UIColor+LightRandom.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIColor+LightRandom.m"; sourceTree = ""; }; 61 | 6A1D3954190E73DE00F1EA81 /* Protocols.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Protocols.h; sourceTree = ""; }; 62 | 6A1D3955190E73F400F1EA81 /* BZSettingsModule.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BZSettingsModule.h; sourceTree = ""; }; 63 | 6A1D3956190E73F400F1EA81 /* BZSettingsModule.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BZSettingsModule.m; sourceTree = ""; }; 64 | 6A1D3957190E73F400F1EA81 /* BZSettingsViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BZSettingsViewController.h; sourceTree = ""; }; 65 | 6A1D3958190E73F400F1EA81 /* BZSettingsViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BZSettingsViewController.m; sourceTree = ""; }; 66 | 6A1D395F190E742800F1EA81 /* BZTagsModule.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BZTagsModule.h; sourceTree = ""; }; 67 | 6A1D3960190E742800F1EA81 /* BZTagsModule.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BZTagsModule.m; sourceTree = ""; }; 68 | 6A1D3961190E742800F1EA81 /* BZTagsViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BZTagsViewController.h; sourceTree = ""; }; 69 | 6A1D3962190E742800F1EA81 /* BZTagsViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BZTagsViewController.m; sourceTree = ""; }; 70 | 6A1D3965190E743A00F1EA81 /* BZDetailModule.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BZDetailModule.h; sourceTree = ""; }; 71 | 6A1D3966190E743A00F1EA81 /* BZDetailModule.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BZDetailModule.m; sourceTree = ""; }; 72 | 6A1D3967190E743A00F1EA81 /* BZDetailViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BZDetailViewCell.h; sourceTree = ""; }; 73 | 6A1D3968190E743A00F1EA81 /* BZDetailViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BZDetailViewCell.m; sourceTree = ""; }; 74 | 6A1D3969190E743A00F1EA81 /* BZDetailViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BZDetailViewController.h; sourceTree = ""; }; 75 | 6A1D396A190E743A00F1EA81 /* BZDetailViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BZDetailViewController.m; sourceTree = ""; }; 76 | 6A1D396E190E744500F1EA81 /* BZWaterfallModule.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BZWaterfallModule.h; sourceTree = ""; }; 77 | 6A1D396F190E744500F1EA81 /* BZWaterfallModule.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BZWaterfallModule.m; sourceTree = ""; }; 78 | 6A1D3970190E744500F1EA81 /* BZWaterfallViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BZWaterfallViewCell.h; sourceTree = ""; }; 79 | 6A1D3971190E744500F1EA81 /* BZWaterfallViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BZWaterfallViewCell.m; sourceTree = ""; }; 80 | 6A1D3972190E744500F1EA81 /* BZWaterfallViewCellModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BZWaterfallViewCellModel.h; sourceTree = ""; }; 81 | 6A1D3973190E744500F1EA81 /* BZWaterfallViewCellModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BZWaterfallViewCellModel.m; sourceTree = ""; }; 82 | 6A1D3974190E744500F1EA81 /* BZWaterfallViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BZWaterfallViewController.h; sourceTree = ""; }; 83 | 6A1D3975190E744500F1EA81 /* BZWaterfallViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BZWaterfallViewController.m; sourceTree = ""; }; 84 | 6A1D3976190E744500F1EA81 /* BZWaterfallViewModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BZWaterfallViewModel.h; sourceTree = ""; }; 85 | 6A1D3977190E744500F1EA81 /* BZWaterfallViewModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BZWaterfallViewModel.m; sourceTree = ""; }; 86 | 6A1D397D190E792800F1EA81 /* UIView+SuperView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIView+SuperView.h"; sourceTree = ""; }; 87 | 6A1D397E190E792800F1EA81 /* UIView+SuperView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIView+SuperView.m"; sourceTree = ""; }; 88 | 6A1D3980190E797E00F1EA81 /* UIView+Layout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIView+Layout.h"; sourceTree = ""; }; 89 | 6A1D3981190E797E00F1EA81 /* UIView+Layout.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIView+Layout.m"; sourceTree = ""; }; 90 | 6A1D3983190E79B800F1EA81 /* UtilsMacro.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UtilsMacro.h; sourceTree = ""; }; 91 | 6A33AC10190E555D007A121D /* bizhi.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = bizhi.app; sourceTree = BUILT_PRODUCTS_DIR; }; 92 | 6A33AC13190E555D007A121D /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 93 | 6A33AC15190E555D007A121D /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; 94 | 6A33AC17190E555D007A121D /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 95 | 6A33AC1B190E555D007A121D /* bizhi-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "bizhi-Info.plist"; sourceTree = ""; }; 96 | 6A33AC1D190E555D007A121D /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 97 | 6A33AC1F190E555D007A121D /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 98 | 6A33AC21190E555D007A121D /* bizhi-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "bizhi-Prefix.pch"; sourceTree = ""; }; 99 | 6A33AC22190E555D007A121D /* BZAppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = BZAppDelegate.h; sourceTree = ""; }; 100 | 6A33AC23190E555D007A121D /* BZAppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = BZAppDelegate.m; sourceTree = ""; }; 101 | 6A33AC25190E555D007A121D /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 102 | 6A33AC2B190E555D007A121D /* bizhiTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = bizhiTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 103 | 6A33AC2C190E555D007A121D /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; }; 104 | 6A33AC34190E555D007A121D /* bizhiTests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "bizhiTests-Info.plist"; sourceTree = ""; }; 105 | 6A33AC36190E555D007A121D /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 106 | 6A33AC38190E555D007A121D /* bizhiTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = bizhiTests.m; sourceTree = ""; }; 107 | 6A33AC44190E5899007A121D /* BZPinModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BZPinModel.h; sourceTree = ""; }; 108 | 6A33AC45190E5899007A121D /* BZPinModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BZPinModel.m; sourceTree = ""; }; 109 | 6A33AC47190E5B29007A121D /* BZAPIManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BZAPIManager.h; sourceTree = ""; }; 110 | 6A33AC48190E5B29007A121D /* BZAPIManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BZAPIManager.m; sourceTree = ""; }; 111 | 974EF92767827CB8C89FBBF8 /* Pods.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = Pods.debug.xcconfig; path = "Pods/Target Support Files/Pods/Pods.debug.xcconfig"; sourceTree = ""; }; 112 | A0D08661F7C4427985F32208 /* libPods.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libPods.a; sourceTree = BUILT_PRODUCTS_DIR; }; 113 | AB1BE59522E79D7CA0EB2783 /* Pods.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = Pods.release.xcconfig; path = "Pods/Target Support Files/Pods/Pods.release.xcconfig"; sourceTree = ""; }; 114 | /* End PBXFileReference section */ 115 | 116 | /* Begin PBXFrameworksBuildPhase section */ 117 | 6A33AC0D190E555D007A121D /* Frameworks */ = { 118 | isa = PBXFrameworksBuildPhase; 119 | buildActionMask = 2147483647; 120 | files = ( 121 | 6A33AC16190E555D007A121D /* CoreGraphics.framework in Frameworks */, 122 | 6A33AC18190E555D007A121D /* UIKit.framework in Frameworks */, 123 | 6A33AC14190E555D007A121D /* Foundation.framework in Frameworks */, 124 | F0F70AFBB7FF42679A7237C3 /* libPods.a in Frameworks */, 125 | ); 126 | runOnlyForDeploymentPostprocessing = 0; 127 | }; 128 | 6A33AC28190E555D007A121D /* Frameworks */ = { 129 | isa = PBXFrameworksBuildPhase; 130 | buildActionMask = 2147483647; 131 | files = ( 132 | 6A33AC2D190E555D007A121D /* XCTest.framework in Frameworks */, 133 | 6A33AC2F190E555D007A121D /* UIKit.framework in Frameworks */, 134 | 6A33AC2E190E555D007A121D /* Foundation.framework in Frameworks */, 135 | ); 136 | runOnlyForDeploymentPostprocessing = 0; 137 | }; 138 | /* End PBXFrameworksBuildPhase section */ 139 | 140 | /* Begin PBXGroup section */ 141 | 212622ECF56172E953E659A6 /* Pods */ = { 142 | isa = PBXGroup; 143 | children = ( 144 | 974EF92767827CB8C89FBBF8 /* Pods.debug.xcconfig */, 145 | AB1BE59522E79D7CA0EB2783 /* Pods.release.xcconfig */, 146 | ); 147 | name = Pods; 148 | sourceTree = ""; 149 | }; 150 | 6A1D394B190E738000F1EA81 /* Modules */ = { 151 | isa = PBXGroup; 152 | children = ( 153 | 6A1D395E190E741700F1EA81 /* Detail */, 154 | 6A1D395D190E740F00F1EA81 /* Waterfall */, 155 | 6A1D395C190E73FF00F1EA81 /* Tags */, 156 | 6A1D395B190E73F600F1EA81 /* Settings */, 157 | ); 158 | name = Modules; 159 | sourceTree = ""; 160 | }; 161 | 6A1D394C190E738900F1EA81 /* Protocols */ = { 162 | isa = PBXGroup; 163 | children = ( 164 | 6A1D3954190E73DE00F1EA81 /* Protocols.h */, 165 | ); 166 | name = Protocols; 167 | sourceTree = ""; 168 | }; 169 | 6A1D394D190E739800F1EA81 /* Categories */ = { 170 | isa = PBXGroup; 171 | children = ( 172 | 6A1D397D190E792800F1EA81 /* UIView+SuperView.h */, 173 | 6A1D397E190E792800F1EA81 /* UIView+SuperView.m */, 174 | 6A1D394E190E73C600F1EA81 /* UICollectionView+FixRefreshControlJump.h */, 175 | 6A1D394F190E73C600F1EA81 /* UICollectionView+FixRefreshControlJump.m */, 176 | 6A1D3950190E73C600F1EA81 /* UIColor+LightRandom.h */, 177 | 6A1D3951190E73C600F1EA81 /* UIColor+LightRandom.m */, 178 | 6A1D3980190E797E00F1EA81 /* UIView+Layout.h */, 179 | 6A1D3981190E797E00F1EA81 /* UIView+Layout.m */, 180 | ); 181 | name = Categories; 182 | sourceTree = ""; 183 | }; 184 | 6A1D395B190E73F600F1EA81 /* Settings */ = { 185 | isa = PBXGroup; 186 | children = ( 187 | 6A1D3955190E73F400F1EA81 /* BZSettingsModule.h */, 188 | 6A1D3956190E73F400F1EA81 /* BZSettingsModule.m */, 189 | 6A1D3957190E73F400F1EA81 /* BZSettingsViewController.h */, 190 | 6A1D3958190E73F400F1EA81 /* BZSettingsViewController.m */, 191 | ); 192 | name = Settings; 193 | sourceTree = ""; 194 | }; 195 | 6A1D395C190E73FF00F1EA81 /* Tags */ = { 196 | isa = PBXGroup; 197 | children = ( 198 | 6A1D395F190E742800F1EA81 /* BZTagsModule.h */, 199 | 6A1D3960190E742800F1EA81 /* BZTagsModule.m */, 200 | 6A1D3961190E742800F1EA81 /* BZTagsViewController.h */, 201 | 6A1D3962190E742800F1EA81 /* BZTagsViewController.m */, 202 | ); 203 | name = Tags; 204 | sourceTree = ""; 205 | }; 206 | 6A1D395D190E740F00F1EA81 /* Waterfall */ = { 207 | isa = PBXGroup; 208 | children = ( 209 | 6A1D396E190E744500F1EA81 /* BZWaterfallModule.h */, 210 | 6A1D396F190E744500F1EA81 /* BZWaterfallModule.m */, 211 | 6A1D3970190E744500F1EA81 /* BZWaterfallViewCell.h */, 212 | 6A1D3971190E744500F1EA81 /* BZWaterfallViewCell.m */, 213 | 6A1D3972190E744500F1EA81 /* BZWaterfallViewCellModel.h */, 214 | 6A1D3973190E744500F1EA81 /* BZWaterfallViewCellModel.m */, 215 | 6A1D3974190E744500F1EA81 /* BZWaterfallViewController.h */, 216 | 6A1D3975190E744500F1EA81 /* BZWaterfallViewController.m */, 217 | 6A1D3976190E744500F1EA81 /* BZWaterfallViewModel.h */, 218 | 6A1D3977190E744500F1EA81 /* BZWaterfallViewModel.m */, 219 | ); 220 | name = Waterfall; 221 | sourceTree = ""; 222 | }; 223 | 6A1D395E190E741700F1EA81 /* Detail */ = { 224 | isa = PBXGroup; 225 | children = ( 226 | 6A1D3965190E743A00F1EA81 /* BZDetailModule.h */, 227 | 6A1D3966190E743A00F1EA81 /* BZDetailModule.m */, 228 | 6A1D3967190E743A00F1EA81 /* BZDetailViewCell.h */, 229 | 6A1D3968190E743A00F1EA81 /* BZDetailViewCell.m */, 230 | 6A1D3969190E743A00F1EA81 /* BZDetailViewController.h */, 231 | 6A1D396A190E743A00F1EA81 /* BZDetailViewController.m */, 232 | ); 233 | name = Detail; 234 | sourceTree = ""; 235 | }; 236 | 6A33AC07190E555D007A121D = { 237 | isa = PBXGroup; 238 | children = ( 239 | 6A33AC19190E555D007A121D /* bizhi */, 240 | 6A33AC32190E555D007A121D /* bizhiTests */, 241 | 6A33AC12190E555D007A121D /* Frameworks */, 242 | 6A33AC11190E555D007A121D /* Products */, 243 | 212622ECF56172E953E659A6 /* Pods */, 244 | ); 245 | sourceTree = ""; 246 | }; 247 | 6A33AC11190E555D007A121D /* Products */ = { 248 | isa = PBXGroup; 249 | children = ( 250 | 6A33AC10190E555D007A121D /* bizhi.app */, 251 | 6A33AC2B190E555D007A121D /* bizhiTests.xctest */, 252 | ); 253 | name = Products; 254 | sourceTree = ""; 255 | }; 256 | 6A33AC12190E555D007A121D /* Frameworks */ = { 257 | isa = PBXGroup; 258 | children = ( 259 | 6A33AC13190E555D007A121D /* Foundation.framework */, 260 | 6A33AC15190E555D007A121D /* CoreGraphics.framework */, 261 | 6A33AC17190E555D007A121D /* UIKit.framework */, 262 | 6A33AC2C190E555D007A121D /* XCTest.framework */, 263 | A0D08661F7C4427985F32208 /* libPods.a */, 264 | ); 265 | name = Frameworks; 266 | sourceTree = ""; 267 | }; 268 | 6A33AC19190E555D007A121D /* bizhi */ = { 269 | isa = PBXGroup; 270 | children = ( 271 | 6A1D3983190E79B800F1EA81 /* UtilsMacro.h */, 272 | 6A1D394D190E739800F1EA81 /* Categories */, 273 | 6A1D394C190E738900F1EA81 /* Protocols */, 274 | 6A1D394B190E738000F1EA81 /* Modules */, 275 | 6A33AC42190E57D2007A121D /* API */, 276 | 6A33AC22190E555D007A121D /* BZAppDelegate.h */, 277 | 6A33AC23190E555D007A121D /* BZAppDelegate.m */, 278 | 6A33AC25190E555D007A121D /* Images.xcassets */, 279 | 6A33AC1A190E555D007A121D /* Supporting Files */, 280 | ); 281 | path = bizhi; 282 | sourceTree = ""; 283 | }; 284 | 6A33AC1A190E555D007A121D /* Supporting Files */ = { 285 | isa = PBXGroup; 286 | children = ( 287 | 6A33AC1B190E555D007A121D /* bizhi-Info.plist */, 288 | 6A33AC1C190E555D007A121D /* InfoPlist.strings */, 289 | 6A33AC1F190E555D007A121D /* main.m */, 290 | 6A33AC21190E555D007A121D /* bizhi-Prefix.pch */, 291 | ); 292 | name = "Supporting Files"; 293 | sourceTree = ""; 294 | }; 295 | 6A33AC32190E555D007A121D /* bizhiTests */ = { 296 | isa = PBXGroup; 297 | children = ( 298 | 6A33AC38190E555D007A121D /* bizhiTests.m */, 299 | 6A33AC33190E555D007A121D /* Supporting Files */, 300 | ); 301 | path = bizhiTests; 302 | sourceTree = ""; 303 | }; 304 | 6A33AC33190E555D007A121D /* Supporting Files */ = { 305 | isa = PBXGroup; 306 | children = ( 307 | 6A33AC34190E555D007A121D /* bizhiTests-Info.plist */, 308 | 6A33AC35190E555D007A121D /* InfoPlist.strings */, 309 | ); 310 | name = "Supporting Files"; 311 | sourceTree = ""; 312 | }; 313 | 6A33AC42190E57D2007A121D /* API */ = { 314 | isa = PBXGroup; 315 | children = ( 316 | 6A33AC43190E57D7007A121D /* Models */, 317 | 6A33AC47190E5B29007A121D /* BZAPIManager.h */, 318 | 6A33AC48190E5B29007A121D /* BZAPIManager.m */, 319 | ); 320 | name = API; 321 | sourceTree = ""; 322 | }; 323 | 6A33AC43190E57D7007A121D /* Models */ = { 324 | isa = PBXGroup; 325 | children = ( 326 | 6A33AC44190E5899007A121D /* BZPinModel.h */, 327 | 6A33AC45190E5899007A121D /* BZPinModel.m */, 328 | 6A1D3947190E71DE00F1EA81 /* BZTagModel.h */, 329 | 6A1D3948190E71DE00F1EA81 /* BZTagModel.m */, 330 | ); 331 | name = Models; 332 | sourceTree = ""; 333 | }; 334 | /* End PBXGroup section */ 335 | 336 | /* Begin PBXNativeTarget section */ 337 | 6A33AC0F190E555D007A121D /* bizhi */ = { 338 | isa = PBXNativeTarget; 339 | buildConfigurationList = 6A33AC3C190E555D007A121D /* Build configuration list for PBXNativeTarget "bizhi" */; 340 | buildPhases = ( 341 | FA80234022C5483395D76428 /* Check Pods Manifest.lock */, 342 | 6A33AC0C190E555D007A121D /* Sources */, 343 | 6A33AC0D190E555D007A121D /* Frameworks */, 344 | 6A33AC0E190E555D007A121D /* Resources */, 345 | 409B7E4B17BC4FA294A5F3C3 /* Copy Pods Resources */, 346 | ); 347 | buildRules = ( 348 | ); 349 | dependencies = ( 350 | ); 351 | name = bizhi; 352 | productName = bizhi; 353 | productReference = 6A33AC10190E555D007A121D /* bizhi.app */; 354 | productType = "com.apple.product-type.application"; 355 | }; 356 | 6A33AC2A190E555D007A121D /* bizhiTests */ = { 357 | isa = PBXNativeTarget; 358 | buildConfigurationList = 6A33AC3F190E555D007A121D /* Build configuration list for PBXNativeTarget "bizhiTests" */; 359 | buildPhases = ( 360 | 6A33AC27190E555D007A121D /* Sources */, 361 | 6A33AC28190E555D007A121D /* Frameworks */, 362 | 6A33AC29190E555D007A121D /* Resources */, 363 | ); 364 | buildRules = ( 365 | ); 366 | dependencies = ( 367 | 6A33AC31190E555D007A121D /* PBXTargetDependency */, 368 | ); 369 | name = bizhiTests; 370 | productName = bizhiTests; 371 | productReference = 6A33AC2B190E555D007A121D /* bizhiTests.xctest */; 372 | productType = "com.apple.product-type.bundle.unit-test"; 373 | }; 374 | /* End PBXNativeTarget section */ 375 | 376 | /* Begin PBXProject section */ 377 | 6A33AC08190E555D007A121D /* Project object */ = { 378 | isa = PBXProject; 379 | attributes = { 380 | CLASSPREFIX = BZ; 381 | LastUpgradeCheck = 0510; 382 | ORGANIZATIONNAME = Huaban; 383 | TargetAttributes = { 384 | 6A33AC2A190E555D007A121D = { 385 | TestTargetID = 6A33AC0F190E555D007A121D; 386 | }; 387 | }; 388 | }; 389 | buildConfigurationList = 6A33AC0B190E555D007A121D /* Build configuration list for PBXProject "bizhi" */; 390 | compatibilityVersion = "Xcode 3.2"; 391 | developmentRegion = English; 392 | hasScannedForEncodings = 0; 393 | knownRegions = ( 394 | en, 395 | ); 396 | mainGroup = 6A33AC07190E555D007A121D; 397 | productRefGroup = 6A33AC11190E555D007A121D /* Products */; 398 | projectDirPath = ""; 399 | projectRoot = ""; 400 | targets = ( 401 | 6A33AC0F190E555D007A121D /* bizhi */, 402 | 6A33AC2A190E555D007A121D /* bizhiTests */, 403 | ); 404 | }; 405 | /* End PBXProject section */ 406 | 407 | /* Begin PBXResourcesBuildPhase section */ 408 | 6A33AC0E190E555D007A121D /* Resources */ = { 409 | isa = PBXResourcesBuildPhase; 410 | buildActionMask = 2147483647; 411 | files = ( 412 | 6A33AC1E190E555D007A121D /* InfoPlist.strings in Resources */, 413 | 6A33AC26190E555D007A121D /* Images.xcassets in Resources */, 414 | ); 415 | runOnlyForDeploymentPostprocessing = 0; 416 | }; 417 | 6A33AC29190E555D007A121D /* Resources */ = { 418 | isa = PBXResourcesBuildPhase; 419 | buildActionMask = 2147483647; 420 | files = ( 421 | 6A33AC37190E555D007A121D /* InfoPlist.strings in Resources */, 422 | ); 423 | runOnlyForDeploymentPostprocessing = 0; 424 | }; 425 | /* End PBXResourcesBuildPhase section */ 426 | 427 | /* Begin PBXShellScriptBuildPhase section */ 428 | 409B7E4B17BC4FA294A5F3C3 /* Copy Pods Resources */ = { 429 | isa = PBXShellScriptBuildPhase; 430 | buildActionMask = 2147483647; 431 | files = ( 432 | ); 433 | inputPaths = ( 434 | ); 435 | name = "Copy Pods Resources"; 436 | outputPaths = ( 437 | ); 438 | runOnlyForDeploymentPostprocessing = 0; 439 | shellPath = /bin/sh; 440 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods/Pods-resources.sh\"\n"; 441 | showEnvVarsInLog = 0; 442 | }; 443 | FA80234022C5483395D76428 /* Check Pods Manifest.lock */ = { 444 | isa = PBXShellScriptBuildPhase; 445 | buildActionMask = 2147483647; 446 | files = ( 447 | ); 448 | inputPaths = ( 449 | ); 450 | name = "Check Pods Manifest.lock"; 451 | outputPaths = ( 452 | ); 453 | runOnlyForDeploymentPostprocessing = 0; 454 | shellPath = /bin/sh; 455 | shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n"; 456 | showEnvVarsInLog = 0; 457 | }; 458 | /* End PBXShellScriptBuildPhase section */ 459 | 460 | /* Begin PBXSourcesBuildPhase section */ 461 | 6A33AC0C190E555D007A121D /* Sources */ = { 462 | isa = PBXSourcesBuildPhase; 463 | buildActionMask = 2147483647; 464 | files = ( 465 | 6A1D396B190E743A00F1EA81 /* BZDetailModule.m in Sources */, 466 | 6A1D3963190E742800F1EA81 /* BZTagsModule.m in Sources */, 467 | 6A1D395A190E73F400F1EA81 /* BZSettingsViewController.m in Sources */, 468 | 6A1D397F190E792800F1EA81 /* UIView+SuperView.m in Sources */, 469 | 6A1D396C190E743A00F1EA81 /* BZDetailViewCell.m in Sources */, 470 | 6A1D3959190E73F400F1EA81 /* BZSettingsModule.m in Sources */, 471 | 6A1D397C190E744500F1EA81 /* BZWaterfallViewModel.m in Sources */, 472 | 6A1D3949190E71DE00F1EA81 /* BZTagModel.m in Sources */, 473 | 6A33AC24190E555D007A121D /* BZAppDelegate.m in Sources */, 474 | 6A1D3964190E742800F1EA81 /* BZTagsViewController.m in Sources */, 475 | 6A1D3952190E73C600F1EA81 /* UICollectionView+FixRefreshControlJump.m in Sources */, 476 | 6A1D3982190E797E00F1EA81 /* UIView+Layout.m in Sources */, 477 | 6A1D397B190E744500F1EA81 /* BZWaterfallViewController.m in Sources */, 478 | 6A1D397A190E744500F1EA81 /* BZWaterfallViewCellModel.m in Sources */, 479 | 6A1D3979190E744500F1EA81 /* BZWaterfallViewCell.m in Sources */, 480 | 6A1D3978190E744500F1EA81 /* BZWaterfallModule.m in Sources */, 481 | 6A1D396D190E743A00F1EA81 /* BZDetailViewController.m in Sources */, 482 | 6A33AC20190E555D007A121D /* main.m in Sources */, 483 | 6A33AC49190E5B29007A121D /* BZAPIManager.m in Sources */, 484 | 6A33AC46190E5899007A121D /* BZPinModel.m in Sources */, 485 | 6A1D3953190E73C600F1EA81 /* UIColor+LightRandom.m in Sources */, 486 | ); 487 | runOnlyForDeploymentPostprocessing = 0; 488 | }; 489 | 6A33AC27190E555D007A121D /* Sources */ = { 490 | isa = PBXSourcesBuildPhase; 491 | buildActionMask = 2147483647; 492 | files = ( 493 | 6A33AC39190E555D007A121D /* bizhiTests.m in Sources */, 494 | ); 495 | runOnlyForDeploymentPostprocessing = 0; 496 | }; 497 | /* End PBXSourcesBuildPhase section */ 498 | 499 | /* Begin PBXTargetDependency section */ 500 | 6A33AC31190E555D007A121D /* PBXTargetDependency */ = { 501 | isa = PBXTargetDependency; 502 | target = 6A33AC0F190E555D007A121D /* bizhi */; 503 | targetProxy = 6A33AC30190E555D007A121D /* PBXContainerItemProxy */; 504 | }; 505 | /* End PBXTargetDependency section */ 506 | 507 | /* Begin PBXVariantGroup section */ 508 | 6A33AC1C190E555D007A121D /* InfoPlist.strings */ = { 509 | isa = PBXVariantGroup; 510 | children = ( 511 | 6A33AC1D190E555D007A121D /* en */, 512 | ); 513 | name = InfoPlist.strings; 514 | sourceTree = ""; 515 | }; 516 | 6A33AC35190E555D007A121D /* InfoPlist.strings */ = { 517 | isa = PBXVariantGroup; 518 | children = ( 519 | 6A33AC36190E555D007A121D /* en */, 520 | ); 521 | name = InfoPlist.strings; 522 | sourceTree = ""; 523 | }; 524 | /* End PBXVariantGroup section */ 525 | 526 | /* Begin XCBuildConfiguration section */ 527 | 6A33AC3A190E555D007A121D /* Debug */ = { 528 | isa = XCBuildConfiguration; 529 | buildSettings = { 530 | ALWAYS_SEARCH_USER_PATHS = NO; 531 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 532 | CLANG_CXX_LIBRARY = "libc++"; 533 | CLANG_ENABLE_MODULES = YES; 534 | CLANG_ENABLE_OBJC_ARC = YES; 535 | CLANG_WARN_BOOL_CONVERSION = YES; 536 | CLANG_WARN_CONSTANT_CONVERSION = YES; 537 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 538 | CLANG_WARN_EMPTY_BODY = YES; 539 | CLANG_WARN_ENUM_CONVERSION = YES; 540 | CLANG_WARN_INT_CONVERSION = YES; 541 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 542 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 543 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 544 | COPY_PHASE_STRIP = NO; 545 | GCC_C_LANGUAGE_STANDARD = gnu99; 546 | GCC_DYNAMIC_NO_PIC = NO; 547 | GCC_OPTIMIZATION_LEVEL = 0; 548 | GCC_PREPROCESSOR_DEFINITIONS = ( 549 | "DEBUG=1", 550 | "$(inherited)", 551 | ); 552 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 553 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 554 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 555 | GCC_WARN_UNDECLARED_SELECTOR = YES; 556 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 557 | GCC_WARN_UNUSED_FUNCTION = YES; 558 | GCC_WARN_UNUSED_VARIABLE = YES; 559 | IPHONEOS_DEPLOYMENT_TARGET = 7.1; 560 | ONLY_ACTIVE_ARCH = YES; 561 | SDKROOT = iphoneos; 562 | }; 563 | name = Debug; 564 | }; 565 | 6A33AC3B190E555D007A121D /* Release */ = { 566 | isa = XCBuildConfiguration; 567 | buildSettings = { 568 | ALWAYS_SEARCH_USER_PATHS = NO; 569 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 570 | CLANG_CXX_LIBRARY = "libc++"; 571 | CLANG_ENABLE_MODULES = YES; 572 | CLANG_ENABLE_OBJC_ARC = YES; 573 | CLANG_WARN_BOOL_CONVERSION = YES; 574 | CLANG_WARN_CONSTANT_CONVERSION = YES; 575 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 576 | CLANG_WARN_EMPTY_BODY = YES; 577 | CLANG_WARN_ENUM_CONVERSION = YES; 578 | CLANG_WARN_INT_CONVERSION = YES; 579 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 580 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 581 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 582 | COPY_PHASE_STRIP = YES; 583 | ENABLE_NS_ASSERTIONS = NO; 584 | GCC_C_LANGUAGE_STANDARD = gnu99; 585 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 586 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 587 | GCC_WARN_UNDECLARED_SELECTOR = YES; 588 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 589 | GCC_WARN_UNUSED_FUNCTION = YES; 590 | GCC_WARN_UNUSED_VARIABLE = YES; 591 | IPHONEOS_DEPLOYMENT_TARGET = 7.1; 592 | SDKROOT = iphoneos; 593 | VALIDATE_PRODUCT = YES; 594 | }; 595 | name = Release; 596 | }; 597 | 6A33AC3D190E555D007A121D /* Debug */ = { 598 | isa = XCBuildConfiguration; 599 | baseConfigurationReference = 974EF92767827CB8C89FBBF8 /* Pods.debug.xcconfig */; 600 | buildSettings = { 601 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 602 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; 603 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 604 | GCC_PREFIX_HEADER = "bizhi/bizhi-Prefix.pch"; 605 | INFOPLIST_FILE = "bizhi/bizhi-Info.plist"; 606 | IPHONEOS_DEPLOYMENT_TARGET = 7.0; 607 | PRODUCT_NAME = "$(TARGET_NAME)"; 608 | WRAPPER_EXTENSION = app; 609 | }; 610 | name = Debug; 611 | }; 612 | 6A33AC3E190E555D007A121D /* Release */ = { 613 | isa = XCBuildConfiguration; 614 | baseConfigurationReference = AB1BE59522E79D7CA0EB2783 /* Pods.release.xcconfig */; 615 | buildSettings = { 616 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 617 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; 618 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 619 | GCC_PREFIX_HEADER = "bizhi/bizhi-Prefix.pch"; 620 | INFOPLIST_FILE = "bizhi/bizhi-Info.plist"; 621 | IPHONEOS_DEPLOYMENT_TARGET = 7.0; 622 | PRODUCT_NAME = "$(TARGET_NAME)"; 623 | WRAPPER_EXTENSION = app; 624 | }; 625 | name = Release; 626 | }; 627 | 6A33AC40190E555D007A121D /* Debug */ = { 628 | isa = XCBuildConfiguration; 629 | buildSettings = { 630 | BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/bizhi.app/bizhi"; 631 | FRAMEWORK_SEARCH_PATHS = ( 632 | "$(SDKROOT)/Developer/Library/Frameworks", 633 | "$(inherited)", 634 | "$(DEVELOPER_FRAMEWORKS_DIR)", 635 | ); 636 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 637 | GCC_PREFIX_HEADER = "bizhi/bizhi-Prefix.pch"; 638 | GCC_PREPROCESSOR_DEFINITIONS = ( 639 | "DEBUG=1", 640 | "$(inherited)", 641 | ); 642 | INFOPLIST_FILE = "bizhiTests/bizhiTests-Info.plist"; 643 | PRODUCT_NAME = "$(TARGET_NAME)"; 644 | TEST_HOST = "$(BUNDLE_LOADER)"; 645 | WRAPPER_EXTENSION = xctest; 646 | }; 647 | name = Debug; 648 | }; 649 | 6A33AC41190E555D007A121D /* Release */ = { 650 | isa = XCBuildConfiguration; 651 | buildSettings = { 652 | BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/bizhi.app/bizhi"; 653 | FRAMEWORK_SEARCH_PATHS = ( 654 | "$(SDKROOT)/Developer/Library/Frameworks", 655 | "$(inherited)", 656 | "$(DEVELOPER_FRAMEWORKS_DIR)", 657 | ); 658 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 659 | GCC_PREFIX_HEADER = "bizhi/bizhi-Prefix.pch"; 660 | INFOPLIST_FILE = "bizhiTests/bizhiTests-Info.plist"; 661 | PRODUCT_NAME = "$(TARGET_NAME)"; 662 | TEST_HOST = "$(BUNDLE_LOADER)"; 663 | WRAPPER_EXTENSION = xctest; 664 | }; 665 | name = Release; 666 | }; 667 | /* End XCBuildConfiguration section */ 668 | 669 | /* Begin XCConfigurationList section */ 670 | 6A33AC0B190E555D007A121D /* Build configuration list for PBXProject "bizhi" */ = { 671 | isa = XCConfigurationList; 672 | buildConfigurations = ( 673 | 6A33AC3A190E555D007A121D /* Debug */, 674 | 6A33AC3B190E555D007A121D /* Release */, 675 | ); 676 | defaultConfigurationIsVisible = 0; 677 | defaultConfigurationName = Release; 678 | }; 679 | 6A33AC3C190E555D007A121D /* Build configuration list for PBXNativeTarget "bizhi" */ = { 680 | isa = XCConfigurationList; 681 | buildConfigurations = ( 682 | 6A33AC3D190E555D007A121D /* Debug */, 683 | 6A33AC3E190E555D007A121D /* Release */, 684 | ); 685 | defaultConfigurationIsVisible = 0; 686 | defaultConfigurationName = Release; 687 | }; 688 | 6A33AC3F190E555D007A121D /* Build configuration list for PBXNativeTarget "bizhiTests" */ = { 689 | isa = XCConfigurationList; 690 | buildConfigurations = ( 691 | 6A33AC40190E555D007A121D /* Debug */, 692 | 6A33AC41190E555D007A121D /* Release */, 693 | ); 694 | defaultConfigurationIsVisible = 0; 695 | defaultConfigurationName = Release; 696 | }; 697 | /* End XCConfigurationList section */ 698 | }; 699 | rootObject = 6A33AC08190E555D007A121D /* Project object */; 700 | } 701 | -------------------------------------------------------------------------------- /bizhi.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /bizhi.xcodeproj/xcuserdata/limboy.xcuserdatad/xcschemes/bizhi.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 42 | 43 | 49 | 50 | 51 | 52 | 61 | 62 | 68 | 69 | 70 | 71 | 72 | 73 | 79 | 80 | 86 | 87 | 88 | 89 | 91 | 92 | 95 | 96 | 97 | -------------------------------------------------------------------------------- /bizhi.xcodeproj/xcuserdata/limboy.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | bizhi.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | 6A33AC0F190E555D007A121D 16 | 17 | primary 18 | 19 | 20 | 6A33AC2A190E555D007A121D 21 | 22 | primary 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /bizhi.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /bizhi/BZAPIManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // BZAPIManager.h 3 | // bizhi 4 | // 5 | // Created by Limboy on 4/28/14. 6 | // Copyright (c) 2014 Huaban. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @class RACSignal; 13 | 14 | @interface BZAPIManager : AFHTTPRequestOperationManager 15 | 16 | + (instancetype)sharedManager; 17 | 18 | - (RACSignal *)fetchPinsWithTag:(NSString *)tag offset:(NSInteger)offset limit:(NSInteger)limit; 19 | 20 | - (RACSignal *)fetchTags; 21 | 22 | @end 23 | -------------------------------------------------------------------------------- /bizhi/BZAPIManager.m: -------------------------------------------------------------------------------- 1 | // 2 | // BZAPIManager.m 3 | // bizhi 4 | // 5 | // Created by Limboy on 4/28/14. 6 | // Copyright (c) 2014 Huaban. All rights reserved. 7 | // 8 | 9 | #import "BZAPIManager.h" 10 | #import 11 | #import 12 | #import "BZTagModel.h" 13 | #import "BZPinModel.h" 14 | 15 | @implementation BZAPIManager 16 | 17 | + (instancetype)sharedManager 18 | { 19 | static BZAPIManager *instance; 20 | static dispatch_once_t onceToken; 21 | dispatch_once(&onceToken, ^{ 22 | instance = [self manager]; 23 | }); 24 | return instance; 25 | } 26 | 27 | - (RACSignal *)fetchPinsWithTag:(NSString *)tag offset:(NSInteger)offset limit:(NSInteger)limit 28 | { 29 | NSString *max = offset ? [NSString stringWithFormat:@"&max=%ld", (long)offset] : @""; 30 | tag = tag ? [NSString stringWithFormat:@"&tag=%@", [tag stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]] : @""; 31 | NSString *urlString = [NSString stringWithFormat:@"http://api.huaban.com/fm/wallpaper/pins?limit=%ld%@%@", (long)limit, max, tag]; 32 | return [self fetchPinsWithURL:urlString]; 33 | } 34 | 35 | - (RACSignal *)fetchPinsWithURL:(NSString *)urlString 36 | { 37 | return [[self rac_GET:urlString parameters:nil] map:^id(RACTuple *tuple) { 38 | NSDictionary *response = tuple.first; 39 | return [[((NSArray *)response[@"pins"]).rac_sequence map:^id(id value) { 40 | return [[BZPinModel alloc] initWithDictionary:value error:nil]; 41 | }] array]; 42 | }]; 43 | } 44 | 45 | - (RACSignal *)fetchTags 46 | { 47 | return [[self rac_GET:@"http://api.huaban.com/fm/wallpaper/tags" parameters:nil] map:^id(RACTuple *tuple) { 48 | NSArray *tags = tuple.first; 49 | return [[tags.rac_sequence map:^id(id value) { 50 | return [[BZTagModel alloc] initWithDictionary:value error:nil]; 51 | }] array]; 52 | }]; 53 | } 54 | 55 | @end 56 | -------------------------------------------------------------------------------- /bizhi/BZAppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // BZAppDelegate.h 3 | // bizhi 4 | // 5 | // Created by Limboy on 4/28/14. 6 | // Copyright (c) 2014 Huaban. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface BZAppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /bizhi/BZAppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // BZAppDelegate.m 3 | // bizhi 4 | // 5 | // Created by Limboy on 4/28/14. 6 | // Copyright (c) 2014 Huaban. All rights reserved. 7 | // 8 | 9 | #import "BZAppDelegate.h" 10 | #import "Protocols.h" 11 | #import 12 | 13 | @implementation BZAppDelegate 14 | 15 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 16 | { 17 | self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; 18 | // Override point for customization after application launch. 19 | self.window.backgroundColor = [UIColor whiteColor]; 20 | [self.window makeKeyAndVisible]; 21 | [self setupRootViewController]; 22 | return YES; 23 | } 24 | 25 | - (void)setupRootViewController 26 | { 27 | UITabBarController *tabViewController = [[UITabBarController alloc] init]; 28 | 29 | UIViewController *waterfallViewController = [[JSObjection defaultInjector] getObject:@protocol(BZWaterfallViewControllerProtocol)]; 30 | [waterfallViewController configureWithLatest]; 31 | UINavigationController *waterfallNavigationController = [[UINavigationController alloc] initWithRootViewController:waterfallViewController]; 32 | waterfallViewController.tabBarItem = [[UITabBarItem alloc] initWithTitle:@"最新" image:[UIImage imageNamed:@"latest"] tag:0]; 33 | waterfallViewController.title = @"最新"; 34 | 35 | UIViewController *tagsViewController = [[JSObjection defaultInjector] getObject:@protocol(BZTagsViewControllerProtocol)]; 36 | UINavigationController *tagsNavigationController = [[UINavigationController alloc] initWithRootViewController:tagsViewController]; 37 | tagsViewController.tabBarItem = [[UITabBarItem alloc] initWithTitle:@"分类" image:[UIImage imageNamed:@"categories"] tag:1]; 38 | tagsViewController.title = @"分类"; 39 | 40 | UIViewController *settingsViewController = [[JSObjection defaultInjector] getObject:@protocol(BZSettingsViewControllerProtocol)]; 41 | settingsViewController.tabBarItem = [[UITabBarItem alloc] initWithTitle:@"设置" image:[UIImage imageNamed:@"settings"] tag:2]; 42 | UINavigationController *settingsNavigationController = [[UINavigationController alloc] initWithRootViewController:settingsViewController]; 43 | settingsViewController.title = @"设置"; 44 | 45 | tabViewController.viewControllers = @[waterfallNavigationController, tagsNavigationController, settingsNavigationController]; 46 | self.window.rootViewController = tabViewController; 47 | } 48 | 49 | 50 | 51 | - (void)applicationWillResignActive:(UIApplication *)application 52 | { 53 | // 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. 54 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 55 | } 56 | 57 | - (void)applicationDidEnterBackground:(UIApplication *)application 58 | { 59 | // 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. 60 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 61 | } 62 | 63 | - (void)applicationWillEnterForeground:(UIApplication *)application 64 | { 65 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. 66 | } 67 | 68 | - (void)applicationDidBecomeActive:(UIApplication *)application 69 | { 70 | // 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. 71 | } 72 | 73 | - (void)applicationWillTerminate:(UIApplication *)application 74 | { 75 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 76 | } 77 | 78 | @end 79 | -------------------------------------------------------------------------------- /bizhi/BZDetailModule.h: -------------------------------------------------------------------------------- 1 | // 2 | // BZDetailModule.h 3 | // ios-bizhi-copy 4 | // 5 | // Created by Limboy on 4/18/14. 6 | // Copyright (c) 2014 Huaban. All rights reserved. 7 | // 8 | 9 | #import "JSObjectionModule.h" 10 | 11 | @interface BZDetailModule : JSObjectionModule 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /bizhi/BZDetailModule.m: -------------------------------------------------------------------------------- 1 | // 2 | // BZDetailModule.m 3 | // ios-bizhi-copy 4 | // 5 | // Created by Limboy on 4/18/14. 6 | // Copyright (c) 2014 Huaban. All rights reserved. 7 | // 8 | 9 | #import "BZDetailModule.h" 10 | #import "BZDetailViewController.h" 11 | #import 12 | 13 | @implementation BZDetailModule 14 | 15 | + (void)load 16 | { 17 | JSObjectionInjector *injector = [JSObjection defaultInjector]; 18 | injector = injector ? : [JSObjection createInjector]; 19 | injector = [injector withModule:[[self alloc] init]]; 20 | [JSObjection setDefaultInjector:injector]; 21 | } 22 | 23 | - (void)configure 24 | { 25 | [self bindClass:[BZDetailViewController class] toProtocol:@protocol(BZDetailViewControllerProtocol)]; 26 | } 27 | 28 | @end 29 | -------------------------------------------------------------------------------- /bizhi/BZDetailViewCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // BZDetailViewCell.h 3 | // ios-bizhi-copy 4 | // 5 | // Created by Limboy on 4/18/14. 6 | // Copyright (c) 2014 Huaban. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class BZPinModel; 12 | 13 | @interface BZDetailViewCell : UICollectionViewCell 14 | - (void)configureCellWithPin:(BZPinModel *)pin; 15 | @property (nonatomic) UIScrollView *detailImageScrollView; 16 | @end 17 | -------------------------------------------------------------------------------- /bizhi/BZDetailViewCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // BZDetailViewCell.m 3 | // ios-bizhi-copy 4 | // 5 | // Created by Limboy on 4/18/14. 6 | // Copyright (c) 2014 Huaban. All rights reserved. 7 | // 8 | 9 | #import "BZDetailViewCell.h" 10 | #import 11 | #import "BZAPIManager.h" 12 | #import "BZPinModel.h" 13 | #import "UIView+Layout.h" 14 | #import "UtilsMacro.h" 15 | #import 16 | #import "UIColor+LightRandom.h" 17 | 18 | @interface BZDetailViewCell () 19 | @property (nonatomic) UIImageView *detailImageView; 20 | @property (nonatomic) UIProgressView *progressView; 21 | @end 22 | 23 | @implementation BZDetailViewCell 24 | 25 | - (id)initWithFrame:(CGRect)frame 26 | { 27 | self = [super initWithFrame:frame]; 28 | if (self) { 29 | // Initialization code 30 | self.detailImageView = [[UIImageView alloc] initWithFrame:self.bounds]; 31 | self.detailImageView.contentMode = UIViewContentModeScaleAspectFill; 32 | self.detailImageScrollView = [[UIScrollView alloc] initWithFrame:self.bounds]; 33 | self.detailImageScrollView.alwaysBounceVertical = YES; 34 | self.detailImageScrollView.contentSize = CGSizeMake(ScreenWidth, ScreenHeight); 35 | [self.detailImageScrollView addSubview:self.detailImageView]; 36 | [self.contentView addSubview:self.detailImageScrollView]; 37 | 38 | self.progressView = [[UIProgressView alloc] initWithProgressViewStyle:UIProgressViewStyleBar]; 39 | if ([self.progressView respondsToSelector:@selector(tintColor)]) { 40 | self.progressView.tintColor = [UIColor grayColor]; 41 | } 42 | self.progressView.trackTintColor = [UIColor colorWithWhite:0.9 alpha:1]; 43 | [self.contentView addSubview:self.progressView]; 44 | self.progressView.frame = CGRectMake(100, ScreenHeight / 2, 120, 2); 45 | } 46 | return self; 47 | } 48 | 49 | - (void)configureCellWithPin:(BZPinModel *)pin 50 | { 51 | @weakify(self); 52 | self.progressView.progress = 0; 53 | self.contentView.backgroundColor = [UIColor lightRandom]; 54 | NSURL *imageURL = [NSURL URLWithString:[pin imageURLWithThumbnailWidth:658]]; 55 | self.progressView.hidden = NO; 56 | [self.detailImageView sd_setImageWithURL:imageURL placeholderImage:nil options:SDWebImageRetryFailed progress:^(NSInteger receivedSize, NSInteger expectedSize) { 57 | @strongify(self); 58 | [self.progressView setProgress:receivedSize / (float)expectedSize]; 59 | } completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) { 60 | @strongify(self); 61 | self.progressView.hidden = YES; 62 | NSInteger finalImageHeight = ScreenWidth / image.size.width * image.size.height; 63 | if (finalImageHeight > ScreenHeight) { 64 | self.detailImageView.size = CGSizeMake(ScreenWidth, finalImageHeight); 65 | self.detailImageScrollView.contentSize = self.detailImageView.size; 66 | } 67 | if (cacheType != SDImageCacheTypeMemory) { 68 | self.detailImageView.alpha = 0; 69 | [UIView animateWithDuration:0.3 animations:^{ 70 | self.detailImageView.alpha = 1; 71 | }]; 72 | } 73 | }]; 74 | } 75 | 76 | @end 77 | -------------------------------------------------------------------------------- /bizhi/BZDetailViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // BZDetailViewController.h 3 | // ios-bizhi-copy 4 | // 5 | // Created by Limboy on 4/17/14. 6 | // Copyright (c) 2014 Huaban. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "Protocols.h" 11 | 12 | @interface BZDetailViewController : UICollectionViewController 13 | @property (nonatomic) NSInteger currentPinIndex; 14 | @property (nonatomic) NSInteger initPinIndex; 15 | @end 16 | -------------------------------------------------------------------------------- /bizhi/BZDetailViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // BZDetailViewController.m 3 | // ios-bizhi-copy 4 | // 5 | // Created by Limboy on 4/17/14. 6 | // Copyright (c) 2014 Huaban. All rights reserved. 7 | // 8 | 9 | #import "BZDetailViewController.h" 10 | #import 11 | #import "UtilsMacro.h" 12 | #import "BZDetailViewCell.h" 13 | #import 14 | #import 15 | #import 16 | #import 17 | #import "BZAPIManager.h" 18 | #import "BZPinModel.h" 19 | #import "UIView+Layout.h" 20 | 21 | static NSString *cellIdentifier = @"cell"; 22 | 23 | @interface BZDetailViewController () 24 | @property (nonatomic) id viewModel; 25 | @property (nonatomic) UIView *actionButtonsContainerView; 26 | @end 27 | 28 | @implementation BZDetailViewController 29 | 30 | - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil 31 | { 32 | UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init]; 33 | layout.minimumLineSpacing = 0; 34 | layout.minimumInteritemSpacing = 0; 35 | layout.scrollDirection = UICollectionViewScrollDirectionHorizontal; 36 | layout.itemSize = CGSizeMake(ScreenWidth, ScreenHeight); 37 | self = [super initWithCollectionViewLayout:layout]; 38 | if (self) { 39 | // Custom initialization 40 | RAC(self, currentPinIndex) = RACObserve(self, initPinIndex); 41 | } 42 | return self; 43 | } 44 | 45 | - (void)configureWithViewModel:(id)viewModel 46 | { 47 | self.viewModel = viewModel; 48 | } 49 | 50 | #pragma mark - UICollectionViewDelegate 51 | 52 | - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section 53 | { 54 | return self.viewModel.pins.count; 55 | } 56 | 57 | - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath 58 | { 59 | BZDetailViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath]; 60 | [cell configureCellWithPin:self.viewModel.pins[indexPath.row]]; 61 | [self addSwipeGestureToCell:cell]; 62 | [self addTouchGestureToCell:cell]; 63 | return cell; 64 | } 65 | 66 | #pragma mark - Utils 67 | 68 | - (void)addGesture:(UIGestureRecognizer *)gesture ToCell:(BZDetailViewCell *)cell 69 | { 70 | __block UIGestureRecognizer *theGesture = gesture; 71 | [cell.detailImageScrollView.gestureRecognizers enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { 72 | if ([obj isKindOfClass:[gesture class]]) { 73 | [cell.detailImageScrollView removeGestureRecognizer:obj]; 74 | } 75 | }]; 76 | [cell.detailImageScrollView addGestureRecognizer: theGesture]; 77 | [cell.detailImageScrollView.panGestureRecognizer requireGestureRecognizerToFail:theGesture]; 78 | } 79 | 80 | - (void)addTouchGestureToCell:(BZDetailViewCell *)cell 81 | { 82 | UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] init]; 83 | [self addGesture:tapGesture ToCell:cell]; 84 | 85 | @weakify(self); 86 | [[tapGesture.rac_gestureSignal takeUntil:cell.rac_prepareForReuseSignal] subscribeNext:^(id x) { 87 | @strongify(self); 88 | if (self.actionButtonsContainerView.hidden) { 89 | self.actionButtonsContainerView.alpha = 0; 90 | self.actionButtonsContainerView.hidden = NO; 91 | [UIView animateWithDuration:0.25 animations:^{ 92 | self.actionButtonsContainerView.alpha = 1; 93 | }]; 94 | } else { 95 | [UIView animateWithDuration:0.25 animations:^{ 96 | self.actionButtonsContainerView.alpha = 0; 97 | } completion:^(BOOL finished) { 98 | self.actionButtonsContainerView.hidden = YES; 99 | }]; 100 | } 101 | }]; 102 | } 103 | 104 | - (void)addSwipeGestureToCell:(BZDetailViewCell *)cell 105 | { 106 | UISwipeGestureRecognizer *swipeGesture = [[UISwipeGestureRecognizer alloc] init]; 107 | swipeGesture.direction = UISwipeGestureRecognizerDirectionDown; 108 | swipeGesture.delegate = self; 109 | [self addGesture:swipeGesture ToCell:cell]; 110 | 111 | @weakify(self); 112 | [[swipeGesture.rac_gestureSignal takeUntil:cell.rac_prepareForReuseSignal] subscribeNext:^(UISwipeGestureRecognizer *gesture) { 113 | @strongify(self); 114 | [self.presentingViewController dismissViewControllerAnimated:YES completion:nil]; 115 | }]; 116 | } 117 | 118 | #pragma mark - UIPanGestureDelegate 119 | 120 | - (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer 121 | { 122 | UIScrollView *scrollView = (UIScrollView *)gestureRecognizer.view; 123 | return scrollView.top <= 0 ? YES : NO; 124 | } 125 | 126 | #pragma mark - Life Cycle 127 | 128 | - (void)viewDidLoad 129 | { 130 | [super viewDidLoad]; 131 | // Do any additional setup after loading the view. 132 | [self.collectionView registerClass:[BZDetailViewCell class] forCellWithReuseIdentifier:cellIdentifier]; 133 | self.collectionView.pagingEnabled = YES; 134 | [self.view addSubview:self.actionButtonsContainerView]; 135 | //self.actionButtonsContainerView.hidden = YES; 136 | 137 | @weakify(self); 138 | [[self rac_signalForSelector:@selector(scrollViewDidScroll:) fromProtocol:@protocol(UIScrollViewDelegate)] subscribeNext:^(RACTuple *tuple) { 139 | @strongify(self); 140 | UIScrollView *scrollView = tuple.first; 141 | if (scrollView.isDragging && scrollView.contentSize.width <= (scrollView.contentOffset.x + scrollView.width)) { 142 | [[self.viewModel fetchMore] subscribeNext:^(NSArray *pins) { 143 | if (!pins.count) { 144 | [SVProgressHUD showErrorWithStatus:@"没有更多了"]; 145 | } else { 146 | NSMutableArray *mutablePins = [NSMutableArray arrayWithArray:self.viewModel.pins]; 147 | [mutablePins addObjectsFromArray:pins]; 148 | self.viewModel.pins = [mutablePins copy]; 149 | } 150 | }]; 151 | } 152 | }]; 153 | 154 | [[self rac_signalForSelector:@selector(scrollViewDidEndDecelerating:) fromProtocol:@protocol(UIScrollViewDelegate)] subscribeNext:^(RACTuple *tuple) { 155 | @strongify(self); 156 | UIScrollView *scrollView = tuple.first; 157 | self.currentPinIndex = scrollView.contentOffset.x / ScreenWidth; 158 | }]; 159 | 160 | self.collectionView.delegate = nil; 161 | self.collectionView.delegate = self; 162 | 163 | [RACObserve(self, viewModel.pins) subscribeNext:^(NSArray *pins) { 164 | @strongify(self); 165 | [self.collectionView reloadData]; 166 | }]; 167 | } 168 | 169 | - (void)viewWillAppear:(BOOL)animated 170 | { 171 | [super viewWillAppear:animated]; 172 | [self.collectionView setContentOffset:CGPointMake(ScreenWidth * self.initPinIndex, 0)]; 173 | } 174 | 175 | - (void)viewWillDisappear:(BOOL)animated 176 | { 177 | [super viewWillDisappear:animated]; 178 | [[UIApplication sharedApplication] setStatusBarHidden:NO]; 179 | } 180 | 181 | - (void)didReceiveMemoryWarning 182 | { 183 | [super didReceiveMemoryWarning]; 184 | // Dispose of any resources that can be recreated. 185 | } 186 | 187 | #pragma mark - Utils 188 | 189 | - (void)shareWithImage:(UIImage *)image 190 | { 191 | NSArray *activityItems = [NSArray arrayWithObjects:image, nil]; 192 | 193 | //-- initialising the activity view controller 194 | UIActivityViewController *activityViewController = [[UIActivityViewController alloc] 195 | initWithActivityItems:activityItems 196 | applicationActivities:nil]; 197 | 198 | 199 | activityViewController.excludedActivityTypes = @[UIActivityTypeAssignToContact, UIActivityTypeCopyToPasteboard, UIActivityTypeAirDrop]; 200 | 201 | //-- define the activity view completion handler 202 | activityViewController.completionHandler = ^(NSString *activityType, BOOL completed){ 203 | if (completed) { 204 | if (activityType != UIActivityTypeSaveToCameraRoll) { 205 | [SVProgressHUD showSuccessWithStatus:@"分享成功"]; 206 | } else { 207 | [SVProgressHUD showSuccessWithStatus:@"下载成功"]; 208 | } 209 | } 210 | }; 211 | 212 | [self presentViewController:activityViewController animated:YES completion:nil]; 213 | } 214 | 215 | #pragma mark - Accessors 216 | 217 | - (UIView *)actionButtonsContainerView 218 | { 219 | if (!_actionButtonsContainerView) { 220 | UIImage *shareButtonImage = [UIImage imageNamed:@"button_share"]; 221 | CGSize containerSize = CGSizeMake(shareButtonImage.size.width + 20, shareButtonImage.size.height + 20); 222 | _actionButtonsContainerView = [[UIView alloc] initWithFrame:CGRectMake((ScreenWidth - containerSize.width) / 2, ScreenHeight - containerSize.height - 20, containerSize.width, containerSize.height)]; 223 | _actionButtonsContainerView.layer.cornerRadius = 6; 224 | _actionButtonsContainerView.backgroundColor = [UIColor colorWithWhite:0 alpha:0.7]; 225 | 226 | UIButton *shareButton = [UIButton buttonWithType:UIButtonTypeCustom]; 227 | [shareButton setImage:shareButtonImage forState:UIControlStateNormal]; 228 | shareButton.origin = CGPointMake(10 , 10); 229 | shareButton.size = shareButtonImage.size; 230 | [_actionButtonsContainerView addSubview:shareButton]; 231 | 232 | @weakify(self); 233 | shareButton.rac_command = [[RACCommand alloc] initWithSignalBlock:^RACSignal *(id input) { 234 | @strongify(self); 235 | BZPinModel *currentPin = (BZPinModel *)self.viewModel.pins[self.currentPinIndex]; 236 | NSString *URLString = [currentPin imageURLWithThumbnailWidth:658]; 237 | return [RACSignal createSignal:^RACDisposable *(id subscriber) { 238 | if (![[SDWebImageManager sharedManager] diskImageExistsForURL:[NSURL URLWithString:URLString]]) { 239 | [SVProgressHUD showWithStatus:@"" maskType:SVProgressHUDMaskTypeBlack]; 240 | } 241 | [[SDWebImageManager sharedManager] downloadImageWithURL:[NSURL URLWithString:URLString] 242 | options:SDWebImageRetryFailed 243 | progress:^(NSInteger receivedSize, NSInteger expectedSize) { 244 | } completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) { 245 | [SVProgressHUD dismiss]; 246 | [subscriber sendCompleted]; 247 | if (!error) { 248 | @strongify(self); 249 | [self shareWithImage:image]; 250 | } 251 | }]; 252 | return nil; 253 | }]; 254 | }]; 255 | } 256 | return _actionButtonsContainerView; 257 | } 258 | 259 | @end 260 | -------------------------------------------------------------------------------- /bizhi/BZPinModel.h: -------------------------------------------------------------------------------- 1 | // 2 | // BZPinModel.h 3 | // bizhi 4 | // 5 | // Created by Limboy on 4/28/14. 6 | // Copyright (c) 2014 Huaban. All rights reserved. 7 | // 8 | 9 | #import "JSONModel.h" 10 | 11 | @interface BZPinModel : JSONModel 12 | @property (nonatomic, assign) NSInteger pinId; 13 | @property (nonatomic, copy) NSString *key; 14 | @property (nonatomic, assign) NSInteger seq; 15 | 16 | - (NSString *)imageURLWithThumbnailWidth:(NSInteger)width; 17 | @end 18 | -------------------------------------------------------------------------------- /bizhi/BZPinModel.m: -------------------------------------------------------------------------------- 1 | // 2 | // BZPinModel.m 3 | // bizhi 4 | // 5 | // Created by Limboy on 4/28/14. 6 | // Copyright (c) 2014 Huaban. All rights reserved. 7 | // 8 | 9 | #import "BZPinModel.h" 10 | 11 | @implementation BZPinModel 12 | 13 | + (JSONKeyMapper *)keyMapper 14 | { 15 | return [[JSONKeyMapper alloc] initWithDictionary:@{ 16 | @"file.key": @"key", 17 | @"pin_id": @"pinId", 18 | }]; 19 | } 20 | 21 | - (NSString *)imageURLWithThumbnailWidth:(NSInteger)width 22 | { 23 | return [NSString stringWithFormat:@"http://img.hb.aicdn.com/%@_fw%ld", self.key, (long)width]; 24 | } 25 | 26 | @end 27 | -------------------------------------------------------------------------------- /bizhi/BZSettingsModule.h: -------------------------------------------------------------------------------- 1 | // 2 | // BZSettingsModule.h 3 | // ios-bizhi-copy 4 | // 5 | // Created by Limboy on 4/21/14. 6 | // Copyright (c) 2014 Huaban. All rights reserved. 7 | // 8 | 9 | #import "JSObjectionModule.h" 10 | 11 | @interface BZSettingsModule : JSObjectionModule 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /bizhi/BZSettingsModule.m: -------------------------------------------------------------------------------- 1 | // 2 | // BZSettingsModule.m 3 | // ios-bizhi-copy 4 | // 5 | // Created by Limboy on 4/21/14. 6 | // Copyright (c) 2014 Huaban. All rights reserved. 7 | // 8 | 9 | #import "BZSettingsModule.h" 10 | #import "Protocols.h" 11 | #import 12 | #import "BZSettingsViewController.h" 13 | 14 | @implementation BZSettingsModule 15 | 16 | + (void)load 17 | { 18 | JSObjectionInjector *injector = [JSObjection defaultInjector]; 19 | injector = injector ? : [JSObjection createInjector]; 20 | injector = [injector withModule:[[self alloc] init]]; 21 | [JSObjection setDefaultInjector:injector]; 22 | } 23 | 24 | - (void)configure 25 | { 26 | [self bindClass:[BZSettingsViewController class] toProtocol:@protocol(BZSettingsViewControllerProtocol)]; 27 | } 28 | 29 | @end 30 | -------------------------------------------------------------------------------- /bizhi/BZSettingsViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // BZSettingsViewController.h 3 | // ios-bizhi-copy 4 | // 5 | // Created by Limboy on 4/21/14. 6 | // Copyright (c) 2014 Huaban. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface BZSettingsViewController : UITableViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /bizhi/BZSettingsViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // BZSettingsViewController.m 3 | // ios-bizhi-copy 4 | // 5 | // Created by Limboy on 4/21/14. 6 | // Copyright (c) 2014 Huaban. All rights reserved. 7 | // 8 | 9 | #import "BZSettingsViewController.h" 10 | #import 11 | #import "UtilsMacro.h" 12 | #import "UIView+Layout.h" 13 | #import 14 | #import 15 | 16 | static NSString *cellIdentifier = @"cell"; 17 | 18 | @interface BZSettingsViewController () 19 | 20 | @end 21 | 22 | @implementation BZSettingsViewController 23 | 24 | - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil 25 | { 26 | self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; 27 | if (self) { 28 | // Custom initialization 29 | } 30 | return self; 31 | } 32 | 33 | - (void)viewDidLoad 34 | { 35 | [super viewDidLoad]; 36 | // Do any additional setup after loading the view. 37 | self.tableView = [[UITableView alloc] initWithFrame:self.tableView.frame style:UITableViewStyleGrouped]; 38 | [self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:cellIdentifier]; 39 | 40 | if ([self respondsToSelector:@selector(edgesForExtendedLayout)]) { 41 | UILabel *footerLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, ScreenWidth, 30)]; 42 | footerLabel.textAlignment = NSTextAlignmentCenter; 43 | footerLabel.font = [UIFont fontWithName:@"Helvetica-Light" size:12]; 44 | footerLabel.textColor = [UIColor colorWithWhite:0.7 alpha:1]; 45 | footerLabel.text = @"close the app, enjoy your life"; 46 | self.tableView.tableFooterView = footerLabel; 47 | } 48 | } 49 | 50 | - (void)didReceiveMemoryWarning 51 | { 52 | [super didReceiveMemoryWarning]; 53 | // Dispose of any resources that can be recreated. 54 | } 55 | 56 | #pragma mark - UITableViewDelegate 57 | 58 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 59 | { 60 | return 1; 61 | } 62 | 63 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 64 | { 65 | UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath]; 66 | cell.selectionStyle = UITableViewCellSelectionStyleNone; 67 | if (indexPath.row == 0) { 68 | cell.textLabel.text = @"清除缓存"; 69 | cell.textLabel.font = [UIFont systemFontOfSize:16]; 70 | cell.imageView.image = [UIImage imageNamed:@"trash"]; 71 | } 72 | return cell; 73 | } 74 | 75 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 76 | { 77 | if (indexPath.row == 0) { 78 | [[SDImageCache sharedImageCache] clearDiskOnCompletion:^{ 79 | [SVProgressHUD showSuccessWithStatus:@"清除成功"]; 80 | }]; 81 | } 82 | } 83 | 84 | @end 85 | -------------------------------------------------------------------------------- /bizhi/BZTagModel.h: -------------------------------------------------------------------------------- 1 | // 2 | // BZTagModel.h 3 | // bizhi 4 | // 5 | // Created by Limboy on 4/28/14. 6 | // Copyright (c) 2014 Huaban. All rights reserved. 7 | // 8 | 9 | #import "JSONModel.h" 10 | 11 | @interface BZTagModel : JSONModel 12 | @property (nonatomic, copy) NSString *tagName; 13 | @property (nonatomic, assign) NSInteger pinCount; 14 | @end 15 | -------------------------------------------------------------------------------- /bizhi/BZTagModel.m: -------------------------------------------------------------------------------- 1 | // 2 | // BZTagModel.m 3 | // bizhi 4 | // 5 | // Created by Limboy on 4/28/14. 6 | // Copyright (c) 2014 Huaban. All rights reserved. 7 | // 8 | 9 | #import "BZTagModel.h" 10 | 11 | @implementation BZTagModel 12 | 13 | + (JSONKeyMapper *)keyMapper 14 | { 15 | return [JSONKeyMapper mapperFromUnderscoreCaseToCamelCase]; 16 | } 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /bizhi/BZTagsModule.h: -------------------------------------------------------------------------------- 1 | // 2 | // BZTagsModule.h 3 | // ios-bizhi-copy 4 | // 5 | // Created by Limboy on 4/21/14. 6 | // Copyright (c) 2014 Huaban. All rights reserved. 7 | // 8 | 9 | #import "JSObjectionModule.h" 10 | 11 | @interface BZTagsModule : JSObjectionModule 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /bizhi/BZTagsModule.m: -------------------------------------------------------------------------------- 1 | // 2 | // BZTagsModule.m 3 | // ios-bizhi-copy 4 | // 5 | // Created by Limboy on 4/21/14. 6 | // Copyright (c) 2014 Huaban. All rights reserved. 7 | // 8 | 9 | #import "BZTagsModule.h" 10 | #import "Protocols.h" 11 | #import "BZTagsViewController.h" 12 | #import 13 | 14 | @implementation BZTagsModule 15 | 16 | + (void)load 17 | { 18 | JSObjectionInjector *injector = [JSObjection defaultInjector]; 19 | injector = injector ? : [JSObjection createInjector]; 20 | injector = [injector withModule:[[self alloc] init]]; 21 | [JSObjection setDefaultInjector:injector]; 22 | } 23 | 24 | - (void)configure 25 | { 26 | [self bindClass:[BZTagsViewController class] toProtocol:@protocol(BZTagsViewControllerProtocol)]; 27 | } 28 | @end 29 | -------------------------------------------------------------------------------- /bizhi/BZTagsViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // CategoriesViewController.h 3 | // ios-bizhi-copy 4 | // 5 | // Created by Limboy on 4/21/14. 6 | // Copyright (c) 2014 Huaban. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface BZTagsViewController : UITableViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /bizhi/BZTagsViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // CategoriesViewController.m 3 | // ios-bizhi-copy 4 | // 5 | // Created by Limboy on 4/21/14. 6 | // Copyright (c) 2014 Huaban. All rights reserved. 7 | // 8 | 9 | #import "BZTagsViewController.h" 10 | #import 11 | #import 12 | #import 13 | #import "Protocols.h" 14 | #import 15 | #import "BZAPIManager.h" 16 | #import "BZTagModel.h" 17 | 18 | static NSString *cellIdentifier = @"cell"; 19 | 20 | @interface BZTagsViewController () 21 | @property (nonatomic) NSArray *tags; 22 | @end 23 | 24 | @implementation BZTagsViewController 25 | 26 | - (id)initWithStyle:(UITableViewStyle)style 27 | { 28 | self = [super initWithStyle:style]; 29 | if (self) { 30 | // Custom initialization 31 | } 32 | return self; 33 | } 34 | 35 | - (void)viewDidLoad 36 | { 37 | [super viewDidLoad]; 38 | 39 | [self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:cellIdentifier]; 40 | @weakify(self); 41 | [RACObserve(self, tags) subscribeNext:^(NSArray *tags) { 42 | @strongify(self); 43 | [self.tableView reloadData]; 44 | }]; 45 | [self.tableView addInfiniteScrollingWithActionHandler:^{ 46 | @strongify(self); 47 | [[[BZAPIManager sharedManager] fetchTags] subscribeNext:^(NSArray *tags) { 48 | self.tags = tags; 49 | [self.tableView.infiniteScrollingView stopAnimating]; 50 | self.tableView.showsInfiniteScrolling = NO; 51 | self.tableView.separatorStyle = UITableViewCellSeparatorStyleSingleLine; 52 | }]; 53 | }]; 54 | 55 | if ([self respondsToSelector:@selector(edgesForExtendedLayout)]) { 56 | self.edgesForExtendedLayout = UIRectEdgeTop; 57 | } 58 | 59 | dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ 60 | [self.tableView triggerInfiniteScrolling]; 61 | }); 62 | 63 | self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone; 64 | } 65 | 66 | - (void)didReceiveMemoryWarning 67 | { 68 | [super didReceiveMemoryWarning]; 69 | // Dispose of any resources that can be recreated. 70 | } 71 | 72 | #pragma mark - Table view data source 73 | 74 | - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView 75 | { 76 | // Return the number of sections. 77 | return 1; 78 | } 79 | 80 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 81 | { 82 | // Return the number of rows in the section. 83 | return self.tags.count; 84 | } 85 | 86 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 87 | { 88 | UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath]; 89 | BZTagModel *tag = ((BZTagModel *)self.tags[indexPath.row]); 90 | NSString *tagName = tag.tagName; 91 | NSString *pinCountString = [NSString stringWithFormat:@"%ld", (long)tag.pinCount]; 92 | NSString *displayString = [NSString stringWithFormat:@"%@ 共%@张", tagName, pinCountString]; 93 | 94 | // Configure the cell... 95 | NSDictionary *stringAttributes = @{NSFontAttributeName: [UIFont systemFontOfSize:16]}; 96 | NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:displayString attributes:stringAttributes]; 97 | [attributedString addAttributes:@{NSFontAttributeName: [UIFont systemFontOfSize:12], NSForegroundColorAttributeName: [UIColor grayColor]} range:NSMakeRange(tagName.length + 1, pinCountString.length + 2)]; 98 | cell.textLabel.attributedText = attributedString; 99 | 100 | cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; 101 | 102 | if ([cell respondsToSelector:@selector(separatorInset)]) { 103 | cell.separatorInset = UIEdgeInsetsZero; 104 | } 105 | 106 | return cell; 107 | } 108 | 109 | - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath 110 | { 111 | return 44; 112 | } 113 | 114 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 115 | { 116 | UIViewController *viewController = [[JSObjection defaultInjector] getObject:@protocol(BZWaterfallViewControllerProtocol)]; 117 | NSString *tagName = ((BZTagModel *)self.tags[indexPath.row]).tagName; 118 | [viewController configureWithTag:tagName]; 119 | viewController.title = tagName; 120 | [self.navigationController pushViewController:viewController animated:YES]; 121 | } 122 | 123 | @end 124 | -------------------------------------------------------------------------------- /bizhi/BZWaterfallModule.h: -------------------------------------------------------------------------------- 1 | // 2 | // BZWaterfallModule.h 3 | // ios-bizhi-copy 4 | // 5 | // Created by Limboy on 4/17/14. 6 | // Copyright (c) 2014 Huaban. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @interface BZWaterfallModule : JSObjectionModule 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /bizhi/BZWaterfallModule.m: -------------------------------------------------------------------------------- 1 | // 2 | // BZWaterfallModule.m 3 | // ios-bizhi-copy 4 | // 5 | // Created by Limboy on 4/17/14. 6 | // Copyright (c) 2014 Huaban. All rights reserved. 7 | // 8 | 9 | #import "BZWaterfallModule.h" 10 | #import 11 | #import "BZWaterfallViewController.h" 12 | #import "Protocols.h" 13 | 14 | @implementation BZWaterfallModule 15 | 16 | + (void)load 17 | { 18 | JSObjectionInjector *injector = [JSObjection defaultInjector]; 19 | injector = injector ? : [JSObjection createInjector]; 20 | injector = [injector withModule:[[self alloc] init]]; 21 | [JSObjection setDefaultInjector:injector]; 22 | } 23 | 24 | - (void)configure 25 | { 26 | [self bindClass:[BZWaterfallViewController class] toProtocol:@protocol(BZWaterfallViewControllerProtocol)]; 27 | } 28 | 29 | @end 30 | -------------------------------------------------------------------------------- /bizhi/BZWaterfallViewCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // BZWaterfallViewCell.h 3 | // ios-bizhi-copy 4 | // 5 | // Created by Limboy on 4/17/14. 6 | // Copyright (c) 2014 Huaban. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class BZWaterfallViewCellModel; 12 | 13 | @interface BZWaterfallViewCell : UICollectionViewCell 14 | - (void)configureWithViewModel:(BZWaterfallViewCellModel *)viewModel; 15 | @property (nonatomic) UIButton *thumbnailImageButton; 16 | @property (nonatomic) BZWaterfallViewCellModel *viewModel; 17 | @end 18 | -------------------------------------------------------------------------------- /bizhi/BZWaterfallViewCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // BZWaterfallViewCell.m 3 | // ios-bizhi-copy 4 | // 5 | // Created by Limboy on 4/17/14. 6 | // Copyright (c) 2014 Huaban. All rights reserved. 7 | // 8 | 9 | #import "BZWaterfallViewCell.h" 10 | #import "UIColor+LightRandom.h" 11 | #import 12 | #import "BZAPIManager.h" 13 | #import "BZWaterfallViewCellModel.h" 14 | #import 15 | #import "BZPinModel.h" 16 | 17 | @interface BZWaterfallViewCell () 18 | @property (nonatomic) UIImageView *thumbnailImageView; 19 | @end 20 | 21 | @implementation BZWaterfallViewCell 22 | 23 | - (id)initWithFrame:(CGRect)frame 24 | { 25 | self = [super initWithFrame:frame]; 26 | if (self) { 27 | // Initialization code 28 | self.thumbnailImageView = [[UIImageView alloc] initWithFrame:self.bounds]; 29 | self.thumbnailImageView.contentMode = UIViewContentModeScaleAspectFill; 30 | self.thumbnailImageView.clipsToBounds = YES; 31 | [self.contentView addSubview:self.thumbnailImageView]; 32 | self.thumbnailImageButton = [UIButton buttonWithType:UIButtonTypeCustom]; 33 | self.thumbnailImageButton.frame = self.thumbnailImageView.frame; 34 | [self.contentView addSubview:self.thumbnailImageButton]; 35 | } 36 | return self; 37 | } 38 | 39 | - (void)configureWithViewModel:(BZWaterfallViewCellModel *)viewModel 40 | { 41 | self.viewModel = viewModel; 42 | self.backgroundColor = [UIColor lightRandom]; 43 | NSURL *imageURL = [NSURL URLWithString:[viewModel.pin imageURLWithThumbnailWidth:236]]; 44 | @weakify(self); 45 | [self.thumbnailImageView sd_setImageWithURL:imageURL placeholderImage:nil options:SDWebImageRetryFailed completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) { 46 | @strongify(self); 47 | if (cacheType != SDImageCacheTypeMemory) { 48 | self.thumbnailImageView.alpha = 0; 49 | [UIView animateWithDuration:0.25 animations:^{ 50 | self.thumbnailImageView.alpha = 1; 51 | }]; 52 | } 53 | }]; 54 | } 55 | 56 | @end 57 | -------------------------------------------------------------------------------- /bizhi/BZWaterfallViewCellModel.h: -------------------------------------------------------------------------------- 1 | // 2 | // BZWaterfallViewCellModel.h 3 | // ios-bizhi-copy 4 | // 5 | // Created by Limboy on 4/18/14. 6 | // Copyright (c) 2014 Huaban. All rights reserved. 7 | // 8 | 9 | #import "RVMViewModel.h" 10 | 11 | @class BZPinModel; 12 | 13 | @interface BZWaterfallViewCellModel : RVMViewModel 14 | @property (nonatomic) BZPinModel *pin; 15 | @property (nonatomic) NSIndexPath *indexPath; 16 | @end 17 | -------------------------------------------------------------------------------- /bizhi/BZWaterfallViewCellModel.m: -------------------------------------------------------------------------------- 1 | // 2 | // BZWaterfallViewCellModel.m 3 | // ios-bizhi-copy 4 | // 5 | // Created by Limboy on 4/18/14. 6 | // Copyright (c) 2014 Huaban. All rights reserved. 7 | // 8 | 9 | #import "BZWaterfallViewCellModel.h" 10 | 11 | @implementation BZWaterfallViewCellModel 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /bizhi/BZWaterfallViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // BZWaterfallViewController.h 3 | // ios-bizhi-copy 4 | // 5 | // Created by Limboy on 4/17/14. 6 | // Copyright (c) 2014 Huaban. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "Protocols.h" 11 | 12 | @interface BZWaterfallViewController : UICollectionViewController 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /bizhi/BZWaterfallViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // BZWaterfallViewController.m 3 | // ios-bizhi-copy 4 | // 5 | // Created by Limboy on 4/17/14. 6 | // Copyright (c) 2014 Huaban. All rights reserved. 7 | // 8 | 9 | #import "BZWaterfallViewController.h" 10 | #import 11 | #import "BZWaterfallViewModel.h" 12 | #import "BZWaterfallViewCell.h" 13 | #import "BZWaterfallViewCellModel.h" 14 | #import 15 | #import 16 | #import 17 | #import "UIView+SuperView.h" 18 | #import 19 | #import 20 | 21 | static NSString *cellIdentifier = @"cell"; 22 | 23 | @interface BZWaterfallViewController () 24 | @property (nonatomic) BZWaterfallViewModel *viewModel; 25 | @property (nonatomic) RACCommand *thumbnailImageButtonCommand; 26 | @property (nonatomic) NSIndexPath *selectedIndexPath; 27 | @end 28 | 29 | @implementation BZWaterfallViewController 30 | 31 | - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil 32 | { 33 | CHTCollectionViewWaterfallLayout *layout = [[CHTCollectionViewWaterfallLayout alloc] init]; 34 | layout.columnCount = 3; 35 | layout.sectionInset = UIEdgeInsetsMake(10, 10, 10, 10); 36 | self = [super initWithCollectionViewLayout:layout]; 37 | if (self) { 38 | self.viewModel = [[BZWaterfallViewModel alloc] init]; 39 | } 40 | return self; 41 | } 42 | 43 | #pragma mark - Public Methods 44 | 45 | - (void)configureWithTag:(NSString *)tag 46 | { 47 | self.viewModel.tag = tag; 48 | } 49 | 50 | - (void)configureWithLatest 51 | { 52 | self.viewModel.tag = @""; 53 | } 54 | 55 | #pragma mark - Accessors 56 | 57 | - (RACCommand *)thumbnailImageButtonCommand 58 | { 59 | if (!_thumbnailImageButtonCommand) { 60 | @weakify(self); 61 | _thumbnailImageButtonCommand = [[RACCommand alloc] initWithSignalBlock:^RACSignal *(UIButton *button) { 62 | BZWaterfallViewCell *cell = (BZWaterfallViewCell *)[button findSuperViewWithClass:[BZWaterfallViewCell class]]; 63 | 64 | return [RACSignal createSignal:^RACDisposable *(id subscriber) { 65 | @strongify(self); 66 | UIViewController * viewController = [[JSObjection defaultInjector] getObject:@protocol(BZDetailViewControllerProtocol)]; 67 | viewController.initPinIndex = cell.viewModel.indexPath.row; 68 | [viewController configureWithViewModel:self.viewModel]; 69 | [self presentViewController:viewController animated:YES completion:^{ 70 | [subscriber sendCompleted]; 71 | }]; 72 | [[RACObserve(viewController, currentPinIndex) skip:1] subscribeNext:^(id x) { 73 | @strongify(self); 74 | self.selectedIndexPath = [NSIndexPath indexPathForRow:[x intValue] inSection:0]; 75 | }]; 76 | return nil; 77 | }]; 78 | }]; 79 | } 80 | return _thumbnailImageButtonCommand; 81 | } 82 | 83 | #pragma mark - UICollectionViewDelegate 84 | 85 | - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section 86 | { 87 | return self.viewModel.pins.count; 88 | } 89 | 90 | - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath 91 | { 92 | BZWaterfallViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath]; 93 | BZWaterfallViewCellModel *viewModel = [[BZWaterfallViewCellModel alloc] init]; 94 | viewModel.pin = self.viewModel.pins[indexPath.row]; 95 | viewModel.indexPath = indexPath; 96 | [cell configureWithViewModel:viewModel]; 97 | cell.thumbnailImageButton.rac_command = self.thumbnailImageButtonCommand;; 98 | return cell; 99 | } 100 | 101 | #pragma mark - CHTCollectionViewDelegateWaterfallLayout 102 | 103 | - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath 104 | { 105 | return CGSizeMake(97, 145); 106 | } 107 | 108 | #pragma mark - Life Cycle 109 | 110 | - (void)viewDidLoad 111 | { 112 | [super viewDidLoad]; 113 | // Do any additional setup after loading the view. 114 | self.collectionView.backgroundColor = [UIColor whiteColor]; 115 | self.collectionView.alwaysBounceVertical = YES; 116 | [self.collectionView registerClass:[BZWaterfallViewCell class] forCellWithReuseIdentifier:cellIdentifier]; 117 | 118 | @weakify(self); 119 | [RACObserve(self, viewModel.pins) subscribeNext:^(NSArray *pins) { 120 | @strongify(self); 121 | [self.collectionView reloadData]; 122 | }]; 123 | 124 | UIRefreshControl *refreshControl = [[UIRefreshControl alloc] init]; 125 | [self.collectionView addSubview:refreshControl]; 126 | [[refreshControl rac_signalForControlEvents:UIControlEventValueChanged] subscribeNext:^(id x) { 127 | @strongify(self); 128 | [[self.viewModel fetchPinsWithTag:self.viewModel.tag offset:0] subscribeNext:^(NSArray *pins) { 129 | self.viewModel.pins = pins; 130 | }]; 131 | [refreshControl endRefreshing]; 132 | }]; 133 | 134 | [self.collectionView addInfiniteScrollingWithActionHandler:^{ 135 | @strongify(self); 136 | [[self.viewModel fetchMore] subscribeNext:^(NSArray *pins) { 137 | if (!pins.count) { 138 | [SVProgressHUD showErrorWithStatus:@"没有更多了"]; 139 | } else { 140 | NSMutableArray *mutablePins = [NSMutableArray arrayWithArray:self.viewModel.pins]; 141 | [mutablePins addObjectsFromArray:pins]; 142 | self.viewModel.pins = [mutablePins copy]; 143 | } 144 | [self.collectionView.infiniteScrollingView stopAnimating]; 145 | }]; 146 | }]; 147 | 148 | dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ 149 | [self.collectionView triggerInfiniteScrolling]; 150 | }); 151 | } 152 | 153 | - (void)viewWillAppear:(BOOL)animated 154 | { 155 | [super viewWillAppear:animated]; 156 | 157 | if (self.selectedIndexPath) { 158 | [self.collectionView scrollToItemAtIndexPath:self.selectedIndexPath atScrollPosition:UICollectionViewScrollPositionCenteredVertically animated:NO]; 159 | } 160 | } 161 | 162 | - (void)didReceiveMemoryWarning 163 | { 164 | [super didReceiveMemoryWarning]; 165 | // Dispose of any resources that can be recreated. 166 | } 167 | 168 | @end 169 | -------------------------------------------------------------------------------- /bizhi/BZWaterfallViewModel.h: -------------------------------------------------------------------------------- 1 | // 2 | // BZWaterfallViewModel.h 3 | // ios-bizhi-copy 4 | // 5 | // Created by Limboy on 4/17/14. 6 | // Copyright (c) 2014 Huaban. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | #import "Protocols.h" 12 | 13 | @interface BZWaterfallViewModel : RVMViewModel 14 | @property (nonatomic) NSArray *pins; 15 | @property (nonatomic) NSString *tag; 16 | @end 17 | -------------------------------------------------------------------------------- /bizhi/BZWaterfallViewModel.m: -------------------------------------------------------------------------------- 1 | // 2 | // BZWaterfallViewModel.m 3 | // ios-bizhi-copy 4 | // 5 | // Created by Limboy on 4/17/14. 6 | // Copyright (c) 2014 Huaban. All rights reserved. 7 | // 8 | 9 | #import "BZWaterfallViewModel.h" 10 | #import "BZAPIManager.h" 11 | #import "BZPinModel.h" 12 | #import 13 | 14 | @interface BZWaterfallViewModel () 15 | @end 16 | 17 | @implementation BZWaterfallViewModel 18 | 19 | #pragma mark - Public Methods 20 | 21 | - (RACSignal *)fetchPinsWithTag:(NSString *)tag offset:(NSUInteger)offset 22 | { 23 | return [[BZAPIManager sharedManager] fetchPinsWithTag:tag offset:offset limit:21]; 24 | } 25 | 26 | - (RACSignal *)fetchMore 27 | { 28 | NSInteger seq = self.pins.count ? ((BZPinModel *)[self.pins lastObject]).seq : 0; 29 | return [[BZAPIManager sharedManager] fetchPinsWithTag:self.tag offset:seq limit:21]; 30 | } 31 | 32 | #pragma mark Accessors 33 | 34 | - (NSArray *)pins 35 | { 36 | if (!_pins) { 37 | _pins = [NSArray array]; 38 | } 39 | return _pins; 40 | } 41 | 42 | @end 43 | -------------------------------------------------------------------------------- /bizhi/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "40x40", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "size" : "60x60", 15 | "idiom" : "iphone", 16 | "filename" : "icon.png", 17 | "scale" : "2x" 18 | } 19 | ], 20 | "info" : { 21 | "version" : 1, 22 | "author" : "xcode" 23 | } 24 | } -------------------------------------------------------------------------------- /bizhi/Images.xcassets/AppIcon.appiconset/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/limboy/bizhi/effa3b29a00b09abdbdbc0b8e0dd54d7aa77cd17/bizhi/Images.xcassets/AppIcon.appiconset/icon.png -------------------------------------------------------------------------------- /bizhi/Images.xcassets/LaunchImage.launchimage/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "orientation" : "portrait", 5 | "idiom" : "iphone", 6 | "extent" : "full-screen", 7 | "minimum-system-version" : "7.0", 8 | "scale" : "2x" 9 | }, 10 | { 11 | "extent" : "full-screen", 12 | "idiom" : "iphone", 13 | "subtype" : "retina4", 14 | "filename" : "launch.png", 15 | "minimum-system-version" : "7.0", 16 | "orientation" : "portrait", 17 | "scale" : "2x" 18 | } 19 | ], 20 | "info" : { 21 | "version" : 1, 22 | "author" : "xcode" 23 | } 24 | } -------------------------------------------------------------------------------- /bizhi/Images.xcassets/LaunchImage.launchimage/launch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/limboy/bizhi/effa3b29a00b09abdbdbc0b8e0dd54d7aa77cd17/bizhi/Images.xcassets/LaunchImage.launchimage/launch.png -------------------------------------------------------------------------------- /bizhi/Images.xcassets/button_download.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "button_download@2x.png" 11 | } 12 | ], 13 | "info" : { 14 | "version" : 1, 15 | "author" : "xcode" 16 | } 17 | } -------------------------------------------------------------------------------- /bizhi/Images.xcassets/button_download.imageset/button_download@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/limboy/bizhi/effa3b29a00b09abdbdbc0b8e0dd54d7aa77cd17/bizhi/Images.xcassets/button_download.imageset/button_download@2x.png -------------------------------------------------------------------------------- /bizhi/Images.xcassets/button_share.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "button_share@2x.png" 11 | } 12 | ], 13 | "info" : { 14 | "version" : 1, 15 | "author" : "xcode" 16 | } 17 | } -------------------------------------------------------------------------------- /bizhi/Images.xcassets/button_share.imageset/button_share@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/limboy/bizhi/effa3b29a00b09abdbdbc0b8e0dd54d7aa77cd17/bizhi/Images.xcassets/button_share.imageset/button_share@2x.png -------------------------------------------------------------------------------- /bizhi/Images.xcassets/categories.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "categories@2x.png" 11 | } 12 | ], 13 | "info" : { 14 | "version" : 1, 15 | "author" : "xcode" 16 | } 17 | } -------------------------------------------------------------------------------- /bizhi/Images.xcassets/categories.imageset/categories@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/limboy/bizhi/effa3b29a00b09abdbdbc0b8e0dd54d7aa77cd17/bizhi/Images.xcassets/categories.imageset/categories@2x.png -------------------------------------------------------------------------------- /bizhi/Images.xcassets/latest.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "latest@2x.png" 11 | } 12 | ], 13 | "info" : { 14 | "version" : 1, 15 | "author" : "xcode" 16 | } 17 | } -------------------------------------------------------------------------------- /bizhi/Images.xcassets/latest.imageset/latest@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/limboy/bizhi/effa3b29a00b09abdbdbc0b8e0dd54d7aa77cd17/bizhi/Images.xcassets/latest.imageset/latest@2x.png -------------------------------------------------------------------------------- /bizhi/Images.xcassets/settings.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "settings@2x.png" 11 | } 12 | ], 13 | "info" : { 14 | "version" : 1, 15 | "author" : "xcode" 16 | } 17 | } -------------------------------------------------------------------------------- /bizhi/Images.xcassets/settings.imageset/settings@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/limboy/bizhi/effa3b29a00b09abdbdbc0b8e0dd54d7aa77cd17/bizhi/Images.xcassets/settings.imageset/settings@2x.png -------------------------------------------------------------------------------- /bizhi/Images.xcassets/trash.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "trash@2x.png" 11 | } 12 | ], 13 | "info" : { 14 | "version" : 1, 15 | "author" : "xcode" 16 | } 17 | } -------------------------------------------------------------------------------- /bizhi/Images.xcassets/trash.imageset/trash@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/limboy/bizhi/effa3b29a00b09abdbdbc0b8e0dd54d7aa77cd17/bizhi/Images.xcassets/trash.imageset/trash@2x.png -------------------------------------------------------------------------------- /bizhi/Protocols.h: -------------------------------------------------------------------------------- 1 | // 2 | // Protocols.h 3 | // ios-bizhi-copy 4 | // 5 | // Created by Limboy on 4/17/14. 6 | // Copyright (c) 2014 Huaban. All rights reserved. 7 | // 8 | 9 | #import 10 | @class RACSignal; 11 | 12 | @protocol BZWaterfallViewControllerProtocol 13 | - (void)configureWithTag:(NSString *)tag; 14 | - (void)configureWithLatest; 15 | @end 16 | 17 | 18 | @protocol BZWaterfallViewModelProtocol 19 | @property (nonatomic) NSArray *pins; 20 | - (RACSignal *)fetchPinsWithTag:(NSString *)tag offset:(NSUInteger)offset; 21 | - (RACSignal *)fetchMore; 22 | @end 23 | 24 | 25 | @protocol BZDetailViewControllerProtocol 26 | @property (nonatomic) NSInteger currentPinIndex; 27 | @property (nonatomic) NSInteger initPinIndex; 28 | - (void)configureWithViewModel:(id)viewModel; 29 | @end 30 | 31 | @protocol BZTagsViewControllerProtocol 32 | @end 33 | 34 | @protocol BZSettingsViewControllerProtocol 35 | @end -------------------------------------------------------------------------------- /bizhi/UICollectionView+FixRefreshControlJump.h: -------------------------------------------------------------------------------- 1 | // 2 | // UICollectionView+FixRefreshControlJump.h 3 | // LilyCommon 4 | // 5 | // Created by Limboy on 4/6/14. 6 | // Copyright (c) 2014 Huaban. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface UICollectionView (FixRefreshControlJump) 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /bizhi/UICollectionView+FixRefreshControlJump.m: -------------------------------------------------------------------------------- 1 | // 2 | // UICollectionView+FixRefreshControlJump.m 3 | // LilyCommon 4 | // 5 | // Created by Limboy on 4/6/14. 6 | // Copyright (c) 2014 Huaban. All rights reserved. 7 | // 8 | 9 | #import "UICollectionView+FixRefreshControlJump.h" 10 | #import 11 | 12 | @implementation UICollectionView (FixRefreshControlJump) 13 | 14 | + (void)load 15 | { 16 | Method originMethod = class_getInstanceMethod([UICollectionView class], @selector(setContentInset:)); 17 | Method newMethod = class_getInstanceMethod([UICollectionView class], @selector(setNewContentInset:)); 18 | method_exchangeImplementations(originMethod, newMethod); 19 | } 20 | 21 | - (void)setNewContentInset:(UIEdgeInsets)contentInset 22 | { 23 | if (self.tracking) { 24 | CGFloat diff = contentInset.top - self.contentInset.top; 25 | CGPoint translation = [self.panGestureRecognizer translationInView:self]; 26 | translation.y -= diff * 3.0 / 2.0; 27 | [self.panGestureRecognizer setTranslation:translation inView:self]; 28 | } 29 | if ([self respondsToSelector:@selector(setNewContentInset:)]) { 30 | [self setNewContentInset:contentInset]; 31 | } 32 | } 33 | 34 | @end 35 | -------------------------------------------------------------------------------- /bizhi/UIColor+LightRandom.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIColor+LightRandom.h 3 | // ios-bizhi-copy 4 | // 5 | // Created by Limboy on 4/18/14. 6 | // Copyright (c) 2014 Huaban. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface UIColor (LightRandom) 12 | + (UIColor *)lightRandom; 13 | @end 14 | -------------------------------------------------------------------------------- /bizhi/UIColor+LightRandom.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIColor+LightRandom.m 3 | // ios-bizhi-copy 4 | // 5 | // Created by Limboy on 4/18/14. 6 | // Copyright (c) 2014 Huaban. All rights reserved. 7 | // 8 | 9 | #import "UIColor+LightRandom.h" 10 | 11 | @implementation UIColor (LightRandom) 12 | 13 | + (UIColor *)lightRandom 14 | { 15 | CGFloat hue = ( arc4random() % 256 / 256.0 ); // 0.0 to 1.0 16 | CGFloat saturation = ( arc4random() % 128 / 256.0 ); // 0.5 to 1.0, away from white 17 | CGFloat brightness = ( arc4random() % 128 / 256.0 ) + 0.5; // 0.5 to 1.0, away from black 18 | return [UIColor colorWithHue:hue saturation:saturation brightness:brightness alpha:1]; 19 | } 20 | 21 | @end 22 | -------------------------------------------------------------------------------- /bizhi/UIView+Layout.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+Utils.h 3 | // Borrowed from Three20 / DTFoundation 4 | // 5 | // Copyright (c) 2013 iOS. No rights reserved. 6 | // 7 | 8 | #import 9 | 10 | 11 | @interface UIView (Utils) 12 | 13 | /** 14 | * Shortcut for frame.origin.x. 15 | * 16 | * Sets frame.origin.x = left 17 | */ 18 | @property (nonatomic) CGFloat left; 19 | 20 | /** 21 | * Shortcut for frame.origin.y 22 | * 23 | * Sets frame.origin.y = top 24 | */ 25 | @property (nonatomic) CGFloat top; 26 | 27 | /** 28 | * Shortcut for frame.origin.x + frame.size.width 29 | * 30 | * Sets frame.origin.x = right - frame.size.width 31 | */ 32 | @property (nonatomic) CGFloat right; 33 | 34 | /** 35 | * Shortcut for frame.origin.y + frame.size.height 36 | * 37 | * Sets frame.origin.y = bottom - frame.size.height 38 | */ 39 | @property (nonatomic) CGFloat bottom; 40 | 41 | /** 42 | * Shortcut for frame.size.width 43 | * 44 | * Sets frame.size.width = width 45 | */ 46 | @property (nonatomic) CGFloat width; 47 | 48 | /** 49 | * Shortcut for frame.size.height 50 | * 51 | * Sets frame.size.height = height 52 | */ 53 | @property (nonatomic) CGFloat height; 54 | 55 | /** 56 | * Shortcut for center.x 57 | * 58 | * Sets center.x = centerX 59 | */ 60 | @property (nonatomic) CGFloat centerX; 61 | 62 | /** 63 | * Shortcut for center.y 64 | * 65 | * Sets center.y = centerY 66 | */ 67 | @property (nonatomic) CGFloat centerY; 68 | 69 | /** 70 | * Return the x coordinate on the screen. 71 | */ 72 | @property (nonatomic, readonly) CGFloat screenX; 73 | 74 | /** 75 | * Return the y coordinate on the screen. 76 | */ 77 | @property (nonatomic, readonly) CGFloat screenY; 78 | 79 | /** 80 | * Return the x coordinate on the screen, taking into account scroll views. 81 | */ 82 | @property (nonatomic, readonly) CGFloat screenViewX; 83 | 84 | /** 85 | * Return the y coordinate on the screen, taking into account scroll views. 86 | */ 87 | @property (nonatomic, readonly) CGFloat screenViewY; 88 | 89 | /** 90 | * Return the view frame on the screen, taking into account scroll views. 91 | */ 92 | @property (nonatomic, readonly) CGRect screenFrame; 93 | 94 | /** 95 | * Shortcut for frame.origin 96 | */ 97 | @property (nonatomic) CGPoint origin; 98 | 99 | /** 100 | * Shortcut for frame.size 101 | */ 102 | @property (nonatomic) CGSize size; 103 | 104 | /** 105 | * Return the width in portrait or the height in landscape. 106 | */ 107 | @property (nonatomic, readonly) CGFloat orientationWidth; 108 | 109 | /** 110 | * Return the height in portrait or the width in landscape. 111 | */ 112 | @property (nonatomic, readonly) CGFloat orientationHeight; 113 | 114 | @end -------------------------------------------------------------------------------- /bizhi/UIView+Layout.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+Utils.m 3 | // Borrowed from Three20 4 | // 5 | // Copyright (c) 2013 iOS. No rights reserved. 6 | // 7 | 8 | #import "UIView+Layout.h" 9 | 10 | #import 11 | 12 | @implementation UIView (Utils) 13 | 14 | 15 | - (CGFloat)left { 16 | return self.frame.origin.x; 17 | } 18 | 19 | 20 | - (void)setLeft:(CGFloat)x { 21 | CGRect frame = self.frame; 22 | frame.origin.x = x; 23 | self.frame = frame; 24 | } 25 | 26 | 27 | - (CGFloat)top { 28 | return self.frame.origin.y; 29 | } 30 | 31 | 32 | - (void)setTop:(CGFloat)y { 33 | CGRect frame = self.frame; 34 | frame.origin.y = y; 35 | self.frame = frame; 36 | } 37 | 38 | 39 | - (CGFloat)right { 40 | return self.frame.origin.x + self.frame.size.width; 41 | } 42 | 43 | 44 | - (void)setRight:(CGFloat)right { 45 | CGRect frame = self.frame; 46 | frame.origin.x = right - frame.size.width; 47 | self.frame = frame; 48 | } 49 | 50 | 51 | - (CGFloat)bottom { 52 | return self.frame.origin.y + self.frame.size.height; 53 | } 54 | 55 | 56 | - (void)setBottom:(CGFloat)bottom { 57 | CGRect frame = self.frame; 58 | frame.origin.y = bottom - frame.size.height; 59 | self.frame = frame; 60 | } 61 | 62 | 63 | - (CGFloat)centerX { 64 | return self.center.x; 65 | } 66 | 67 | 68 | - (void)setCenterX:(CGFloat)centerX { 69 | self.center = CGPointMake(centerX, self.center.y); 70 | } 71 | 72 | 73 | - (CGFloat)centerY { 74 | return self.center.y; 75 | } 76 | 77 | 78 | - (void)setCenterY:(CGFloat)centerY { 79 | self.center = CGPointMake(self.center.x, centerY); 80 | } 81 | 82 | 83 | - (CGFloat)width { 84 | return self.frame.size.width; 85 | } 86 | 87 | 88 | - (void)setWidth:(CGFloat)width { 89 | CGRect frame = self.frame; 90 | frame.size.width = width; 91 | self.frame = frame; 92 | } 93 | 94 | 95 | - (CGFloat)height { 96 | return self.frame.size.height; 97 | } 98 | 99 | 100 | - (void)setHeight:(CGFloat)height { 101 | CGRect frame = self.frame; 102 | frame.size.height = height; 103 | self.frame = frame; 104 | } 105 | 106 | 107 | - (CGFloat)screenX { 108 | CGFloat x = 0.0f; 109 | for (UIView* view = self; view; view = view.superview) { 110 | x += view.left; 111 | } 112 | return x; 113 | } 114 | 115 | 116 | - (CGFloat)screenY { 117 | CGFloat y = 0.0f; 118 | for (UIView* view = self; view; view = view.superview) { 119 | y += view.top; 120 | } 121 | return y; 122 | } 123 | 124 | 125 | - (CGFloat)screenViewX { 126 | CGFloat x = 0.0f; 127 | for (UIView* view = self; view; view = view.superview) { 128 | x += view.left; 129 | 130 | if ([view isKindOfClass:[UIScrollView class]]) { 131 | UIScrollView* scrollView = (UIScrollView*)view; 132 | x -= scrollView.contentOffset.x; 133 | } 134 | } 135 | 136 | return x; 137 | } 138 | 139 | 140 | - (CGFloat)screenViewY { 141 | CGFloat y = 0; 142 | for (UIView* view = self; view; view = view.superview) { 143 | y += view.top; 144 | 145 | if ([view isKindOfClass:[UIScrollView class]]) { 146 | UIScrollView* scrollView = (UIScrollView*)view; 147 | y -= scrollView.contentOffset.y; 148 | } 149 | } 150 | return y; 151 | } 152 | 153 | 154 | - (CGRect)screenFrame { 155 | return CGRectMake(self.screenViewX, self.screenViewY, self.width, self.height); 156 | } 157 | 158 | 159 | - (CGPoint)origin { 160 | return self.frame.origin; 161 | } 162 | 163 | 164 | - (void)setOrigin:(CGPoint)origin { 165 | CGRect frame = self.frame; 166 | frame.origin = origin; 167 | self.frame = frame; 168 | } 169 | 170 | 171 | - (CGSize)size { 172 | return self.frame.size; 173 | } 174 | 175 | 176 | - (void)setSize:(CGSize)size { 177 | CGRect frame = self.frame; 178 | frame.size = size; 179 | self.frame = frame; 180 | } 181 | 182 | 183 | - (CGFloat)orientationWidth { 184 | return UIInterfaceOrientationIsLandscape([UIApplication sharedApplication].statusBarOrientation) 185 | ? self.height : self.width; 186 | } 187 | 188 | 189 | - (CGFloat)orientationHeight { 190 | return UIInterfaceOrientationIsLandscape([UIApplication sharedApplication].statusBarOrientation) 191 | ? self.width : self.height; 192 | } 193 | 194 | 195 | - (CGPoint)offsetFromView:(UIView*)otherView { 196 | CGFloat x = 0.0f, y = 0.0f; 197 | for (UIView* view = self; view && view != otherView; view = view.superview) { 198 | x += view.left; 199 | y += view.top; 200 | } 201 | return CGPointMake(x, y); 202 | } 203 | 204 | @end -------------------------------------------------------------------------------- /bizhi/UIView+SuperView.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+SuperView.h 3 | // HBToolkit 4 | // 5 | // Created by Limboy on 4/18/14. 6 | // Copyright (c) 2014 Huaban. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface UIView (SuperView) 12 | 13 | - (UIView *)findSuperViewWithClass:(Class)superViewClass; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /bizhi/UIView+SuperView.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+SuperView.m 3 | // HBToolkit 4 | // 5 | // Created by Limboy on 4/18/14. 6 | // Copyright (c) 2014 Huaban. All rights reserved. 7 | // 8 | 9 | #import "UIView+SuperView.h" 10 | 11 | @implementation UIView (SuperView) 12 | 13 | - (UIView *)findSuperViewWithClass:(Class)superViewClass { 14 | 15 | UIView *superView = self.superview; 16 | UIView *foundSuperView = nil; 17 | 18 | while (nil != superView && nil == foundSuperView) { 19 | if ([superView isKindOfClass:superViewClass]) { 20 | foundSuperView = superView; 21 | } else { 22 | superView = superView.superview; 23 | } 24 | } 25 | return foundSuperView; 26 | } 27 | 28 | @end 29 | -------------------------------------------------------------------------------- /bizhi/UtilsMacro.h: -------------------------------------------------------------------------------- 1 | #define ApplicationDelegate ((AppDelegate *)[[UIApplication sharedApplication] delegate]) 2 | #define UserDefaults [NSUserDefaults standardUserDefaults] 3 | #define NavBarHeight self.navigationController.navigationBar.bounds.size.height 4 | #define TabBarHeight self.tabBarController.tabBar.bounds.size.height 5 | #define ScreenWidth [[UIScreen mainScreen] bounds].size.width 6 | #define ScreenHeight [[UIScreen mainScreen] bounds].size.height 7 | #define ViewWidth(v) v.frame.size.width 8 | #define ViewHeight(v) v.frame.size.height 9 | #define ViewX(v) v.frame.origin.x 10 | #define ViewY(v) v.frame.origin.y 11 | #define SelfViewWidth self.view.bounds.size.width 12 | #define SelfViewHeight self.view.bounds.size.height 13 | #define RectX(f) f.origin.x 14 | #define RectY(f) f.origin.y 15 | #define RectWidth(f) f.size.width 16 | #define RectHeight(f) f.size.height 17 | #define RectSetWidth(f, w) CGRectMake(RectX(f), RectY(f), w, RectHeight(f)) 18 | #define RectSetHeight(f, h) CGRectMake(RectX(f), RectY(f), RectWidth(f), h) 19 | #define RectSetX(f, x) CGRectMake(x, RectY(f), RectWidth(f), RectHeight(f)) 20 | #define RectSetY(f, y) CGRectMake(RectX(f), y, RectWidth(f), RectHeight(f)) 21 | #define RectSetSize(f, w, h) CGRectMake(RectX(f), RectY(f), w, h) 22 | #define RectSetOrigin(f, x, y) CGRectMake(x, y, RectWidth(f), RectHeight(f)) 23 | #define RGB(r, g, b) [UIColor colorWithRed:r/255.0 green:g/255.0 blue:b/255.0 alpha:1.0] 24 | #define RGBA(r, g, b, a) [UIColor colorWithRed:r/255.0 green:g/255.0 blue:b/255.0 alpha:a] 25 | #define HEXCOLOR(c) [UIColor colorWithRed:((c>>16)&0xFF)/255.0 green:((c>>8)&0xFF)/255.0 blue:(c&0xFF)/255.0 alpha:1.0] 26 | #define F(string, args...) [NSString stringWithFormat:string, args] 27 | #define ALERT(title, msg) [[[UIAlertView alloc] initWithTitle:title\ 28 | message:msg\ 29 | delegate:nil\ 30 | cancelButtonTitle:@"确定"\ 31 | otherButtonTitles:nil] show] -------------------------------------------------------------------------------- /bizhi/bizhi-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | ${PRODUCT_NAME} 9 | CFBundleExecutable 10 | ${EXECUTABLE_NAME} 11 | CFBundleIdentifier 12 | com.huaban.${PRODUCT_NAME:rfc1034identifier} 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | ${PRODUCT_NAME} 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1.0 25 | LSRequiresIPhoneOS 26 | 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /bizhi/bizhi-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header 3 | // 4 | // The contents of this file are implicitly included at the beginning of every source file. 5 | // 6 | 7 | #import 8 | 9 | #ifndef __IPHONE_3_0 10 | #warning "This project uses features only available in iOS SDK 3.0 and later." 11 | #endif 12 | 13 | #ifdef __OBJC__ 14 | #import 15 | #import 16 | #endif 17 | -------------------------------------------------------------------------------- /bizhi/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /bizhi/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // bizhi 4 | // 5 | // Created by Limboy on 4/28/14. 6 | // Copyright (c) 2014 Huaban. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "BZAppDelegate.h" 12 | 13 | int main(int argc, char * argv[]) 14 | { 15 | @autoreleasepool { 16 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([BZAppDelegate class])); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /bizhiTests/bizhiTests-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | com.huaban.${PRODUCT_NAME:rfc1034identifier} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundlePackageType 14 | BNDL 15 | CFBundleShortVersionString 16 | 1.0 17 | CFBundleSignature 18 | ???? 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /bizhiTests/bizhiTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // bizhiTests.m 3 | // bizhiTests 4 | // 5 | // Created by Limboy on 4/28/14. 6 | // Copyright (c) 2014 Huaban. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface bizhiTests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation bizhiTests 16 | 17 | - (void)setUp 18 | { 19 | [super setUp]; 20 | // Put setup code here. This method is called before the invocation of each test method in the class. 21 | } 22 | 23 | - (void)tearDown 24 | { 25 | // Put teardown code here. This method is called after the invocation of each test method in the class. 26 | [super tearDown]; 27 | } 28 | 29 | - (void)testExample 30 | { 31 | XCTFail(@"No implementation for \"%s\"", __PRETTY_FUNCTION__); 32 | } 33 | 34 | @end 35 | -------------------------------------------------------------------------------- /bizhiTests/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /screenshot.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/limboy/bizhi/effa3b29a00b09abdbdbc0b8e0dd54d7aa77cd17/screenshot.jpg --------------------------------------------------------------------------------