├── example.png
├── Example
├── CenterFlow
│ ├── tabbar-image.png
│ ├── Default-568h@2x.png
│ ├── tabbar-image@2x.png
│ ├── tabbar-image@3x.png
│ ├── KTAwesomeCell.h
│ ├── KTAwesomeSizingCell.h
│ ├── KTSelfSizingCollectionViewController.h
│ ├── KTAppDelegate.h
│ ├── main.m
│ ├── KTHeaderFooterView.h
│ ├── KTVariableHeightCollectionViewController.h
│ ├── KTBasicCollectionViewController.h
│ ├── Constants.h
│ ├── Images.xcassets
│ │ └── AppIcon.appiconset
│ │ │ └── Contents.json
│ ├── KTHeaderFooterView.m
│ ├── Info.plist
│ ├── KTAwesomeSizingCell.m
│ ├── KTAwesomeCell.m
│ ├── Constants.m
│ ├── KTVariableHeightCollectionViewController.m
│ ├── KTSelfSizingCollectionViewController.m
│ ├── Launch.storyboard
│ ├── KTAppDelegate.m
│ └── KTBasicCollectionViewController.m
└── CenterFlow.xcodeproj
│ ├── project.xcworkspace
│ └── contents.xcworkspacedata
│ └── project.pbxproj
├── .gitignore
├── KTCenterFlowLayout.h
├── KTCenterFlowLayout.podspec
├── CHANGELOG.md
├── LICENSE
├── README.md
└── KTCenterFlowLayout.m
/example.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/keighl/KTCenterFlowLayout/HEAD/example.png
--------------------------------------------------------------------------------
/Example/CenterFlow/tabbar-image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/keighl/KTCenterFlowLayout/HEAD/Example/CenterFlow/tabbar-image.png
--------------------------------------------------------------------------------
/Example/CenterFlow/Default-568h@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/keighl/KTCenterFlowLayout/HEAD/Example/CenterFlow/Default-568h@2x.png
--------------------------------------------------------------------------------
/Example/CenterFlow/tabbar-image@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/keighl/KTCenterFlowLayout/HEAD/Example/CenterFlow/tabbar-image@2x.png
--------------------------------------------------------------------------------
/Example/CenterFlow/tabbar-image@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/keighl/KTCenterFlowLayout/HEAD/Example/CenterFlow/tabbar-image@3x.png
--------------------------------------------------------------------------------
/Example/CenterFlow.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Xcode
2 | #
3 | build/
4 | *.pbxuser
5 | !default.pbxuser
6 | *.mode1v3
7 | !default.mode1v3
8 | *.mode2v3
9 | !default.mode2v3
10 | *.perspectivev3
11 | !default.perspectivev3
12 | xcuserdata
13 | *.xccheckout
14 | *.moved-aside
15 | DerivedData
16 | *.hmap
17 | *.ipa
18 | *.xcuserstate
19 |
20 | Pods/
21 |
22 | .DS_Store
23 |
--------------------------------------------------------------------------------
/Example/CenterFlow/KTAwesomeCell.h:
--------------------------------------------------------------------------------
1 | //
2 | // AwesomeCell.h
3 | // CenterFlow
4 | //
5 | // Created by Kyle Truscott on 10/9/14.
6 | // Copyright (c) 2014 keighl. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface KTAwesomeCell : UICollectionViewCell
12 | @property (strong) UILabel *label;
13 | @end
14 |
--------------------------------------------------------------------------------
/Example/CenterFlow/KTAwesomeSizingCell.h:
--------------------------------------------------------------------------------
1 | //
2 | // KTAwesomeSizingCell.h
3 | // CenterFlow
4 | //
5 | // Created by Kyle Truscott on 5/4/16.
6 | // Copyright © 2016 keighl. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface KTAwesomeSizingCell : UICollectionViewCell
12 | @property (strong) UILabel *label;
13 | @end
14 |
--------------------------------------------------------------------------------
/KTCenterFlowLayout.h:
--------------------------------------------------------------------------------
1 | //
2 | // KTCenterFlowLayout.h
3 | //
4 | // Created by Kyle Truscott on 10/9/14.
5 | // Copyright (c) 2014 keighl. All rights reserved.
6 | //
7 |
8 | #import
9 |
10 | /**
11 | * Aligns cells to the center of a collection view.
12 | */
13 | @interface KTCenterFlowLayout : UICollectionViewFlowLayout
14 |
15 | @end
16 |
--------------------------------------------------------------------------------
/Example/CenterFlow/KTSelfSizingCollectionViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // KTSelfSizingCollectionViewController.h
3 | // CenterFlow
4 | //
5 | // Created by Kyle Truscott on 5/3/16.
6 | // Copyright © 2016 keighl. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface KTSelfSizingCollectionViewController : UICollectionViewController
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/Example/CenterFlow/KTAppDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.h
3 | // CenterFlow
4 | //
5 | // Created by Kyle Truscott on 10/9/14.
6 | // Copyright (c) 2014 keighl. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface KTAppDelegate : UIResponder
12 |
13 | @property (strong, nonatomic) UIWindow *window;
14 |
15 | @end
16 |
17 |
--------------------------------------------------------------------------------
/Example/CenterFlow/main.m:
--------------------------------------------------------------------------------
1 | //
2 | // main.m
3 | // CenterFlow
4 | //
5 | // Created by Kyle Truscott on 10/9/14.
6 | // Copyright (c) 2014 keighl. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "KTAppDelegate.h"
11 |
12 | int main(int argc, char * argv[]) {
13 | @autoreleasepool {
14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([KTAppDelegate class]));
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/Example/CenterFlow/KTHeaderFooterView.h:
--------------------------------------------------------------------------------
1 | //
2 | // KTHeaderFooterView.h
3 | // CenterFlow
4 | //
5 | // Created by Kyle Truscott on 6/14/16.
6 | // Copyright © 2016 keighl. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | static NSString *KTHeaderFooterViewID = @"KTHeaderFooterView";
12 |
13 | @interface KTHeaderFooterView : UICollectionReusableView
14 | @property (strong, nonatomic) UILabel *label;
15 | @end
16 |
--------------------------------------------------------------------------------
/Example/CenterFlow/KTVariableHeightCollectionViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // KTVariableHeightCollectionViewController.h
3 | // CenterFlow
4 | //
5 | // Created by Kyle Truscott on 5/3/16.
6 | // Copyright © 2016 keighl. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "KTBasicCollectionViewController.h"
11 |
12 | @interface KTVariableHeightCollectionViewController : KTBasicCollectionViewController
13 | @end
14 |
--------------------------------------------------------------------------------
/Example/CenterFlow/KTBasicCollectionViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // MainController.h
3 | // CenterFlow
4 | //
5 | // Created by Kyle Truscott on 10/9/14.
6 | // Copyright (c) 2014 keighl. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "KTAwesomeCell.h"
11 |
12 | @interface KTBasicCollectionViewController : UICollectionViewController
13 | @property (strong) NSArray *states;
14 | @property (strong) KTAwesomeCell *sizingCell;
15 | @end
16 |
--------------------------------------------------------------------------------
/Example/CenterFlow/Constants.h:
--------------------------------------------------------------------------------
1 | //
2 | // Constants.h
3 | // CenterFlow
4 | //
5 | // Created by Kyle Truscott on 5/3/16.
6 | // Copyright © 2016 keighl. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | static NSString *headerCellID = @"HeaderCell";
12 | static NSString *footerCellID = @"FooterCell";
13 | static NSString *stateCellID = @"StateCell";
14 |
15 | @interface Constants : NSObject
16 | + (NSArray *)states;
17 | @end
18 |
--------------------------------------------------------------------------------
/KTCenterFlowLayout.podspec:
--------------------------------------------------------------------------------
1 | Pod::Spec.new do |s|
2 | s.name = "KTCenterFlowLayout"
3 | s.version = "1.3.1"
4 | s.summary = "Aligns cells to the center of a collection view."
5 |
6 | s.homepage = "https://github.com/keighl/KTCenterFlowLayout"
7 | s.license = 'MIT'
8 | s.author = { "keighl" => "keighl@keighl.com" }
9 | s.source = { :git => "https://github.com/keighl/KTCenterFlowLayout.git", :tag => s.version.to_s }
10 | s.social_media_url = 'https://twitter.com/keighl'
11 |
12 | s.ios.deployment_target = '7.0'
13 | s.tvos.deployment_target = '9.0'
14 | s.requires_arc = true
15 |
16 | s.source_files = 'KTCenterFlowLayout.{h,m}'
17 |
18 | s.frameworks = 'UIKit'
19 |
20 | end
21 |
--------------------------------------------------------------------------------
/Example/CenterFlow/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" : "29x29",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "40x40",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "40x40",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "60x60",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "60x60",
31 | "scale" : "3x"
32 | }
33 | ],
34 | "info" : {
35 | "version" : 1,
36 | "author" : "xcode"
37 | }
38 | }
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Changelog
2 |
3 | All notable changes to this project will be documented in this file.
4 |
5 | ## 1.3.1 - 2016-05-14
6 |
7 | * Adds important nil check (#25)
8 |
9 | ## 1.3 - 2016-05-14
10 |
11 | * Fixes broken header/footer supplementary views
12 |
13 | ## 1.2 - 2016-05-14
14 |
15 | * Refactoring layout logic
16 |
17 | ## 1.1.1 - 2015-09-15
18 |
19 | * Fixes a caching issue on iOS9 by deep copying `[super layoutAttributesForElementsInRect:rect]`. Thanks [@fwaddle](https://github.com/fwaddle)
20 |
21 | ## 1.1 - 2015-09-15
22 |
23 | * Uses flow layout `minimumInteritemSpacingForSectionAtIndex` from delegate if available. Thanks [@danblakemore](https://github.com/danblakemore)
24 |
25 | ## 1.0.0 - 2015-05-06
26 |
27 | * Fixes issues where variable cell heights on 3x res screen pile up on top of each other
28 |
29 | ## 0.0.2 - 2015-03-21
30 |
31 | * Small style tweaks
32 |
33 | ## 0.0.1 - 2014-10-09
34 |
35 | * Intitial version!
36 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) keighl (http://github.com/keighl)
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy
4 | of this software and associated documentation files (the "Software"), to deal
5 | in the Software without restriction, including without limitation the rights
6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 | copies of the Software, and to permit persons to whom the Software is
8 | furnished to do so, subject to the following conditions:
9 |
10 | The above copyright notice and this permission notice shall be included in
11 | all copies or substantial portions of the Software.
12 |
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 | THE SOFTWARE.
20 |
--------------------------------------------------------------------------------
/Example/CenterFlow/KTHeaderFooterView.m:
--------------------------------------------------------------------------------
1 | //
2 | // KTHeaderFooterView.m
3 | // CenterFlow
4 | //
5 | // Created by Kyle Truscott on 6/14/16.
6 | // Copyright © 2016 keighl. All rights reserved.
7 | //
8 |
9 | #import "KTHeaderFooterView.h"
10 |
11 | @implementation KTHeaderFooterView
12 |
13 | - (instancetype)initWithFrame:(CGRect)frame
14 | {
15 | self = [super initWithFrame:frame];
16 |
17 | if (self)
18 | {
19 | self.backgroundColor = [UIColor colorWithWhite:0.97 alpha:1];
20 |
21 | self.label = [UILabel new];
22 | self.label.translatesAutoresizingMaskIntoConstraints = NO;
23 | self.label.font = [UIFont systemFontOfSize:14];
24 | self.label.backgroundColor = [UIColor clearColor];
25 | self.label.preferredMaxLayoutWidth = 100;
26 | self.label.textAlignment = NSTextAlignmentCenter;
27 | [self addSubview:self.label];
28 |
29 | NSDictionary *views = NSDictionaryOfVariableBindings(_label);
30 |
31 | [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[_label]|" options:0 metrics:nil views:views]];
32 | [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"|[_label]|" options:0 metrics:nil views:views]];
33 | }
34 |
35 | return self;
36 | }
37 |
38 |
39 | @end
40 |
--------------------------------------------------------------------------------
/Example/CenterFlow/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | com.keighl.$(PRODUCT_NAME:rfc1034identifier)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 | LSRequiresIPhoneOS
24 |
25 | UILaunchStoryboardName
26 | Launch
27 | UIRequiredDeviceCapabilities
28 |
29 | armv7
30 |
31 | UISupportedInterfaceOrientations
32 |
33 | UIInterfaceOrientationPortrait
34 | UIInterfaceOrientationPortraitUpsideDown
35 | UIInterfaceOrientationLandscapeLeft
36 | UIInterfaceOrientationLandscapeRight
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # KTCenterFlowLayout
2 |
3 | []()
4 |
5 | KTCenterFlowLayout is a subclass of UICollectionViewFlowLayout which Aligns cells to the center of a collection view. It effectively enforces the `minimumInteritemSpacing`.
6 |
7 | ### Usage
8 |
9 | ```ruby
10 | # In your Podfile
11 |
12 | pod 'KTCenterFlowLayout'
13 | ```
14 |
15 | Objective-C:
16 |
17 | ```objective-c
18 | KTCenterFlowLayout *layout = [KTCenterFlowLayout new];
19 | layout.minimumInteritemSpacing = 10.f;
20 | layout.minimumLineSpacing = 10.f;
21 |
22 | [[UICollectionViewController alloc] initWithCollectionViewLayout:layout];
23 | ```
24 |
25 | Swift:
26 |
27 | ```swift
28 | let layout = KTCenterFlowLayout()
29 | layout.minimumInteritemSpacing = 10.0
30 | layout.minimumLineSpacing = 10.0
31 |
32 | UICollectionViewController(collectionViewLayout: layout)
33 | ```
34 |
35 | ### Example
36 |
37 | See the layout in use in the `./Example` app:
38 |
39 |
40 |
41 | ### Horizontal Scrolling
42 |
43 | This layout **doesn't** work with `UICollectionViewScrollDirection.horizontal`.
44 |
45 | ### Self-sizing cells
46 |
47 | This layout **doesn't** work with self-sizing collection view cells (`estimatedItemSize`). Of course, neither does the vanilla `UICollectionViewFlowLayout`. Pull requests appreciated from anybody interested in solving self-sizing layouts!
48 |
--------------------------------------------------------------------------------
/Example/CenterFlow/KTAwesomeSizingCell.m:
--------------------------------------------------------------------------------
1 | //
2 | // KTAwesomeSizingCell.m
3 | // CenterFlow
4 | //
5 | // Created by Kyle Truscott on 5/4/16.
6 | // Copyright © 2016 keighl. All rights reserved.
7 | //
8 |
9 | #import "KTAwesomeSizingCell.h"
10 |
11 | @implementation KTAwesomeSizingCell
12 |
13 | - (instancetype)initWithFrame:(CGRect)frame
14 | {
15 | self = [super initWithFrame:frame];
16 |
17 | if (self)
18 | {
19 | self.clipsToBounds = NO;
20 | self.contentView.clipsToBounds = NO;
21 |
22 | self.contentView.layer.borderColor = [UIColor blueColor].CGColor;
23 | self.contentView.layer.borderWidth = 1.f;
24 |
25 | self.label = [UILabel new];
26 | self.label.translatesAutoresizingMaskIntoConstraints = NO;
27 | self.label.font = [UIFont systemFontOfSize:14];
28 | self.label.backgroundColor = [UIColor clearColor];
29 | self.label.textColor = [UIColor blueColor];
30 | self.label.preferredMaxLayoutWidth = 100;
31 | [self.contentView addSubview:self.label];
32 |
33 | NSDictionary *views = NSDictionaryOfVariableBindings(_label);
34 |
35 | [self.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-10-[_label]-10-|" options:0 metrics:nil views:views]];
36 | [self.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"|-10-[_label]-10-|" options:0 metrics:nil views:views]];
37 |
38 | }
39 |
40 | return self;
41 | }
42 |
43 | @end
44 |
--------------------------------------------------------------------------------
/Example/CenterFlow/KTAwesomeCell.m:
--------------------------------------------------------------------------------
1 | //
2 | // AwesomeCell.m
3 | // CenterFlow
4 | //
5 | // Created by Kyle Truscott on 10/9/14.
6 | // Copyright (c) 2014 keighl. All rights reserved.
7 | //
8 |
9 | #import "KTAwesomeCell.h"
10 |
11 | @implementation KTAwesomeCell
12 |
13 | - (instancetype)initWithFrame:(CGRect)frame
14 | {
15 | self = [super initWithFrame:frame];
16 |
17 | if (self)
18 | {
19 | self.clipsToBounds = NO;
20 | self.contentView.clipsToBounds = NO;
21 |
22 | self.contentView.layer.borderColor = [UIColor blueColor].CGColor;
23 | self.contentView.layer.borderWidth = 1.f;
24 |
25 | self.label = [UILabel new];
26 | self.label.translatesAutoresizingMaskIntoConstraints = NO;
27 | self.label.font = [UIFont systemFontOfSize:14];
28 | self.label.backgroundColor = [UIColor clearColor];
29 | self.label.textColor = [UIColor blueColor];
30 | [self.contentView addSubview:self.label];
31 |
32 | NSDictionary *views = NSDictionaryOfVariableBindings(_label);
33 |
34 | [self.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-10-[_label]" options:0 metrics:nil views:views]];
35 | [self.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"|-10-[_label]" options:0 metrics:nil views:views]];
36 |
37 | }
38 |
39 | return self;
40 | }
41 |
42 | - (CGSize)intrinsicContentSize
43 | {
44 | CGSize size = self.label.intrinsicContentSize;
45 | size.width += 20;
46 | size.height += 20;
47 | return size;
48 | }
49 |
50 | @end
51 |
--------------------------------------------------------------------------------
/Example/CenterFlow/Constants.m:
--------------------------------------------------------------------------------
1 | //
2 | // Constants.m
3 | // CenterFlow
4 | //
5 | // Created by Kyle Truscott on 5/3/16.
6 | // Copyright © 2016 keighl. All rights reserved.
7 | //
8 |
9 | #import "Constants.h"
10 |
11 | @implementation Constants
12 |
13 | + (NSArray *)states
14 | {
15 | return @[
16 | @"Alabama",
17 | @"Alaska",
18 | @"Arizona",
19 | @"Arkansas",
20 | @"California",
21 | @"Colorado",
22 | @"Connecticut",
23 | @"Delaware",
24 | @"District Of Columbia",
25 | @"Florida",
26 | @"Georgia",
27 | @"Hawaii",
28 | @"Idaho",
29 | @"Illinois",
30 | @"Indiana",
31 | @"Iowa",
32 | @"Kansas",
33 | @"Kentucky",
34 | @"Louisiana",
35 | @"Maine",
36 | @"Maryland",
37 | @"Massachusetts",
38 | @"Michigan",
39 | @"Minnesota",
40 | @"Mississippi",
41 | @"Missouri",
42 | @"Montana",
43 | @"Nebraska",
44 | @"Nevada",
45 | @"New Hampshire",
46 | @"New Jersey",
47 | @"New Mexico",
48 | @"New York",
49 | @"North Carolina",
50 | @"North Dakota",
51 | @"Ohio",
52 | @"Oklahoma",
53 | @"Oregon",
54 | @"Pennsylvania",
55 | @"Rhode Island",
56 | @"South Carolina",
57 | @"South Dakota",
58 | @"Tennessee",
59 | @"Texas",
60 | @"Utah",
61 | @"Vermont",
62 | @"Virginia",
63 | @"Washington",
64 | @"West Virginia",
65 | @"Wisconsin",
66 | @"Wyoming"
67 | ];
68 | }
69 |
70 | @end
71 |
--------------------------------------------------------------------------------
/Example/CenterFlow/KTVariableHeightCollectionViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // KTVariableHeightCollectionViewController.m
3 | // CenterFlow
4 | //
5 | // Created by Kyle Truscott on 5/3/16.
6 | // Copyright © 2016 keighl. All rights reserved.
7 | //
8 |
9 | #import "KTVariableHeightCollectionViewController.h"
10 | #import "KTCenterFlowLayout.h"
11 | #import "KTAwesomeCell.h"
12 | #import "Constants.h"
13 |
14 | @interface KTVariableHeightCollectionViewController ()
15 | @end
16 |
17 | @implementation KTVariableHeightCollectionViewController
18 |
19 | #pragma mark - UICollectionViewDelegate
20 |
21 | - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
22 | {
23 | KTAwesomeCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:stateCellID
24 | forIndexPath:indexPath];
25 |
26 | NSString *text = self.states[indexPath.row];
27 | cell.label.text = text;
28 | cell.label.font = [self fontForText:text];
29 | return cell;
30 | }
31 |
32 |
33 | #pragma mark - UICollectionViewDelegateFlowLayout
34 |
35 | - (CGSize)collectionView:(UICollectionView *)collectionView
36 | layout:(UICollectionViewFlowLayout *)collectionViewLayout
37 | sizeForItemAtIndexPath:(NSIndexPath *)indexPath
38 | {
39 | NSString *text = self.states[indexPath.row];
40 | self.sizingCell.label.text = self.states[indexPath.row];
41 | self.sizingCell.label.font = [self fontForText:text];
42 | return self.sizingCell.intrinsicContentSize;
43 | }
44 |
45 | - (UIFont *)fontForText:(NSString *)text
46 | {
47 | if (text.length == 7)
48 | {
49 | return [UIFont systemFontOfSize:16];
50 | }
51 |
52 | if (text.length == 8)
53 | {
54 | return [UIFont systemFontOfSize:24];
55 | }
56 |
57 | if (text.length == 5)
58 | {
59 | return [UIFont systemFontOfSize:10];
60 | }
61 |
62 | return [UIFont systemFontOfSize:14];
63 | }
64 |
65 | @end
66 |
--------------------------------------------------------------------------------
/Example/CenterFlow/KTSelfSizingCollectionViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // KTSelfSizingCollectionViewController.m
3 | // CenterFlow
4 | //
5 | // Created by Kyle Truscott on 5/3/16.
6 | // Copyright © 2016 keighl. All rights reserved.
7 | //
8 |
9 | #import "KTSelfSizingCollectionViewController.h"
10 | #import "KTCenterFlowLayout.h"
11 | #import "KTAwesomeSizingCell.h"
12 | #import "Constants.h"
13 |
14 | @interface KTSelfSizingCollectionViewController ()
15 | @property (strong) NSArray *states;
16 | @property (strong) KTAwesomeSizingCell *sizingCell;
17 | @end
18 |
19 | @implementation KTSelfSizingCollectionViewController
20 |
21 | - (void)viewDidLoad
22 | {
23 | [super viewDidLoad];
24 |
25 | self.collectionView.backgroundColor = [UIColor whiteColor];
26 |
27 | [(KTCenterFlowLayout *)self.collectionViewLayout setEstimatedItemSize:CGSizeMake(100, 50)];
28 | [(KTCenterFlowLayout *)self.collectionViewLayout setMinimumInteritemSpacing:15.f];
29 | [(KTCenterFlowLayout *)self.collectionViewLayout setMinimumLineSpacing:15.f];
30 | [(KTCenterFlowLayout *)self.collectionViewLayout setSectionInset:UIEdgeInsetsMake(20, 20, 20, 20)];
31 |
32 | [self.collectionView registerClass:[KTAwesomeSizingCell class] forCellWithReuseIdentifier:stateCellID];
33 |
34 | self.sizingCell = [KTAwesomeSizingCell new];
35 |
36 | self.states = [Constants states];
37 | }
38 |
39 | #pragma mark - UICollectionViewDataSource
40 |
41 | - (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
42 | {
43 | return 1;
44 | }
45 |
46 | - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
47 | {
48 | return self.states.count;
49 | }
50 |
51 | #pragma mark - UICollectionViewDelegate
52 |
53 | - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
54 | {
55 | KTAwesomeSizingCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:stateCellID
56 | forIndexPath:indexPath];
57 |
58 | cell.label.text = self.states[indexPath.row];
59 | return cell;
60 | }
61 |
62 | @end
63 |
--------------------------------------------------------------------------------
/Example/CenterFlow/Launch.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/Example/CenterFlow/KTAppDelegate.m:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.m
3 | // CenterFlow
4 | //
5 | // Created by Kyle Truscott on 10/9/14.
6 | // Copyright (c) 2014 keighl. All rights reserved.
7 | //
8 |
9 | #import "KTAppDelegate.h"
10 | #import "KTBasicCollectionViewController.h"
11 | #import "KTVariableHeightCollectionViewController.h"
12 | #import "KTSelfSizingCollectionViewController.h"
13 | #import "KTCenterFlowLayout.h"
14 |
15 | @interface KTAppDelegate ()
16 |
17 | @end
18 |
19 | @implementation KTAppDelegate
20 |
21 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
22 | {
23 | self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
24 | self.window.backgroundColor = [UIColor whiteColor];
25 |
26 | UINavigationController *basicNavController = [UINavigationController new];
27 | basicNavController.tabBarItem = [[UITabBarItem alloc] initWithTitle:@"Vanilla" image:[UIImage imageNamed:@"tabbar-image"] tag:2];
28 | KTBasicCollectionViewController *basicController = [[KTBasicCollectionViewController alloc] initWithCollectionViewLayout:[UICollectionViewFlowLayout new]];
29 | basicController.title = @"UICollectionViewFlowLayout";
30 | [basicNavController setViewControllers:@[basicController]];
31 |
32 | UINavigationController *centerNavController = [UINavigationController new];
33 | KTBasicCollectionViewController *centerController = [[KTBasicCollectionViewController alloc] initWithCollectionViewLayout:[KTCenterFlowLayout new]];
34 | centerController.title = @"KTCenterFlowLayout";
35 | centerNavController.tabBarItem = [[UITabBarItem alloc] initWithTitle:@"Centered" image:[UIImage imageNamed:@"tabbar-image"] tag:2];
36 | [centerNavController setViewControllers:@[centerController]];
37 |
38 | UINavigationController *heightsNavController = [UINavigationController new];
39 | heightsNavController.tabBarItem = [[UITabBarItem alloc] initWithTitle:@"Variable Height" image:[UIImage imageNamed:@"tabbar-image"] tag:1];
40 | KTVariableHeightCollectionViewController *heightsController = [[KTVariableHeightCollectionViewController alloc] initWithCollectionViewLayout:[KTCenterFlowLayout new]];
41 | heightsController.title = @"Variable Height";
42 | [heightsNavController setViewControllers:@[heightsController]];
43 |
44 | UINavigationController *selfsizeNavController = [UINavigationController new];
45 | selfsizeNavController.tabBarItem = [[UITabBarItem alloc] initWithTitle:@"Self Sizing" image:[UIImage imageNamed:@"tabbar-image"] tag:2];
46 | KTSelfSizingCollectionViewController *selfsizeController = [[KTSelfSizingCollectionViewController alloc] initWithCollectionViewLayout:[KTCenterFlowLayout new]];
47 | selfsizeController.title = @"Self Sizing";
48 | [selfsizeNavController setViewControllers:@[selfsizeController]];
49 |
50 | UITabBarController *tabBarController = [[UITabBarController alloc] init];
51 | [tabBarController setViewControllers:@[
52 | basicNavController,
53 | centerNavController,
54 | heightsNavController,
55 | //selfsizeNavController
56 | ]];
57 |
58 | self.window.rootViewController = tabBarController;
59 | [self.window makeKeyAndVisible];
60 | return YES;
61 | }
62 |
63 | - (void)applicationWillResignActive:(UIApplication *)application
64 | {
65 | }
66 |
67 | - (void)applicationDidEnterBackground:(UIApplication *)application
68 | {
69 | }
70 |
71 | - (void)applicationWillEnterForeground:(UIApplication *)application
72 | {
73 |
74 | }
75 |
76 | - (void)applicationDidBecomeActive:(UIApplication *)application
77 | {
78 | }
79 |
80 | - (void)applicationWillTerminate:(UIApplication *)application
81 | {
82 | }
83 |
84 | @end
85 |
--------------------------------------------------------------------------------
/Example/CenterFlow/KTBasicCollectionViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // MainController.m
3 | // CenterFlow
4 | //
5 | // Created by Kyle Truscott on 10/9/14.
6 | // Copyright (c) 2014 keighl. All rights reserved.
7 | //
8 |
9 | #import "KTBasicCollectionViewController.h"
10 | #import "KTCenterFlowLayout.h"
11 | #import "Constants.h"
12 | #import "KTHeaderFooterView.h"
13 |
14 | @interface KTBasicCollectionViewController ()
15 | @end
16 |
17 | @implementation KTBasicCollectionViewController
18 |
19 | - (void)viewDidLoad
20 | {
21 | [super viewDidLoad];
22 |
23 | self.collectionView.backgroundColor = [UIColor whiteColor];
24 |
25 | [(KTCenterFlowLayout *)self.collectionViewLayout setMinimumInteritemSpacing:15.f];
26 | [(KTCenterFlowLayout *)self.collectionViewLayout setMinimumLineSpacing:15.f];
27 | [(KTCenterFlowLayout *)self.collectionViewLayout setSectionInset:UIEdgeInsetsMake(20, 20, 20, 20)];
28 |
29 | [self.collectionView registerClass:[KTHeaderFooterView class] forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:headerCellID];
30 | [self.collectionView registerClass:[KTHeaderFooterView class] forSupplementaryViewOfKind:UICollectionElementKindSectionFooter withReuseIdentifier:footerCellID];
31 | [self.collectionView registerClass:[KTAwesomeCell class] forCellWithReuseIdentifier:stateCellID];
32 |
33 | self.sizingCell = [KTAwesomeCell new];
34 |
35 | self.states = [Constants states];
36 | }
37 |
38 | #pragma mark - UICollectionViewDataSource
39 |
40 | - (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
41 | {
42 | return 1;
43 | }
44 |
45 | - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
46 | {
47 | return self.states.count;
48 | }
49 |
50 | #pragma mark - UICollectionViewDelegate
51 |
52 | - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
53 | {
54 | KTAwesomeCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:stateCellID
55 | forIndexPath:indexPath];
56 |
57 | cell.label.text = self.states[indexPath.row];
58 | return cell;
59 | }
60 |
61 | - (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView
62 | viewForSupplementaryElementOfKind:(NSString *)kind
63 | atIndexPath:(NSIndexPath *)indexPath
64 | {
65 | if (kind == UICollectionElementKindSectionHeader)
66 | {
67 | KTHeaderFooterView *header = [collectionView dequeueReusableSupplementaryViewOfKind:kind withReuseIdentifier:headerCellID forIndexPath:indexPath];
68 | header.label.text = @"50 states...";
69 | return header;
70 | }
71 |
72 | if (kind == UICollectionElementKindSectionFooter)
73 | {
74 | KTHeaderFooterView *header = [collectionView dequeueReusableSupplementaryViewOfKind:kind withReuseIdentifier:footerCellID forIndexPath:indexPath];
75 | header.label.text = @"...that's all of 'em.";
76 | return header;
77 | }
78 |
79 | return nil;
80 | }
81 |
82 | #pragma mark - UICollectionViewDelegateFlowLayout
83 |
84 | - (CGSize)collectionView:(UICollectionView *)collectionView
85 | layout:(UICollectionViewFlowLayout *)collectionViewLayout
86 | sizeForItemAtIndexPath:(NSIndexPath *)indexPath
87 | {
88 | self.sizingCell.label.text = self.states[indexPath.row];
89 | return self.sizingCell.intrinsicContentSize;
90 | }
91 |
92 | - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout referenceSizeForHeaderInSection:(NSInteger)section;
93 | {
94 | CGFloat width = collectionView.bounds.size.width;
95 | return CGSizeMake(width, 40);
96 | }
97 |
98 | - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout referenceSizeForFooterInSection:(NSInteger)section;
99 | {
100 | CGFloat width = collectionView.bounds.size.width;
101 | return CGSizeMake(width, 40);
102 | }
103 |
104 | @end
105 |
--------------------------------------------------------------------------------
/KTCenterFlowLayout.m:
--------------------------------------------------------------------------------
1 | //
2 | // KTCenterFlowLayout.m
3 | //
4 | // Created by Kyle Truscott on 10/9/14.
5 | // Copyright (c) 2014 keighl. All rights reserved.
6 | //
7 |
8 | #import "KTCenterFlowLayout.h"
9 |
10 | @interface KTCenterFlowLayout ()
11 | @property (nonatomic) NSMutableDictionary *attrCache;
12 | @end
13 |
14 | @implementation KTCenterFlowLayout
15 |
16 | - (void)prepareLayout
17 | {
18 | // Clear the attrCache
19 | self.attrCache = [NSMutableDictionary new];
20 | }
21 |
22 | - (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect
23 | {
24 | NSMutableArray *updatedAttributes = [NSMutableArray new];
25 |
26 | NSInteger sections = [self.collectionView numberOfSections];
27 | NSInteger s = 0;
28 | while (s < sections)
29 | {
30 | NSInteger rows = [self.collectionView numberOfItemsInSection:s];
31 | NSInteger r = 0;
32 | while (r < rows)
33 | {
34 | NSIndexPath *indexPath = [NSIndexPath indexPathForRow:r inSection:s];
35 |
36 | UICollectionViewLayoutAttributes *attrs = [self layoutAttributesForItemAtIndexPath:indexPath];
37 |
38 | if (attrs && CGRectIntersectsRect(attrs.frame, rect))
39 | {
40 | [updatedAttributes addObject:attrs];
41 | }
42 |
43 | UICollectionViewLayoutAttributes *headerAttrs = [super layoutAttributesForSupplementaryViewOfKind:UICollectionElementKindSectionHeader
44 | atIndexPath:indexPath];
45 |
46 | if (headerAttrs && CGRectIntersectsRect(headerAttrs.frame, rect))
47 | {
48 | [updatedAttributes addObject:headerAttrs];
49 | }
50 |
51 | UICollectionViewLayoutAttributes *footerAttrs = [super layoutAttributesForSupplementaryViewOfKind:UICollectionElementKindSectionFooter
52 | atIndexPath:indexPath];
53 |
54 | if (footerAttrs && CGRectIntersectsRect(footerAttrs.frame, rect))
55 | {
56 | [updatedAttributes addObject:footerAttrs];
57 | }
58 |
59 | r++;
60 | }
61 | s++;
62 | }
63 |
64 | return updatedAttributes;
65 | }
66 |
67 | - (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath
68 | {
69 | if (self.attrCache[indexPath])
70 | {
71 | return self.attrCache[indexPath];
72 | }
73 |
74 | // Find the other items in the same "row"
75 | NSMutableArray *rowBuddies = [NSMutableArray new];
76 |
77 | // Calculate the available width to center stuff within
78 | // sectionInset is NOT applicable here because a) we're centering stuff
79 | // and b) Flow layout has arranged the cells to respect the inset. We're
80 | // just hijacking the X position.
81 | CGFloat collectionViewWidth = CGRectGetWidth(self.collectionView.bounds) -
82 | self.collectionView.contentInset.left -
83 | self.collectionView.contentInset.right;
84 |
85 | // To find other items in the "row", we need a rect to check intersects against.
86 | // Take the item attributes frame (from vanilla flow layout), and stretch it out
87 | CGRect rowTestFrame = [super layoutAttributesForItemAtIndexPath:indexPath].frame;
88 | rowTestFrame.origin.x = 0;
89 | rowTestFrame.size.width = collectionViewWidth;
90 |
91 | NSInteger totalRows = [self.collectionView numberOfItemsInSection:indexPath.section];
92 |
93 | // From this item, work backwards to find the first item in the row
94 | // Decrement the row index until a) we get to 0, b) we reach a previous row
95 | NSInteger rowStartIDX = indexPath.row;
96 | while (true)
97 | {
98 | NSInteger prevIDX = rowStartIDX - 1;
99 |
100 | if (prevIDX < 0)
101 | {
102 | break;
103 | }
104 |
105 | NSIndexPath *prevPath = [NSIndexPath indexPathForRow:prevIDX inSection:indexPath.section];
106 | CGRect prevFrame = [super layoutAttributesForItemAtIndexPath:prevPath].frame;
107 |
108 | // If the item intersects the test frame, it's in the same row
109 | if (CGRectIntersectsRect(prevFrame, rowTestFrame))
110 | rowStartIDX = prevIDX;
111 | else
112 | // Found previous row, escape!
113 | break;
114 | }
115 |
116 | // Now, work back UP to find the last item in the row
117 | // For each item in the row, add it's attributes to rowBuddies
118 | NSInteger buddyIDX = rowStartIDX;
119 | while (true)
120 | {
121 | if (buddyIDX > (totalRows-1))
122 | {
123 | break;
124 | }
125 |
126 | NSIndexPath *buddyPath = [NSIndexPath indexPathForRow:buddyIDX inSection:indexPath.section];
127 |
128 | UICollectionViewLayoutAttributes *buddyAttributes = [super layoutAttributesForItemAtIndexPath:buddyPath];
129 |
130 | if (CGRectIntersectsRect(buddyAttributes.frame, rowTestFrame))
131 | {
132 | // If the item intersects the test frame, it's in the same row
133 | [rowBuddies addObject:[buddyAttributes copy]];
134 | buddyIDX++;
135 | }
136 | else
137 | {
138 | // Encountered next row
139 | break;
140 | }
141 | }
142 |
143 | id flowDelegate = (id) [[self collectionView] delegate];
144 | BOOL delegateSupportsInteritemSpacing = [flowDelegate respondsToSelector:@selector(collectionView:layout:minimumInteritemSpacingForSectionAtIndex:)];
145 |
146 | // x-x-x-x ... sum up the interim space
147 | CGFloat interitemSpacing = [self minimumInteritemSpacing];
148 |
149 | // Check for minimumInteritemSpacingForSectionAtIndex support
150 | if (delegateSupportsInteritemSpacing && rowBuddies.count > 0)
151 | {
152 | interitemSpacing = [flowDelegate collectionView:self.collectionView
153 | layout:self
154 | minimumInteritemSpacingForSectionAtIndex:indexPath.section];
155 | }
156 |
157 | CGFloat aggregateInteritemSpacing = interitemSpacing * (rowBuddies.count -1);
158 |
159 | // Sum the width of all elements in the row
160 | CGFloat aggregateItemWidths = 0.f;
161 | for (UICollectionViewLayoutAttributes *itemAttributes in rowBuddies)
162 | aggregateItemWidths += CGRectGetWidth(itemAttributes.frame);
163 |
164 | // Build an alignment rect
165 | // | |x-x-x-x| |
166 | CGFloat alignmentWidth = aggregateItemWidths + aggregateInteritemSpacing;
167 | CGFloat alignmentXOffset = (collectionViewWidth - alignmentWidth) / 2.f;
168 |
169 | // Adjust each item's position to be centered
170 | CGRect previousFrame = CGRectZero;
171 | for (UICollectionViewLayoutAttributes *itemAttributes in rowBuddies)
172 | {
173 | CGRect itemFrame = itemAttributes.frame;
174 |
175 | if (CGRectEqualToRect(previousFrame, CGRectZero))
176 | itemFrame.origin.x = alignmentXOffset;
177 | else
178 | itemFrame.origin.x = CGRectGetMaxX(previousFrame) + interitemSpacing;
179 |
180 | itemAttributes.frame = itemFrame;
181 | previousFrame = itemFrame;
182 |
183 | // Finally, add it to the cache
184 | self.attrCache[itemAttributes.indexPath] = itemAttributes;
185 | }
186 |
187 | return self.attrCache[indexPath];
188 | }
189 |
190 | @end
191 |
--------------------------------------------------------------------------------
/Example/CenterFlow.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | CF0E9DA41AE914A300754C1D /* Launch.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = CF0E9DA31AE914A300754C1D /* Launch.storyboard */; };
11 | CF12786A1D10D155007BD3CC /* KTHeaderFooterView.m in Sources */ = {isa = PBXBuildFile; fileRef = CF1278691D10D155007BD3CC /* KTHeaderFooterView.m */; };
12 | CF1EDF8D1CDA54EA004D7709 /* KTAwesomeSizingCell.m in Sources */ = {isa = PBXBuildFile; fileRef = CF1EDF8C1CDA54EA004D7709 /* KTAwesomeSizingCell.m */; };
13 | CF2A543419E702E500BAFA7F /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = CF2A543319E702E500BAFA7F /* main.m */; };
14 | CF2A543719E702E500BAFA7F /* KTAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = CF2A543619E702E500BAFA7F /* KTAppDelegate.m */; };
15 | CF2A543F19E702E500BAFA7F /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = CF2A543E19E702E500BAFA7F /* Images.xcassets */; };
16 | CF2A545919E704C700BAFA7F /* KTBasicCollectionViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = CF2A545819E704C700BAFA7F /* KTBasicCollectionViewController.m */; };
17 | CF2A545C19E7061300BAFA7F /* KTAwesomeCell.m in Sources */ = {isa = PBXBuildFile; fileRef = CF2A545B19E7061300BAFA7F /* KTAwesomeCell.m */; };
18 | CF2A545E19E7084100BAFA7F /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = CF2A545D19E7084100BAFA7F /* Default-568h@2x.png */; };
19 | CFA1AADE1CDA724B00373D0E /* tabbar-image.png in Resources */ = {isa = PBXBuildFile; fileRef = CFA1AADB1CDA724B00373D0E /* tabbar-image.png */; };
20 | CFA1AADF1CDA724B00373D0E /* tabbar-image@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = CFA1AADC1CDA724B00373D0E /* tabbar-image@2x.png */; };
21 | CFA1AAE01CDA724B00373D0E /* tabbar-image@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = CFA1AADD1CDA724B00373D0E /* tabbar-image@3x.png */; };
22 | CFD354581CD942170009443A /* KTCenterFlowLayout.m in Sources */ = {isa = PBXBuildFile; fileRef = CFD354571CD942170009443A /* KTCenterFlowLayout.m */; };
23 | CFD3545B1CD9485A0009443A /* Constants.m in Sources */ = {isa = PBXBuildFile; fileRef = CFD3545A1CD9485A0009443A /* Constants.m */; };
24 | CFD3545E1CD949780009443A /* KTVariableHeightCollectionViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = CFD3545D1CD949780009443A /* KTVariableHeightCollectionViewController.m */; };
25 | CFD354611CD94AA70009443A /* KTSelfSizingCollectionViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = CFD354601CD94AA70009443A /* KTSelfSizingCollectionViewController.m */; };
26 | /* End PBXBuildFile section */
27 |
28 | /* Begin PBXFileReference section */
29 | 19FE6FBDF1A7F0531B0558FC /* libPods-CenterFlow.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-CenterFlow.a"; sourceTree = BUILT_PRODUCTS_DIR; };
30 | BA0FF2F233AC4708DDDF959F /* libPods-CenterFlowTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-CenterFlowTests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
31 | CF0E9DA31AE914A300754C1D /* Launch.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Launch.storyboard; sourceTree = ""; };
32 | CF1278681D10D155007BD3CC /* KTHeaderFooterView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KTHeaderFooterView.h; sourceTree = ""; };
33 | CF1278691D10D155007BD3CC /* KTHeaderFooterView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KTHeaderFooterView.m; sourceTree = ""; };
34 | CF1EDF8B1CDA54EA004D7709 /* KTAwesomeSizingCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KTAwesomeSizingCell.h; sourceTree = ""; };
35 | CF1EDF8C1CDA54EA004D7709 /* KTAwesomeSizingCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KTAwesomeSizingCell.m; sourceTree = ""; };
36 | CF2A542E19E702E500BAFA7F /* CenterFlow.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = CenterFlow.app; sourceTree = BUILT_PRODUCTS_DIR; };
37 | CF2A543219E702E500BAFA7F /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
38 | CF2A543319E702E500BAFA7F /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; };
39 | CF2A543519E702E500BAFA7F /* KTAppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KTAppDelegate.h; sourceTree = ""; };
40 | CF2A543619E702E500BAFA7F /* KTAppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KTAppDelegate.m; sourceTree = ""; };
41 | CF2A543E19E702E500BAFA7F /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; };
42 | CF2A545719E704C700BAFA7F /* KTBasicCollectionViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KTBasicCollectionViewController.h; sourceTree = ""; };
43 | CF2A545819E704C700BAFA7F /* KTBasicCollectionViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KTBasicCollectionViewController.m; sourceTree = ""; };
44 | CF2A545A19E7061300BAFA7F /* KTAwesomeCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KTAwesomeCell.h; sourceTree = ""; };
45 | CF2A545B19E7061300BAFA7F /* KTAwesomeCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KTAwesomeCell.m; sourceTree = ""; };
46 | CF2A545D19E7084100BAFA7F /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-568h@2x.png"; sourceTree = ""; };
47 | CFA1AADB1CDA724B00373D0E /* tabbar-image.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "tabbar-image.png"; sourceTree = ""; };
48 | CFA1AADC1CDA724B00373D0E /* tabbar-image@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "tabbar-image@2x.png"; sourceTree = ""; };
49 | CFA1AADD1CDA724B00373D0E /* tabbar-image@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "tabbar-image@3x.png"; sourceTree = ""; };
50 | CFD354561CD942170009443A /* KTCenterFlowLayout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = KTCenterFlowLayout.h; path = ../../KTCenterFlowLayout.h; sourceTree = ""; };
51 | CFD354571CD942170009443A /* KTCenterFlowLayout.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = KTCenterFlowLayout.m; path = ../../KTCenterFlowLayout.m; sourceTree = ""; };
52 | CFD354591CD9485A0009443A /* Constants.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Constants.h; sourceTree = ""; };
53 | CFD3545A1CD9485A0009443A /* Constants.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Constants.m; sourceTree = ""; };
54 | CFD3545C1CD949780009443A /* KTVariableHeightCollectionViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KTVariableHeightCollectionViewController.h; sourceTree = ""; };
55 | CFD3545D1CD949780009443A /* KTVariableHeightCollectionViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KTVariableHeightCollectionViewController.m; sourceTree = ""; };
56 | CFD3545F1CD94AA70009443A /* KTSelfSizingCollectionViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KTSelfSizingCollectionViewController.h; sourceTree = ""; };
57 | CFD354601CD94AA70009443A /* KTSelfSizingCollectionViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KTSelfSizingCollectionViewController.m; sourceTree = ""; };
58 | D7C963BB7B28CF1B2966D389 /* libPods.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libPods.a; sourceTree = BUILT_PRODUCTS_DIR; };
59 | /* End PBXFileReference section */
60 |
61 | /* Begin PBXFrameworksBuildPhase section */
62 | CF2A542B19E702E500BAFA7F /* Frameworks */ = {
63 | isa = PBXFrameworksBuildPhase;
64 | buildActionMask = 2147483647;
65 | files = (
66 | );
67 | runOnlyForDeploymentPostprocessing = 0;
68 | };
69 | /* End PBXFrameworksBuildPhase section */
70 |
71 | /* Begin PBXGroup section */
72 | 0405686C57B14B068693DE2D /* Frameworks */ = {
73 | isa = PBXGroup;
74 | children = (
75 | 19FE6FBDF1A7F0531B0558FC /* libPods-CenterFlow.a */,
76 | BA0FF2F233AC4708DDDF959F /* libPods-CenterFlowTests.a */,
77 | D7C963BB7B28CF1B2966D389 /* libPods.a */,
78 | );
79 | name = Frameworks;
80 | sourceTree = "";
81 | };
82 | CF2A542519E702E500BAFA7F = {
83 | isa = PBXGroup;
84 | children = (
85 | CF2A543019E702E500BAFA7F /* CenterFlow */,
86 | CF2A542F19E702E500BAFA7F /* Products */,
87 | 0405686C57B14B068693DE2D /* Frameworks */,
88 | );
89 | sourceTree = "";
90 | };
91 | CF2A542F19E702E500BAFA7F /* Products */ = {
92 | isa = PBXGroup;
93 | children = (
94 | CF2A542E19E702E500BAFA7F /* CenterFlow.app */,
95 | );
96 | name = Products;
97 | sourceTree = "";
98 | };
99 | CF2A543019E702E500BAFA7F /* CenterFlow */ = {
100 | isa = PBXGroup;
101 | children = (
102 | CFA1AADB1CDA724B00373D0E /* tabbar-image.png */,
103 | CFA1AADC1CDA724B00373D0E /* tabbar-image@2x.png */,
104 | CFA1AADD1CDA724B00373D0E /* tabbar-image@3x.png */,
105 | CFD354561CD942170009443A /* KTCenterFlowLayout.h */,
106 | CFD354571CD942170009443A /* KTCenterFlowLayout.m */,
107 | CF2A545D19E7084100BAFA7F /* Default-568h@2x.png */,
108 | CF2A543519E702E500BAFA7F /* KTAppDelegate.h */,
109 | CF2A543619E702E500BAFA7F /* KTAppDelegate.m */,
110 | CF2A543E19E702E500BAFA7F /* Images.xcassets */,
111 | CF2A543119E702E500BAFA7F /* Supporting Files */,
112 | CF2A545719E704C700BAFA7F /* KTBasicCollectionViewController.h */,
113 | CF2A545819E704C700BAFA7F /* KTBasicCollectionViewController.m */,
114 | CF2A545A19E7061300BAFA7F /* KTAwesomeCell.h */,
115 | CF2A545B19E7061300BAFA7F /* KTAwesomeCell.m */,
116 | CF0E9DA31AE914A300754C1D /* Launch.storyboard */,
117 | CFD354591CD9485A0009443A /* Constants.h */,
118 | CFD3545A1CD9485A0009443A /* Constants.m */,
119 | CFD3545C1CD949780009443A /* KTVariableHeightCollectionViewController.h */,
120 | CFD3545D1CD949780009443A /* KTVariableHeightCollectionViewController.m */,
121 | CFD3545F1CD94AA70009443A /* KTSelfSizingCollectionViewController.h */,
122 | CFD354601CD94AA70009443A /* KTSelfSizingCollectionViewController.m */,
123 | CF1EDF8B1CDA54EA004D7709 /* KTAwesomeSizingCell.h */,
124 | CF1EDF8C1CDA54EA004D7709 /* KTAwesomeSizingCell.m */,
125 | CF1278681D10D155007BD3CC /* KTHeaderFooterView.h */,
126 | CF1278691D10D155007BD3CC /* KTHeaderFooterView.m */,
127 | );
128 | path = CenterFlow;
129 | sourceTree = "";
130 | };
131 | CF2A543119E702E500BAFA7F /* Supporting Files */ = {
132 | isa = PBXGroup;
133 | children = (
134 | CF2A543219E702E500BAFA7F /* Info.plist */,
135 | CF2A543319E702E500BAFA7F /* main.m */,
136 | );
137 | name = "Supporting Files";
138 | sourceTree = "";
139 | };
140 | /* End PBXGroup section */
141 |
142 | /* Begin PBXNativeTarget section */
143 | CF2A542D19E702E500BAFA7F /* CenterFlow */ = {
144 | isa = PBXNativeTarget;
145 | buildConfigurationList = CF2A545119E702E500BAFA7F /* Build configuration list for PBXNativeTarget "CenterFlow" */;
146 | buildPhases = (
147 | CF2A542A19E702E500BAFA7F /* Sources */,
148 | CF2A542B19E702E500BAFA7F /* Frameworks */,
149 | CF2A542C19E702E500BAFA7F /* Resources */,
150 | );
151 | buildRules = (
152 | );
153 | dependencies = (
154 | );
155 | name = CenterFlow;
156 | productName = CenterFlow;
157 | productReference = CF2A542E19E702E500BAFA7F /* CenterFlow.app */;
158 | productType = "com.apple.product-type.application";
159 | };
160 | /* End PBXNativeTarget section */
161 |
162 | /* Begin PBXProject section */
163 | CF2A542619E702E500BAFA7F /* Project object */ = {
164 | isa = PBXProject;
165 | attributes = {
166 | LastUpgradeCheck = 0600;
167 | ORGANIZATIONNAME = keighl;
168 | TargetAttributes = {
169 | CF2A542D19E702E500BAFA7F = {
170 | CreatedOnToolsVersion = 6.0.1;
171 | };
172 | };
173 | };
174 | buildConfigurationList = CF2A542919E702E500BAFA7F /* Build configuration list for PBXProject "CenterFlow" */;
175 | compatibilityVersion = "Xcode 3.2";
176 | developmentRegion = English;
177 | hasScannedForEncodings = 0;
178 | knownRegions = (
179 | en,
180 | Base,
181 | );
182 | mainGroup = CF2A542519E702E500BAFA7F;
183 | productRefGroup = CF2A542F19E702E500BAFA7F /* Products */;
184 | projectDirPath = "";
185 | projectRoot = "";
186 | targets = (
187 | CF2A542D19E702E500BAFA7F /* CenterFlow */,
188 | );
189 | };
190 | /* End PBXProject section */
191 |
192 | /* Begin PBXResourcesBuildPhase section */
193 | CF2A542C19E702E500BAFA7F /* Resources */ = {
194 | isa = PBXResourcesBuildPhase;
195 | buildActionMask = 2147483647;
196 | files = (
197 | CFA1AADF1CDA724B00373D0E /* tabbar-image@2x.png in Resources */,
198 | CF2A543F19E702E500BAFA7F /* Images.xcassets in Resources */,
199 | CF2A545E19E7084100BAFA7F /* Default-568h@2x.png in Resources */,
200 | CF0E9DA41AE914A300754C1D /* Launch.storyboard in Resources */,
201 | CFA1AADE1CDA724B00373D0E /* tabbar-image.png in Resources */,
202 | CFA1AAE01CDA724B00373D0E /* tabbar-image@3x.png in Resources */,
203 | );
204 | runOnlyForDeploymentPostprocessing = 0;
205 | };
206 | /* End PBXResourcesBuildPhase section */
207 |
208 | /* Begin PBXSourcesBuildPhase section */
209 | CF2A542A19E702E500BAFA7F /* Sources */ = {
210 | isa = PBXSourcesBuildPhase;
211 | buildActionMask = 2147483647;
212 | files = (
213 | CF2A543719E702E500BAFA7F /* KTAppDelegate.m in Sources */,
214 | CFD354611CD94AA70009443A /* KTSelfSizingCollectionViewController.m in Sources */,
215 | CF1EDF8D1CDA54EA004D7709 /* KTAwesomeSizingCell.m in Sources */,
216 | CF12786A1D10D155007BD3CC /* KTHeaderFooterView.m in Sources */,
217 | CFD354581CD942170009443A /* KTCenterFlowLayout.m in Sources */,
218 | CF2A545C19E7061300BAFA7F /* KTAwesomeCell.m in Sources */,
219 | CFD3545E1CD949780009443A /* KTVariableHeightCollectionViewController.m in Sources */,
220 | CF2A545919E704C700BAFA7F /* KTBasicCollectionViewController.m in Sources */,
221 | CF2A543419E702E500BAFA7F /* main.m in Sources */,
222 | CFD3545B1CD9485A0009443A /* Constants.m in Sources */,
223 | );
224 | runOnlyForDeploymentPostprocessing = 0;
225 | };
226 | /* End PBXSourcesBuildPhase section */
227 |
228 | /* Begin XCBuildConfiguration section */
229 | CF2A544F19E702E500BAFA7F /* Debug */ = {
230 | isa = XCBuildConfiguration;
231 | buildSettings = {
232 | ALWAYS_SEARCH_USER_PATHS = NO;
233 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
234 | CLANG_CXX_LIBRARY = "libc++";
235 | CLANG_ENABLE_MODULES = YES;
236 | CLANG_ENABLE_OBJC_ARC = YES;
237 | CLANG_WARN_BOOL_CONVERSION = YES;
238 | CLANG_WARN_CONSTANT_CONVERSION = YES;
239 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
240 | CLANG_WARN_EMPTY_BODY = YES;
241 | CLANG_WARN_ENUM_CONVERSION = YES;
242 | CLANG_WARN_INT_CONVERSION = YES;
243 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
244 | CLANG_WARN_UNREACHABLE_CODE = YES;
245 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
246 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
247 | COPY_PHASE_STRIP = NO;
248 | ENABLE_STRICT_OBJC_MSGSEND = YES;
249 | GCC_C_LANGUAGE_STANDARD = gnu99;
250 | GCC_DYNAMIC_NO_PIC = NO;
251 | GCC_OPTIMIZATION_LEVEL = 0;
252 | GCC_PREPROCESSOR_DEFINITIONS = (
253 | "DEBUG=1",
254 | "$(inherited)",
255 | );
256 | GCC_SYMBOLS_PRIVATE_EXTERN = NO;
257 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
258 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
259 | GCC_WARN_UNDECLARED_SELECTOR = YES;
260 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
261 | GCC_WARN_UNUSED_FUNCTION = YES;
262 | GCC_WARN_UNUSED_VARIABLE = YES;
263 | IPHONEOS_DEPLOYMENT_TARGET = 8.0;
264 | MTL_ENABLE_DEBUG_INFO = YES;
265 | ONLY_ACTIVE_ARCH = YES;
266 | SDKROOT = iphoneos;
267 | };
268 | name = Debug;
269 | };
270 | CF2A545019E702E500BAFA7F /* Release */ = {
271 | isa = XCBuildConfiguration;
272 | buildSettings = {
273 | ALWAYS_SEARCH_USER_PATHS = NO;
274 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
275 | CLANG_CXX_LIBRARY = "libc++";
276 | CLANG_ENABLE_MODULES = YES;
277 | CLANG_ENABLE_OBJC_ARC = YES;
278 | CLANG_WARN_BOOL_CONVERSION = YES;
279 | CLANG_WARN_CONSTANT_CONVERSION = YES;
280 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
281 | CLANG_WARN_EMPTY_BODY = YES;
282 | CLANG_WARN_ENUM_CONVERSION = YES;
283 | CLANG_WARN_INT_CONVERSION = YES;
284 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
285 | CLANG_WARN_UNREACHABLE_CODE = YES;
286 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
287 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
288 | COPY_PHASE_STRIP = YES;
289 | ENABLE_NS_ASSERTIONS = NO;
290 | ENABLE_STRICT_OBJC_MSGSEND = YES;
291 | GCC_C_LANGUAGE_STANDARD = gnu99;
292 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
293 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
294 | GCC_WARN_UNDECLARED_SELECTOR = YES;
295 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
296 | GCC_WARN_UNUSED_FUNCTION = YES;
297 | GCC_WARN_UNUSED_VARIABLE = YES;
298 | IPHONEOS_DEPLOYMENT_TARGET = 8.0;
299 | MTL_ENABLE_DEBUG_INFO = NO;
300 | SDKROOT = iphoneos;
301 | VALIDATE_PRODUCT = YES;
302 | };
303 | name = Release;
304 | };
305 | CF2A545219E702E500BAFA7F /* Debug */ = {
306 | isa = XCBuildConfiguration;
307 | buildSettings = {
308 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
309 | INFOPLIST_FILE = CenterFlow/Info.plist;
310 | IPHONEOS_DEPLOYMENT_TARGET = 7.0;
311 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
312 | PRODUCT_NAME = "$(TARGET_NAME)";
313 | };
314 | name = Debug;
315 | };
316 | CF2A545319E702E500BAFA7F /* Release */ = {
317 | isa = XCBuildConfiguration;
318 | buildSettings = {
319 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
320 | INFOPLIST_FILE = CenterFlow/Info.plist;
321 | IPHONEOS_DEPLOYMENT_TARGET = 7.0;
322 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
323 | PRODUCT_NAME = "$(TARGET_NAME)";
324 | };
325 | name = Release;
326 | };
327 | /* End XCBuildConfiguration section */
328 |
329 | /* Begin XCConfigurationList section */
330 | CF2A542919E702E500BAFA7F /* Build configuration list for PBXProject "CenterFlow" */ = {
331 | isa = XCConfigurationList;
332 | buildConfigurations = (
333 | CF2A544F19E702E500BAFA7F /* Debug */,
334 | CF2A545019E702E500BAFA7F /* Release */,
335 | );
336 | defaultConfigurationIsVisible = 0;
337 | defaultConfigurationName = Release;
338 | };
339 | CF2A545119E702E500BAFA7F /* Build configuration list for PBXNativeTarget "CenterFlow" */ = {
340 | isa = XCConfigurationList;
341 | buildConfigurations = (
342 | CF2A545219E702E500BAFA7F /* Debug */,
343 | CF2A545319E702E500BAFA7F /* Release */,
344 | );
345 | defaultConfigurationIsVisible = 0;
346 | defaultConfigurationName = Release;
347 | };
348 | /* End XCConfigurationList section */
349 | };
350 | rootObject = CF2A542619E702E500BAFA7F /* Project object */;
351 | }
352 |
--------------------------------------------------------------------------------