├── Screenshots └── screenshot1.png ├── CCListViewExample ├── CCListViewExample │ ├── en.lproj │ │ └── InfoPlist.strings │ ├── doge.png │ ├── AppDelegate.h │ ├── VerticalListViewController.h │ ├── HorizontalListViewController.h │ ├── VerticalListViewController.m │ ├── HorizontalListViewController.m │ ├── main.m │ ├── CCListViewExample-Prefix.pch │ ├── CCListViewController.h │ ├── Images.xcassets │ │ ├── AppIcon.appiconset │ │ │ └── Contents.json │ │ └── LaunchImage.launchimage │ │ │ └── Contents.json │ ├── CCListViewExample-Info.plist │ ├── AppDelegate.m │ ├── Base.lproj │ │ └── Main.storyboard │ └── CCListViewController.m ├── CCListViewExampleTests │ ├── en.lproj │ │ └── InfoPlist.strings │ ├── CCListViewExampleTests-Info.plist │ └── CCListViewExampleTests.m └── CCListViewExample.xcodeproj │ ├── project.xcworkspace │ └── contents.xcworkspacedata │ ├── xcshareddata │ └── xcschemes │ │ ├── All Tests.xcscheme │ │ ├── CCListView Podspec Lint.xcscheme │ │ └── CCListViewExample.xcscheme │ └── project.pbxproj ├── Tools ├── TravisCI │ ├── finished.sh │ └── deploy.sh └── Signing │ ├── createKeyChain.sh │ ├── AppleWWDRCA.cer.enc │ ├── Distribution Certificate.cer.enc │ ├── Distribution Certificate.p12.enc │ └── CCListViewExample_Enterprise.mobileprovision.enc ├── .gitignore ├── Podfile ├── Source ├── UIScrollView+Utility.h ├── UIScrollView+Utility.m ├── CCListView.h └── CCListView.m ├── Podfile.lock ├── LICENSE.md ├── CCListView.podspec ├── .travis.yml └── README.md /Screenshots/screenshot1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Adorkable/CCListView/master/Screenshots/screenshot1.png -------------------------------------------------------------------------------- /CCListViewExample/CCListViewExample/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /CCListViewExample/CCListViewExampleTests/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /CCListViewExample/CCListViewExample/doge.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Adorkable/CCListView/master/CCListViewExample/CCListViewExample/doge.png -------------------------------------------------------------------------------- /Tools/TravisCI/finished.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | security delete-keychain ios-build.keychain 3 | rm -f "~/Library/MobileDevice/Provisioning Profiles/$PROFILE_NAME.mobileprovision" -------------------------------------------------------------------------------- /CCListViewExample/CCListViewExample.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /CCListViewExample.xcworkspace/ 2 | 3 | /Pods/ 4 | 5 | xcuserdata 6 | 7 | /Tools/Signing/AppleWWDRCA.cer 8 | /Tools/Signing/CCListViewExample_Enterprise.mobileprovision 9 | /Tools/Signing/Distribution Certificate.cer 10 | /Tools/Signing/Distribution Certificate.p12 11 | -------------------------------------------------------------------------------- /Podfile: -------------------------------------------------------------------------------- 1 | xcodeproj 'CCListViewExample/CCListViewExample.xcodeproj/' 2 | 3 | target "CCListViewExample" do 4 | if ENV['TRAVIS'] 5 | pod "CCListView", :path => ENV['TRAVIS_BUILD_DIR'] 6 | else 7 | pod "CCListView", :path => "./" 8 | end 9 | pod "FLKAutoLayout" 10 | end 11 | -------------------------------------------------------------------------------- /Source/UIScrollView+Utility.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIScrollView+Utility.h 3 | // CodecademyMobile 4 | // 5 | // Created by Ian Grossberg on 2/28/14. 6 | // Copyright (c) 2014 Codecademy. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface UIScrollView (Utility) 12 | 13 | - (void)forceWidth:(CGFloat)width; 14 | - (void)forceHeight:(CGFloat)height; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /CCListViewExample/CCListViewExample/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // CCListViewExample 4 | // 5 | // Created by Ian Grossberg on 6/27/14. 6 | // Copyright (c) 2014 Codecademy. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /CCListViewExample/CCListViewExample/VerticalListViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // CCListViewExample 4 | // 5 | // Created by Ian Grossberg on 6/27/14. 6 | // Copyright (c) 2014 Codecademy. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "CCListViewController.h" 12 | 13 | @interface VerticalListViewController : CCListViewController 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /CCListViewExample/CCListViewExample/HorizontalListViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // HorizontalListViewController.h 3 | // CCListViewExample 4 | // 5 | // Created by Ian Grossberg on 7/1/14. 6 | // Copyright (c) 2014 Codecademy. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "CCListViewController.h" 12 | 13 | @interface HorizontalListViewController : CCListViewController 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - CCListView (0.1.0): 3 | - FLKAutoLayout 4 | - FLKAutoLayout (0.1.1) 5 | 6 | DEPENDENCIES: 7 | - CCListView (from `./`) 8 | - FLKAutoLayout 9 | 10 | EXTERNAL SOURCES: 11 | CCListView: 12 | :path: ./ 13 | 14 | SPEC CHECKSUMS: 15 | CCListView: 4915670a868683c69abb87b34b19a67d46e7621f 16 | FLKAutoLayout: 9fa39aac2903b274fbeed6be74154cdb937a04fc 17 | 18 | COCOAPODS: 0.33.1 19 | -------------------------------------------------------------------------------- /CCListViewExample/CCListViewExample/VerticalListViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // CCListViewExample 4 | // 5 | // Created by Ian Grossberg on 6/27/14. 6 | // Copyright (c) 2014 Codecademy. All rights reserved. 7 | // 8 | 9 | #import "VerticalListViewController.h" 10 | 11 | @implementation VerticalListViewController 12 | 13 | + (BOOL)horizontalContent 14 | { 15 | return NO; 16 | } 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /CCListViewExample/CCListViewExample/HorizontalListViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // HorizontalListViewController.m 3 | // CCListViewExample 4 | // 5 | // Created by Ian Grossberg on 7/1/14. 6 | // Copyright (c) 2014 Codecademy. All rights reserved. 7 | // 8 | 9 | #import "HorizontalListViewController.h" 10 | 11 | @implementation HorizontalListViewController 12 | 13 | + (BOOL)horizontalContent 14 | { 15 | return YES; 16 | } 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /CCListViewExample/CCListViewExample/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // CCListViewExample 4 | // 5 | // Created by Ian Grossberg on 6/27/14. 6 | // Copyright (c) 2014 Codecademy. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "AppDelegate.h" 12 | 13 | int main(int argc, char * argv[]) 14 | { 15 | @autoreleasepool { 16 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /CCListViewExample/CCListViewExample/CCListViewExample-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_5_0 10 | #warning "This project uses features only available in iOS SDK 5.0 and later." 11 | #endif 12 | 13 | #ifdef __OBJC__ 14 | #import 15 | #import 16 | #endif 17 | -------------------------------------------------------------------------------- /CCListViewExample/CCListViewExample/CCListViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // CCListViewController.h 3 | // CCListViewExample 4 | // 5 | // Created by Ian Grossberg on 7/1/14. 6 | // Copyright (c) 2014 Codecademy. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import 12 | 13 | @interface CCListViewController : UIViewController 14 | 15 | + (BOOL)horizontalContent; 16 | - (void)sharedInit; 17 | 18 | @property (weak, nonatomic) IBOutlet CCListView *listView; 19 | 20 | + (UILabel *)createJunkLabel; 21 | + (UITextView *)createJunkTextView; 22 | 23 | @end 24 | -------------------------------------------------------------------------------- /Tools/Signing/createKeyChain.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | security create-keychain -p travis ios-build.keychain 3 | security import ./Tools/Signing/AppleWWDRCA.cer -k ~/Library/Keychains/ios-build.keychain -T /usr/bin/codesign 4 | security import ./Tools/Signing/Distribution\ Certificate.cer -k ~/Library/Keychains/ios-build.keychain -T /usr/bin/codesign 5 | security import ./Tools/Signing/Distribution\ Certificate.p12 -k ~/Library/Keychains/ios-build.keychain -P "$KEY_PASSWORD" -T /usr/bin/codesign 6 | security default-keychain -s ios-build.keychain 7 | mkdir -p ~/Library/MobileDevice/Provisioning\ Profiles 8 | cp "./Tools/Signing/$PROFILE_NAME.mobileprovision" ~/Library/MobileDevice/Provisioning\ Profiles/ -------------------------------------------------------------------------------- /CCListViewExample/CCListViewExampleTests/CCListViewExampleTests-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | com.codecademy.${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 | -------------------------------------------------------------------------------- /CCListViewExample/CCListViewExampleTests/CCListViewExampleTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // CCListViewExampleTests.m 3 | // CCListViewExampleTests 4 | // 5 | // Created by Ian Grossberg on 6/27/14. 6 | // Copyright (c) 2014 Codecademy. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface CCListViewExampleTests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation CCListViewExampleTests 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 | -------------------------------------------------------------------------------- /CCListViewExample/CCListViewExample/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 | "idiom" : "iphone", 15 | "size" : "60x60", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "ipad", 20 | "size" : "29x29", 21 | "scale" : "1x" 22 | }, 23 | { 24 | "idiom" : "ipad", 25 | "size" : "29x29", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "ipad", 30 | "size" : "40x40", 31 | "scale" : "1x" 32 | }, 33 | { 34 | "idiom" : "ipad", 35 | "size" : "40x40", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "ipad", 40 | "size" : "76x76", 41 | "scale" : "1x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "76x76", 46 | "scale" : "2x" 47 | } 48 | ], 49 | "info" : { 50 | "version" : 1, 51 | "author" : "xcode" 52 | } 53 | } -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2014 Ian Grossberg, Ryzac Inc. 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | 24 | 25 | -------------------------------------------------------------------------------- /Tools/TravisCI/deploy.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | if [[ "$TRAVIS_PULL_REQUEST" != "false" ]]; then 3 | echo "This is a pull request. No deployment will be done." 4 | exit 0 5 | fi 6 | if [[ "$TRAVIS_BRANCH" != "master" ]]; then 7 | echo "Testing on a branch other than master. No deployment will be done." 8 | exit 0 9 | fi 10 | 11 | PROVISIONING_PROFILE="$HOME/Library/MobileDevice/Provisioning Profiles/$PROFILE_NAME.mobileprovision" 12 | OUTPUTDIR="$PWD/build/Release-iphoneos" 13 | 14 | xcrun -log -sdk iphoneos PackageApplication "$OUTPUTDIR/$APP_NAME.app" -o "$OUTPUTDIR/$APP_NAME.ipa" -sign "$DEVELOPER_NAME" -embed "$PROVISIONING_PROFILE" 15 | 16 | RELEASE_DATE=`date '+%Y-%m-%d %H:%M:%S'` 17 | RELEASE_NOTES="Travis Build: $TRAVIS_BUILD_NUMBER\nUploaded: $RELEASE_DATE" # TODO: swap out for actual build number? 18 | 19 | zip -r -9 "$OUTPUTDIR/$APP_NAME.app.dSYM.zip" "$OUTPUTDIR/$APP_NAME.app.dSYM" 20 | 21 | curl http://testflightapp.com/api/builds.json \ 22 | -F file="@$OUTPUTDIR/$APP_NAME.ipa" \ 23 | -F dsym="@$OUTPUTDIR/$APP_NAME.app.dSYM.zip" \ 24 | -F api_token="$TESTFLIGHT_API_TOKEN" \ 25 | -F team_token="$TESTFLIGHT_TEAM_TOKEN" \ 26 | -F distribution_lists='Mobile Devs' \ 27 | -F notes="$RELEASE_NOTES" -------------------------------------------------------------------------------- /CCListView.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | 3 | s.name = "CCListView" 4 | s.version = "0.1.0" 5 | s.summary = "CCListView is a highly customizable sequential view container." 6 | 7 | s.description = <<-DESC 8 | **CCListView** is a highly customizable sequential view container. It can be configured to: 9 | 10 | * optionally scroll contained content 11 | * arrange content horizontally or vertically 12 | 13 | You can build **CCListViews** that contain **CCListViews** (that contain **CCListViews**...) and they even support scrolling views within scrolling views. 14 | DESC 15 | 16 | s.homepage = "http://github.com/Codecademy/CCListView.git" 17 | s.screenshots = "https://github.com/Codecademy/CCListView/blob/master/Screenshots/screenshot1.png?raw=true" 18 | s.license = "MIT" 19 | s.authors = { 'Ian Grossberg / Codecademy' => 'yo.ian.g@gmail.com' } 20 | s.platform = :ios, "6.0" 21 | 22 | s.source = { :git => "https://github.com/Codecademy/CCListView.git", :tag => "0.1.0" } 23 | s.source_files = "Source", "Source/**/*.{h,m}" 24 | s.public_header_files = "Source/CCListView.h" 25 | s.requires_arc = true 26 | s.dependency "FLKAutoLayout" 27 | end 28 | -------------------------------------------------------------------------------- /CCListViewExample/CCListViewExample/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 | "orientation" : "portrait", 12 | "idiom" : "iphone", 13 | "subtype" : "retina4", 14 | "extent" : "full-screen", 15 | "minimum-system-version" : "7.0", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "orientation" : "portrait", 20 | "idiom" : "ipad", 21 | "extent" : "full-screen", 22 | "minimum-system-version" : "7.0", 23 | "scale" : "1x" 24 | }, 25 | { 26 | "orientation" : "landscape", 27 | "idiom" : "ipad", 28 | "extent" : "full-screen", 29 | "minimum-system-version" : "7.0", 30 | "scale" : "1x" 31 | }, 32 | { 33 | "orientation" : "portrait", 34 | "idiom" : "ipad", 35 | "extent" : "full-screen", 36 | "minimum-system-version" : "7.0", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "orientation" : "landscape", 41 | "idiom" : "ipad", 42 | "extent" : "full-screen", 43 | "minimum-system-version" : "7.0", 44 | "scale" : "2x" 45 | } 46 | ], 47 | "info" : { 48 | "version" : 1, 49 | "author" : "xcode" 50 | } 51 | } -------------------------------------------------------------------------------- /Tools/Signing/AppleWWDRCA.cer.enc: -------------------------------------------------------------------------------- 1 | U2FsdGVkX1/MO/kUgw3DaLm7OcjZng4FN0x5ATEi2qs1LOjxnzwOjc25h6s5ABO+ 2 | 1869+WUP8hk/uiSLcSHDDQ9r1w5alW3z+beslKI+dpGafflC4JVuPgwfFePvUv4s 3 | zVUU198bUEL+FCKKIruoGut8Mha44Ns2aeLyfYx0HIDeVs7ZXwbAuLRfozBD0Ww9 4 | H7lsiKZMR3BmQaQ0iJymdQnmqYdithNzoGFShslBpANU0ZlcrN8ZTBScPcqNPxpG 5 | k9NN8u/qfMNUOeSdcoTYMsxqSjUZm8OuMQCLa5+LnlETlyN6jaLreR9Edw+n/LcN 6 | 1w7fs4z1Ae7wOYZJfkzTe3uBQdSMyCdtX9n6ZWhyiT47ozBXSvdH8aimW3FlrVbx 7 | hDOL52l8KPvhAtUp8cxwIRc6kEkoRGd6gs67yTLxOFOkw1tVi+yn55WyjmKKXjHk 8 | 3zQWkpfuIiYImcC5f7xZKoFiBOvlAbZOKKgXvh3IaQiLMFt+xUm+/jo76yLYdlQ3 9 | Mh3RFBsG2wXZmNc+vaLsLxEaBTYmk041Ow1fjQOUdE05CNSqnZ2nZHfWtCcy1mRA 10 | pccWB5I3/bBYulEHY701Es+6LguUZqZhGEYiUxv3bVrnZ/CokfDFVm8ncvqKy45g 11 | B06v+H23UgX1686UDn1c0gE1w1Rt5aIpVoYaAmlie/waT04tqC0mXHGhlMfxF+HF 12 | 4gUceM+aJJjNl9zoHf5tRgGNcuLbqESgo7qvpAb/2rLKj+hLhiGR0bZKjgFnuy+K 13 | bIUWlXgnv5BuQKfU4+68CprjMighO4HqkSYbAjwQ7KkcrSNGGiKyQLj5x3QCRaQz 14 | S8G49AHH0JZnJQYLq+uhBghS1F+50PVC5PtnCGbTHZ0iIPpRG+w1S0Ga2ybZG2fL 15 | 0xwq4qq2U4ieeblFb+l9TmAh+Ao6ZNGzvnbJZkl3ax5fTUYLW6+PkEFwFubFqjr4 16 | kbrW8o8m7eT++zsXraBt/3DBGiZnqBKtoLQT7XBmL41jJjywL5LVU1c5qsh18H0+ 17 | hKKX/Pl9gm/eFma7ICSOToEtwIcLbj5Vz/QcQAPfYF1kzSHipz0xbhsqFSX816Uu 18 | zpTqiCQXyGaxVpwlG3fi8GdV5jfANt7DMPbxseOOiz4ffePrUWr7fXYTlfxp1hDI 19 | Z91/VCUOMf3DGxlKnLPgaTA9PiDd8SnHzwrjpx9UG13zhfWYpvlz8lpvrpvVzVPT 20 | Th6PhiaKTqiNSZGUSgX6wDUoMjNwW4/3ZYh3LGoqtiKDAdkA7N1uyXeyyi99WgC2 21 | e7TmT9EtefhtO4WM1XAI7RCMKF09MIjXSJU0XChaFnQjx9/FIixecV5AnjJ70QVJ 22 | kLFY3qJXbJHOEnU7PDKjflccuRSgXceP+KCoF/2jqt9jI3mDKlafXpoYdH3cUUf9 23 | 2or5lyOzjI7t2jhBxUxE128BdTqvddpMuklIaUtllTg= 24 | -------------------------------------------------------------------------------- /CCListViewExample/CCListViewExample/CCListViewExample-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | ${PRODUCT_NAME} 9 | CFBundleExecutable 10 | ${EXECUTABLE_NAME} 11 | CFBundleIdentifier 12 | com.codecademy.${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 | UIMainStoryboardFile 28 | Main 29 | UIMainStoryboardFile~ipad 30 | Main 31 | UIRequiredDeviceCapabilities 32 | 33 | armv7 34 | 35 | UIStatusBarHidden 36 | 37 | UISupportedInterfaceOrientations 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationLandscapeLeft 41 | UIInterfaceOrientationLandscapeRight 42 | UIInterfaceOrientationPortraitUpsideDown 43 | 44 | UISupportedInterfaceOrientations~ipad 45 | 46 | UIInterfaceOrientationPortrait 47 | UIInterfaceOrientationPortraitUpsideDown 48 | UIInterfaceOrientationLandscapeLeft 49 | UIInterfaceOrientationLandscapeRight 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /Tools/Signing/Distribution Certificate.cer.enc: -------------------------------------------------------------------------------- 1 | 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 31 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: objective-c 2 | env: 3 | global: 4 | - APP_NAME="CCListViewExample" 5 | - 'DEVELOPER_NAME="iPhone Distribution: Ryzac Inc."' 6 | - PROFILE_NAME="CCListViewExample_Enterprise" 7 | - secure: IUWvVMx2Hv53tI2vCx3aYXtBqUZ/xt1j9yLPK5zmYUd8AILTsBrfT8oB9jrU7aDGb2049Dth/sCwBvIIBcbnOC2HCG4580+YKYpjV9fJAOdJJ5X1pZopIpn4sR6YnNID8xDLvkYN7odKxB8KTsrm5hm0v4XBmOFsdQLveWjwGGI= 8 | - secure: Q50hMN9J/aaYYh0b4n8tKYd6u1qBGpgDEKsqdNZIMTBAjD7yADQvahAZlORPNekzOPS905a3hwb+b+rhCXvCzyn+VJgEAJbEw8e7av2Ei5xz/RjNpLa9liIPUfpIin56RSxSZoV9UF72J+iowG12O5j5BvqcFsE7gxPdT6kF6pY= 9 | - secure: "aTlYVWyA20Nq7P/MHIyXq+6ovLYRkifWCVk0UIusPcXwnY0tWeCOD2rEqaIgfFIDL5KYMVYCqHEfHrrBtCvVWc91/DkTCz8ERcqYEMGpXUoMHy8eAxzZxMuO+xo9Trlwgm28Yp7hnOMWWxQS+HUM5ju0hHRqRcWeGuExkVIfmPQ=" 10 | - secure: "IbSnGqjT44ulLEsMA3jjjhKJ67l2TzY1mS4/vm2LeblLDU4W1ckf+7ctdoQtX94zpjEAFFpRxxvWNmH+9L0GiYb7lw0lEAqR1Pvq8p20Yi4cmHgVFo3A1K3a6LMM9p3qvcnEFQ6V85Ur9AqSdAs0nXsw6BwS6lM41SdftqviOgA=" 11 | before_script: 12 | - openssl aes-256-cbc -k "$ENCRYPTION_SECRET" -in Tools/Signing/AppleWWDRCA.cer.enc -d -a -out Tools/Signing/AppleWWDRCA.cer 13 | - openssl aes-256-cbc -k "$ENCRYPTION_SECRET" -in Tools/Signing/CCListViewExample_Enterprise.mobileprovision.enc -d -a -out Tools/Signing/CCListViewExample_Enterprise.mobileprovision 14 | - openssl aes-256-cbc -k "$ENCRYPTION_SECRET" -in "Tools/Signing/Distribution Certificate.cer.enc" -d -a -out "Tools/Signing/Distribution Certificate.cer" 15 | - openssl aes-256-cbc -k "$ENCRYPTION_SECRET" -in "Tools/Signing/Distribution Certificate.p12.enc" -d -a -out "Tools/Signing/Distribution Certificate.p12" 16 | - "./Tools/Signing/createKeyChain.sh" 17 | xcode_project: CCListViewExample.xcworkspace 18 | xcode_scheme: CCListViewExample 19 | before_install: gem install cocoapods 20 | xcode_sdk: iphonesimulator 21 | script: 22 | - xctool -workspace CCListViewExample.xcworkspace -scheme "CCListViewExample" -sdk iphonesimulator 23 | - xctool -workspace CCListViewExample.xcworkspace -scheme "CCListViewExample" -sdk iphoneos -configuration Release build OBJROOT=$PWD/build SYMROOT=$PWD/build 24 | - pod spec lint CCListView.podspec 25 | after_success: 26 | - "./Tools/TravisCI/deploy.sh" 27 | after_script: 28 | - "./Tools/TravisCI/finished.sh" 29 | -------------------------------------------------------------------------------- /CCListViewExample/CCListViewExample/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // CCListViewExample 4 | // 5 | // Created by Ian Grossberg on 6/27/14. 6 | // Copyright (c) 2014 Codecademy. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | 11 | @implementation AppDelegate 12 | 13 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 14 | { 15 | // Override point for customization after application launch. 16 | return YES; 17 | } 18 | 19 | - (void)applicationWillResignActive:(UIApplication *)application 20 | { 21 | // 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. 22 | // 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. 23 | } 24 | 25 | - (void)applicationDidEnterBackground:(UIApplication *)application 26 | { 27 | // 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. 28 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 29 | } 30 | 31 | - (void)applicationWillEnterForeground:(UIApplication *)application 32 | { 33 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. 34 | } 35 | 36 | - (void)applicationDidBecomeActive:(UIApplication *)application 37 | { 38 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 39 | } 40 | 41 | - (void)applicationWillTerminate:(UIApplication *)application 42 | { 43 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 44 | } 45 | 46 | @end 47 | -------------------------------------------------------------------------------- /CCListViewExample/CCListViewExample.xcodeproj/xcshareddata/xcschemes/All Tests.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 42 | 43 | 44 | 45 | 51 | 52 | 54 | 55 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /CCListViewExample/CCListViewExample.xcodeproj/xcshareddata/xcschemes/CCListView Podspec Lint.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 42 | 43 | 44 | 45 | 51 | 52 | 54 | 55 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /Source/UIScrollView+Utility.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIScrollView+Utility.m 3 | // CodecademyMobile 4 | // 5 | // Created by Ian Grossberg on 2/28/14. 6 | // Copyright (c) 2014 Codecademy. All rights reserved. 7 | // 8 | 9 | #import "UIScrollView+Utility.h" 10 | 11 | @implementation UIScrollView (Utility) 12 | 13 | - (void)forceWidth:(CGFloat)width 14 | { 15 | UIView *forceWidth = [ [UIView alloc] initWithFrame:CGRectMake(0, 0, width, 1.0f) ]; // TODO: test with 0 height 16 | 17 | [forceWidth setBackgroundColor:[UIColor clearColor] ]; 18 | [forceWidth setUserInteractionEnabled:NO]; 19 | 20 | [self addSubview:forceWidth]; 21 | 22 | NSDictionary *viewsDictionary = NSDictionaryOfVariableBindings(forceWidth); 23 | [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:[NSString stringWithFormat:@"H:|[forceWidth(%f)]|", width] 24 | options:0 25 | metrics:0 26 | views:viewsDictionary] ]; 27 | [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[forceWidth]" 28 | options:0 29 | metrics:0 30 | views:viewsDictionary] ]; 31 | } 32 | 33 | - (void)forceHeight:(CGFloat)height 34 | { 35 | UIView *forceheight = [ [UIView alloc] initWithFrame:CGRectMake(0, 0, 1.0f, height) ]; // TODO: test with 0 width 36 | 37 | [forceheight setBackgroundColor:[UIColor clearColor] ]; 38 | [forceheight setUserInteractionEnabled:NO]; 39 | 40 | [self addSubview:forceheight]; 41 | 42 | NSDictionary *viewsDictionary = NSDictionaryOfVariableBindings(forceheight); 43 | [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[forceheight]" 44 | options:0 45 | metrics:0 46 | views:viewsDictionary] ]; 47 | [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:[NSString stringWithFormat:@"V:|[forceheight(%f)]|", height] 48 | options:0 49 | metrics:0 50 | views:viewsDictionary] ]; 51 | } 52 | 53 | @end 54 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | CCListView 2 | === 3 | 4 | [![Pod Version](http://img.shields.io/cocoapods/v/CCListView.svg?style=flat)](http://cocoadocs.org/docsets/CCListView/) 5 | [![Pod Platform](http://img.shields.io/cocoapods/p/CCListView.svg?style=flat)](http://cocoadocs.org/docsets/CCListView/) 6 | [![Pod License](http://img.shields.io/cocoapods/l/CCListView.svg?style=flat)](http://cocoadocs.org/docsets/CCListView/) 7 | [![Travis Build Status](http://img.shields.io/travis/Codecademy/CCListView.svg?style=flat)](https://travis-ci.org/Codecademy/CCListView) 8 | 9 | **CCListView** is a highly customizable sequential view container. It can be configured to: 10 | 11 | * optionally scroll contained content 12 | * arrange content horizontally or vertically 13 | 14 | You can build **CCListViews** that contain **CCListViews** (that contain **CCListViews**...) and they even support scrolling views within scrolling views. 15 | 16 | ![screenshot1](https://github.com/Codecademy/CCListView/blob/master/Screenshots/screenshot1.png?raw=true) 17 | 18 | Installation 19 | --- 20 | **CCListView** is available through **[cocoapods](http://cocoapods.org)**, to install simple add the following line to your `PodFile`: 21 | 22 | ``` ruby 23 | pod "CCListView" 24 | ``` 25 | 26 | Alternatively you can clone the **[github repo](https://github.com/Codecademy/CCListView)**. 27 | 28 | Setup 29 | --- 30 | Once you've installed the class: 31 | 32 | * Include the CCListView header 33 | 34 | ``` objective-c 35 | #import 36 | ``` 37 | 38 | * From there you can either create your CCListView instance in Interface Builder (for now will default to vertical content and scrolling enabled) or in code by using: 39 | 40 | 41 | ``` objective-c 42 | CCListView *listView = [ [CCListView alloc] initWithFrame:(CGRect)frame horizontal:(BOOL)horizontal scrolling:(BOOL)scrolling]; 43 | ``` 44 | 45 | Passing `YES` into `horizontal` will result in content being arranged horizontally left to right, passing `NO` will result in content being arranged vertically from top to bottom. 46 | 47 | Passing `YES` into `scrolling` will enable scrolling within your list view, passing `NO` will disable scrolling. 48 | 49 | * From here you can add, insert, and remove content views as well as customize further behaviors of the list view. For now please check out the class interface declared in `CCListView.h` to learn what's available! 50 | 51 | 52 | Contributing 53 | --- 54 | **CCListView** is a simple utility class, as such the class interface has largely been built out of need. If you have any ideas, suggestions or bugs to report please [create an issue](https://github.com/Codecademy/CCListView/issues/new) labeled *feature* or *bug* (check to see if the issue exists first please!). Or suggest a pull request! 55 | -------------------------------------------------------------------------------- /Source/CCListView.h: -------------------------------------------------------------------------------- 1 | // 2 | // CCListView.h 3 | // CodecademyMobile 4 | // 5 | // Created by Ian Grossberg on 3/31/14. 6 | // Copyright (c) 2014 Codecademy. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface CCListView : UIView 12 | 13 | - (instancetype)initWithFrame:(CGRect)frame horizontal:(BOOL)horizontal scrolling:(BOOL)scrolling; 14 | 15 | - (void)sharedInit:(BOOL)horizontal scrolling:(BOOL)scrolling; // for subclassing, do not call directly unless you impliment your own init path 16 | 17 | // TODO: eventually support bottom to top and right to left? 18 | @property (readonly,getter = isHorizonal) BOOL horizontal; 19 | 20 | @property (readwrite) CGFloat contentViewSpacing; 21 | @property (readwrite) BOOL shouldConstrainTrailingEdge; 22 | 23 | @property (readwrite, getter = isPerpendicularScrollingEnabled) BOOL perpendicularScrollingEnabled; 24 | 25 | @property (readwrite, getter = isScrollingDirectionalLockEnabled) BOOL scrollingDirectionalLockEnabled; 26 | 27 | - (void)addContentView:(UIView *)contentView; 28 | - (void)insertContentView:(UIView *)contentView atIndex:(NSUInteger)index; 29 | @property (strong, readwrite) void (^addedOrInsertedContentViewHandler)(UIView *contentView, NSUInteger atIndex); 30 | 31 | - (void)enumerateContentViews:(void (^)(UIView *view, NSUInteger index, BOOL *stop) )block; 32 | 33 | @property (readonly) UIView *firstContentView; 34 | @property (readonly) UIView *lastContentView; 35 | 36 | - (UIView *)contentViewAtIndex:(NSUInteger)index; 37 | - (UIView *)contentViewAtLocation:(CGPoint)location inView:(UIView *)relativeView; 38 | - (NSUInteger)indexOfContentView:(UIView *)contentView; 39 | - (NSUInteger)countofContentViews; 40 | 41 | - (CGPoint)insertPointOfContentViewAtIndex:(NSUInteger)index; 42 | 43 | @property (readonly) CGSize contentSize; 44 | 45 | - (BOOL)isContentView:(UIView *)view; 46 | - (BOOL)contentViewIsFirst:(UIView *)contentView; 47 | - (BOOL)contentViewIsLast:(UIView *)contentView; 48 | 49 | - (NSUInteger)contentViewIndexForLocation:(CGPoint)location inView:(UIView *)inView; 50 | 51 | - (void)removeContentView:(UIView *)contentView; 52 | - (void)removeContentViewAtIndex:(NSUInteger)index; 53 | @property (strong, readwrite) void (^removedContentViewHandler)(UIView *contentView, NSUInteger atIndex); 54 | 55 | - (void)removeAllContentViews; 56 | 57 | @property (weak, readwrite) UIView *containerView; 58 | @property (weak, readonly) UIScrollView *scrollContainerView; // if our container view is a UIScrollView the result will point to our container view, otherwise it will be NULL 59 | 60 | + (CCListView *)parentListView:(UIView *)forView; 61 | 62 | #if DEBUG 63 | @property (readwrite, getter = isDebugShowFieldBoundsEnabled) BOOL debugShowFieldBoundsEnabled; 64 | #endif 65 | 66 | @end 67 | -------------------------------------------------------------------------------- /CCListViewExample/CCListViewExample.xcodeproj/xcshareddata/xcschemes/CCListViewExample.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 | -------------------------------------------------------------------------------- /Tools/Signing/Distribution Certificate.p12.enc: -------------------------------------------------------------------------------- 1 | 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 67 | 3IMx47WXnL1qs6gUpYBkiQ== 68 | -------------------------------------------------------------------------------- /CCListViewExample/CCListViewExample/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | -------------------------------------------------------------------------------- /CCListViewExample/CCListViewExample/CCListViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // CCListViewController.m 3 | // CCListViewExample 4 | // 5 | // Created by Ian Grossberg on 7/1/14. 6 | // Copyright (c) 2014 Codecademy. All rights reserved. 7 | // 8 | 9 | #import "CCListViewController.h" 10 | 11 | #import 12 | 13 | @interface CCListViewController () 14 | 15 | @end 16 | 17 | @implementation CCListViewController 18 | 19 | - (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil 20 | { 21 | self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; 22 | if (self) { 23 | [self sharedInit]; 24 | } 25 | return self; 26 | } 27 | 28 | - (instancetype)initWithCoder:(NSCoder *)aDecoder 29 | { 30 | self = [super initWithCoder:aDecoder]; 31 | if (self) { 32 | [self sharedInit]; 33 | } 34 | return self; 35 | } 36 | 37 | - (void)sharedInit 38 | { 39 | } 40 | 41 | + (BOOL)horizontalContent 42 | { 43 | return NO; 44 | } 45 | 46 | - (void)viewDidLoad 47 | { 48 | [super viewDidLoad]; 49 | 50 | [self ensureListView]; 51 | 52 | [self.listView addContentView:[CCListViewController createJunkLabel] ]; 53 | [self.listView addContentView:[CCListViewController createJunkTextView] ]; 54 | [self.listView addContentView:[CCListViewController createImageView] ]; 55 | [self.listView addContentView:[CCListViewController createJunkLabel] ]; 56 | [self.listView addContentView:[CCListViewController createJunkTextView] ]; 57 | [self.listView addContentView:[CCListViewController createImageView] ]; 58 | [self.listView addContentView:[CCListViewController createJunkLabel] ]; 59 | [self.listView addContentView:[CCListViewController createJunkTextView] ]; 60 | [self.listView addContentView:[CCListViewController createImageView] ]; 61 | [self.listView addContentView:[CCListViewController createJunkLabel] ]; 62 | [self.listView addContentView:[CCListViewController createJunkTextView] ]; 63 | [self.listView addContentView:[CCListViewController createImageView] ]; 64 | } 65 | 66 | - (void)ensureListView 67 | { 68 | if (!self.listView) 69 | { 70 | CCListView *listView = [ [CCListView alloc] initWithFrame:self.view.bounds horizontal:[ [self class] horizontalContent] scrolling:YES]; 71 | self.listView = listView; 72 | 73 | [self.view addSubview:self.listView]; 74 | self.listView.translatesAutoresizingMaskIntoConstraints = NO; 75 | 76 | [self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.listView 77 | attribute:NSLayoutAttributeTop 78 | relatedBy:NSLayoutRelationEqual 79 | toItem:self.topLayoutGuide 80 | attribute:NSLayoutAttributeBottom 81 | multiplier:1.0 82 | constant:0.0] ]; 83 | 84 | [self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.listView 85 | attribute:NSLayoutAttributeBottom 86 | relatedBy:NSLayoutRelationEqual 87 | toItem:self.bottomLayoutGuide 88 | attribute:NSLayoutAttributeTop 89 | multiplier:1.0 90 | constant:0.0] ]; 91 | 92 | [self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.listView 93 | attribute:NSLayoutAttributeLeft 94 | relatedBy:NSLayoutRelationEqual 95 | toItem:self.view 96 | attribute:NSLayoutAttributeLeft 97 | multiplier:1.0 98 | constant:0.0] ]; 99 | 100 | [self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.listView 101 | attribute:NSLayoutAttributeRight 102 | relatedBy:NSLayoutRelationEqual 103 | toItem:self.view 104 | attribute:NSLayoutAttributeRight 105 | multiplier:1.0 106 | constant:0.0] ]; 107 | 108 | 109 | self.listView.backgroundColor = [UIColor grayColor]; 110 | } 111 | 112 | self.listView.perpendicularScrollingEnabled = NO; 113 | self.listView.scrollingDirectionalLockEnabled = YES; 114 | 115 | #if DEBUG 116 | self.listView.debugShowFieldBoundsEnabled = YES; 117 | #endif 118 | } 119 | 120 | + (UILabel *)createJunkLabel 121 | { 122 | UILabel *junk = [ [UILabel alloc] init]; 123 | [junk setText:@"Heyoooooooooooooooooooo"]; 124 | [junk sizeToFit]; 125 | [junk setBackgroundColor:[UIColor colorWithRed:0.993 green:0.702 blue:1.000 alpha:1.000] ]; 126 | return junk; 127 | } 128 | 129 | + (UITextView *)createJunkTextView 130 | { 131 | UITextView *junk = [ [UITextView alloc] init]; 132 | [junk setText:@"This is a disertation on junk, junk junk junk junk junk junk junk junk junk junk junk junk junk junk junk junk junkjunk junk junk junk junk junk junk junk junk junk junk junk junk junk junk junk junkjunk junk junk junk junk junk junk junk junk junk junk junk junk junk junk junk junkjunk junk junk junk junk junk junk junk junk junk junk junk junk junk junk junk junk."]; 133 | [junk setBackgroundColor:[UIColor colorWithRed:0.689 green:0.677 blue:0.999 alpha:1.000] ]; 134 | 135 | [junk setFrame:CGRectMake(0, 0, 100, 200) ]; 136 | [junk constrainWidth:[NSString stringWithFormat:@"%f", junk.frame.size.width] ]; 137 | [junk constrainHeight:[NSString stringWithFormat:@"%f", junk.frame.size.height] ]; 138 | return junk; 139 | } 140 | 141 | + (UIImageView *)createImageView 142 | { 143 | UIImageView *junk = [ [UIImageView alloc] initWithImage:[UIImage imageNamed:@"doge"] ]; 144 | [junk setFrame:CGRectMake(0, 0, 226, 170) ]; 145 | [junk constrainWidth:[NSString stringWithFormat:@"%f", junk.frame.size.width] ]; 146 | [junk constrainHeight:[NSString stringWithFormat:@"%f", junk.frame.size.height] ]; 147 | return junk; 148 | } 149 | 150 | @end 151 | -------------------------------------------------------------------------------- /Tools/Signing/CCListViewExample_Enterprise.mobileprovision.enc: -------------------------------------------------------------------------------- 1 | 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 55 | eF/Nzyk9B01Val+Lb9m+aFJGBIMC16PY/wgDu7QPU7djv9P4+KimlmTKz3QaPrwJ 56 | 3Pb6QFmp+aIEELA2xDtJy8Bk1GnTwxRuwFaIrywpOQQrDOlbCOcTmz1x/5Yc0Bja 57 | u7NHqtEB30ockvXcfMYECqItmEHk1rIWgFPmLQed75EhU8oNWUO5Nafyns1wB1Ic 58 | wao1p5TVRe19jYX3Qh94yvj3gyUV+XzI5DKlWw2VutNyGKJp6t6K+2+D9VC1dV1s 59 | Y7kNpyOS+myEEuL6G+TpGiKnWDDmt4dci/HvpmVNKk8qCfxg3l1FrU2t5nruMmY5 60 | BlAXAW5MCMYRn+tWTctsKoTsJC5JN6dZlMvuEhZMYpKKw0XsQ+ndwnoMQoDuNs74 61 | PFJIzk0JW33aOBag40ZRrN5hZfiBLVjOqToF6nrP1wykbFFQk6h6x+EW2zjM0N/5 62 | escsRdwmV7F4toyHr3k41wVHpjjDij58O6XijOHN+b5gJW/tCWELDMXR00GeYH1d 63 | QNI49rU4Pys7KZbZm9b+PBuLUjPkWUSOD5h808gynByckjQyK/evRGfrQ93+hBcC 64 | J/TE9AwNYQy+K0c5O+GGVJN0Zep+Xdt2umROIe1yd4XSnTkmpiAvpc03gn7GXGq5 65 | z3chotg+9H0z248zGLERp9hajCf7W1HVM+Lof3Rj/2jY63C3N16yV0p3KhXjV/fN 66 | 5Fh7U5G+t3/fksIna2OlftC+n2pAIVByBglmoidaBEboiv9SNJWfLKoByCaIomoi 67 | 9onBPRy0sVK1UdCdZ+wckhNp4bgmQaSO7AKvu4WXX312d7RR3DA6BK3KhigfwKZS 68 | R2TVnHHO9CNWbq0HfFbP/xdu0Vbp9t4hGZXYqQdpsE+KJSK7fXYO4hMYraldfWpS 69 | nATCmmipZetM9Lb/n7cJzvw3O3cRySlOK08SkGRSy6E17ah8u3Y2jmVJ4KW3ElBi 70 | 7m1864sQxBo/6mSzk0eMCR76FKNaZwIwmsTAZ6Ock8NZ/qAHL4JwvKvxp8HKwhmU 71 | 76bOzCPB6z7OnIbkXlU0gmAOHZm2a8sELZpUgJzspb2y2p3mC8m7Zpm/X8FOYMlc 72 | QCpfLFh1v+1LA3TfYwOHrpRAV9Xs6SDkdaWAAaGD7EBuQcPk4IlAertrRW1tC2kp 73 | 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 156 | -------------------------------------------------------------------------------- /Source/CCListView.m: -------------------------------------------------------------------------------- 1 | // 2 | // CCListView.m 3 | // CodecademyMobile 4 | // 5 | // Created by Ian Grossberg on 3/31/14. 6 | // Copyright (c) 2014 Codecademy. All rights reserved. 7 | // 8 | 9 | #import "CCListView.h" 10 | 11 | #import "UIScrollView+Utility.h" 12 | #import 13 | 14 | #ifndef NSLogVerbose 15 | #define NSLogVerbose NSLog 16 | #endif 17 | 18 | #ifndef NSLogWarn 19 | #define NSLogWarn NSLog 20 | #endif 21 | 22 | #ifndef NSLogError 23 | #define NSLogError NSLog 24 | #endif 25 | 26 | const NSString *CodingContentViewPreviousConstraintsKey = @"CodingContentViewPreviousConstraints"; 27 | const NSString *CodingContentViewNextConstraintsKey = @"CodingContentViewNextConstraints"; 28 | 29 | @interface CCListView () 30 | 31 | @property (strong, readwrite) NSMutableArray *contentViews; 32 | @property (strong, readwrite) NSMutableDictionary *contentViewsConstraints; 33 | 34 | // the last content view's contraints to the bottom, these are the ones that change the most with each newly added content view 35 | @property (strong, readwrite) NSArray *lastContentViewContraints; // TODO: wrap into contentViewsConstraints dict 36 | 37 | @property (readwrite) CGFloat disabledPerpendicularScrollingLastPositionComponent; 38 | 39 | @end 40 | 41 | @implementation CCListView 42 | 43 | @synthesize horizontal = _horizontal; 44 | 45 | - (instancetype)initWithFrame:(CGRect)frame horizontal:(BOOL)horizontal scrolling:(BOOL)scrolling 46 | { 47 | self = [super initWithFrame:frame]; 48 | if (self) 49 | { 50 | [self sharedInit:horizontal scrolling:scrolling]; 51 | } 52 | return self; 53 | } 54 | 55 | - (id)initWithCoder:(NSCoder *)aDecoder 56 | { 57 | self = [super initWithCoder:aDecoder]; 58 | if (self) 59 | { 60 | [self sharedInit:NO scrolling:YES]; 61 | } 62 | return self; 63 | } 64 | 65 | - (id)initWithFrame:(CGRect)frame 66 | { 67 | self = [super initWithFrame:frame]; 68 | if (self) 69 | { 70 | [self sharedInit:NO scrolling:YES]; 71 | } 72 | return self; 73 | } 74 | 75 | - (void)sharedInit:(BOOL)horizontal scrolling:(BOOL)scrolling 76 | { 77 | _horizontal = horizontal; 78 | 79 | self.shouldConstrainTrailingEdge = NO; 80 | 81 | #if DEBUG 82 | self.debugShowFieldBoundsEnabled = NO; 83 | #endif 84 | self.contentViews = [NSMutableArray array]; 85 | self.contentViewsConstraints = [NSMutableDictionary dictionary]; 86 | 87 | [self ensureContentView:scrolling]; 88 | } 89 | 90 | - (void)ensureContentView:(BOOL)scrolling 91 | { 92 | if (!self.containerView) 93 | { 94 | UIView *contentView; 95 | if (scrolling) 96 | { 97 | contentView = [ [UIScrollView alloc] initWithFrame:self.bounds]; 98 | } else 99 | { 100 | contentView = [ [UIView alloc] initWithFrame:self.bounds]; 101 | } 102 | 103 | [self addSubview:contentView]; 104 | 105 | self.containerView = contentView; 106 | 107 | self.containerView.translatesAutoresizingMaskIntoConstraints = NO; 108 | 109 | self.containerView.backgroundColor = [UIColor clearColor]; 110 | 111 | [self.containerView alignLeading:@"0" trailing:@"0" toView:self]; 112 | [self.containerView alignTop:@"0" bottom:@"0" toView:self]; 113 | 114 | if (scrolling && self.scrollContainerView) 115 | { 116 | UIScrollView *contentScrollView = self.scrollContainerView; 117 | contentScrollView.delegate = self; 118 | 119 | if (self.horizontal) 120 | { 121 | contentScrollView.contentInset = UIEdgeInsetsMake(10.0f, 0, 10.0f, 0); 122 | 123 | CGFloat forceHeight = contentScrollView.frame.size.height - contentScrollView.contentInset.top - contentScrollView.contentInset.bottom; 124 | 125 | [contentScrollView forceHeight:forceHeight]; // necessary for containing scrolling content that we don't want autosizing up 126 | 127 | } else 128 | { 129 | contentScrollView.contentInset = UIEdgeInsetsMake(0, 10.0f, 0, 10.0f); 130 | 131 | CGFloat forceWidth = contentScrollView.frame.size.width - contentScrollView.contentInset.left - contentScrollView.contentInset.right; 132 | 133 | [contentScrollView forceWidth:forceWidth]; // necessary for containing scrolling content that we don't want autosizing up 134 | } 135 | } 136 | } 137 | 138 | self.contentViewSpacing = 5.0f; 139 | } 140 | 141 | @synthesize perpendicularScrollingEnabled = _perpendicularScrollingEnabled; 142 | - (void)setPerpendicularScrollingEnabled:(BOOL)perpendicularScrollingEnabled 143 | { 144 | _perpendicularScrollingEnabled = perpendicularScrollingEnabled; 145 | if (!_perpendicularScrollingEnabled && self.scrollContainerView) 146 | { 147 | if (self.horizontal) 148 | { 149 | self.disabledPerpendicularScrollingLastPositionComponent = self.scrollContainerView.contentOffset.y; 150 | } else 151 | { 152 | self.disabledPerpendicularScrollingLastPositionComponent = self.scrollContainerView.contentOffset.x; 153 | } 154 | } 155 | } 156 | 157 | - (BOOL)isPerpendicularScrollingEnabled 158 | { 159 | return _perpendicularScrollingEnabled; 160 | } 161 | 162 | - (void)scrollViewDidScroll:(UIScrollView *)scrollView 163 | { 164 | if (!self.perpendicularScrollingEnabled) 165 | { 166 | if (self.horizontal) 167 | { 168 | [scrollView setContentOffset:CGPointMake(scrollView.contentOffset.x, self.disabledPerpendicularScrollingLastPositionComponent) ]; 169 | } else 170 | { 171 | [scrollView setContentOffset:CGPointMake(self.disabledPerpendicularScrollingLastPositionComponent, scrollView.contentOffset.y)]; 172 | } 173 | } 174 | } 175 | 176 | - (void)setScrollingDirectionalLockEnabled:(BOOL)directionalLockEnabled 177 | { 178 | if (self.scrollContainerView) 179 | { 180 | self.scrollContainerView.directionalLockEnabled = directionalLockEnabled; 181 | } 182 | } 183 | 184 | - (BOOL)isScrollingDirectionalLockEnabled 185 | { 186 | BOOL result = NO; 187 | if (self.scrollContainerView) 188 | { 189 | result = self.scrollContainerView.directionalLockEnabled; 190 | } 191 | return result; 192 | } 193 | 194 | - (UIScrollView *)scrollContainerView 195 | { 196 | UIScrollView *result; 197 | 198 | if ( [self.containerView isKindOfClass:[UIScrollView class] ] ) 199 | { 200 | result = (UIScrollView *)self.containerView; 201 | } 202 | 203 | return result; 204 | } 205 | 206 | - (void)addContentView:(UIView *)newView 207 | { 208 | if (newView) 209 | { 210 | newView.translatesAutoresizingMaskIntoConstraints = NO; 211 | 212 | [self.containerView addSubview:newView]; 213 | 214 | __block UIView *previousView = [self.contentViews lastObject]; 215 | 216 | NSDictionary *viewsDictionary = NSDictionaryOfVariableBindings(newView); 217 | 218 | [self constrainViewToBounds:newView]; 219 | 220 | if (self.lastContentViewContraints.count > 0) 221 | { 222 | [previousView.superview removeConstraints:self.lastContentViewContraints]; 223 | self.lastContentViewContraints = nil; 224 | } 225 | 226 | [self constrainView:newView toPrevious:previousView]; 227 | 228 | NSArray *bottomConstraints; 229 | NSString *bottomConstraintString; 230 | if (self.horizontal) 231 | { 232 | bottomConstraintString = [NSString stringWithFormat:@"H:[newView]|"]; 233 | } else 234 | { 235 | bottomConstraintString = [NSString stringWithFormat:@"V:[newView]|"]; 236 | } 237 | bottomConstraints = [NSLayoutConstraint constraintsWithVisualFormat:bottomConstraintString 238 | options:0 239 | metrics:0 240 | views:viewsDictionary]; 241 | [newView.superview addConstraints:bottomConstraints]; 242 | self.lastContentViewContraints = bottomConstraints; 243 | 244 | #if DEBUG 245 | [self setDebugShowFieldBoundsOnView:newView]; 246 | #endif 247 | NSUInteger index = (unsigned long)(self.contentViews.count); 248 | [self.contentViews addObject:newView]; 249 | 250 | if (self.addedOrInsertedContentViewHandler) 251 | { 252 | self.addedOrInsertedContentViewHandler(newView, index); 253 | } 254 | 255 | NSLogVerbose(@"Added view %@ at index %lu", newView, (unsigned long)index); 256 | } else 257 | { 258 | NSLogWarn(@"Attempted to add nil view"); 259 | } 260 | } 261 | 262 | 263 | - (void)insertContentView:(UIView *)view atIndex:(NSUInteger)index 264 | { 265 | if (index < self.contentViews.count) 266 | { 267 | UIView *previousView; 268 | if (index != 0) 269 | { 270 | previousView = [self contentViewAtIndex:index - 1]; 271 | } 272 | UIView *nextView = [self contentViewAtIndex:index]; 273 | 274 | [self removeConstraintsOfType:CodingContentViewPreviousConstraintsKey forView:nextView]; 275 | 276 | [self.containerView addSubview:view]; 277 | 278 | [self constrainViewToBounds:view]; 279 | 280 | [self constrainView:view toPrevious:previousView]; 281 | [self constrainView:nextView toPrevious:view]; 282 | 283 | #if DEBUG 284 | [self setDebugShowFieldBoundsOnView:view]; 285 | #endif 286 | 287 | [self.contentViews insertObject:view atIndex:index]; 288 | 289 | if (self.addedOrInsertedContentViewHandler) 290 | { 291 | self.addedOrInsertedContentViewHandler(view, index); 292 | } 293 | 294 | NSLogVerbose(@"Inserted view %@ at index %lu", view, (unsigned long)index); 295 | } else 296 | { 297 | [self addContentView:view]; 298 | } 299 | } 300 | 301 | - (void)constrainViewToBounds:(UIView *)constrainView 302 | { 303 | if (self.horizontal) 304 | { 305 | [constrainView alignTopEdgeWithView:self.containerView predicate:@"0"]; 306 | if (self.shouldConstrainTrailingEdge) 307 | { 308 | [constrainView alignBottomEdgeWithView:self.containerView predicate:@"0"]; 309 | } else 310 | { 311 | [constrainView alignBottomEdgeWithView:self.containerView predicate:@"<=0"]; 312 | } 313 | 314 | } else 315 | { 316 | [constrainView alignLeadingEdgeWithView:self.containerView predicate:@"0"]; 317 | if (self.shouldConstrainTrailingEdge) 318 | { 319 | [constrainView alignTrailingEdgeWithView:self.containerView predicate:@"0"]; 320 | } else 321 | { 322 | [constrainView alignTrailingEdgeWithView:self.containerView predicate:@"<=0"]; 323 | } 324 | } 325 | } 326 | 327 | - (void)constrainView:(UIView *)constrainView toPrevious:(UIView *)previousView 328 | { 329 | if (constrainView) 330 | { 331 | NSArray *addedConstraints; 332 | if (!previousView) 333 | { 334 | NSDictionary *viewsDictionary = NSDictionaryOfVariableBindings(constrainView); 335 | NSString *topConstraintString; 336 | if (self.horizontal) 337 | { 338 | topConstraintString = [NSString stringWithFormat:@"H:|[constrainView]"]; 339 | } else 340 | { 341 | topConstraintString = [NSString stringWithFormat:@"V:|[constrainView]"]; 342 | } 343 | addedConstraints = [NSLayoutConstraint constraintsWithVisualFormat:topConstraintString 344 | options:0 345 | metrics:0 346 | views:viewsDictionary]; 347 | [constrainView.superview addConstraints:addedConstraints]; 348 | } else 349 | { 350 | NSDictionary *viewsDictionary = NSDictionaryOfVariableBindings(constrainView, previousView); 351 | NSString *topConstraintString; 352 | if (self.horizontal) 353 | { 354 | topConstraintString = [NSString stringWithFormat:@"H:[previousView]-%f-[constrainView]", self.contentViewSpacing]; 355 | } else 356 | { 357 | topConstraintString = [NSString stringWithFormat:@"V:[previousView]-%f-[constrainView]", self.contentViewSpacing]; 358 | } 359 | addedConstraints = [NSLayoutConstraint constraintsWithVisualFormat:topConstraintString 360 | options:0 361 | metrics:0 362 | views:viewsDictionary]; 363 | [constrainView.superview addConstraints:addedConstraints]; 364 | } 365 | 366 | [self addConstraints:addedConstraints ofType:CodingContentViewPreviousConstraintsKey forView:constrainView]; 367 | } else 368 | { 369 | NSLogWarn(@"Attempting to constrain view but it's nil"); 370 | } 371 | } 372 | 373 | - (NSString *)constraintsKeyForView:(UIView *)view 374 | { 375 | return [NSString stringWithFormat:@"%d", (int)view]; 376 | } 377 | 378 | // TODO: w/ removeConstraintsOfType below: make functionality or naming consistent, add only adds to dict, remove removes from view and dict 379 | - (void)addConstraints:(NSArray *)constraints ofType:(const NSString *)constraintType forView:(UIView *)view 380 | { 381 | if (constraints) 382 | { 383 | NSMutableDictionary *constraintsDict = [self getConstraintsForView:view]; 384 | if (!constraintsDict) 385 | { 386 | constraintsDict = [NSMutableDictionary dictionaryWithCapacity:2]; 387 | } 388 | 389 | [constraintsDict setObject:constraints forKey:constraintType]; 390 | 391 | [self.contentViewsConstraints setObject:constraintsDict forKey:[self constraintsKeyForView:view] ]; 392 | } else 393 | { 394 | NSLogWarn(@"Attempting to add constraints for %@ but constraints list is nil", view); 395 | } 396 | } 397 | 398 | - (NSMutableDictionary *)getConstraintsForView:(UIView *)view 399 | { 400 | return [self.contentViewsConstraints objectForKey:[self constraintsKeyForView:view] ]; 401 | } 402 | 403 | - (void)removeConstraintsOfType:(const NSString *)constraintType forView:(UIView *)view 404 | { 405 | if (view) 406 | { 407 | NSMutableDictionary *constraintsDict = [self getConstraintsForView:view]; 408 | NSArray *constraints = [constraintsDict objectForKey:constraintType]; 409 | if (constraints.count > 0) 410 | { 411 | [constraintsDict removeObjectForKey:constraintType]; 412 | [view.superview removeConstraints:constraints]; 413 | } else 414 | { 415 | NSLogWarn(@"No constraints of type %@ found for %@", constraintType, view); 416 | } 417 | } else 418 | { 419 | NSLogWarn(@"Attempting to remove constraints for type %@ but view is nil", constraintType); 420 | } 421 | } 422 | 423 | - (void)enumerateContentViews:(void (^)(UIView *view, NSUInteger index, BOOL *stop) )block 424 | { 425 | if (block) 426 | { 427 | NSUInteger index = 0; 428 | BOOL stop = NO; 429 | for (id object in self.contentViews) 430 | { 431 | if ( [object isKindOfClass:[UIView class] ] ) 432 | { 433 | block( (UIView *)object, index, &stop); 434 | if (stop) 435 | { 436 | break; 437 | } 438 | index ++; 439 | } 440 | } 441 | } 442 | } 443 | 444 | - (UIView *)firstContentView 445 | { 446 | return self.contentViews.firstObject; 447 | } 448 | 449 | - (UIView *)lastContentView 450 | { 451 | return self.contentViews.lastObject; 452 | } 453 | 454 | - (UIView *)contentViewAtIndex:(NSUInteger)index 455 | { 456 | UIView *result; 457 | if (index < self.contentViews.count) 458 | { 459 | result = [self.contentViews objectAtIndex:index]; 460 | } else 461 | { 462 | NSLogWarn(@"Attempting to retrieve content view at index (%lu) but only have a count of (%lu)", (unsigned long)index, (unsigned long)self.contentViews.count); 463 | } 464 | return result; 465 | } 466 | 467 | - (UIView *)previousContentViewFromView:(UIView *)view 468 | { 469 | UIView *result; 470 | 471 | if ( ![self contentViewIsFirst:view] ) 472 | { 473 | NSUInteger index = [self indexOfContentView:view]; 474 | result = [self contentViewAtIndex:index - 1]; 475 | } 476 | 477 | return result; 478 | } 479 | 480 | - (UIView *)nextContentViewFromView:(UIView *)view 481 | { 482 | UIView *result; 483 | 484 | if ( ![self contentViewIsLast:view] ) 485 | { 486 | NSUInteger index = [self indexOfContentView:view]; 487 | result = [self contentViewAtIndex:index + 1]; 488 | } 489 | 490 | return result; 491 | } 492 | 493 | - (NSUInteger)indexOfContentView:(UIView *)contentView 494 | { 495 | return [self.contentViews indexOfObject:contentView]; 496 | } 497 | 498 | - (NSUInteger)countofContentViews 499 | { 500 | return self.contentViews.count; 501 | } 502 | 503 | - (CGPoint)originOfContentViewAtIndex:(NSUInteger)index 504 | { 505 | CGPoint result; 506 | if (index < [self countofContentViews] ) 507 | { 508 | UIView *viewAtIndex = [self contentViewAtIndex:index]; 509 | result = viewAtIndex.frame.origin; 510 | } else 511 | { 512 | UIView *lastView = [self lastContentView]; 513 | if (self.horizontal) 514 | { 515 | result.x = lastView.frame.origin.x + lastView.frame.size.width + self.contentViewSpacing; 516 | result.y = lastView.frame.origin.y; 517 | } else 518 | { 519 | result.x = lastView.frame.origin.x; 520 | result.y = lastView.frame.origin.y + lastView.frame.size.height + self.contentViewSpacing; 521 | } 522 | } 523 | 524 | return result; 525 | } 526 | 527 | - (CGPoint)insertPointOfContentViewAtIndex:(NSUInteger)index 528 | { 529 | CGPoint result; 530 | 531 | CGPoint viewOrigin = [self originOfContentViewAtIndex:index]; 532 | 533 | if (self.horizontal) 534 | { 535 | result.x = viewOrigin.x - self.contentViewSpacing / 2.0f; 536 | result.y = viewOrigin.y; 537 | } else 538 | { 539 | result.x = viewOrigin.x; 540 | result.y = viewOrigin.y - self.contentViewSpacing / 2.0f; 541 | } 542 | 543 | if (self.scrollContainerView) 544 | { 545 | CGPoint offset = self.scrollContainerView.contentOffset; 546 | 547 | result.x -= offset.x; 548 | result.y -= offset.y; 549 | } 550 | 551 | return result; 552 | } 553 | 554 | - (CGSize)contentSize 555 | { 556 | CGSize result; 557 | if (self.scrollContainerView) 558 | { 559 | result = self.scrollContainerView.contentSize; 560 | } else 561 | { 562 | result = self.containerView.frame.size; 563 | } 564 | 565 | return result; 566 | } 567 | 568 | - (UIView *)contentViewAtLocation:(CGPoint)location inView:(UIView *)relativeView 569 | { 570 | __block UIView *result; 571 | 572 | [self enumerateContentViews:^(UIView *view, NSUInteger index, BOOL *stop) 573 | { 574 | CGPoint relativeLocation = [view.superview convertPoint:location fromView:relativeView]; 575 | if (CGRectContainsPoint(view.frame, relativeLocation) ) 576 | { 577 | result = view; 578 | *stop = YES; 579 | } else 580 | { 581 | CGPoint nextViewOrigin; 582 | 583 | UIView *nextView = [self nextContentViewFromView:view]; 584 | if (nextView) 585 | { 586 | nextViewOrigin = nextView.frame.origin; 587 | } else 588 | { 589 | nextViewOrigin = [self originOfContentViewAtIndex:[self countofContentViews] ]; 590 | } 591 | 592 | if (self.horizontal) 593 | { 594 | if ( abs( (int)view.frame.origin.x - (int)relativeLocation.x) < abs( (int)nextViewOrigin.x - (int)relativeLocation.x) ) 595 | { 596 | result = view; 597 | *stop = YES; 598 | } 599 | } else 600 | { 601 | if ( abs( (int)view.frame.origin.y - (int)relativeLocation.y) < abs( (int)nextViewOrigin.y - (int)relativeLocation.y) ) 602 | { 603 | result = view; 604 | *stop = YES; 605 | } 606 | } 607 | } 608 | } ]; 609 | 610 | return result; 611 | } 612 | 613 | - (BOOL)isContentView:(UIView *)view 614 | { 615 | return [self.contentViews containsObject:view]; 616 | } 617 | 618 | - (BOOL)contentViewIsFirst:(UIView *)contentView 619 | { 620 | return [self.contentViews firstObject] == contentView; 621 | } 622 | 623 | - (BOOL)contentViewIsLast:(UIView *)contentView 624 | { 625 | return [self.contentViews lastObject] == contentView; 626 | } 627 | 628 | - (NSUInteger)contentViewIndexForLocation:(CGPoint)location inView:(UIView *)inView 629 | { 630 | NSUInteger result = NSNotFound; 631 | 632 | UIView *contentViewForLocation = [self contentViewAtLocation:location inView:inView]; 633 | if (contentViewForLocation) 634 | { 635 | result = [self indexOfContentView:contentViewForLocation]; 636 | } 637 | 638 | return result; 639 | } 640 | 641 | - (void)removeContentView:(UIView *)contentView 642 | { 643 | if ( [self.contentViews containsObject:contentView] ) 644 | { 645 | NSUInteger index = [self indexOfContentView:contentView]; 646 | 647 | UIView *previousView = [self previousContentViewFromView:contentView]; 648 | UIView *nextView = [self nextContentViewFromView:contentView]; 649 | 650 | [self.contentViews removeObject:contentView]; 651 | 652 | [self removeConstraintsOfType:CodingContentViewPreviousConstraintsKey forView:contentView]; 653 | if (nextView) 654 | { 655 | [self removeConstraintsOfType:CodingContentViewPreviousConstraintsKey forView:nextView]; 656 | [self constrainView:nextView toPrevious:previousView]; 657 | } 658 | 659 | [contentView removeFromSuperview]; 660 | 661 | if (self.removedContentViewHandler) 662 | { 663 | self.removedContentViewHandler(contentView, index); 664 | } 665 | 666 | NSLogVerbose(@"Removed view %@ from index %lu", contentView, (unsigned long)index); 667 | } else 668 | { 669 | NSLogWarn(@"Attempting to remove a content view (%@) not current in the list", contentView); 670 | } 671 | } 672 | 673 | - (void)removeContentViewAtIndex:(NSUInteger)index 674 | { 675 | if (index < self.contentViews.count) 676 | { 677 | UIView *contentView = [self.contentViews objectAtIndex:index]; 678 | [self removeContentView:contentView]; 679 | } else 680 | { 681 | NSLogWarn(@"Attempting to remove an index (%lu) past the content views count (%lu)", (unsigned long)index, (unsigned long)self.contentViews.count); 682 | } 683 | } 684 | 685 | - (void)removeAllContentViews 686 | { 687 | NSArray *contentViews = [self.contentViews copy]; 688 | [contentViews enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) 689 | { 690 | if ( [obj isKindOfClass:[UIView class] ] ) 691 | { 692 | [self removeContentView:obj]; 693 | } 694 | }]; 695 | } 696 | 697 | - (BOOL)resignFirstResponder 698 | { 699 | __block BOOL resigned = NO; 700 | 701 | [self enumerateContentViews:^(UIView *view, NSUInteger index, BOOL *stop) 702 | { 703 | resigned = *stop = [view resignFirstResponder]; 704 | } ]; 705 | 706 | if (!resigned) 707 | { 708 | resigned = [super resignFirstResponder]; 709 | } 710 | return resigned; 711 | } 712 | 713 | + (CCListView *)parentListView:(UIView *)forView; 714 | { 715 | CCListView *result; 716 | 717 | UIView *immediateParent = [forView superview]; 718 | if ( [immediateParent isKindOfClass:[UIView class] ] || [immediateParent isKindOfClass:[UIScrollView class] ] ) 719 | { 720 | UIView *nextParent = [immediateParent superview]; 721 | if ( [nextParent isKindOfClass:[CCListView class] ] ) 722 | { 723 | result = (CCListView *)nextParent; 724 | } 725 | } 726 | 727 | return result; 728 | } 729 | 730 | #pragma mark Debug 731 | 732 | #if DEBUG 733 | @synthesize debugShowFieldBoundsEnabled = _debugShowFieldBoundsEnabled; 734 | - (void)setDebugShowFieldBoundsEnabled:(BOOL)debugShowFieldBoundsEnabled 735 | { 736 | _debugShowFieldBoundsEnabled = debugShowFieldBoundsEnabled; 737 | for (id object in self.contentViews) 738 | { 739 | if ( [object isKindOfClass:[UIView class] ] ) 740 | { 741 | [self setDebugShowFieldBoundsOnView:object]; 742 | } 743 | } 744 | } 745 | 746 | - (void)setDebugShowFieldBoundsOnView:(UIView *)view 747 | { 748 | if (self.isDebugShowFieldBoundsEnabled) 749 | { 750 | [view.layer setBorderColor:[UIColor redColor].CGColor ]; 751 | [view.layer setBorderWidth:1.0f]; 752 | } 753 | } 754 | 755 | - (BOOL)isDebugShowFieldBoundsEnabled 756 | { 757 | return _debugShowFieldBoundsEnabled; 758 | } 759 | 760 | #endif 761 | 762 | @end 763 | -------------------------------------------------------------------------------- /CCListViewExample/CCListViewExample.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXAggregateTarget section */ 10 | 3C9777CE195E0DE0005C4700 /* Podspec Lint */ = { 11 | isa = PBXAggregateTarget; 12 | buildConfigurationList = 3C9777CF195E0DE0005C4700 /* Build configuration list for PBXAggregateTarget "Podspec Lint" */; 13 | buildPhases = ( 14 | 3C9777D2195E0DEA005C4700 /* ShellScript */, 15 | ); 16 | dependencies = ( 17 | ); 18 | name = "Podspec Lint"; 19 | productName = "Podspec Lint"; 20 | }; 21 | 3C9777D3195E0E97005C4700 /* All Tests */ = { 22 | isa = PBXAggregateTarget; 23 | buildConfigurationList = 3C9777D4195E0E97005C4700 /* Build configuration list for PBXAggregateTarget "All Tests" */; 24 | buildPhases = ( 25 | ); 26 | dependencies = ( 27 | 3C9777D8195E0E9F005C4700 /* PBXTargetDependency */, 28 | 3C9777DA195E0E9F005C4700 /* PBXTargetDependency */, 29 | ); 30 | name = "All Tests"; 31 | productName = "All Tests"; 32 | }; 33 | /* End PBXAggregateTarget section */ 34 | 35 | /* Begin PBXBuildFile section */ 36 | 3C54D71619633D7D00165E56 /* HorizontalListViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 3C54D71519633D7D00165E56 /* HorizontalListViewController.m */; }; 37 | 3C54D71919633DB600165E56 /* CCListViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 3C54D71819633DB600165E56 /* CCListViewController.m */; }; 38 | 3C977790195E0D3C005C4700 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3C97778F195E0D3C005C4700 /* Foundation.framework */; }; 39 | 3C977792195E0D3C005C4700 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3C977791195E0D3C005C4700 /* CoreGraphics.framework */; }; 40 | 3C977794195E0D3C005C4700 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3C977793195E0D3C005C4700 /* UIKit.framework */; }; 41 | 3C97779A195E0D3C005C4700 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 3C977798195E0D3C005C4700 /* InfoPlist.strings */; }; 42 | 3C97779C195E0D3C005C4700 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 3C97779B195E0D3C005C4700 /* main.m */; }; 43 | 3C9777A0195E0D3C005C4700 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 3C97779F195E0D3C005C4700 /* AppDelegate.m */; }; 44 | 3C9777A3195E0D3C005C4700 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 3C9777A1195E0D3C005C4700 /* Main.storyboard */; }; 45 | 3C9777A9195E0D3C005C4700 /* VerticalListViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 3C9777A8195E0D3C005C4700 /* VerticalListViewController.m */; }; 46 | 3C9777AB195E0D3C005C4700 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 3C9777AA195E0D3C005C4700 /* Images.xcassets */; }; 47 | 3C9777B2195E0D3C005C4700 /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3C9777B1195E0D3C005C4700 /* XCTest.framework */; }; 48 | 3C9777B3195E0D3C005C4700 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3C97778F195E0D3C005C4700 /* Foundation.framework */; }; 49 | 3C9777B4195E0D3C005C4700 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3C977793195E0D3C005C4700 /* UIKit.framework */; }; 50 | 3C9777BC195E0D3C005C4700 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 3C9777BA195E0D3C005C4700 /* InfoPlist.strings */; }; 51 | 3C9777BE195E0D3C005C4700 /* CCListViewExampleTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 3C9777BD195E0D3C005C4700 /* CCListViewExampleTests.m */; }; 52 | 3C9777C9195E0D62005C4700 /* CCListView.podspec in Resources */ = {isa = PBXBuildFile; fileRef = 3C9777C8195E0D62005C4700 /* CCListView.podspec */; }; 53 | 3C9B04871964867300FAD524 /* doge.png in Resources */ = {isa = PBXBuildFile; fileRef = 3C9B04861964867300FAD524 /* doge.png */; }; 54 | 52136C31A8ED401BB1F6EB3A /* libPods-CCListViewExample.a in Frameworks */ = {isa = PBXBuildFile; fileRef = A247147D88DC45FD8AD25556 /* libPods-CCListViewExample.a */; }; 55 | /* End PBXBuildFile section */ 56 | 57 | /* Begin PBXContainerItemProxy section */ 58 | 3C9777B5195E0D3C005C4700 /* PBXContainerItemProxy */ = { 59 | isa = PBXContainerItemProxy; 60 | containerPortal = 3C977784195E0D3C005C4700 /* Project object */; 61 | proxyType = 1; 62 | remoteGlobalIDString = 3C97778B195E0D3C005C4700; 63 | remoteInfo = CCListViewExample; 64 | }; 65 | 3C9777D7195E0E9F005C4700 /* PBXContainerItemProxy */ = { 66 | isa = PBXContainerItemProxy; 67 | containerPortal = 3C977784195E0D3C005C4700 /* Project object */; 68 | proxyType = 1; 69 | remoteGlobalIDString = 3C9777AF195E0D3C005C4700; 70 | remoteInfo = CCListViewExampleTests; 71 | }; 72 | 3C9777D9195E0E9F005C4700 /* PBXContainerItemProxy */ = { 73 | isa = PBXContainerItemProxy; 74 | containerPortal = 3C977784195E0D3C005C4700 /* Project object */; 75 | proxyType = 1; 76 | remoteGlobalIDString = 3C9777CE195E0DE0005C4700; 77 | remoteInfo = "Podspec Lint"; 78 | }; 79 | /* End PBXContainerItemProxy section */ 80 | 81 | /* Begin PBXFileReference section */ 82 | 3C54D71419633D7D00165E56 /* HorizontalListViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HorizontalListViewController.h; sourceTree = ""; }; 83 | 3C54D71519633D7D00165E56 /* HorizontalListViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HorizontalListViewController.m; sourceTree = ""; }; 84 | 3C54D71719633DB600165E56 /* CCListViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCListViewController.h; sourceTree = ""; }; 85 | 3C54D71819633DB600165E56 /* CCListViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CCListViewController.m; sourceTree = ""; }; 86 | 3C97778C195E0D3C005C4700 /* CCListViewExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = CCListViewExample.app; sourceTree = BUILT_PRODUCTS_DIR; }; 87 | 3C97778F195E0D3C005C4700 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 88 | 3C977791195E0D3C005C4700 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; 89 | 3C977793195E0D3C005C4700 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 90 | 3C977797195E0D3C005C4700 /* CCListViewExample-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "CCListViewExample-Info.plist"; sourceTree = ""; }; 91 | 3C977799195E0D3C005C4700 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 92 | 3C97779B195E0D3C005C4700 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 93 | 3C97779D195E0D3C005C4700 /* CCListViewExample-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "CCListViewExample-Prefix.pch"; sourceTree = ""; }; 94 | 3C97779E195E0D3C005C4700 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 95 | 3C97779F195E0D3C005C4700 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 96 | 3C9777A2195E0D3C005C4700 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 97 | 3C9777A7195E0D3C005C4700 /* VerticalListViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = VerticalListViewController.h; sourceTree = ""; }; 98 | 3C9777A8195E0D3C005C4700 /* VerticalListViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = VerticalListViewController.m; sourceTree = ""; }; 99 | 3C9777AA195E0D3C005C4700 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 100 | 3C9777B0195E0D3C005C4700 /* CCListViewExampleTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = CCListViewExampleTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 101 | 3C9777B1195E0D3C005C4700 /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; }; 102 | 3C9777B9195E0D3C005C4700 /* CCListViewExampleTests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "CCListViewExampleTests-Info.plist"; sourceTree = ""; }; 103 | 3C9777BB195E0D3C005C4700 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 104 | 3C9777BD195E0D3C005C4700 /* CCListViewExampleTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CCListViewExampleTests.m; sourceTree = ""; }; 105 | 3C9777C8195E0D62005C4700 /* CCListView.podspec */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = CCListView.podspec; path = ../CCListView.podspec; sourceTree = ""; }; 106 | 3C9B04821964828A00FAD524 /* LICENSE.md */ = {isa = PBXFileReference; lastKnownFileType = text; name = LICENSE.md; path = ../LICENSE.md; sourceTree = ""; }; 107 | 3C9B04831964828A00FAD524 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = text; name = README.md; path = ../README.md; sourceTree = ""; }; 108 | 3C9B04861964867300FAD524 /* doge.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = doge.png; sourceTree = ""; }; 109 | 3C9B04891964886D00FAD524 /* screenshot1.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = screenshot1.png; sourceTree = ""; }; 110 | 58423AAC5FF24F838A28BEB3 /* Pods-CCListViewExample.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CCListViewExample.xcconfig"; path = "../Pods/Pods-CCListViewExample.xcconfig"; sourceTree = ""; }; 111 | A247147D88DC45FD8AD25556 /* libPods-CCListViewExample.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-CCListViewExample.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 112 | /* End PBXFileReference section */ 113 | 114 | /* Begin PBXFrameworksBuildPhase section */ 115 | 3C977789195E0D3C005C4700 /* Frameworks */ = { 116 | isa = PBXFrameworksBuildPhase; 117 | buildActionMask = 2147483647; 118 | files = ( 119 | 3C977792195E0D3C005C4700 /* CoreGraphics.framework in Frameworks */, 120 | 3C977794195E0D3C005C4700 /* UIKit.framework in Frameworks */, 121 | 3C977790195E0D3C005C4700 /* Foundation.framework in Frameworks */, 122 | 52136C31A8ED401BB1F6EB3A /* libPods-CCListViewExample.a in Frameworks */, 123 | ); 124 | runOnlyForDeploymentPostprocessing = 0; 125 | }; 126 | 3C9777AD195E0D3C005C4700 /* Frameworks */ = { 127 | isa = PBXFrameworksBuildPhase; 128 | buildActionMask = 2147483647; 129 | files = ( 130 | 3C9777B2195E0D3C005C4700 /* XCTest.framework in Frameworks */, 131 | 3C9777B4195E0D3C005C4700 /* UIKit.framework in Frameworks */, 132 | 3C9777B3195E0D3C005C4700 /* Foundation.framework in Frameworks */, 133 | ); 134 | runOnlyForDeploymentPostprocessing = 0; 135 | }; 136 | /* End PBXFrameworksBuildPhase section */ 137 | 138 | /* Begin PBXGroup section */ 139 | 3C977783195E0D3C005C4700 = { 140 | isa = PBXGroup; 141 | children = ( 142 | 3C9B04821964828A00FAD524 /* LICENSE.md */, 143 | 3C9B04831964828A00FAD524 /* README.md */, 144 | 3C9B04881964886D00FAD524 /* Screenshots */, 145 | 3C9777C8195E0D62005C4700 /* CCListView.podspec */, 146 | 3C977795195E0D3C005C4700 /* CCListViewExample */, 147 | 3C9777B7195E0D3C005C4700 /* CCListViewExampleTests */, 148 | 3C97778E195E0D3C005C4700 /* Frameworks */, 149 | 3C97778D195E0D3C005C4700 /* Products */, 150 | 58423AAC5FF24F838A28BEB3 /* Pods-CCListViewExample.xcconfig */, 151 | ); 152 | sourceTree = ""; 153 | }; 154 | 3C97778D195E0D3C005C4700 /* Products */ = { 155 | isa = PBXGroup; 156 | children = ( 157 | 3C97778C195E0D3C005C4700 /* CCListViewExample.app */, 158 | 3C9777B0195E0D3C005C4700 /* CCListViewExampleTests.xctest */, 159 | ); 160 | name = Products; 161 | sourceTree = ""; 162 | }; 163 | 3C97778E195E0D3C005C4700 /* Frameworks */ = { 164 | isa = PBXGroup; 165 | children = ( 166 | 3C97778F195E0D3C005C4700 /* Foundation.framework */, 167 | 3C977791195E0D3C005C4700 /* CoreGraphics.framework */, 168 | 3C977793195E0D3C005C4700 /* UIKit.framework */, 169 | 3C9777B1195E0D3C005C4700 /* XCTest.framework */, 170 | A247147D88DC45FD8AD25556 /* libPods-CCListViewExample.a */, 171 | ); 172 | name = Frameworks; 173 | sourceTree = ""; 174 | }; 175 | 3C977795195E0D3C005C4700 /* CCListViewExample */ = { 176 | isa = PBXGroup; 177 | children = ( 178 | 3C9B04861964867300FAD524 /* doge.png */, 179 | 3C97779E195E0D3C005C4700 /* AppDelegate.h */, 180 | 3C97779F195E0D3C005C4700 /* AppDelegate.m */, 181 | 3C9777A1195E0D3C005C4700 /* Main.storyboard */, 182 | 3C9777A7195E0D3C005C4700 /* VerticalListViewController.h */, 183 | 3C9777A8195E0D3C005C4700 /* VerticalListViewController.m */, 184 | 3C9777AA195E0D3C005C4700 /* Images.xcassets */, 185 | 3C977796195E0D3C005C4700 /* Supporting Files */, 186 | 3C54D71419633D7D00165E56 /* HorizontalListViewController.h */, 187 | 3C54D71519633D7D00165E56 /* HorizontalListViewController.m */, 188 | 3C54D71719633DB600165E56 /* CCListViewController.h */, 189 | 3C54D71819633DB600165E56 /* CCListViewController.m */, 190 | ); 191 | path = CCListViewExample; 192 | sourceTree = ""; 193 | }; 194 | 3C977796195E0D3C005C4700 /* Supporting Files */ = { 195 | isa = PBXGroup; 196 | children = ( 197 | 3C977797195E0D3C005C4700 /* CCListViewExample-Info.plist */, 198 | 3C977798195E0D3C005C4700 /* InfoPlist.strings */, 199 | 3C97779B195E0D3C005C4700 /* main.m */, 200 | 3C97779D195E0D3C005C4700 /* CCListViewExample-Prefix.pch */, 201 | ); 202 | name = "Supporting Files"; 203 | sourceTree = ""; 204 | }; 205 | 3C9777B7195E0D3C005C4700 /* CCListViewExampleTests */ = { 206 | isa = PBXGroup; 207 | children = ( 208 | 3C9777BD195E0D3C005C4700 /* CCListViewExampleTests.m */, 209 | 3C9777B8195E0D3C005C4700 /* Supporting Files */, 210 | ); 211 | path = CCListViewExampleTests; 212 | sourceTree = ""; 213 | }; 214 | 3C9777B8195E0D3C005C4700 /* Supporting Files */ = { 215 | isa = PBXGroup; 216 | children = ( 217 | 3C9777B9195E0D3C005C4700 /* CCListViewExampleTests-Info.plist */, 218 | 3C9777BA195E0D3C005C4700 /* InfoPlist.strings */, 219 | ); 220 | name = "Supporting Files"; 221 | sourceTree = ""; 222 | }; 223 | 3C9B04881964886D00FAD524 /* Screenshots */ = { 224 | isa = PBXGroup; 225 | children = ( 226 | 3C9B04891964886D00FAD524 /* screenshot1.png */, 227 | ); 228 | name = Screenshots; 229 | path = ../Screenshots; 230 | sourceTree = ""; 231 | }; 232 | /* End PBXGroup section */ 233 | 234 | /* Begin PBXNativeTarget section */ 235 | 3C97778B195E0D3C005C4700 /* CCListViewExample */ = { 236 | isa = PBXNativeTarget; 237 | buildConfigurationList = 3C9777C1195E0D3C005C4700 /* Build configuration list for PBXNativeTarget "CCListViewExample" */; 238 | buildPhases = ( 239 | 1F6FDF5DB22846EC9197DCB7 /* Check Pods Manifest.lock */, 240 | 3C977788195E0D3C005C4700 /* Sources */, 241 | 3C977789195E0D3C005C4700 /* Frameworks */, 242 | 3C97778A195E0D3C005C4700 /* Resources */, 243 | 9BE2D323B84B499F88521ECC /* Copy Pods Resources */, 244 | ); 245 | buildRules = ( 246 | ); 247 | dependencies = ( 248 | ); 249 | name = CCListViewExample; 250 | productName = CCListViewExample; 251 | productReference = 3C97778C195E0D3C005C4700 /* CCListViewExample.app */; 252 | productType = "com.apple.product-type.application"; 253 | }; 254 | 3C9777AF195E0D3C005C4700 /* CCListViewExampleTests */ = { 255 | isa = PBXNativeTarget; 256 | buildConfigurationList = 3C9777C4195E0D3C005C4700 /* Build configuration list for PBXNativeTarget "CCListViewExampleTests" */; 257 | buildPhases = ( 258 | 3C9777AC195E0D3C005C4700 /* Sources */, 259 | 3C9777AD195E0D3C005C4700 /* Frameworks */, 260 | 3C9777AE195E0D3C005C4700 /* Resources */, 261 | ); 262 | buildRules = ( 263 | ); 264 | dependencies = ( 265 | 3C9777B6195E0D3C005C4700 /* PBXTargetDependency */, 266 | ); 267 | name = CCListViewExampleTests; 268 | productName = CCListViewExampleTests; 269 | productReference = 3C9777B0195E0D3C005C4700 /* CCListViewExampleTests.xctest */; 270 | productType = "com.apple.product-type.bundle.unit-test"; 271 | }; 272 | /* End PBXNativeTarget section */ 273 | 274 | /* Begin PBXProject section */ 275 | 3C977784195E0D3C005C4700 /* Project object */ = { 276 | isa = PBXProject; 277 | attributes = { 278 | LastUpgradeCheck = 0510; 279 | ORGANIZATIONNAME = Codecademy; 280 | TargetAttributes = { 281 | 3C9777AF195E0D3C005C4700 = { 282 | TestTargetID = 3C97778B195E0D3C005C4700; 283 | }; 284 | }; 285 | }; 286 | buildConfigurationList = 3C977787195E0D3C005C4700 /* Build configuration list for PBXProject "CCListViewExample" */; 287 | compatibilityVersion = "Xcode 3.2"; 288 | developmentRegion = English; 289 | hasScannedForEncodings = 0; 290 | knownRegions = ( 291 | en, 292 | Base, 293 | ); 294 | mainGroup = 3C977783195E0D3C005C4700; 295 | productRefGroup = 3C97778D195E0D3C005C4700 /* Products */; 296 | projectDirPath = ""; 297 | projectRoot = ""; 298 | targets = ( 299 | 3C97778B195E0D3C005C4700 /* CCListViewExample */, 300 | 3C9777AF195E0D3C005C4700 /* CCListViewExampleTests */, 301 | 3C9777CE195E0DE0005C4700 /* Podspec Lint */, 302 | 3C9777D3195E0E97005C4700 /* All Tests */, 303 | ); 304 | }; 305 | /* End PBXProject section */ 306 | 307 | /* Begin PBXResourcesBuildPhase section */ 308 | 3C97778A195E0D3C005C4700 /* Resources */ = { 309 | isa = PBXResourcesBuildPhase; 310 | buildActionMask = 2147483647; 311 | files = ( 312 | 3C9777C9195E0D62005C4700 /* CCListView.podspec in Resources */, 313 | 3C9B04871964867300FAD524 /* doge.png in Resources */, 314 | 3C9777AB195E0D3C005C4700 /* Images.xcassets in Resources */, 315 | 3C9777A3195E0D3C005C4700 /* Main.storyboard in Resources */, 316 | 3C97779A195E0D3C005C4700 /* InfoPlist.strings in Resources */, 317 | ); 318 | runOnlyForDeploymentPostprocessing = 0; 319 | }; 320 | 3C9777AE195E0D3C005C4700 /* Resources */ = { 321 | isa = PBXResourcesBuildPhase; 322 | buildActionMask = 2147483647; 323 | files = ( 324 | 3C9777BC195E0D3C005C4700 /* InfoPlist.strings in Resources */, 325 | ); 326 | runOnlyForDeploymentPostprocessing = 0; 327 | }; 328 | /* End PBXResourcesBuildPhase section */ 329 | 330 | /* Begin PBXShellScriptBuildPhase section */ 331 | 1F6FDF5DB22846EC9197DCB7 /* Check Pods Manifest.lock */ = { 332 | isa = PBXShellScriptBuildPhase; 333 | buildActionMask = 2147483647; 334 | files = ( 335 | ); 336 | inputPaths = ( 337 | ); 338 | name = "Check Pods Manifest.lock"; 339 | outputPaths = ( 340 | ); 341 | runOnlyForDeploymentPostprocessing = 0; 342 | shellPath = /bin/sh; 343 | 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"; 344 | showEnvVarsInLog = 0; 345 | }; 346 | 3C9777D2195E0DEA005C4700 /* ShellScript */ = { 347 | isa = PBXShellScriptBuildPhase; 348 | buildActionMask = 2147483647; 349 | files = ( 350 | ); 351 | inputPaths = ( 352 | ); 353 | outputPaths = ( 354 | ); 355 | runOnlyForDeploymentPostprocessing = 0; 356 | shellPath = /bin/sh; 357 | shellScript = "if [ -z \"${TRAVIS}\" ]; then\n cd ${SRCROOT}/..\nelse\n cd ${TRAVIS_BUILD_DIR}\nfi\n\npod spec lint CCListView.podspec"; 358 | }; 359 | 9BE2D323B84B499F88521ECC /* Copy Pods Resources */ = { 360 | isa = PBXShellScriptBuildPhase; 361 | buildActionMask = 2147483647; 362 | files = ( 363 | ); 364 | inputPaths = ( 365 | ); 366 | name = "Copy Pods Resources"; 367 | outputPaths = ( 368 | ); 369 | runOnlyForDeploymentPostprocessing = 0; 370 | shellPath = /bin/sh; 371 | shellScript = "\"${SRCROOT}/../Pods/Pods-CCListViewExample-resources.sh\"\n"; 372 | showEnvVarsInLog = 0; 373 | }; 374 | /* End PBXShellScriptBuildPhase section */ 375 | 376 | /* Begin PBXSourcesBuildPhase section */ 377 | 3C977788195E0D3C005C4700 /* Sources */ = { 378 | isa = PBXSourcesBuildPhase; 379 | buildActionMask = 2147483647; 380 | files = ( 381 | 3C9777A9195E0D3C005C4700 /* VerticalListViewController.m in Sources */, 382 | 3C54D71919633DB600165E56 /* CCListViewController.m in Sources */, 383 | 3C9777A0195E0D3C005C4700 /* AppDelegate.m in Sources */, 384 | 3C54D71619633D7D00165E56 /* HorizontalListViewController.m in Sources */, 385 | 3C97779C195E0D3C005C4700 /* main.m in Sources */, 386 | ); 387 | runOnlyForDeploymentPostprocessing = 0; 388 | }; 389 | 3C9777AC195E0D3C005C4700 /* Sources */ = { 390 | isa = PBXSourcesBuildPhase; 391 | buildActionMask = 2147483647; 392 | files = ( 393 | 3C9777BE195E0D3C005C4700 /* CCListViewExampleTests.m in Sources */, 394 | ); 395 | runOnlyForDeploymentPostprocessing = 0; 396 | }; 397 | /* End PBXSourcesBuildPhase section */ 398 | 399 | /* Begin PBXTargetDependency section */ 400 | 3C9777B6195E0D3C005C4700 /* PBXTargetDependency */ = { 401 | isa = PBXTargetDependency; 402 | target = 3C97778B195E0D3C005C4700 /* CCListViewExample */; 403 | targetProxy = 3C9777B5195E0D3C005C4700 /* PBXContainerItemProxy */; 404 | }; 405 | 3C9777D8195E0E9F005C4700 /* PBXTargetDependency */ = { 406 | isa = PBXTargetDependency; 407 | target = 3C9777AF195E0D3C005C4700 /* CCListViewExampleTests */; 408 | targetProxy = 3C9777D7195E0E9F005C4700 /* PBXContainerItemProxy */; 409 | }; 410 | 3C9777DA195E0E9F005C4700 /* PBXTargetDependency */ = { 411 | isa = PBXTargetDependency; 412 | target = 3C9777CE195E0DE0005C4700 /* Podspec Lint */; 413 | targetProxy = 3C9777D9195E0E9F005C4700 /* PBXContainerItemProxy */; 414 | }; 415 | /* End PBXTargetDependency section */ 416 | 417 | /* Begin PBXVariantGroup section */ 418 | 3C977798195E0D3C005C4700 /* InfoPlist.strings */ = { 419 | isa = PBXVariantGroup; 420 | children = ( 421 | 3C977799195E0D3C005C4700 /* en */, 422 | ); 423 | name = InfoPlist.strings; 424 | sourceTree = ""; 425 | }; 426 | 3C9777A1195E0D3C005C4700 /* Main.storyboard */ = { 427 | isa = PBXVariantGroup; 428 | children = ( 429 | 3C9777A2195E0D3C005C4700 /* Base */, 430 | ); 431 | name = Main.storyboard; 432 | sourceTree = ""; 433 | }; 434 | 3C9777BA195E0D3C005C4700 /* InfoPlist.strings */ = { 435 | isa = PBXVariantGroup; 436 | children = ( 437 | 3C9777BB195E0D3C005C4700 /* en */, 438 | ); 439 | name = InfoPlist.strings; 440 | sourceTree = ""; 441 | }; 442 | /* End PBXVariantGroup section */ 443 | 444 | /* Begin XCBuildConfiguration section */ 445 | 3C9777BF195E0D3C005C4700 /* Debug */ = { 446 | isa = XCBuildConfiguration; 447 | buildSettings = { 448 | ALWAYS_SEARCH_USER_PATHS = NO; 449 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 450 | CLANG_CXX_LIBRARY = "libc++"; 451 | CLANG_ENABLE_MODULES = YES; 452 | CLANG_ENABLE_OBJC_ARC = YES; 453 | CLANG_WARN_BOOL_CONVERSION = YES; 454 | CLANG_WARN_CONSTANT_CONVERSION = YES; 455 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 456 | CLANG_WARN_EMPTY_BODY = YES; 457 | CLANG_WARN_ENUM_CONVERSION = YES; 458 | CLANG_WARN_INT_CONVERSION = YES; 459 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 460 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 461 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 462 | COPY_PHASE_STRIP = NO; 463 | GCC_C_LANGUAGE_STANDARD = gnu99; 464 | GCC_DYNAMIC_NO_PIC = NO; 465 | GCC_OPTIMIZATION_LEVEL = 0; 466 | GCC_PREPROCESSOR_DEFINITIONS = ( 467 | "DEBUG=1", 468 | "$(inherited)", 469 | ); 470 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 471 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 472 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 473 | GCC_WARN_UNDECLARED_SELECTOR = YES; 474 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 475 | GCC_WARN_UNUSED_FUNCTION = YES; 476 | GCC_WARN_UNUSED_VARIABLE = YES; 477 | IPHONEOS_DEPLOYMENT_TARGET = 7.1; 478 | ONLY_ACTIVE_ARCH = YES; 479 | SDKROOT = iphoneos; 480 | TARGETED_DEVICE_FAMILY = "1,2"; 481 | }; 482 | name = Debug; 483 | }; 484 | 3C9777C0195E0D3C005C4700 /* Release */ = { 485 | isa = XCBuildConfiguration; 486 | buildSettings = { 487 | ALWAYS_SEARCH_USER_PATHS = NO; 488 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 489 | CLANG_CXX_LIBRARY = "libc++"; 490 | CLANG_ENABLE_MODULES = YES; 491 | CLANG_ENABLE_OBJC_ARC = YES; 492 | CLANG_WARN_BOOL_CONVERSION = YES; 493 | CLANG_WARN_CONSTANT_CONVERSION = YES; 494 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 495 | CLANG_WARN_EMPTY_BODY = YES; 496 | CLANG_WARN_ENUM_CONVERSION = YES; 497 | CLANG_WARN_INT_CONVERSION = YES; 498 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 499 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 500 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 501 | COPY_PHASE_STRIP = YES; 502 | ENABLE_NS_ASSERTIONS = NO; 503 | GCC_C_LANGUAGE_STANDARD = gnu99; 504 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 505 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 506 | GCC_WARN_UNDECLARED_SELECTOR = YES; 507 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 508 | GCC_WARN_UNUSED_FUNCTION = YES; 509 | GCC_WARN_UNUSED_VARIABLE = YES; 510 | IPHONEOS_DEPLOYMENT_TARGET = 7.1; 511 | SDKROOT = iphoneos; 512 | TARGETED_DEVICE_FAMILY = "1,2"; 513 | VALIDATE_PRODUCT = YES; 514 | }; 515 | name = Release; 516 | }; 517 | 3C9777C2195E0D3C005C4700 /* Debug */ = { 518 | isa = XCBuildConfiguration; 519 | baseConfigurationReference = 58423AAC5FF24F838A28BEB3 /* Pods-CCListViewExample.xcconfig */; 520 | buildSettings = { 521 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 522 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; 523 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 524 | GCC_PREFIX_HEADER = "CCListViewExample/CCListViewExample-Prefix.pch"; 525 | INFOPLIST_FILE = "CCListViewExample/CCListViewExample-Info.plist"; 526 | PRODUCT_NAME = "$(TARGET_NAME)"; 527 | WRAPPER_EXTENSION = app; 528 | }; 529 | name = Debug; 530 | }; 531 | 3C9777C3195E0D3C005C4700 /* Release */ = { 532 | isa = XCBuildConfiguration; 533 | baseConfigurationReference = 58423AAC5FF24F838A28BEB3 /* Pods-CCListViewExample.xcconfig */; 534 | buildSettings = { 535 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 536 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; 537 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution: Ryzac Inc."; 538 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 539 | GCC_PREFIX_HEADER = "CCListViewExample/CCListViewExample-Prefix.pch"; 540 | INFOPLIST_FILE = "CCListViewExample/CCListViewExample-Info.plist"; 541 | PRODUCT_NAME = "$(TARGET_NAME)"; 542 | WRAPPER_EXTENSION = app; 543 | }; 544 | name = Release; 545 | }; 546 | 3C9777C5195E0D3C005C4700 /* Debug */ = { 547 | isa = XCBuildConfiguration; 548 | buildSettings = { 549 | BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/CCListViewExample.app/CCListViewExample"; 550 | FRAMEWORK_SEARCH_PATHS = ( 551 | "$(SDKROOT)/Developer/Library/Frameworks", 552 | "$(inherited)", 553 | "$(DEVELOPER_FRAMEWORKS_DIR)", 554 | ); 555 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 556 | GCC_PREFIX_HEADER = "CCListViewExample/CCListViewExample-Prefix.pch"; 557 | GCC_PREPROCESSOR_DEFINITIONS = ( 558 | "DEBUG=1", 559 | "$(inherited)", 560 | ); 561 | INFOPLIST_FILE = "CCListViewExampleTests/CCListViewExampleTests-Info.plist"; 562 | PRODUCT_NAME = "$(TARGET_NAME)"; 563 | TEST_HOST = "$(BUNDLE_LOADER)"; 564 | WRAPPER_EXTENSION = xctest; 565 | }; 566 | name = Debug; 567 | }; 568 | 3C9777C6195E0D3C005C4700 /* Release */ = { 569 | isa = XCBuildConfiguration; 570 | buildSettings = { 571 | BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/CCListViewExample.app/CCListViewExample"; 572 | FRAMEWORK_SEARCH_PATHS = ( 573 | "$(SDKROOT)/Developer/Library/Frameworks", 574 | "$(inherited)", 575 | "$(DEVELOPER_FRAMEWORKS_DIR)", 576 | ); 577 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 578 | GCC_PREFIX_HEADER = "CCListViewExample/CCListViewExample-Prefix.pch"; 579 | INFOPLIST_FILE = "CCListViewExampleTests/CCListViewExampleTests-Info.plist"; 580 | PRODUCT_NAME = "$(TARGET_NAME)"; 581 | TEST_HOST = "$(BUNDLE_LOADER)"; 582 | WRAPPER_EXTENSION = xctest; 583 | }; 584 | name = Release; 585 | }; 586 | 3C9777D0195E0DE0005C4700 /* Debug */ = { 587 | isa = XCBuildConfiguration; 588 | buildSettings = { 589 | PRODUCT_NAME = "$(TARGET_NAME)"; 590 | }; 591 | name = Debug; 592 | }; 593 | 3C9777D1195E0DE0005C4700 /* Release */ = { 594 | isa = XCBuildConfiguration; 595 | buildSettings = { 596 | PRODUCT_NAME = "$(TARGET_NAME)"; 597 | }; 598 | name = Release; 599 | }; 600 | 3C9777D5195E0E97005C4700 /* Debug */ = { 601 | isa = XCBuildConfiguration; 602 | buildSettings = { 603 | PRODUCT_NAME = "$(TARGET_NAME)"; 604 | }; 605 | name = Debug; 606 | }; 607 | 3C9777D6195E0E97005C4700 /* Release */ = { 608 | isa = XCBuildConfiguration; 609 | buildSettings = { 610 | PRODUCT_NAME = "$(TARGET_NAME)"; 611 | }; 612 | name = Release; 613 | }; 614 | /* End XCBuildConfiguration section */ 615 | 616 | /* Begin XCConfigurationList section */ 617 | 3C977787195E0D3C005C4700 /* Build configuration list for PBXProject "CCListViewExample" */ = { 618 | isa = XCConfigurationList; 619 | buildConfigurations = ( 620 | 3C9777BF195E0D3C005C4700 /* Debug */, 621 | 3C9777C0195E0D3C005C4700 /* Release */, 622 | ); 623 | defaultConfigurationIsVisible = 0; 624 | defaultConfigurationName = Release; 625 | }; 626 | 3C9777C1195E0D3C005C4700 /* Build configuration list for PBXNativeTarget "CCListViewExample" */ = { 627 | isa = XCConfigurationList; 628 | buildConfigurations = ( 629 | 3C9777C2195E0D3C005C4700 /* Debug */, 630 | 3C9777C3195E0D3C005C4700 /* Release */, 631 | ); 632 | defaultConfigurationIsVisible = 0; 633 | defaultConfigurationName = Release; 634 | }; 635 | 3C9777C4195E0D3C005C4700 /* Build configuration list for PBXNativeTarget "CCListViewExampleTests" */ = { 636 | isa = XCConfigurationList; 637 | buildConfigurations = ( 638 | 3C9777C5195E0D3C005C4700 /* Debug */, 639 | 3C9777C6195E0D3C005C4700 /* Release */, 640 | ); 641 | defaultConfigurationIsVisible = 0; 642 | defaultConfigurationName = Release; 643 | }; 644 | 3C9777CF195E0DE0005C4700 /* Build configuration list for PBXAggregateTarget "Podspec Lint" */ = { 645 | isa = XCConfigurationList; 646 | buildConfigurations = ( 647 | 3C9777D0195E0DE0005C4700 /* Debug */, 648 | 3C9777D1195E0DE0005C4700 /* Release */, 649 | ); 650 | defaultConfigurationIsVisible = 0; 651 | defaultConfigurationName = Release; 652 | }; 653 | 3C9777D4195E0E97005C4700 /* Build configuration list for PBXAggregateTarget "All Tests" */ = { 654 | isa = XCConfigurationList; 655 | buildConfigurations = ( 656 | 3C9777D5195E0E97005C4700 /* Debug */, 657 | 3C9777D6195E0E97005C4700 /* Release */, 658 | ); 659 | defaultConfigurationIsVisible = 0; 660 | defaultConfigurationName = Release; 661 | }; 662 | /* End XCConfigurationList section */ 663 | }; 664 | rootObject = 3C977784195E0D3C005C4700 /* Project object */; 665 | } 666 | --------------------------------------------------------------------------------