├── .gitignore
├── .swift-version
├── .swiftpm
└── xcode
│ └── package.xcworkspace
│ └── contents.xcworkspacedata
├── .travis.yml
├── LICENSE
├── Package.swift
├── README.md
├── Source
├── LayoutAlignment.swift
├── LayoutInfo.swift
├── TagCellLayout.swift
└── TagCellLayoutDelegate.swift
├── TagCellLayout.podspec
├── TagCellLayout.xcodeproj
├── project.pbxproj
├── project.xcworkspace
│ └── contents.xcworkspacedata
├── xcshareddata
│ └── xcschemes
│ │ └── TagCellLayout.xcscheme
└── xcuserdata
│ └── riteshgupta.xcuserdatad
│ ├── xcdebugger
│ └── Breakpoints_v2.xcbkptlist
│ └── xcschemes
│ └── xcschememanagement.plist
└── TagCellLayout
├── AppDelegate.swift
├── Assets.xcassets
└── AppIcon.appiconset
│ └── Contents.json
├── Base.lproj
├── LaunchScreen.storyboard
└── Main.storyboard
├── Info.plist
├── Readme_Resources
├── tag_cc.png
├── tag_ll.png
└── tag_rr.png
├── TagCollectionViewCell.swift
├── TagCollectionViewCell.xib
└── ViewController.swift
/.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 | # CocoaPods
21 | #
22 | # We recommend against adding the Pods directory to your .gitignore. However
23 | # you should judge for yourself, the pros and cons are mentioned at:
24 | # http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control
25 | #
26 | # Pods/
27 |
28 | # Carthage
29 | #
30 | # Add this line if you want to avoid checking in source code from Carthage dependencies.
31 | # Carthage/Checkouts
32 |
33 | Carthage/Build
34 |
35 | ### macOS ###
36 | *.DS_Store
37 | .AppleDouble
38 | .LSOverride
39 |
40 | # Icon must end with two \r
41 | Icon
42 |
43 | # Thumbnails
44 | ._*
45 |
46 | # Files that might appear in the root of a volume
47 | .DocumentRevisions-V100
48 | .fseventsd
49 | .Spotlight-V100
50 | .TemporaryItems
51 | .Trashes
52 | .VolumeIcon.icns
53 | .com.apple.timemachine.donotpresent
54 |
55 | # Directories potentially created on remote AFP share
56 | .AppleDB
57 | .AppleDesktop
58 | Network Trash Folder
59 | Temporary Items
60 | .apdisk
61 |
--------------------------------------------------------------------------------
/.swift-version:
--------------------------------------------------------------------------------
1 | 4.0
2 |
--------------------------------------------------------------------------------
/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: objective-c
2 |
3 | branches:
4 | only:
5 | - master
6 |
7 | xcode_project: TagCellLayout.xcodeproj
8 | xcode_scheme: TagCellLayout
9 | osx_image: xcode7.1
10 | xcode_sdk: iphonesimulator9.1
11 |
12 | script:
13 | - xcodebuild clean build -project TagCellLayout.xcodeproj -scheme TagCellLayout CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015 Ritesh Gupta
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
23 |
--------------------------------------------------------------------------------
/Package.swift:
--------------------------------------------------------------------------------
1 | // swift-tools-version: 5.7
2 | // The swift-tools-version declares the minimum version of Swift required to build this package.
3 |
4 | import PackageDescription
5 |
6 | let package = Package(
7 | name: "TagCellLayout",
8 | platforms: [
9 | .iOS(.v11)
10 | ],
11 | products: [
12 | .library(name: "TagCellLayout", targets: ["TagCellLayout"])
13 | ],
14 | targets: [
15 | .target(
16 | name: "TagCellLayout",
17 | path: "Source"
18 | )
19 | ]
20 | )
21 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # TagCellLayout
2 |
3 | [](https://travis-ci.org/riteshhgupta/TagCellLayout)
4 | [](https://cocoapods.org/pods/TagCellLayout)
5 | [](https://cocoapods.org/pods/TagCellLayout)
6 | [](https://opensource.org/licenses/MIT)
7 |
8 | ## About
9 |
10 | Its an ui-collection-view LAYOUT class that takes care of all the logic behind making tags like layout using UICollectionView. It also allows you to adjust the alignment of your layout i.e Left || Centre || Right. Now you just have to take care of your tag view and nothing else. Aaaand it also supports **multi-line** tags 🚀
11 |
12 | ## Screenshots
13 |
14 | 
15 | 
16 | 
17 |
18 | ## Usage
19 |
20 | - Init Method:
21 |
22 | ```swift
23 | import TagCellLayout
24 |
25 | let tagCellLayout = TagCellLayout(alignment: .center, delegate: self)
26 | collectionView.collectionViewLayout = tagCellLayout
27 | ```
28 |
29 | - Tag Alignment:
30 |
31 | ```alignment``` can be Left or Center or Right. If its nil then by default Left alignment will be applied.
32 |
33 |
34 | ## Delegate Methods
35 | - Protocol to conform - `TagCellLayoutDelegate`
36 |
37 |
38 | - Methods
39 |
40 |
41 | ```swift
42 | - func tagCellLayoutTagSize(layout: TagCellLayout, atIndex index:Int) -> CGSize
43 | ```
44 |
45 | ## Architecture
46 |
47 | - ```func tagCellLayoutTagSize(layout: TagCellLayout, atIndex index:Int) -> CGSize```
48 |
49 | is called for every tag where you will calculate their size and pass it on to TagCellLayout class for further calculations.
50 |
51 | - ```collectionView.numberOfItemsInSection(0)```
52 |
53 | internally the number of tags is calculated by the above method.
54 |
55 | ## Installation
56 | To integrate TagCellLayout into your Xcode project using CocoaPods, specify it in your Podfile:
57 |
58 | `Swift-4.0`
59 |
60 | ```ruby
61 | source 'https://github.com/CocoaPods/Specs.git'
62 | platform :ios, '8.0'
63 | use_frameworks!
64 |
65 | pod 'TagCellLayout', :git => 'https://github.com/riteshhgupta/TagCellLayout.git'
66 | ```
67 |
68 | `Swift-3.2`
69 |
70 | ```ruby
71 | source 'https://github.com/CocoaPods/Specs.git'
72 | platform :ios, '8.0'
73 | use_frameworks!
74 |
75 | pod 'TagCellLayout', :git => 'https://github.com/riteshhgupta/TagCellLayout.git', :branch => 'swift3.2'
76 | ```
77 |
78 | `Swift-3.0`
79 |
80 | ```ruby
81 | source 'https://github.com/CocoaPods/Specs.git'
82 | platform :ios, '8.0'
83 | use_frameworks!
84 |
85 | pod 'TagCellLayout', :git => 'https://github.com/riteshhgupta/TagCellLayout.git', :branch => 'swift3.0'
86 | ```
87 |
88 | `Swift-2.3`
89 |
90 | ```ruby
91 | source 'https://github.com/CocoaPods/Specs.git'
92 | platform :ios, '8.0'
93 | use_frameworks!
94 |
95 | pod 'TagCellLayout', :git => 'https://github.com/riteshhgupta/TagCellLayout.git', :branch => 'swift2.3'
96 | ```
97 |
98 | `Swift-2.2`
99 |
100 | ```ruby
101 | source 'https://github.com/CocoaPods/Specs.git'
102 | platform :ios, '8.0'
103 | use_frameworks!
104 |
105 | pod 'TagCellLayout', '~> 0.3'
106 | ```
107 |
108 | ## Contributing
109 |
110 | Open an issue or send pull request [here](https://github.com/riteshhgupta/TagCellLayout/issues/new).
111 |
112 | ## Licence
113 |
114 | TagCellLayout is available under the MIT license. See the LICENSE file for more info.
115 |
--------------------------------------------------------------------------------
/Source/LayoutAlignment.swift:
--------------------------------------------------------------------------------
1 | //
2 | // LayoutAlignment.swift
3 | // TagCellLayout
4 | //
5 | // Created by Ritesh Gupta on 06/01/18.
6 | // Copyright © 2018 Ritesh. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import UIKit
11 |
12 | public extension TagCellLayout {
13 |
14 | enum LayoutAlignment: Int {
15 |
16 | case left
17 | case center
18 | case right
19 | }
20 | }
21 |
22 | extension TagCellLayout.LayoutAlignment {
23 |
24 | var distributionDivisionFactor: CGFloat {
25 | switch self {
26 | case .center:
27 | return 2
28 | default:
29 | return 1
30 | }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/Source/LayoutInfo.swift:
--------------------------------------------------------------------------------
1 | //
2 | // LayoutInfo.swift
3 | // TagCellLayout
4 | //
5 | // Created by Ritesh Gupta on 06/01/18.
6 | // Copyright © 2018 Ritesh. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import UIKit
11 |
12 | public extension TagCellLayout {
13 |
14 | struct LayoutInfo {
15 |
16 | var layoutAttribute: UICollectionViewLayoutAttributes
17 | var whiteSpace: CGFloat = 0.0
18 | var isFirstElementInARow = false
19 |
20 | init(layoutAttribute: UICollectionViewLayoutAttributes) {
21 | self.layoutAttribute = layoutAttribute
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/Source/TagCellLayout.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TagCellLayout.swift
3 | // TagCellLayout
4 | //
5 | // Created by Ritesh-Gupta on 20/11/15.
6 | // Copyright © 2015 Ritesh. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import UIKit
11 |
12 | public class TagCellLayout: UICollectionViewLayout {
13 |
14 | let alignment: LayoutAlignment
15 |
16 | var layoutInfoList: [LayoutInfo] = []
17 | var numberOfTagsInCurrentRow = 0
18 | var currentTagIndex: Int = 0
19 |
20 |
21 | weak var delegate: TagCellLayoutDelegate?
22 |
23 | //MARK: - Init Methods
24 |
25 | public init(alignment: LayoutAlignment = .left, delegate: TagCellLayoutDelegate?) {
26 | self.delegate = delegate
27 | self.alignment = alignment
28 | super.init()
29 | }
30 |
31 | required public init?(coder aDecoder: NSCoder) {
32 | alignment = .left
33 | super.init(coder: aDecoder)
34 | }
35 |
36 | override convenience init() {
37 | self.init(delegate: nil)
38 | }
39 |
40 | //MARK: - Override Methods
41 |
42 | override public func prepare() {
43 | resetLayoutState()
44 | setupTagCellLayout()
45 | }
46 | public override func layoutAttributesForItem(at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? {
47 | guard layoutInfoList.count > indexPath.row else { return nil }
48 | return layoutInfoList[indexPath.row].layoutAttribute
49 | }
50 |
51 | override public func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
52 | guard !layoutInfoList.isEmpty else { return nil }
53 | return layoutInfoList
54 | .lazy
55 | .map { $0.layoutAttribute }
56 | .filter { rect.intersects($0.frame) }
57 | }
58 |
59 | override public var collectionViewContentSize: CGSize {
60 | let width = collectionViewWidth
61 | let height = layoutInfoList
62 | .filter { $0.isFirstElementInARow }
63 | .reduce(0, { $0 + $1.layoutAttribute.frame.height })
64 | return CGSize(width: width, height: height)
65 | }
66 | }
67 |
68 | //MARK: - Private Methods
69 |
70 | private extension TagCellLayout {
71 |
72 | var currentTagFrame: CGRect {
73 | guard let info = currentTagLayoutInfo?.layoutAttribute else { return .zero }
74 | var frame = info.frame
75 | frame.origin.x += info.bounds.width
76 | return frame
77 | }
78 |
79 | var currentTagLayoutInfo: LayoutInfo? {
80 | let index = max(0, currentTagIndex - 1)
81 | guard layoutInfoList.count > index else { return nil }
82 | return layoutInfoList[index]
83 | }
84 |
85 | var tagsCount: Int {
86 | return collectionView?.numberOfItems(inSection: 0) ?? 0
87 | }
88 |
89 | var collectionViewWidth: CGFloat {
90 | return collectionView?.frame.size.width ?? 0
91 | }
92 |
93 | var isLastRow: Bool {
94 | return currentTagIndex == (tagsCount - 1)
95 | }
96 |
97 | func setupTagCellLayout() {
98 | // delegate and collectionview shouldn't be nil
99 | guard delegate != nil, collectionView != nil else {
100 | // otherwise throwing an error
101 | handleErrorState()
102 | return
103 | }
104 | // basic layout setup which is independent of TagAlignment type
105 | basicLayoutSetup()
106 |
107 | // handle if TagAlignment is other than Left
108 | handleTagAlignment()
109 | }
110 |
111 | func basicLayoutSetup() {
112 | // asking the client for a fixed tag height
113 |
114 | // iterating over every tag and constructing its layout attribute
115 | (0 ..< tagsCount).forEach {
116 | currentTagIndex = $0
117 |
118 | // creating layout and adding it to the dataSource
119 | createLayoutAttributes()
120 |
121 | // configuring white space info || this is later used for .Right or .Center alignment
122 | configureWhiteSpace()
123 |
124 | // processing info for next tag || setting up the coordinates for next tag
125 | configurePositionForNextTag()
126 |
127 | // handling tha layout for last row separately
128 | handleWhiteSpaceForLastRow()
129 | }
130 | }
131 |
132 | func createLayoutAttributes() {
133 | // calculating tag-size
134 | let tagSize = delegate!.tagCellLayoutTagSize(layout: self, atIndex: currentTagIndex)
135 |
136 | let layoutInfo = tagCellLayoutInfo(tagIndex: currentTagIndex, tagSize: tagSize)
137 | layoutInfoList.append(layoutInfo)
138 | }
139 |
140 | func tagCellLayoutInfo(tagIndex: Int, tagSize: CGSize) -> LayoutInfo {
141 | // local data-structure (TagCellLayoutInfo) that has been used in this library to store attribute and white-space info
142 | var isFirstElementInARow = tagIndex == 0
143 | var tagFrame = currentTagFrame
144 | tagFrame.size = tagSize
145 |
146 | // if next tag goes out of screen then move it to next row
147 | if shouldMoveTagToNextRow(tagWidth: tagSize.width) {
148 | tagFrame.origin.x = 0.0
149 | tagFrame.origin.y += currentTagFrame.height
150 | isFirstElementInARow = true
151 | }
152 | let attribute = layoutAttribute(tagIndex: tagIndex, tagFrame: tagFrame)
153 | var info = LayoutInfo(layoutAttribute: attribute)
154 | info.isFirstElementInARow = isFirstElementInARow
155 | return info
156 | }
157 |
158 | func shouldMoveTagToNextRow(tagWidth: CGFloat) -> Bool {
159 | return ((currentTagFrame.origin.x + tagWidth) > collectionViewWidth)
160 | }
161 |
162 | func layoutAttribute(tagIndex: Int, tagFrame: CGRect) -> UICollectionViewLayoutAttributes {
163 | let indexPath = IndexPath(item: tagIndex, section: 0)
164 | let layoutAttribute = UICollectionViewLayoutAttributes(forCellWith: indexPath)
165 | layoutAttribute.frame = tagFrame
166 | return layoutAttribute
167 | }
168 |
169 | func configureWhiteSpace() {
170 | let layoutInfo = layoutInfoList[currentTagIndex].layoutAttribute
171 | let tagWidth = layoutInfo.frame.size.width
172 | if shouldMoveTagToNextRow(tagWidth: tagWidth) {
173 | applyWhiteSpace(startingIndex: (currentTagIndex - 1))
174 | }
175 | }
176 |
177 | func applyWhiteSpace(startingIndex: Int) {
178 | let lastIndex = startingIndex - numberOfTagsInCurrentRow
179 | let whiteSpace = calculateWhiteSpace(tagIndex: startingIndex)
180 |
181 | for tagIndex in (lastIndex+1) ..< (startingIndex+1) {
182 | insertWhiteSpace(tagIndex: tagIndex, whiteSpace: whiteSpace)
183 | }
184 | }
185 |
186 | func calculateWhiteSpace(tagIndex: Int) -> CGFloat {
187 | let tagFrame = tagFrameForIndex(tagIndex: tagIndex)
188 | let whiteSpace = collectionViewWidth - (tagFrame.origin.x + tagFrame.size.width)
189 | return whiteSpace
190 | }
191 |
192 | func insertWhiteSpace(tagIndex: Int, whiteSpace: CGFloat) {
193 | var info = layoutInfoList[tagIndex]
194 | let factor = alignment.distributionDivisionFactor
195 | info.whiteSpace = whiteSpace/factor
196 | layoutInfoList[tagIndex] = info
197 | }
198 |
199 | func tagFrameForIndex(tagIndex: Int) -> CGRect {
200 | let tagFrame = tagIndex > -1 ? layoutInfoList[tagIndex].layoutAttribute.frame : .zero
201 | return tagFrame
202 | }
203 |
204 | func configurePositionForNextTag() {
205 | let layoutInfo = layoutInfoList[currentTagIndex].layoutAttribute
206 | let moveTag = shouldMoveTagToNextRow(tagWidth: layoutInfo.frame.size.width)
207 | numberOfTagsInCurrentRow = moveTag ? 1 : (numberOfTagsInCurrentRow + 1)
208 | }
209 |
210 | func handleTagAlignment() {
211 | guard alignment != .left else { return }
212 | let tagsCount = collectionView!.numberOfItems(inSection: 0)
213 | for tagIndex in 0 ..< tagsCount {
214 | var tagFrame = layoutInfoList[tagIndex].layoutAttribute.frame
215 | let whiteSpace = layoutInfoList[tagIndex].whiteSpace
216 | tagFrame.origin.x += whiteSpace
217 | let tagAttribute = layoutAttribute(tagIndex: tagIndex, tagFrame: tagFrame)
218 | layoutInfoList[tagIndex].layoutAttribute = tagAttribute
219 | }
220 | }
221 |
222 | func handleWhiteSpaceForLastRow() {
223 | guard isLastRow else { return }
224 | applyWhiteSpace(startingIndex: (tagsCount-1))
225 | }
226 |
227 | func handleErrorState() {
228 | print("TagCollectionViewCellLayout is not properly configured")
229 | }
230 |
231 | func resetLayoutState() {
232 | layoutInfoList = Array()
233 | numberOfTagsInCurrentRow = 0
234 | }
235 | }
236 |
--------------------------------------------------------------------------------
/Source/TagCellLayoutDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TagCellLayoutDelegate.swift
3 | // TagCellLayout
4 | //
5 | // Created by Ritesh Gupta on 06/01/18.
6 | // Copyright © 2018 Ritesh. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import UIKit
11 |
12 | public protocol TagCellLayoutDelegate: NSObjectProtocol {
13 |
14 | func tagCellLayoutTagSize(layout: TagCellLayout, atIndex index:Int) -> CGSize
15 | }
16 |
--------------------------------------------------------------------------------
/TagCellLayout.podspec:
--------------------------------------------------------------------------------
1 | Pod::Spec.new do |spec|
2 | spec.name = 'TagCellLayout'
3 | spec.version = '1.0'
4 | spec.summary = 'Tag layout for UICollectoionView supporting 3 types of alignments - Left || Centre || Right'
5 | spec.author = {
6 | 'Ritesh Gupta' => 'rg.riteshh@gmail.com'
7 | }
8 | spec.license = 'MIT'
9 | spec.homepage = 'https://github.com/riteshhgupta/TagCellLayout'
10 | spec.source = {
11 | :git => 'https://github.com/riteshhgupta/TagCellLayout.git',
12 | :tag => '1.0'
13 | }
14 | spec.ios.deployment_target = "8.0"
15 | spec.source_files = 'Source/*.{swift}'
16 | spec.requires_arc = true
17 | end
18 |
--------------------------------------------------------------------------------
/TagCellLayout.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 3D9228F720009CE000CD120C /* TagCellLayoutDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D9228F620009CE000CD120C /* TagCellLayoutDelegate.swift */; };
11 | 3D9228F920009D0900CD120C /* LayoutAlignment.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D9228F820009D0900CD120C /* LayoutAlignment.swift */; };
12 | 3D9228FB2000A32C00CD120C /* LayoutInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D9228FA2000A32C00CD120C /* LayoutInfo.swift */; };
13 | 3DF12F161BFF4107001B6902 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3DF12F151BFF4107001B6902 /* AppDelegate.swift */; };
14 | 3DF12F181BFF4107001B6902 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3DF12F171BFF4107001B6902 /* ViewController.swift */; };
15 | 3DF12F1B1BFF4107001B6902 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 3DF12F191BFF4107001B6902 /* Main.storyboard */; };
16 | 3DF12F1D1BFF4107001B6902 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 3DF12F1C1BFF4107001B6902 /* Assets.xcassets */; };
17 | 3DF12F201BFF4107001B6902 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 3DF12F1E1BFF4107001B6902 /* LaunchScreen.storyboard */; };
18 | 3DF12F281BFF4372001B6902 /* TagCellLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3DF12F271BFF4372001B6902 /* TagCellLayout.swift */; };
19 | 3DF12F2D1BFF45EC001B6902 /* TagCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3DF12F2C1BFF45EB001B6902 /* TagCollectionViewCell.swift */; };
20 | 3DF12F2F1BFF461E001B6902 /* TagCollectionViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 3DF12F2E1BFF461E001B6902 /* TagCollectionViewCell.xib */; };
21 | /* End PBXBuildFile section */
22 |
23 | /* Begin PBXFileReference section */
24 | 3D9228F620009CE000CD120C /* TagCellLayoutDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = TagCellLayoutDelegate.swift; path = Source/TagCellLayoutDelegate.swift; sourceTree = SOURCE_ROOT; };
25 | 3D9228F820009D0900CD120C /* LayoutAlignment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = LayoutAlignment.swift; path = Source/LayoutAlignment.swift; sourceTree = SOURCE_ROOT; };
26 | 3D9228FA2000A32C00CD120C /* LayoutInfo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = LayoutInfo.swift; path = Source/LayoutInfo.swift; sourceTree = SOURCE_ROOT; };
27 | 3DF12F121BFF4107001B6902 /* TagCellLayout.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = TagCellLayout.app; sourceTree = BUILT_PRODUCTS_DIR; };
28 | 3DF12F151BFF4107001B6902 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
29 | 3DF12F171BFF4107001B6902 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; };
30 | 3DF12F1A1BFF4107001B6902 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
31 | 3DF12F1C1BFF4107001B6902 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
32 | 3DF12F1F1BFF4107001B6902 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; };
33 | 3DF12F211BFF4107001B6902 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
34 | 3DF12F271BFF4372001B6902 /* TagCellLayout.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = TagCellLayout.swift; path = Source/TagCellLayout.swift; sourceTree = SOURCE_ROOT; };
35 | 3DF12F2C1BFF45EB001B6902 /* TagCollectionViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TagCollectionViewCell.swift; sourceTree = ""; };
36 | 3DF12F2E1BFF461E001B6902 /* TagCollectionViewCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = TagCollectionViewCell.xib; sourceTree = ""; };
37 | /* End PBXFileReference section */
38 |
39 | /* Begin PBXFrameworksBuildPhase section */
40 | 3DF12F0F1BFF4107001B6902 /* Frameworks */ = {
41 | isa = PBXFrameworksBuildPhase;
42 | buildActionMask = 2147483647;
43 | files = (
44 | );
45 | runOnlyForDeploymentPostprocessing = 0;
46 | };
47 | /* End PBXFrameworksBuildPhase section */
48 |
49 | /* Begin PBXGroup section */
50 | 3DF12F091BFF4107001B6902 = {
51 | isa = PBXGroup;
52 | children = (
53 | 3DF12F291BFF437E001B6902 /* Source */,
54 | 3DF12F141BFF4107001B6902 /* TagCellLayout */,
55 | 3DF12F131BFF4107001B6902 /* Products */,
56 | );
57 | sourceTree = "";
58 | };
59 | 3DF12F131BFF4107001B6902 /* Products */ = {
60 | isa = PBXGroup;
61 | children = (
62 | 3DF12F121BFF4107001B6902 /* TagCellLayout.app */,
63 | );
64 | name = Products;
65 | sourceTree = "";
66 | };
67 | 3DF12F141BFF4107001B6902 /* TagCellLayout */ = {
68 | isa = PBXGroup;
69 | children = (
70 | 3DF12F151BFF4107001B6902 /* AppDelegate.swift */,
71 | 3DF12F171BFF4107001B6902 /* ViewController.swift */,
72 | 3DF12F2C1BFF45EB001B6902 /* TagCollectionViewCell.swift */,
73 | 3DF12F2E1BFF461E001B6902 /* TagCollectionViewCell.xib */,
74 | 3DF12F191BFF4107001B6902 /* Main.storyboard */,
75 | 3DF12F1C1BFF4107001B6902 /* Assets.xcassets */,
76 | 3DF12F1E1BFF4107001B6902 /* LaunchScreen.storyboard */,
77 | 3DF12F211BFF4107001B6902 /* Info.plist */,
78 | );
79 | path = TagCellLayout;
80 | sourceTree = "";
81 | };
82 | 3DF12F291BFF437E001B6902 /* Source */ = {
83 | isa = PBXGroup;
84 | children = (
85 | 3DF12F271BFF4372001B6902 /* TagCellLayout.swift */,
86 | 3D9228F620009CE000CD120C /* TagCellLayoutDelegate.swift */,
87 | 3D9228F820009D0900CD120C /* LayoutAlignment.swift */,
88 | 3D9228FA2000A32C00CD120C /* LayoutInfo.swift */,
89 | );
90 | name = Source;
91 | path = TagCellLayout;
92 | sourceTree = "";
93 | };
94 | /* End PBXGroup section */
95 |
96 | /* Begin PBXNativeTarget section */
97 | 3DF12F111BFF4107001B6902 /* TagCellLayout */ = {
98 | isa = PBXNativeTarget;
99 | buildConfigurationList = 3DF12F241BFF4107001B6902 /* Build configuration list for PBXNativeTarget "TagCellLayout" */;
100 | buildPhases = (
101 | 3DF12F0E1BFF4107001B6902 /* Sources */,
102 | 3DF12F0F1BFF4107001B6902 /* Frameworks */,
103 | 3DF12F101BFF4107001B6902 /* Resources */,
104 | );
105 | buildRules = (
106 | );
107 | dependencies = (
108 | );
109 | name = TagCellLayout;
110 | productName = TagCellLayout;
111 | productReference = 3DF12F121BFF4107001B6902 /* TagCellLayout.app */;
112 | productType = "com.apple.product-type.application";
113 | };
114 | /* End PBXNativeTarget section */
115 |
116 | /* Begin PBXProject section */
117 | 3DF12F0A1BFF4107001B6902 /* Project object */ = {
118 | isa = PBXProject;
119 | attributes = {
120 | LastSwiftUpdateCheck = 0710;
121 | LastUpgradeCheck = 0920;
122 | ORGANIZATIONNAME = Ritesh;
123 | TargetAttributes = {
124 | 3DF12F111BFF4107001B6902 = {
125 | CreatedOnToolsVersion = 7.1;
126 | DevelopmentTeam = G436LJ5F52;
127 | ProvisioningStyle = Automatic;
128 | };
129 | };
130 | };
131 | buildConfigurationList = 3DF12F0D1BFF4107001B6902 /* Build configuration list for PBXProject "TagCellLayout" */;
132 | compatibilityVersion = "Xcode 3.2";
133 | developmentRegion = English;
134 | hasScannedForEncodings = 0;
135 | knownRegions = (
136 | en,
137 | Base,
138 | );
139 | mainGroup = 3DF12F091BFF4107001B6902;
140 | productRefGroup = 3DF12F131BFF4107001B6902 /* Products */;
141 | projectDirPath = "";
142 | projectRoot = "";
143 | targets = (
144 | 3DF12F111BFF4107001B6902 /* TagCellLayout */,
145 | );
146 | };
147 | /* End PBXProject section */
148 |
149 | /* Begin PBXResourcesBuildPhase section */
150 | 3DF12F101BFF4107001B6902 /* Resources */ = {
151 | isa = PBXResourcesBuildPhase;
152 | buildActionMask = 2147483647;
153 | files = (
154 | 3DF12F201BFF4107001B6902 /* LaunchScreen.storyboard in Resources */,
155 | 3DF12F2F1BFF461E001B6902 /* TagCollectionViewCell.xib in Resources */,
156 | 3DF12F1D1BFF4107001B6902 /* Assets.xcassets in Resources */,
157 | 3DF12F1B1BFF4107001B6902 /* Main.storyboard in Resources */,
158 | );
159 | runOnlyForDeploymentPostprocessing = 0;
160 | };
161 | /* End PBXResourcesBuildPhase section */
162 |
163 | /* Begin PBXSourcesBuildPhase section */
164 | 3DF12F0E1BFF4107001B6902 /* Sources */ = {
165 | isa = PBXSourcesBuildPhase;
166 | buildActionMask = 2147483647;
167 | files = (
168 | 3D9228F920009D0900CD120C /* LayoutAlignment.swift in Sources */,
169 | 3DF12F181BFF4107001B6902 /* ViewController.swift in Sources */,
170 | 3D9228FB2000A32C00CD120C /* LayoutInfo.swift in Sources */,
171 | 3D9228F720009CE000CD120C /* TagCellLayoutDelegate.swift in Sources */,
172 | 3DF12F161BFF4107001B6902 /* AppDelegate.swift in Sources */,
173 | 3DF12F2D1BFF45EC001B6902 /* TagCollectionViewCell.swift in Sources */,
174 | 3DF12F281BFF4372001B6902 /* TagCellLayout.swift in Sources */,
175 | );
176 | runOnlyForDeploymentPostprocessing = 0;
177 | };
178 | /* End PBXSourcesBuildPhase section */
179 |
180 | /* Begin PBXVariantGroup section */
181 | 3DF12F191BFF4107001B6902 /* Main.storyboard */ = {
182 | isa = PBXVariantGroup;
183 | children = (
184 | 3DF12F1A1BFF4107001B6902 /* Base */,
185 | );
186 | name = Main.storyboard;
187 | sourceTree = "";
188 | };
189 | 3DF12F1E1BFF4107001B6902 /* LaunchScreen.storyboard */ = {
190 | isa = PBXVariantGroup;
191 | children = (
192 | 3DF12F1F1BFF4107001B6902 /* Base */,
193 | );
194 | name = LaunchScreen.storyboard;
195 | sourceTree = "";
196 | };
197 | /* End PBXVariantGroup section */
198 |
199 | /* Begin XCBuildConfiguration section */
200 | 3DF12F221BFF4107001B6902 /* Debug */ = {
201 | isa = XCBuildConfiguration;
202 | buildSettings = {
203 | ALWAYS_SEARCH_USER_PATHS = NO;
204 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
205 | CLANG_CXX_LIBRARY = "libc++";
206 | CLANG_ENABLE_MODULES = YES;
207 | CLANG_ENABLE_OBJC_ARC = YES;
208 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
209 | CLANG_WARN_BOOL_CONVERSION = YES;
210 | CLANG_WARN_COMMA = YES;
211 | CLANG_WARN_CONSTANT_CONVERSION = YES;
212 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
213 | CLANG_WARN_EMPTY_BODY = YES;
214 | CLANG_WARN_ENUM_CONVERSION = YES;
215 | CLANG_WARN_INFINITE_RECURSION = YES;
216 | CLANG_WARN_INT_CONVERSION = YES;
217 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
218 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
219 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
220 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
221 | CLANG_WARN_STRICT_PROTOTYPES = YES;
222 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
223 | CLANG_WARN_UNREACHABLE_CODE = YES;
224 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
225 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
226 | COPY_PHASE_STRIP = NO;
227 | DEBUG_INFORMATION_FORMAT = dwarf;
228 | ENABLE_STRICT_OBJC_MSGSEND = YES;
229 | ENABLE_TESTABILITY = YES;
230 | GCC_C_LANGUAGE_STANDARD = gnu99;
231 | GCC_DYNAMIC_NO_PIC = NO;
232 | GCC_NO_COMMON_BLOCKS = YES;
233 | GCC_OPTIMIZATION_LEVEL = 0;
234 | GCC_PREPROCESSOR_DEFINITIONS = (
235 | "DEBUG=1",
236 | "$(inherited)",
237 | );
238 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
239 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
240 | GCC_WARN_UNDECLARED_SELECTOR = YES;
241 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
242 | GCC_WARN_UNUSED_FUNCTION = YES;
243 | GCC_WARN_UNUSED_VARIABLE = YES;
244 | IPHONEOS_DEPLOYMENT_TARGET = 9.1;
245 | MTL_ENABLE_DEBUG_INFO = YES;
246 | ONLY_ACTIVE_ARCH = YES;
247 | SDKROOT = iphoneos;
248 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
249 | };
250 | name = Debug;
251 | };
252 | 3DF12F231BFF4107001B6902 /* Release */ = {
253 | isa = XCBuildConfiguration;
254 | buildSettings = {
255 | ALWAYS_SEARCH_USER_PATHS = NO;
256 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
257 | CLANG_CXX_LIBRARY = "libc++";
258 | CLANG_ENABLE_MODULES = YES;
259 | CLANG_ENABLE_OBJC_ARC = YES;
260 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
261 | CLANG_WARN_BOOL_CONVERSION = YES;
262 | CLANG_WARN_COMMA = YES;
263 | CLANG_WARN_CONSTANT_CONVERSION = YES;
264 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
265 | CLANG_WARN_EMPTY_BODY = YES;
266 | CLANG_WARN_ENUM_CONVERSION = YES;
267 | CLANG_WARN_INFINITE_RECURSION = YES;
268 | CLANG_WARN_INT_CONVERSION = YES;
269 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
270 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
271 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
272 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
273 | CLANG_WARN_STRICT_PROTOTYPES = YES;
274 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
275 | CLANG_WARN_UNREACHABLE_CODE = YES;
276 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
277 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
278 | COPY_PHASE_STRIP = NO;
279 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
280 | ENABLE_NS_ASSERTIONS = NO;
281 | ENABLE_STRICT_OBJC_MSGSEND = YES;
282 | GCC_C_LANGUAGE_STANDARD = gnu99;
283 | GCC_NO_COMMON_BLOCKS = YES;
284 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
285 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
286 | GCC_WARN_UNDECLARED_SELECTOR = YES;
287 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
288 | GCC_WARN_UNUSED_FUNCTION = YES;
289 | GCC_WARN_UNUSED_VARIABLE = YES;
290 | IPHONEOS_DEPLOYMENT_TARGET = 9.1;
291 | MTL_ENABLE_DEBUG_INFO = NO;
292 | SDKROOT = iphoneos;
293 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
294 | VALIDATE_PRODUCT = YES;
295 | };
296 | name = Release;
297 | };
298 | 3DF12F251BFF4107001B6902 /* Debug */ = {
299 | isa = XCBuildConfiguration;
300 | buildSettings = {
301 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
302 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
303 | CODE_SIGN_STYLE = Automatic;
304 | DEVELOPMENT_TEAM = G436LJ5F52;
305 | INFOPLIST_FILE = TagCellLayout/Info.plist;
306 | IPHONEOS_DEPLOYMENT_TARGET = 8.0;
307 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
308 | PRODUCT_BUNDLE_IDENTIFIER = com.Ritesh.TagCellLayout;
309 | PRODUCT_NAME = "$(TARGET_NAME)";
310 | PROVISIONING_PROFILE = "";
311 | PROVISIONING_PROFILE_SPECIFIER = "";
312 | SWIFT_VERSION = 4.0;
313 | };
314 | name = Debug;
315 | };
316 | 3DF12F261BFF4107001B6902 /* Release */ = {
317 | isa = XCBuildConfiguration;
318 | buildSettings = {
319 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
320 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
321 | CODE_SIGN_STYLE = Automatic;
322 | DEVELOPMENT_TEAM = G436LJ5F52;
323 | INFOPLIST_FILE = TagCellLayout/Info.plist;
324 | IPHONEOS_DEPLOYMENT_TARGET = 8.0;
325 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
326 | PRODUCT_BUNDLE_IDENTIFIER = com.Ritesh.TagCellLayout;
327 | PRODUCT_NAME = "$(TARGET_NAME)";
328 | PROVISIONING_PROFILE = "";
329 | PROVISIONING_PROFILE_SPECIFIER = "";
330 | SWIFT_VERSION = 4.0;
331 | };
332 | name = Release;
333 | };
334 | /* End XCBuildConfiguration section */
335 |
336 | /* Begin XCConfigurationList section */
337 | 3DF12F0D1BFF4107001B6902 /* Build configuration list for PBXProject "TagCellLayout" */ = {
338 | isa = XCConfigurationList;
339 | buildConfigurations = (
340 | 3DF12F221BFF4107001B6902 /* Debug */,
341 | 3DF12F231BFF4107001B6902 /* Release */,
342 | );
343 | defaultConfigurationIsVisible = 0;
344 | defaultConfigurationName = Release;
345 | };
346 | 3DF12F241BFF4107001B6902 /* Build configuration list for PBXNativeTarget "TagCellLayout" */ = {
347 | isa = XCConfigurationList;
348 | buildConfigurations = (
349 | 3DF12F251BFF4107001B6902 /* Debug */,
350 | 3DF12F261BFF4107001B6902 /* Release */,
351 | );
352 | defaultConfigurationIsVisible = 0;
353 | defaultConfigurationName = Release;
354 | };
355 | /* End XCConfigurationList section */
356 | };
357 | rootObject = 3DF12F0A1BFF4107001B6902 /* Project object */;
358 | }
359 |
--------------------------------------------------------------------------------
/TagCellLayout.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/TagCellLayout.xcodeproj/xcshareddata/xcschemes/TagCellLayout.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
31 |
32 |
33 |
34 |
40 |
41 |
42 |
43 |
44 |
45 |
56 |
58 |
64 |
65 |
66 |
67 |
68 |
69 |
75 |
77 |
83 |
84 |
85 |
86 |
88 |
89 |
92 |
93 |
94 |
--------------------------------------------------------------------------------
/TagCellLayout.xcodeproj/xcuserdata/riteshgupta.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
--------------------------------------------------------------------------------
/TagCellLayout.xcodeproj/xcuserdata/riteshgupta.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | TagCellLayout.xcscheme_^#shared#^_
8 |
9 | orderHint
10 | 0
11 |
12 |
13 | SuppressBuildableAutocreation
14 |
15 | 3DF12F111BFF4107001B6902
16 |
17 | primary
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/TagCellLayout/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // TagCellLayout
4 | //
5 | // Created by Ritesh-Gupta on 20/11/15.
6 | // Copyright © 2015 Ritesh. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | @UIApplicationMain
12 | class AppDelegate: UIResponder, UIApplicationDelegate {
13 |
14 | var window: UIWindow?
15 | }
16 |
17 |
--------------------------------------------------------------------------------
/TagCellLayout/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "29x29",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "29x29",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "40x40",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "40x40",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "60x60",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "60x60",
31 | "scale" : "3x"
32 | }
33 | ],
34 | "info" : {
35 | "version" : 1,
36 | "author" : "xcode"
37 | }
38 | }
--------------------------------------------------------------------------------
/TagCellLayout/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/TagCellLayout/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 |
--------------------------------------------------------------------------------
/TagCellLayout/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 | LSRequiresIPhoneOS
24 |
25 | UILaunchStoryboardName
26 | LaunchScreen
27 | UIMainStoryboardFile
28 | Main
29 | UIRequiredDeviceCapabilities
30 |
31 | armv7
32 |
33 | UISupportedInterfaceOrientations
34 |
35 | UIInterfaceOrientationPortrait
36 | UIInterfaceOrientationLandscapeLeft
37 | UIInterfaceOrientationLandscapeRight
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/TagCellLayout/Readme_Resources/tag_cc.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/riteshhgupta/TagCellLayout/ffd3413e6af94807b21e04947014eb36aa17f375/TagCellLayout/Readme_Resources/tag_cc.png
--------------------------------------------------------------------------------
/TagCellLayout/Readme_Resources/tag_ll.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/riteshhgupta/TagCellLayout/ffd3413e6af94807b21e04947014eb36aa17f375/TagCellLayout/Readme_Resources/tag_ll.png
--------------------------------------------------------------------------------
/TagCellLayout/Readme_Resources/tag_rr.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/riteshhgupta/TagCellLayout/ffd3413e6af94807b21e04947014eb36aa17f375/TagCellLayout/Readme_Resources/tag_rr.png
--------------------------------------------------------------------------------
/TagCellLayout/TagCollectionViewCell.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TagCollectionViewCell.swift
3 | // TagCellLayout
4 | //
5 | // Created by Ritesh-Gupta on 20/11/15.
6 | // Copyright © 2015 Ritesh. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import UIKit
11 |
12 | class TagCollectionViewCell: UICollectionViewCell {
13 |
14 | @IBOutlet weak var tagView: UILabel?
15 |
16 | override func awakeFromNib() {
17 | if let tagView = tagView {
18 | tagView.layer.cornerRadius = tagView.frame.size.height/2 - 2
19 | tagView.layer.borderColor = UIColor.blue.cgColor
20 | tagView.layer.borderWidth = 3.0
21 | }
22 | }
23 |
24 | func configure(with text: String) {
25 | tagView?.text = text
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/TagCellLayout/TagCollectionViewCell.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/TagCellLayout/ViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.swift
3 | // TagCellLayout
4 | //
5 | // Created by Ritesh-Gupta on 20/11/15.
6 | // Copyright © 2015 Ritesh. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class ViewController: UIViewController {
12 |
13 | @IBOutlet weak var collectionView: UICollectionView?
14 |
15 | var longString = "start ––– Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. ––– end"
16 |
17 | var oneLineHeight: CGFloat {
18 | return 54.0
19 | }
20 |
21 | var longTagIndex: Int {
22 | return 1
23 | }
24 |
25 | override func viewDidLoad() {
26 | super.viewDidLoad()
27 | // Do any additional setup after loading the view, typically from a nib.
28 | }
29 |
30 | override func viewDidAppear(_ animated: Bool) {
31 | super.viewDidAppear(animated)
32 | defaultSetup()
33 |
34 | // THIS IS ALL WHAT IS REQUIRED TO SETUP YOUR TAGS
35 |
36 | let tagCellLayout = TagCellLayout(alignment: .center, delegate: self)
37 | collectionView?.collectionViewLayout = tagCellLayout
38 | }
39 |
40 | //MARK: - Default Methods
41 |
42 | func defaultSetup() {
43 | let nib = UINib(nibName: "TagCollectionViewCell", bundle: nil)
44 | collectionView?.register(nib, forCellWithReuseIdentifier: "TagCollectionViewCell")
45 | }
46 | }
47 |
48 | extension ViewController: UICollectionViewDelegate, UICollectionViewDataSource {
49 |
50 | //MARK: - UICollectionView Delegate/Datasource Methods
51 |
52 | func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
53 | let identifier = "TagCollectionViewCell"
54 | let cell = collectionView.dequeueReusableCell(withReuseIdentifier: identifier, for: indexPath) as! TagCollectionViewCell
55 | if indexPath.row == longTagIndex || indexPath.row == (longTagIndex + 3) {
56 | cell.configure(with: longString)
57 | } else {
58 | cell.configure(with: "Tags")
59 | }
60 | return cell
61 | }
62 |
63 | func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
64 | return 1
65 | }
66 |
67 | func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
68 | return 10
69 | }
70 | }
71 |
72 | extension ViewController: TagCellLayoutDelegate {
73 |
74 | func tagCellLayoutTagSize(layout: TagCellLayout, atIndex index: Int) -> CGSize {
75 | if index == longTagIndex || index == (longTagIndex + 3) {
76 | var s = textSize(text: longString, font: UIFont.systemFont(ofSize: 17.0), collectionView: collectionView!)
77 | s.height += 8.0
78 | return s
79 | } else {
80 | let width = CGFloat(index % 2 == 0 ? 80 : 120)
81 | return CGSize(width: width, height: oneLineHeight)
82 | }
83 | }
84 | }
85 |
86 | extension ViewController {
87 |
88 | func textSize(text: String, font: UIFont, collectionView: UICollectionView) -> CGSize {
89 | var f = collectionView.bounds
90 | f.size.height = 9999.0
91 | let label = UILabel()
92 | label.numberOfLines = 0
93 | label.text = text
94 | label.font = font
95 | var s = label.sizeThatFits(f.size)
96 | s.height = max(oneLineHeight, s.height)
97 | return s
98 | }
99 | }
100 |
--------------------------------------------------------------------------------