├── .gitignore
├── .swiftpm
└── xcode
│ └── package.xcworkspace
│ └── contents.xcworkspacedata
├── Assets
├── 01.gif
├── 02.gif
├── 03.gif
├── 04.gif
├── 05.gif
├── 06.gif
├── 07.gif
├── 08.gif
└── 09.gif
├── Demo
├── GridCompositionalView.xcodeproj
│ ├── project.pbxproj
│ ├── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ │ └── IDEWorkspaceChecks.plist
│ └── xcshareddata
│ │ └── xcschemes
│ │ ├── iOS.xcscheme
│ │ └── macOS.xcscheme
├── Shared
│ ├── Assets.xcassets
│ │ ├── AccentColor.colorset
│ │ │ └── Contents.json
│ │ ├── AppIcon.appiconset
│ │ │ └── Contents.json
│ │ └── Contents.json
│ ├── Comics.xcassets
│ │ ├── 1-1.imageset
│ │ │ ├── 6796934.jpg
│ │ │ └── Contents.json
│ │ ├── 1-10.imageset
│ │ │ ├── Contents.json
│ │ │ └── images.jpeg
│ │ ├── 1-11.imageset
│ │ │ ├── Contents.json
│ │ │ └── batman-the-killing-joke-u4.jpeg
│ │ ├── 1-12.imageset
│ │ │ ├── Contents.json
│ │ │ └── spider-man-1-cover-117628.jpg
│ │ ├── 1-13.imageset
│ │ │ ├── Contents.json
│ │ │ └── Wonder_Woman_Vol_4_36.jpg
│ │ ├── 1-14.imageset
│ │ │ ├── Contents.json
│ │ │ └── hulk-181-comic-book-series-photo-u1.jpeg
│ │ ├── 1-15.imageset
│ │ │ ├── Contents.json
│ │ │ └── hulk-340-comic-book-series-photo-u1.jpeg
│ │ ├── 1-16.imageset
│ │ │ ├── Contents.json
│ │ │ └── e6dae1633d136653126297a89be83f29.jpg
│ │ ├── 1-17.imageset
│ │ │ ├── Contents.json
│ │ │ └── spider-man-vol-2-1-comic-book-series-photo-u1.jpeg
│ │ ├── 1-18.imageset
│ │ │ ├── Contents.json
│ │ │ └── superman-75-comic-book-series-photo-u1.jpeg
│ │ ├── 1-19.imageset
│ │ │ ├── Contents.json
│ │ │ └── uncanny-x-men-101-comic-book-series-photo-u1.jpeg
│ │ ├── 1-2.imageset
│ │ │ ├── Contents.json
│ │ │ └── amazing-fantasy-15-comic-book-series-photo-u1.jpeg
│ │ ├── 1-20.imageset
│ │ │ ├── Contents.json
│ │ │ └── wonder-woman-72-comic-book-series-photo-u1.jpeg
│ │ ├── 1-3.imageset
│ │ │ ├── Contents.json
│ │ │ └── amazing-spider-man-1-comic-book-series-photo-u1.jpeg
│ │ ├── 1-4.imageset
│ │ │ ├── Contents.json
│ │ │ └── amazing-spider-man-39-comic-book-series-photo-u1.jpeg
│ │ ├── 1-5.imageset
│ │ │ ├── Contents.json
│ │ │ └── amazing-spider-man-300-comic-book-series-photo-u1.jpeg
│ │ ├── 1-6.imageset
│ │ │ ├── Contents.json
│ │ │ └── c29c90b3881385de5042597cfcfc3d7b.jpg
│ │ ├── 1-7.imageset
│ │ │ ├── Contents.json
│ │ │ └── batman-404-comic-book-series-photo-u1.jpeg
│ │ ├── 1-8.imageset
│ │ │ ├── Contents.json
│ │ │ └── Wonder_Woman_Vol_4_45.jpg
│ │ ├── 1-9.imageset
│ │ │ ├── Contents.json
│ │ │ └── batman-harley-quinn-comic-book-series-photo-u1.jpeg
│ │ └── Contents.json
│ ├── ComicsData.plist
│ ├── Data Model
│ │ ├── Comics.swift
│ │ ├── ComicsLoader.swift
│ │ └── ComicsManager.swift
│ └── EntryApp.swift
├── Tests iOS
│ ├── Info.plist
│ └── Tests_iOS.swift
├── Tests macOS
│ ├── Info.plist
│ └── Tests_macOS.swift
├── iOS
│ └── Info.plist
└── macOS
│ ├── Info.plist
│ └── macOS.entitlements
├── LICENSE
├── Package.swift
├── README.md
├── Sources
└── GridCompositionalLayout
│ ├── CompositionalGridLayout.swift
│ ├── GridCompositionalLayout.swift
│ └── IndexManager.swift
├── Tests
├── GridCompositionalLayoutTests
│ ├── GridCompositionalLayoutTests.swift
│ └── XCTestManifests.swift
└── LinuxMain.swift
└── logo.jpg
/.gitignore:
--------------------------------------------------------------------------------
1 | ## OS X Finder
2 | .DS_Store
3 |
4 | ## Build generated
5 | build/
6 | DerivedData
7 |
8 | ## Various settings
9 | *.pbxuser
10 | !default.pbxuser
11 | *.mode1v3
12 | !default.mode1v3
13 | *.mode2v3
14 | !default.mode2v3
15 | *.perspectivev3
16 | !default.perspectivev3
17 | xcuserdata
18 |
19 | ## Other
20 | *.xccheckout
21 | *.moved-aside
22 | *.xcuserstate
23 | *.xcscmblueprint
24 |
25 | ## Obj-C/Swift specific
26 | *.hmap
27 | *.ipa
28 |
29 | # Swift Package Manager
30 | .build/
31 |
32 | # Carthage
33 | Carthage/Build
34 |
--------------------------------------------------------------------------------
/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Assets/01.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eleev/grid-compositional-layout/831e171557ac1bf10de30fb8238e3830fde9adcb/Assets/01.gif
--------------------------------------------------------------------------------
/Assets/02.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eleev/grid-compositional-layout/831e171557ac1bf10de30fb8238e3830fde9adcb/Assets/02.gif
--------------------------------------------------------------------------------
/Assets/03.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eleev/grid-compositional-layout/831e171557ac1bf10de30fb8238e3830fde9adcb/Assets/03.gif
--------------------------------------------------------------------------------
/Assets/04.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eleev/grid-compositional-layout/831e171557ac1bf10de30fb8238e3830fde9adcb/Assets/04.gif
--------------------------------------------------------------------------------
/Assets/05.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eleev/grid-compositional-layout/831e171557ac1bf10de30fb8238e3830fde9adcb/Assets/05.gif
--------------------------------------------------------------------------------
/Assets/06.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eleev/grid-compositional-layout/831e171557ac1bf10de30fb8238e3830fde9adcb/Assets/06.gif
--------------------------------------------------------------------------------
/Assets/07.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eleev/grid-compositional-layout/831e171557ac1bf10de30fb8238e3830fde9adcb/Assets/07.gif
--------------------------------------------------------------------------------
/Assets/08.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eleev/grid-compositional-layout/831e171557ac1bf10de30fb8238e3830fde9adcb/Assets/08.gif
--------------------------------------------------------------------------------
/Assets/09.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eleev/grid-compositional-layout/831e171557ac1bf10de30fb8238e3830fde9adcb/Assets/09.gif
--------------------------------------------------------------------------------
/Demo/GridCompositionalView.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 52;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | A94CDEE624A7615D00688A3D /* GridCompositionalLayout in Frameworks */ = {isa = PBXBuildFile; productRef = A94CDEE524A7615D00688A3D /* GridCompositionalLayout */; };
11 | A94CDEE824A7616200688A3D /* GridCompositionalLayout in Frameworks */ = {isa = PBXBuildFile; productRef = A94CDEE724A7616200688A3D /* GridCompositionalLayout */; };
12 | A97DAF7724A36F4C00918952 /* Tests_iOS.swift in Sources */ = {isa = PBXBuildFile; fileRef = A97DAF7624A36F4C00918952 /* Tests_iOS.swift */; };
13 | A97DAF8224A36F4C00918952 /* Tests_macOS.swift in Sources */ = {isa = PBXBuildFile; fileRef = A97DAF8124A36F4C00918952 /* Tests_macOS.swift */; };
14 | A97DAF8424A36F4C00918952 /* EntryApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = A97DAF5B24A36F4B00918952 /* EntryApp.swift */; };
15 | A97DAF8524A36F4C00918952 /* EntryApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = A97DAF5B24A36F4B00918952 /* EntryApp.swift */; };
16 | A97DAF8824A36F4C00918952 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = A97DAF5D24A36F4B00918952 /* Assets.xcassets */; };
17 | A97DAF8924A36F4C00918952 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = A97DAF5D24A36F4B00918952 /* Assets.xcassets */; };
18 | A97DAF9E24A370C900918952 /* Comics.swift in Sources */ = {isa = PBXBuildFile; fileRef = A97DAF9D24A370C900918952 /* Comics.swift */; };
19 | A97DAFA024A370DF00918952 /* ComicsLoader.swift in Sources */ = {isa = PBXBuildFile; fileRef = A97DAF9F24A370DF00918952 /* ComicsLoader.swift */; };
20 | A97DAFA224A370F200918952 /* ComicsManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = A97DAFA124A370F200918952 /* ComicsManager.swift */; };
21 | A97DAFA424A3713800918952 /* ComicsData.plist in Resources */ = {isa = PBXBuildFile; fileRef = A97DAFA324A3713800918952 /* ComicsData.plist */; };
22 | A97DAFA524A3713800918952 /* ComicsData.plist in Resources */ = {isa = PBXBuildFile; fileRef = A97DAFA324A3713800918952 /* ComicsData.plist */; };
23 | A97DAFA724A3714400918952 /* Comics.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = A97DAFA624A3714400918952 /* Comics.xcassets */; };
24 | A97DAFA824A3714400918952 /* Comics.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = A97DAFA624A3714400918952 /* Comics.xcassets */; };
25 | A97DAFA924A371A900918952 /* Comics.swift in Sources */ = {isa = PBXBuildFile; fileRef = A97DAF9D24A370C900918952 /* Comics.swift */; };
26 | A97DAFAA24A371A900918952 /* ComicsLoader.swift in Sources */ = {isa = PBXBuildFile; fileRef = A97DAF9F24A370DF00918952 /* ComicsLoader.swift */; };
27 | A97DAFAB24A371A900918952 /* ComicsManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = A97DAFA124A370F200918952 /* ComicsManager.swift */; };
28 | A97DAFAC24A371EF00918952 /* GridCompositionalView.app in Resources */ = {isa = PBXBuildFile; fileRef = A97DAF6224A36F4B00918952 /* GridCompositionalView.app */; };
29 | /* End PBXBuildFile section */
30 |
31 | /* Begin PBXContainerItemProxy section */
32 | A97DAF7324A36F4C00918952 /* PBXContainerItemProxy */ = {
33 | isa = PBXContainerItemProxy;
34 | containerPortal = A97DAF5624A36F4B00918952 /* Project object */;
35 | proxyType = 1;
36 | remoteGlobalIDString = A97DAF6124A36F4B00918952;
37 | remoteInfo = iOS;
38 | };
39 | A97DAF7E24A36F4C00918952 /* PBXContainerItemProxy */ = {
40 | isa = PBXContainerItemProxy;
41 | containerPortal = A97DAF5624A36F4B00918952 /* Project object */;
42 | proxyType = 1;
43 | remoteGlobalIDString = A97DAF6924A36F4B00918952;
44 | remoteInfo = macOS;
45 | };
46 | A97DAFAD24A371EF00918952 /* PBXContainerItemProxy */ = {
47 | isa = PBXContainerItemProxy;
48 | containerPortal = A97DAF5624A36F4B00918952 /* Project object */;
49 | proxyType = 1;
50 | remoteGlobalIDString = A97DAF6124A36F4B00918952;
51 | remoteInfo = iOS;
52 | };
53 | /* End PBXContainerItemProxy section */
54 |
55 | /* Begin PBXFileReference section */
56 | A94CDEE424A7615300688A3D /* GridCompositionalView */ = {isa = PBXFileReference; lastKnownFileType = folder; name = GridCompositionalView; path = ..; sourceTree = ""; };
57 | A97DAF5B24A36F4B00918952 /* EntryApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EntryApp.swift; sourceTree = ""; };
58 | A97DAF5D24A36F4B00918952 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
59 | A97DAF6224A36F4B00918952 /* GridCompositionalView.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = GridCompositionalView.app; sourceTree = BUILT_PRODUCTS_DIR; };
60 | A97DAF6524A36F4B00918952 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
61 | A97DAF6A24A36F4B00918952 /* GridCompositionalView.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = GridCompositionalView.app; sourceTree = BUILT_PRODUCTS_DIR; };
62 | A97DAF6C24A36F4B00918952 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
63 | A97DAF6D24A36F4B00918952 /* macOS.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = macOS.entitlements; sourceTree = ""; };
64 | A97DAF7224A36F4C00918952 /* Tests iOS.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "Tests iOS.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
65 | A97DAF7624A36F4C00918952 /* Tests_iOS.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Tests_iOS.swift; sourceTree = ""; };
66 | A97DAF7824A36F4C00918952 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
67 | A97DAF7D24A36F4C00918952 /* Tests macOS.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "Tests macOS.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
68 | A97DAF8124A36F4C00918952 /* Tests_macOS.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Tests_macOS.swift; sourceTree = ""; };
69 | A97DAF8324A36F4C00918952 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
70 | A97DAF9D24A370C900918952 /* Comics.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Comics.swift; sourceTree = ""; };
71 | A97DAF9F24A370DF00918952 /* ComicsLoader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComicsLoader.swift; sourceTree = ""; };
72 | A97DAFA124A370F200918952 /* ComicsManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComicsManager.swift; sourceTree = ""; };
73 | A97DAFA324A3713800918952 /* ComicsData.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = ComicsData.plist; sourceTree = ""; };
74 | A97DAFA624A3714400918952 /* Comics.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Comics.xcassets; sourceTree = ""; };
75 | /* End PBXFileReference section */
76 |
77 | /* Begin PBXFrameworksBuildPhase section */
78 | A97DAF5F24A36F4B00918952 /* Frameworks */ = {
79 | isa = PBXFrameworksBuildPhase;
80 | buildActionMask = 2147483647;
81 | files = (
82 | A94CDEE624A7615D00688A3D /* GridCompositionalLayout in Frameworks */,
83 | );
84 | runOnlyForDeploymentPostprocessing = 0;
85 | };
86 | A97DAF6724A36F4B00918952 /* Frameworks */ = {
87 | isa = PBXFrameworksBuildPhase;
88 | buildActionMask = 2147483647;
89 | files = (
90 | A94CDEE824A7616200688A3D /* GridCompositionalLayout in Frameworks */,
91 | );
92 | runOnlyForDeploymentPostprocessing = 0;
93 | };
94 | A97DAF6F24A36F4C00918952 /* Frameworks */ = {
95 | isa = PBXFrameworksBuildPhase;
96 | buildActionMask = 2147483647;
97 | files = (
98 | );
99 | runOnlyForDeploymentPostprocessing = 0;
100 | };
101 | A97DAF7A24A36F4C00918952 /* Frameworks */ = {
102 | isa = PBXFrameworksBuildPhase;
103 | buildActionMask = 2147483647;
104 | files = (
105 | );
106 | runOnlyForDeploymentPostprocessing = 0;
107 | };
108 | /* End PBXFrameworksBuildPhase section */
109 |
110 | /* Begin PBXGroup section */
111 | A97DAF5524A36F4B00918952 = {
112 | isa = PBXGroup;
113 | children = (
114 | A94CDEE424A7615300688A3D /* GridCompositionalView */,
115 | A97DAF5A24A36F4B00918952 /* Shared */,
116 | A97DAF6424A36F4B00918952 /* iOS */,
117 | A97DAF6B24A36F4B00918952 /* macOS */,
118 | A97DAF7524A36F4C00918952 /* Tests iOS */,
119 | A97DAF8024A36F4C00918952 /* Tests macOS */,
120 | A97DAF6324A36F4B00918952 /* Products */,
121 | A97DAF9924A3709C00918952 /* Frameworks */,
122 | );
123 | sourceTree = "";
124 | };
125 | A97DAF5A24A36F4B00918952 /* Shared */ = {
126 | isa = PBXGroup;
127 | children = (
128 | A97DAF9C24A370C100918952 /* Data Model */,
129 | A97DAF5B24A36F4B00918952 /* EntryApp.swift */,
130 | A97DAF5D24A36F4B00918952 /* Assets.xcassets */,
131 | A97DAFA624A3714400918952 /* Comics.xcassets */,
132 | A97DAFA324A3713800918952 /* ComicsData.plist */,
133 | );
134 | path = Shared;
135 | sourceTree = "";
136 | };
137 | A97DAF6324A36F4B00918952 /* Products */ = {
138 | isa = PBXGroup;
139 | children = (
140 | A97DAF6224A36F4B00918952 /* GridCompositionalView.app */,
141 | A97DAF6A24A36F4B00918952 /* GridCompositionalView.app */,
142 | A97DAF7224A36F4C00918952 /* Tests iOS.xctest */,
143 | A97DAF7D24A36F4C00918952 /* Tests macOS.xctest */,
144 | );
145 | name = Products;
146 | sourceTree = "";
147 | };
148 | A97DAF6424A36F4B00918952 /* iOS */ = {
149 | isa = PBXGroup;
150 | children = (
151 | A97DAF6524A36F4B00918952 /* Info.plist */,
152 | );
153 | path = iOS;
154 | sourceTree = "";
155 | };
156 | A97DAF6B24A36F4B00918952 /* macOS */ = {
157 | isa = PBXGroup;
158 | children = (
159 | A97DAF6C24A36F4B00918952 /* Info.plist */,
160 | A97DAF6D24A36F4B00918952 /* macOS.entitlements */,
161 | );
162 | path = macOS;
163 | sourceTree = "";
164 | };
165 | A97DAF7524A36F4C00918952 /* Tests iOS */ = {
166 | isa = PBXGroup;
167 | children = (
168 | A97DAF7624A36F4C00918952 /* Tests_iOS.swift */,
169 | A97DAF7824A36F4C00918952 /* Info.plist */,
170 | );
171 | path = "Tests iOS";
172 | sourceTree = "";
173 | };
174 | A97DAF8024A36F4C00918952 /* Tests macOS */ = {
175 | isa = PBXGroup;
176 | children = (
177 | A97DAF8124A36F4C00918952 /* Tests_macOS.swift */,
178 | A97DAF8324A36F4C00918952 /* Info.plist */,
179 | );
180 | path = "Tests macOS";
181 | sourceTree = "";
182 | };
183 | A97DAF9924A3709C00918952 /* Frameworks */ = {
184 | isa = PBXGroup;
185 | children = (
186 | );
187 | name = Frameworks;
188 | sourceTree = "";
189 | };
190 | A97DAF9C24A370C100918952 /* Data Model */ = {
191 | isa = PBXGroup;
192 | children = (
193 | A97DAF9D24A370C900918952 /* Comics.swift */,
194 | A97DAF9F24A370DF00918952 /* ComicsLoader.swift */,
195 | A97DAFA124A370F200918952 /* ComicsManager.swift */,
196 | );
197 | path = "Data Model";
198 | sourceTree = "";
199 | };
200 | /* End PBXGroup section */
201 |
202 | /* Begin PBXNativeTarget section */
203 | A97DAF6124A36F4B00918952 /* iOS */ = {
204 | isa = PBXNativeTarget;
205 | buildConfigurationList = A97DAF8C24A36F4C00918952 /* Build configuration list for PBXNativeTarget "iOS" */;
206 | buildPhases = (
207 | A97DAF5E24A36F4B00918952 /* Sources */,
208 | A97DAF5F24A36F4B00918952 /* Frameworks */,
209 | A97DAF6024A36F4B00918952 /* Resources */,
210 | );
211 | buildRules = (
212 | );
213 | dependencies = (
214 | );
215 | name = iOS;
216 | packageProductDependencies = (
217 | A94CDEE524A7615D00688A3D /* GridCompositionalLayout */,
218 | );
219 | productName = iOS;
220 | productReference = A97DAF6224A36F4B00918952 /* GridCompositionalView.app */;
221 | productType = "com.apple.product-type.application";
222 | };
223 | A97DAF6924A36F4B00918952 /* macOS */ = {
224 | isa = PBXNativeTarget;
225 | buildConfigurationList = A97DAF8F24A36F4C00918952 /* Build configuration list for PBXNativeTarget "macOS" */;
226 | buildPhases = (
227 | A97DAF6624A36F4B00918952 /* Sources */,
228 | A97DAF6724A36F4B00918952 /* Frameworks */,
229 | A97DAF6824A36F4B00918952 /* Resources */,
230 | );
231 | buildRules = (
232 | );
233 | dependencies = (
234 | A97DAFAE24A371EF00918952 /* PBXTargetDependency */,
235 | );
236 | name = macOS;
237 | packageProductDependencies = (
238 | A94CDEE724A7616200688A3D /* GridCompositionalLayout */,
239 | );
240 | productName = macOS;
241 | productReference = A97DAF6A24A36F4B00918952 /* GridCompositionalView.app */;
242 | productType = "com.apple.product-type.application";
243 | };
244 | A97DAF7124A36F4C00918952 /* Tests iOS */ = {
245 | isa = PBXNativeTarget;
246 | buildConfigurationList = A97DAF9224A36F4C00918952 /* Build configuration list for PBXNativeTarget "Tests iOS" */;
247 | buildPhases = (
248 | A97DAF6E24A36F4C00918952 /* Sources */,
249 | A97DAF6F24A36F4C00918952 /* Frameworks */,
250 | A97DAF7024A36F4C00918952 /* Resources */,
251 | );
252 | buildRules = (
253 | );
254 | dependencies = (
255 | A97DAF7424A36F4C00918952 /* PBXTargetDependency */,
256 | );
257 | name = "Tests iOS";
258 | productName = "Tests iOS";
259 | productReference = A97DAF7224A36F4C00918952 /* Tests iOS.xctest */;
260 | productType = "com.apple.product-type.bundle.ui-testing";
261 | };
262 | A97DAF7C24A36F4C00918952 /* Tests macOS */ = {
263 | isa = PBXNativeTarget;
264 | buildConfigurationList = A97DAF9524A36F4C00918952 /* Build configuration list for PBXNativeTarget "Tests macOS" */;
265 | buildPhases = (
266 | A97DAF7924A36F4C00918952 /* Sources */,
267 | A97DAF7A24A36F4C00918952 /* Frameworks */,
268 | A97DAF7B24A36F4C00918952 /* Resources */,
269 | );
270 | buildRules = (
271 | );
272 | dependencies = (
273 | A97DAF7F24A36F4C00918952 /* PBXTargetDependency */,
274 | );
275 | name = "Tests macOS";
276 | productName = "Tests macOS";
277 | productReference = A97DAF7D24A36F4C00918952 /* Tests macOS.xctest */;
278 | productType = "com.apple.product-type.bundle.ui-testing";
279 | };
280 | /* End PBXNativeTarget section */
281 |
282 | /* Begin PBXProject section */
283 | A97DAF5624A36F4B00918952 /* Project object */ = {
284 | isa = PBXProject;
285 | attributes = {
286 | LastSwiftUpdateCheck = 1200;
287 | LastUpgradeCheck = 1200;
288 | TargetAttributes = {
289 | A97DAF6124A36F4B00918952 = {
290 | CreatedOnToolsVersion = 12.0;
291 | };
292 | A97DAF6924A36F4B00918952 = {
293 | CreatedOnToolsVersion = 12.0;
294 | };
295 | A97DAF7124A36F4C00918952 = {
296 | CreatedOnToolsVersion = 12.0;
297 | TestTargetID = A97DAF6124A36F4B00918952;
298 | };
299 | A97DAF7C24A36F4C00918952 = {
300 | CreatedOnToolsVersion = 12.0;
301 | TestTargetID = A97DAF6924A36F4B00918952;
302 | };
303 | };
304 | };
305 | buildConfigurationList = A97DAF5924A36F4B00918952 /* Build configuration list for PBXProject "GridCompositionalView" */;
306 | compatibilityVersion = "Xcode 9.3";
307 | developmentRegion = en;
308 | hasScannedForEncodings = 0;
309 | knownRegions = (
310 | en,
311 | Base,
312 | );
313 | mainGroup = A97DAF5524A36F4B00918952;
314 | productRefGroup = A97DAF6324A36F4B00918952 /* Products */;
315 | projectDirPath = "";
316 | projectRoot = "";
317 | targets = (
318 | A97DAF6124A36F4B00918952 /* iOS */,
319 | A97DAF6924A36F4B00918952 /* macOS */,
320 | A97DAF7124A36F4C00918952 /* Tests iOS */,
321 | A97DAF7C24A36F4C00918952 /* Tests macOS */,
322 | );
323 | };
324 | /* End PBXProject section */
325 |
326 | /* Begin PBXResourcesBuildPhase section */
327 | A97DAF6024A36F4B00918952 /* Resources */ = {
328 | isa = PBXResourcesBuildPhase;
329 | buildActionMask = 2147483647;
330 | files = (
331 | A97DAFA424A3713800918952 /* ComicsData.plist in Resources */,
332 | A97DAFA724A3714400918952 /* Comics.xcassets in Resources */,
333 | A97DAF8824A36F4C00918952 /* Assets.xcassets in Resources */,
334 | );
335 | runOnlyForDeploymentPostprocessing = 0;
336 | };
337 | A97DAF6824A36F4B00918952 /* Resources */ = {
338 | isa = PBXResourcesBuildPhase;
339 | buildActionMask = 2147483647;
340 | files = (
341 | A97DAFA524A3713800918952 /* ComicsData.plist in Resources */,
342 | A97DAFA824A3714400918952 /* Comics.xcassets in Resources */,
343 | A97DAFAC24A371EF00918952 /* GridCompositionalView.app in Resources */,
344 | A97DAF8924A36F4C00918952 /* Assets.xcassets in Resources */,
345 | );
346 | runOnlyForDeploymentPostprocessing = 0;
347 | };
348 | A97DAF7024A36F4C00918952 /* Resources */ = {
349 | isa = PBXResourcesBuildPhase;
350 | buildActionMask = 2147483647;
351 | files = (
352 | );
353 | runOnlyForDeploymentPostprocessing = 0;
354 | };
355 | A97DAF7B24A36F4C00918952 /* Resources */ = {
356 | isa = PBXResourcesBuildPhase;
357 | buildActionMask = 2147483647;
358 | files = (
359 | );
360 | runOnlyForDeploymentPostprocessing = 0;
361 | };
362 | /* End PBXResourcesBuildPhase section */
363 |
364 | /* Begin PBXSourcesBuildPhase section */
365 | A97DAF5E24A36F4B00918952 /* Sources */ = {
366 | isa = PBXSourcesBuildPhase;
367 | buildActionMask = 2147483647;
368 | files = (
369 | A97DAF8424A36F4C00918952 /* EntryApp.swift in Sources */,
370 | A97DAFA224A370F200918952 /* ComicsManager.swift in Sources */,
371 | A97DAFA024A370DF00918952 /* ComicsLoader.swift in Sources */,
372 | A97DAF9E24A370C900918952 /* Comics.swift in Sources */,
373 | );
374 | runOnlyForDeploymentPostprocessing = 0;
375 | };
376 | A97DAF6624A36F4B00918952 /* Sources */ = {
377 | isa = PBXSourcesBuildPhase;
378 | buildActionMask = 2147483647;
379 | files = (
380 | A97DAFAA24A371A900918952 /* ComicsLoader.swift in Sources */,
381 | A97DAF8524A36F4C00918952 /* EntryApp.swift in Sources */,
382 | A97DAFA924A371A900918952 /* Comics.swift in Sources */,
383 | A97DAFAB24A371A900918952 /* ComicsManager.swift in Sources */,
384 | );
385 | runOnlyForDeploymentPostprocessing = 0;
386 | };
387 | A97DAF6E24A36F4C00918952 /* Sources */ = {
388 | isa = PBXSourcesBuildPhase;
389 | buildActionMask = 2147483647;
390 | files = (
391 | A97DAF7724A36F4C00918952 /* Tests_iOS.swift in Sources */,
392 | );
393 | runOnlyForDeploymentPostprocessing = 0;
394 | };
395 | A97DAF7924A36F4C00918952 /* Sources */ = {
396 | isa = PBXSourcesBuildPhase;
397 | buildActionMask = 2147483647;
398 | files = (
399 | A97DAF8224A36F4C00918952 /* Tests_macOS.swift in Sources */,
400 | );
401 | runOnlyForDeploymentPostprocessing = 0;
402 | };
403 | /* End PBXSourcesBuildPhase section */
404 |
405 | /* Begin PBXTargetDependency section */
406 | A97DAF7424A36F4C00918952 /* PBXTargetDependency */ = {
407 | isa = PBXTargetDependency;
408 | target = A97DAF6124A36F4B00918952 /* iOS */;
409 | targetProxy = A97DAF7324A36F4C00918952 /* PBXContainerItemProxy */;
410 | };
411 | A97DAF7F24A36F4C00918952 /* PBXTargetDependency */ = {
412 | isa = PBXTargetDependency;
413 | target = A97DAF6924A36F4B00918952 /* macOS */;
414 | targetProxy = A97DAF7E24A36F4C00918952 /* PBXContainerItemProxy */;
415 | };
416 | A97DAFAE24A371EF00918952 /* PBXTargetDependency */ = {
417 | isa = PBXTargetDependency;
418 | target = A97DAF6124A36F4B00918952 /* iOS */;
419 | targetProxy = A97DAFAD24A371EF00918952 /* PBXContainerItemProxy */;
420 | };
421 | /* End PBXTargetDependency section */
422 |
423 | /* Begin XCBuildConfiguration section */
424 | A97DAF8A24A36F4C00918952 /* Debug */ = {
425 | isa = XCBuildConfiguration;
426 | buildSettings = {
427 | ALWAYS_SEARCH_USER_PATHS = NO;
428 | CLANG_ANALYZER_NONNULL = YES;
429 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
430 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
431 | CLANG_CXX_LIBRARY = "libc++";
432 | CLANG_ENABLE_MODULES = YES;
433 | CLANG_ENABLE_OBJC_ARC = YES;
434 | CLANG_ENABLE_OBJC_WEAK = YES;
435 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
436 | CLANG_WARN_BOOL_CONVERSION = YES;
437 | CLANG_WARN_COMMA = YES;
438 | CLANG_WARN_CONSTANT_CONVERSION = YES;
439 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
440 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
441 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
442 | CLANG_WARN_EMPTY_BODY = YES;
443 | CLANG_WARN_ENUM_CONVERSION = YES;
444 | CLANG_WARN_INFINITE_RECURSION = YES;
445 | CLANG_WARN_INT_CONVERSION = YES;
446 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
447 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
448 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
449 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
450 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
451 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
452 | CLANG_WARN_STRICT_PROTOTYPES = YES;
453 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
454 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
455 | CLANG_WARN_UNREACHABLE_CODE = YES;
456 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
457 | COPY_PHASE_STRIP = NO;
458 | DEBUG_INFORMATION_FORMAT = dwarf;
459 | ENABLE_STRICT_OBJC_MSGSEND = YES;
460 | ENABLE_TESTABILITY = YES;
461 | GCC_C_LANGUAGE_STANDARD = gnu11;
462 | GCC_DYNAMIC_NO_PIC = NO;
463 | GCC_NO_COMMON_BLOCKS = YES;
464 | GCC_OPTIMIZATION_LEVEL = 0;
465 | GCC_PREPROCESSOR_DEFINITIONS = (
466 | "DEBUG=1",
467 | "$(inherited)",
468 | );
469 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
470 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
471 | GCC_WARN_UNDECLARED_SELECTOR = YES;
472 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
473 | GCC_WARN_UNUSED_FUNCTION = YES;
474 | GCC_WARN_UNUSED_VARIABLE = YES;
475 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
476 | MTL_FAST_MATH = YES;
477 | ONLY_ACTIVE_ARCH = YES;
478 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
479 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
480 | };
481 | name = Debug;
482 | };
483 | A97DAF8B24A36F4C00918952 /* Release */ = {
484 | isa = XCBuildConfiguration;
485 | buildSettings = {
486 | ALWAYS_SEARCH_USER_PATHS = NO;
487 | CLANG_ANALYZER_NONNULL = YES;
488 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
489 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
490 | CLANG_CXX_LIBRARY = "libc++";
491 | CLANG_ENABLE_MODULES = YES;
492 | CLANG_ENABLE_OBJC_ARC = YES;
493 | CLANG_ENABLE_OBJC_WEAK = YES;
494 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
495 | CLANG_WARN_BOOL_CONVERSION = YES;
496 | CLANG_WARN_COMMA = YES;
497 | CLANG_WARN_CONSTANT_CONVERSION = YES;
498 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
499 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
500 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
501 | CLANG_WARN_EMPTY_BODY = YES;
502 | CLANG_WARN_ENUM_CONVERSION = YES;
503 | CLANG_WARN_INFINITE_RECURSION = YES;
504 | CLANG_WARN_INT_CONVERSION = YES;
505 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
506 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
507 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
508 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
509 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
510 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
511 | CLANG_WARN_STRICT_PROTOTYPES = YES;
512 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
513 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
514 | CLANG_WARN_UNREACHABLE_CODE = YES;
515 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
516 | COPY_PHASE_STRIP = NO;
517 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
518 | ENABLE_NS_ASSERTIONS = NO;
519 | ENABLE_STRICT_OBJC_MSGSEND = YES;
520 | GCC_C_LANGUAGE_STANDARD = gnu11;
521 | GCC_NO_COMMON_BLOCKS = YES;
522 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
523 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
524 | GCC_WARN_UNDECLARED_SELECTOR = YES;
525 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
526 | GCC_WARN_UNUSED_FUNCTION = YES;
527 | GCC_WARN_UNUSED_VARIABLE = YES;
528 | MTL_ENABLE_DEBUG_INFO = NO;
529 | MTL_FAST_MATH = YES;
530 | SWIFT_COMPILATION_MODE = wholemodule;
531 | SWIFT_OPTIMIZATION_LEVEL = "-O";
532 | };
533 | name = Release;
534 | };
535 | A97DAF8D24A36F4C00918952 /* Debug */ = {
536 | isa = XCBuildConfiguration;
537 | buildSettings = {
538 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
539 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
540 | CODE_SIGN_STYLE = Automatic;
541 | DEVELOPMENT_TEAM = T3K58FE38R;
542 | ENABLE_PREVIEWS = YES;
543 | INFOPLIST_FILE = iOS/Info.plist;
544 | IPHONEOS_DEPLOYMENT_TARGET = 14.0;
545 | LD_RUNPATH_SEARCH_PATHS = (
546 | "$(inherited)",
547 | "@executable_path/Frameworks",
548 | );
549 | PRODUCT_BUNDLE_IDENTIFIER = eleev.astemir.GridCompositionalView;
550 | PRODUCT_NAME = GridCompositionalView;
551 | SDKROOT = iphoneos;
552 | SWIFT_VERSION = 5.0;
553 | TARGETED_DEVICE_FAMILY = "1,2";
554 | };
555 | name = Debug;
556 | };
557 | A97DAF8E24A36F4C00918952 /* Release */ = {
558 | isa = XCBuildConfiguration;
559 | buildSettings = {
560 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
561 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
562 | CODE_SIGN_STYLE = Automatic;
563 | DEVELOPMENT_TEAM = T3K58FE38R;
564 | ENABLE_PREVIEWS = YES;
565 | INFOPLIST_FILE = iOS/Info.plist;
566 | IPHONEOS_DEPLOYMENT_TARGET = 14.0;
567 | LD_RUNPATH_SEARCH_PATHS = (
568 | "$(inherited)",
569 | "@executable_path/Frameworks",
570 | );
571 | PRODUCT_BUNDLE_IDENTIFIER = eleev.astemir.GridCompositionalView;
572 | PRODUCT_NAME = GridCompositionalView;
573 | SDKROOT = iphoneos;
574 | SWIFT_VERSION = 5.0;
575 | TARGETED_DEVICE_FAMILY = "1,2";
576 | VALIDATE_PRODUCT = YES;
577 | };
578 | name = Release;
579 | };
580 | A97DAF9024A36F4C00918952 /* Debug */ = {
581 | isa = XCBuildConfiguration;
582 | buildSettings = {
583 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
584 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
585 | CODE_SIGN_ENTITLEMENTS = macOS/macOS.entitlements;
586 | CODE_SIGN_STYLE = Automatic;
587 | COMBINE_HIDPI_IMAGES = YES;
588 | DEVELOPMENT_TEAM = T3K58FE38R;
589 | ENABLE_HARDENED_RUNTIME = YES;
590 | ENABLE_PREVIEWS = YES;
591 | INFOPLIST_FILE = macOS/Info.plist;
592 | LD_RUNPATH_SEARCH_PATHS = (
593 | "$(inherited)",
594 | "@executable_path/../Frameworks",
595 | );
596 | MACOSX_DEPLOYMENT_TARGET = 10.16;
597 | PRODUCT_BUNDLE_IDENTIFIER = eleev.astemir.GridCompositionalView;
598 | PRODUCT_NAME = GridCompositionalView;
599 | SDKROOT = macosx;
600 | SWIFT_VERSION = 5.0;
601 | };
602 | name = Debug;
603 | };
604 | A97DAF9124A36F4C00918952 /* Release */ = {
605 | isa = XCBuildConfiguration;
606 | buildSettings = {
607 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
608 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
609 | CODE_SIGN_ENTITLEMENTS = macOS/macOS.entitlements;
610 | CODE_SIGN_STYLE = Automatic;
611 | COMBINE_HIDPI_IMAGES = YES;
612 | DEVELOPMENT_TEAM = T3K58FE38R;
613 | ENABLE_HARDENED_RUNTIME = YES;
614 | ENABLE_PREVIEWS = YES;
615 | INFOPLIST_FILE = macOS/Info.plist;
616 | LD_RUNPATH_SEARCH_PATHS = (
617 | "$(inherited)",
618 | "@executable_path/../Frameworks",
619 | );
620 | MACOSX_DEPLOYMENT_TARGET = 10.16;
621 | PRODUCT_BUNDLE_IDENTIFIER = eleev.astemir.GridCompositionalView;
622 | PRODUCT_NAME = GridCompositionalView;
623 | SDKROOT = macosx;
624 | SWIFT_VERSION = 5.0;
625 | };
626 | name = Release;
627 | };
628 | A97DAF9324A36F4C00918952 /* Debug */ = {
629 | isa = XCBuildConfiguration;
630 | buildSettings = {
631 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
632 | CODE_SIGN_STYLE = Automatic;
633 | DEVELOPMENT_TEAM = T3K58FE38R;
634 | INFOPLIST_FILE = "Tests iOS/Info.plist";
635 | IPHONEOS_DEPLOYMENT_TARGET = 14.0;
636 | LD_RUNPATH_SEARCH_PATHS = (
637 | "$(inherited)",
638 | "@executable_path/Frameworks",
639 | "@loader_path/Frameworks",
640 | );
641 | PRODUCT_BUNDLE_IDENTIFIER = "eleev.astemir.Tests-iOS";
642 | PRODUCT_NAME = "$(TARGET_NAME)";
643 | SDKROOT = iphoneos;
644 | SWIFT_VERSION = 5.0;
645 | TARGETED_DEVICE_FAMILY = "1,2";
646 | TEST_TARGET_NAME = iOS;
647 | };
648 | name = Debug;
649 | };
650 | A97DAF9424A36F4C00918952 /* Release */ = {
651 | isa = XCBuildConfiguration;
652 | buildSettings = {
653 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
654 | CODE_SIGN_STYLE = Automatic;
655 | DEVELOPMENT_TEAM = T3K58FE38R;
656 | INFOPLIST_FILE = "Tests iOS/Info.plist";
657 | IPHONEOS_DEPLOYMENT_TARGET = 14.0;
658 | LD_RUNPATH_SEARCH_PATHS = (
659 | "$(inherited)",
660 | "@executable_path/Frameworks",
661 | "@loader_path/Frameworks",
662 | );
663 | PRODUCT_BUNDLE_IDENTIFIER = "eleev.astemir.Tests-iOS";
664 | PRODUCT_NAME = "$(TARGET_NAME)";
665 | SDKROOT = iphoneos;
666 | SWIFT_VERSION = 5.0;
667 | TARGETED_DEVICE_FAMILY = "1,2";
668 | TEST_TARGET_NAME = iOS;
669 | VALIDATE_PRODUCT = YES;
670 | };
671 | name = Release;
672 | };
673 | A97DAF9624A36F4C00918952 /* Debug */ = {
674 | isa = XCBuildConfiguration;
675 | buildSettings = {
676 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
677 | CODE_SIGN_STYLE = Automatic;
678 | COMBINE_HIDPI_IMAGES = YES;
679 | DEVELOPMENT_TEAM = T3K58FE38R;
680 | INFOPLIST_FILE = "Tests macOS/Info.plist";
681 | LD_RUNPATH_SEARCH_PATHS = (
682 | "$(inherited)",
683 | "@executable_path/../Frameworks",
684 | "@loader_path/../Frameworks",
685 | );
686 | MACOSX_DEPLOYMENT_TARGET = 10.15;
687 | PRODUCT_BUNDLE_IDENTIFIER = "eleev.astemir.Tests-macOS";
688 | PRODUCT_NAME = "$(TARGET_NAME)";
689 | SDKROOT = macosx;
690 | SWIFT_VERSION = 5.0;
691 | TEST_TARGET_NAME = macOS;
692 | };
693 | name = Debug;
694 | };
695 | A97DAF9724A36F4C00918952 /* Release */ = {
696 | isa = XCBuildConfiguration;
697 | buildSettings = {
698 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
699 | CODE_SIGN_STYLE = Automatic;
700 | COMBINE_HIDPI_IMAGES = YES;
701 | DEVELOPMENT_TEAM = T3K58FE38R;
702 | INFOPLIST_FILE = "Tests macOS/Info.plist";
703 | LD_RUNPATH_SEARCH_PATHS = (
704 | "$(inherited)",
705 | "@executable_path/../Frameworks",
706 | "@loader_path/../Frameworks",
707 | );
708 | MACOSX_DEPLOYMENT_TARGET = 10.15;
709 | PRODUCT_BUNDLE_IDENTIFIER = "eleev.astemir.Tests-macOS";
710 | PRODUCT_NAME = "$(TARGET_NAME)";
711 | SDKROOT = macosx;
712 | SWIFT_VERSION = 5.0;
713 | TEST_TARGET_NAME = macOS;
714 | };
715 | name = Release;
716 | };
717 | /* End XCBuildConfiguration section */
718 |
719 | /* Begin XCConfigurationList section */
720 | A97DAF5924A36F4B00918952 /* Build configuration list for PBXProject "GridCompositionalView" */ = {
721 | isa = XCConfigurationList;
722 | buildConfigurations = (
723 | A97DAF8A24A36F4C00918952 /* Debug */,
724 | A97DAF8B24A36F4C00918952 /* Release */,
725 | );
726 | defaultConfigurationIsVisible = 0;
727 | defaultConfigurationName = Release;
728 | };
729 | A97DAF8C24A36F4C00918952 /* Build configuration list for PBXNativeTarget "iOS" */ = {
730 | isa = XCConfigurationList;
731 | buildConfigurations = (
732 | A97DAF8D24A36F4C00918952 /* Debug */,
733 | A97DAF8E24A36F4C00918952 /* Release */,
734 | );
735 | defaultConfigurationIsVisible = 0;
736 | defaultConfigurationName = Release;
737 | };
738 | A97DAF8F24A36F4C00918952 /* Build configuration list for PBXNativeTarget "macOS" */ = {
739 | isa = XCConfigurationList;
740 | buildConfigurations = (
741 | A97DAF9024A36F4C00918952 /* Debug */,
742 | A97DAF9124A36F4C00918952 /* Release */,
743 | );
744 | defaultConfigurationIsVisible = 0;
745 | defaultConfigurationName = Release;
746 | };
747 | A97DAF9224A36F4C00918952 /* Build configuration list for PBXNativeTarget "Tests iOS" */ = {
748 | isa = XCConfigurationList;
749 | buildConfigurations = (
750 | A97DAF9324A36F4C00918952 /* Debug */,
751 | A97DAF9424A36F4C00918952 /* Release */,
752 | );
753 | defaultConfigurationIsVisible = 0;
754 | defaultConfigurationName = Release;
755 | };
756 | A97DAF9524A36F4C00918952 /* Build configuration list for PBXNativeTarget "Tests macOS" */ = {
757 | isa = XCConfigurationList;
758 | buildConfigurations = (
759 | A97DAF9624A36F4C00918952 /* Debug */,
760 | A97DAF9724A36F4C00918952 /* Release */,
761 | );
762 | defaultConfigurationIsVisible = 0;
763 | defaultConfigurationName = Release;
764 | };
765 | /* End XCConfigurationList section */
766 |
767 | /* Begin XCSwiftPackageProductDependency section */
768 | A94CDEE524A7615D00688A3D /* GridCompositionalLayout */ = {
769 | isa = XCSwiftPackageProductDependency;
770 | productName = GridCompositionalLayout;
771 | };
772 | A94CDEE724A7616200688A3D /* GridCompositionalLayout */ = {
773 | isa = XCSwiftPackageProductDependency;
774 | productName = GridCompositionalLayout;
775 | };
776 | /* End XCSwiftPackageProductDependency section */
777 | };
778 | rootObject = A97DAF5624A36F4B00918952 /* Project object */;
779 | }
780 |
--------------------------------------------------------------------------------
/Demo/GridCompositionalView.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Demo/GridCompositionalView.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Demo/GridCompositionalView.xcodeproj/xcshareddata/xcschemes/iOS.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
43 |
45 |
51 |
52 |
53 |
54 |
60 |
62 |
68 |
69 |
70 |
71 |
73 |
74 |
77 |
78 |
79 |
--------------------------------------------------------------------------------
/Demo/GridCompositionalView.xcodeproj/xcshareddata/xcschemes/macOS.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
43 |
45 |
51 |
52 |
53 |
54 |
60 |
62 |
68 |
69 |
70 |
71 |
73 |
74 |
77 |
78 |
79 |
--------------------------------------------------------------------------------
/Demo/Shared/Assets.xcassets/AccentColor.colorset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "colors" : [
3 | {
4 | "idiom" : "universal"
5 | }
6 | ],
7 | "info" : {
8 | "author" : "xcode",
9 | "version" : 1
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/Demo/Shared/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "scale" : "2x",
6 | "size" : "20x20"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "scale" : "3x",
11 | "size" : "20x20"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "scale" : "2x",
16 | "size" : "29x29"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "scale" : "3x",
21 | "size" : "29x29"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "scale" : "2x",
26 | "size" : "40x40"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "scale" : "3x",
31 | "size" : "40x40"
32 | },
33 | {
34 | "idiom" : "iphone",
35 | "scale" : "2x",
36 | "size" : "60x60"
37 | },
38 | {
39 | "idiom" : "iphone",
40 | "scale" : "3x",
41 | "size" : "60x60"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "scale" : "1x",
46 | "size" : "20x20"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "scale" : "2x",
51 | "size" : "20x20"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "scale" : "1x",
56 | "size" : "29x29"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "scale" : "2x",
61 | "size" : "29x29"
62 | },
63 | {
64 | "idiom" : "ipad",
65 | "scale" : "1x",
66 | "size" : "40x40"
67 | },
68 | {
69 | "idiom" : "ipad",
70 | "scale" : "2x",
71 | "size" : "40x40"
72 | },
73 | {
74 | "idiom" : "ipad",
75 | "scale" : "1x",
76 | "size" : "76x76"
77 | },
78 | {
79 | "idiom" : "ipad",
80 | "scale" : "2x",
81 | "size" : "76x76"
82 | },
83 | {
84 | "idiom" : "ipad",
85 | "scale" : "2x",
86 | "size" : "83.5x83.5"
87 | },
88 | {
89 | "idiom" : "ios-marketing",
90 | "scale" : "1x",
91 | "size" : "1024x1024"
92 | },
93 | {
94 | "idiom" : "mac",
95 | "scale" : "1x",
96 | "size" : "16x16"
97 | },
98 | {
99 | "idiom" : "mac",
100 | "scale" : "2x",
101 | "size" : "16x16"
102 | },
103 | {
104 | "idiom" : "mac",
105 | "scale" : "1x",
106 | "size" : "32x32"
107 | },
108 | {
109 | "idiom" : "mac",
110 | "scale" : "2x",
111 | "size" : "32x32"
112 | },
113 | {
114 | "idiom" : "mac",
115 | "scale" : "1x",
116 | "size" : "128x128"
117 | },
118 | {
119 | "idiom" : "mac",
120 | "scale" : "2x",
121 | "size" : "128x128"
122 | },
123 | {
124 | "idiom" : "mac",
125 | "scale" : "1x",
126 | "size" : "256x256"
127 | },
128 | {
129 | "idiom" : "mac",
130 | "scale" : "2x",
131 | "size" : "256x256"
132 | },
133 | {
134 | "idiom" : "mac",
135 | "scale" : "1x",
136 | "size" : "512x512"
137 | },
138 | {
139 | "idiom" : "mac",
140 | "scale" : "2x",
141 | "size" : "512x512"
142 | }
143 | ],
144 | "info" : {
145 | "author" : "xcode",
146 | "version" : 1
147 | }
148 | }
149 |
--------------------------------------------------------------------------------
/Demo/Shared/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/Demo/Shared/Comics.xcassets/1-1.imageset/6796934.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eleev/grid-compositional-layout/831e171557ac1bf10de30fb8238e3830fde9adcb/Demo/Shared/Comics.xcassets/1-1.imageset/6796934.jpg
--------------------------------------------------------------------------------
/Demo/Shared/Comics.xcassets/1-1.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "6796934.jpg",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/Demo/Shared/Comics.xcassets/1-10.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "images.jpeg",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/Demo/Shared/Comics.xcassets/1-10.imageset/images.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eleev/grid-compositional-layout/831e171557ac1bf10de30fb8238e3830fde9adcb/Demo/Shared/Comics.xcassets/1-10.imageset/images.jpeg
--------------------------------------------------------------------------------
/Demo/Shared/Comics.xcassets/1-11.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "batman-the-killing-joke-u4.jpeg",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/Demo/Shared/Comics.xcassets/1-11.imageset/batman-the-killing-joke-u4.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eleev/grid-compositional-layout/831e171557ac1bf10de30fb8238e3830fde9adcb/Demo/Shared/Comics.xcassets/1-11.imageset/batman-the-killing-joke-u4.jpeg
--------------------------------------------------------------------------------
/Demo/Shared/Comics.xcassets/1-12.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "spider-man-1-cover-117628.jpg",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/Demo/Shared/Comics.xcassets/1-12.imageset/spider-man-1-cover-117628.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eleev/grid-compositional-layout/831e171557ac1bf10de30fb8238e3830fde9adcb/Demo/Shared/Comics.xcassets/1-12.imageset/spider-man-1-cover-117628.jpg
--------------------------------------------------------------------------------
/Demo/Shared/Comics.xcassets/1-13.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "Wonder_Woman_Vol_4_36.jpg",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/Demo/Shared/Comics.xcassets/1-13.imageset/Wonder_Woman_Vol_4_36.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eleev/grid-compositional-layout/831e171557ac1bf10de30fb8238e3830fde9adcb/Demo/Shared/Comics.xcassets/1-13.imageset/Wonder_Woman_Vol_4_36.jpg
--------------------------------------------------------------------------------
/Demo/Shared/Comics.xcassets/1-14.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "hulk-181-comic-book-series-photo-u1.jpeg",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/Demo/Shared/Comics.xcassets/1-14.imageset/hulk-181-comic-book-series-photo-u1.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eleev/grid-compositional-layout/831e171557ac1bf10de30fb8238e3830fde9adcb/Demo/Shared/Comics.xcassets/1-14.imageset/hulk-181-comic-book-series-photo-u1.jpeg
--------------------------------------------------------------------------------
/Demo/Shared/Comics.xcassets/1-15.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "hulk-340-comic-book-series-photo-u1.jpeg",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/Demo/Shared/Comics.xcassets/1-15.imageset/hulk-340-comic-book-series-photo-u1.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eleev/grid-compositional-layout/831e171557ac1bf10de30fb8238e3830fde9adcb/Demo/Shared/Comics.xcassets/1-15.imageset/hulk-340-comic-book-series-photo-u1.jpeg
--------------------------------------------------------------------------------
/Demo/Shared/Comics.xcassets/1-16.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "e6dae1633d136653126297a89be83f29.jpg",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/Demo/Shared/Comics.xcassets/1-16.imageset/e6dae1633d136653126297a89be83f29.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eleev/grid-compositional-layout/831e171557ac1bf10de30fb8238e3830fde9adcb/Demo/Shared/Comics.xcassets/1-16.imageset/e6dae1633d136653126297a89be83f29.jpg
--------------------------------------------------------------------------------
/Demo/Shared/Comics.xcassets/1-17.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "spider-man-vol-2-1-comic-book-series-photo-u1.jpeg",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/Demo/Shared/Comics.xcassets/1-17.imageset/spider-man-vol-2-1-comic-book-series-photo-u1.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eleev/grid-compositional-layout/831e171557ac1bf10de30fb8238e3830fde9adcb/Demo/Shared/Comics.xcassets/1-17.imageset/spider-man-vol-2-1-comic-book-series-photo-u1.jpeg
--------------------------------------------------------------------------------
/Demo/Shared/Comics.xcassets/1-18.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "superman-75-comic-book-series-photo-u1.jpeg",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/Demo/Shared/Comics.xcassets/1-18.imageset/superman-75-comic-book-series-photo-u1.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eleev/grid-compositional-layout/831e171557ac1bf10de30fb8238e3830fde9adcb/Demo/Shared/Comics.xcassets/1-18.imageset/superman-75-comic-book-series-photo-u1.jpeg
--------------------------------------------------------------------------------
/Demo/Shared/Comics.xcassets/1-19.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "uncanny-x-men-101-comic-book-series-photo-u1.jpeg",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/Demo/Shared/Comics.xcassets/1-19.imageset/uncanny-x-men-101-comic-book-series-photo-u1.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eleev/grid-compositional-layout/831e171557ac1bf10de30fb8238e3830fde9adcb/Demo/Shared/Comics.xcassets/1-19.imageset/uncanny-x-men-101-comic-book-series-photo-u1.jpeg
--------------------------------------------------------------------------------
/Demo/Shared/Comics.xcassets/1-2.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "amazing-fantasy-15-comic-book-series-photo-u1.jpeg",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/Demo/Shared/Comics.xcassets/1-2.imageset/amazing-fantasy-15-comic-book-series-photo-u1.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eleev/grid-compositional-layout/831e171557ac1bf10de30fb8238e3830fde9adcb/Demo/Shared/Comics.xcassets/1-2.imageset/amazing-fantasy-15-comic-book-series-photo-u1.jpeg
--------------------------------------------------------------------------------
/Demo/Shared/Comics.xcassets/1-20.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "wonder-woman-72-comic-book-series-photo-u1.jpeg",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/Demo/Shared/Comics.xcassets/1-20.imageset/wonder-woman-72-comic-book-series-photo-u1.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eleev/grid-compositional-layout/831e171557ac1bf10de30fb8238e3830fde9adcb/Demo/Shared/Comics.xcassets/1-20.imageset/wonder-woman-72-comic-book-series-photo-u1.jpeg
--------------------------------------------------------------------------------
/Demo/Shared/Comics.xcassets/1-3.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "amazing-spider-man-1-comic-book-series-photo-u1.jpeg",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/Demo/Shared/Comics.xcassets/1-3.imageset/amazing-spider-man-1-comic-book-series-photo-u1.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eleev/grid-compositional-layout/831e171557ac1bf10de30fb8238e3830fde9adcb/Demo/Shared/Comics.xcassets/1-3.imageset/amazing-spider-man-1-comic-book-series-photo-u1.jpeg
--------------------------------------------------------------------------------
/Demo/Shared/Comics.xcassets/1-4.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "amazing-spider-man-39-comic-book-series-photo-u1.jpeg",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/Demo/Shared/Comics.xcassets/1-4.imageset/amazing-spider-man-39-comic-book-series-photo-u1.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eleev/grid-compositional-layout/831e171557ac1bf10de30fb8238e3830fde9adcb/Demo/Shared/Comics.xcassets/1-4.imageset/amazing-spider-man-39-comic-book-series-photo-u1.jpeg
--------------------------------------------------------------------------------
/Demo/Shared/Comics.xcassets/1-5.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "amazing-spider-man-300-comic-book-series-photo-u1.jpeg",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/Demo/Shared/Comics.xcassets/1-5.imageset/amazing-spider-man-300-comic-book-series-photo-u1.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eleev/grid-compositional-layout/831e171557ac1bf10de30fb8238e3830fde9adcb/Demo/Shared/Comics.xcassets/1-5.imageset/amazing-spider-man-300-comic-book-series-photo-u1.jpeg
--------------------------------------------------------------------------------
/Demo/Shared/Comics.xcassets/1-6.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "c29c90b3881385de5042597cfcfc3d7b.jpg",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/Demo/Shared/Comics.xcassets/1-6.imageset/c29c90b3881385de5042597cfcfc3d7b.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eleev/grid-compositional-layout/831e171557ac1bf10de30fb8238e3830fde9adcb/Demo/Shared/Comics.xcassets/1-6.imageset/c29c90b3881385de5042597cfcfc3d7b.jpg
--------------------------------------------------------------------------------
/Demo/Shared/Comics.xcassets/1-7.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "batman-404-comic-book-series-photo-u1.jpeg",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/Demo/Shared/Comics.xcassets/1-7.imageset/batman-404-comic-book-series-photo-u1.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eleev/grid-compositional-layout/831e171557ac1bf10de30fb8238e3830fde9adcb/Demo/Shared/Comics.xcassets/1-7.imageset/batman-404-comic-book-series-photo-u1.jpeg
--------------------------------------------------------------------------------
/Demo/Shared/Comics.xcassets/1-8.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "Wonder_Woman_Vol_4_45.jpg",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/Demo/Shared/Comics.xcassets/1-8.imageset/Wonder_Woman_Vol_4_45.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eleev/grid-compositional-layout/831e171557ac1bf10de30fb8238e3830fde9adcb/Demo/Shared/Comics.xcassets/1-8.imageset/Wonder_Woman_Vol_4_45.jpg
--------------------------------------------------------------------------------
/Demo/Shared/Comics.xcassets/1-9.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "batman-harley-quinn-comic-book-series-photo-u1.jpeg",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/Demo/Shared/Comics.xcassets/1-9.imageset/batman-harley-quinn-comic-book-series-photo-u1.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eleev/grid-compositional-layout/831e171557ac1bf10de30fb8238e3830fde9adcb/Demo/Shared/Comics.xcassets/1-9.imageset/batman-harley-quinn-comic-book-series-photo-u1.jpeg
--------------------------------------------------------------------------------
/Demo/Shared/Comics.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/Demo/Shared/ComicsData.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Caption
7 | Super Man
8 | Comment
9 | Action Comics
10 | Cover
11 | 1-1
12 |
13 |
14 | Caption
15 | Spider Man
16 | Comment
17 | Amazing Fantasy
18 | Cover
19 | 1-2
20 |
21 |
22 | Caption
23 | Chamelion Strikes
24 | Comment
25 | The Amazing Spider Man
26 | Cover
27 | 1-3
28 |
29 |
30 | Caption
31 | Green Goblin
32 | Comment
33 | The Amazing Spider Man
34 | Cover
35 | 1-4
36 |
37 |
38 | Caption
39 | Anniversary Issue
40 | Comment
41 | The Amazing Spider Man
42 | Cover
43 | 1-5
44 |
45 |
46 | Caption
47 | Batman and Joker
48 | Comment
49 | The Batman
50 | Cover
51 | 1-6
52 |
53 |
54 | Caption
55 | Death of Parents
56 | Comment
57 | The Batman
58 | Cover
59 | 1-7
60 |
61 |
62 | Caption
63 | Bane
64 | Comment
65 | The Batman
66 | Cover
67 | 1-8
68 |
69 |
70 | Caption
71 | Harley and Joker
72 | Comment
73 | Batman
74 | Cover
75 | 1-9
76 |
77 |
78 | Caption
79 | Dark Knight
80 | Comment
81 | Batman
82 | Cover
83 | 1-10
84 |
85 |
86 | Caption
87 | The Killing Joke
88 | Comment
89 | Batman
90 | Cover
91 | 1-11
92 |
93 |
94 | Caption
95 | No More!
96 | Comment
97 | Capitan America
98 | Cover
99 | 1-12
100 |
101 |
102 | Caption
103 | Shocker!
104 | Comment
105 | Crisys
106 | Cover
107 | 1-13
108 |
109 |
110 | Caption
111 | Shocker!
112 | Comment
113 | Crisys
114 | Cover
115 | 1-14
116 |
117 |
118 | Caption
119 | Hulk
120 | Comment
121 | The Incredable Hulk!
122 | Cover
123 | 1-15
124 |
125 |
126 | Caption
127 | Logan
128 | Comment
129 | The Incredable Hulk!
130 | Cover
131 | 1-16
132 |
133 |
134 | Caption
135 | Silver Surfer
136 | Comment
137 | Sky-Ryder
138 | Cover
139 | 1-17
140 |
141 |
142 | Caption
143 | Amazing Spider Man
144 | Comment
145 | The Legend
146 | Cover
147 | 1-18
148 |
149 |
150 | Caption
151 | Death Of Super Man
152 | Comment
153 | Super Man
154 | Cover
155 | 1-19
156 |
157 |
158 | Caption
159 | Shocker!
160 | Comment
161 | Crisys
162 | Cover
163 | 1-20
164 |
165 |
166 |
167 |
--------------------------------------------------------------------------------
/Demo/Shared/Data Model/Comics.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Comics.swift
3 | // Shared
4 | //
5 | // Created by Astemir Eleev on 24.06.2020.
6 | // Copyright © 2020 Astemir Eleev, Inc. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | struct Comics: Identifiable {
12 |
13 | // MARK: - Properties
14 |
15 | var id: UUID = .init()
16 |
17 | var imageName: String
18 | var caption: String
19 | var comment: String
20 |
21 | // MARK: - Initializers
22 |
23 | init(imageName: String, caption: String, comment: String) {
24 | self.caption = caption
25 | self.comment = comment
26 | self.imageName = imageName
27 | }
28 |
29 | init?(dictionary: [String : String]) {
30 | guard let image = dictionary["Cover"], let caption = dictionary["Caption"], let comment = dictionary["Comment"] else {
31 | debugPrint(#function + " one of the data properties from ComicData.plist could not be unwrapped or is nil")
32 | return nil
33 | }
34 | self.init(imageName: image, caption: caption, comment: comment)
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/Demo/Shared/Data Model/ComicsLoader.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ComicsLoader.swift
3 | // Shared
4 | //
5 | // Created by Astemir Eleev on 24.06.2020.
6 | // Copyright © 2020 Astemir Eleev, Inc. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | struct ComicsLoader {
12 |
13 | // MARK: - Properties
14 |
15 | static let dataSource = "ComicsData"
16 | static let type = "plist"
17 |
18 | // MARK: - Methods
19 |
20 | static func covers(duplicationFactor: Int = 0) -> [Comics] {
21 | var covers = [Comics]()
22 |
23 | guard let url = Bundle.main.url(forResource: dataSource, withExtension: type), let coverDict = NSArray(contentsOf: url) as? [[String : String]] else {
24 |
25 | debugPrint(#function + " could not find Comics asset catalog or something went wrong" )
26 | return covers
27 | }
28 |
29 | for dictPair in coverDict {
30 | if let comicCover = Comics(dictionary: dictPair) {
31 | covers += [comicCover]
32 | }
33 | }
34 |
35 | for _ in 0.. some View {
133 | GridCompositionalView(navigationTitle: navigationTitle,
134 | items: comicsManager.comics.count,
135 | columns: columns) { (index) -> AnyView in
136 | gridCellView(for: index)
137 | }
138 | }
139 |
140 | private func gridCellView(for index: Int) -> AnyView {
141 | AnyView(
142 | Image(comicsManager.comics[index].imageName)
143 | .resizable()
144 | .aspectRatio(contentMode: .fit)
145 | .cornerRadius(6)
146 | .shadow(radius: 10)
147 | )
148 | }
149 | }
150 |
--------------------------------------------------------------------------------
/Demo/Tests iOS/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE)
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 |
22 |
23 |
--------------------------------------------------------------------------------
/Demo/Tests iOS/Tests_iOS.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Tests_iOS.swift
3 | // Shared
4 | //
5 | // Created by Astemir Eleev on 24.06.2020.
6 | // Copyright © 2020 Astemir Eleev, Inc. All rights reserved.
7 | //
8 |
9 | import XCTest
10 |
11 | class Tests_iOS: XCTestCase {
12 |
13 | override func setUpWithError() throws {
14 | // Put setup code here. This method is called before the invocation of each test method in the class.
15 |
16 | // In UI tests it is usually best to stop immediately when a failure occurs.
17 | continueAfterFailure = false
18 |
19 | // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this.
20 | }
21 |
22 | override func tearDownWithError() throws {
23 | // Put teardown code here. This method is called after the invocation of each test method in the class.
24 | }
25 |
26 | func testExample() throws {
27 | // UI tests must launch the application that they test.
28 | let app = XCUIApplication()
29 | app.launch()
30 |
31 | // Use recording to get started writing UI tests.
32 | // Use XCTAssert and related functions to verify your tests produce the correct results.
33 | }
34 |
35 | func testLaunchPerformance() throws {
36 | if #available(macOS 10.15, iOS 13.0, tvOS 13.0, *) {
37 | // This measures how long it takes to launch your application.
38 | measure(metrics: [XCTApplicationLaunchMetric()]) {
39 | XCUIApplication().launch()
40 | }
41 | }
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/Demo/Tests macOS/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE)
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 |
22 |
23 |
--------------------------------------------------------------------------------
/Demo/Tests macOS/Tests_macOS.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Tests_macOS.swift
3 | // Shared
4 | //
5 | // Created by Astemir Eleev on 24.06.2020.
6 | // Copyright © 2020 Astemir Eleev, Inc. All rights reserved.
7 | //
8 |
9 | import XCTest
10 |
11 | class Tests_macOS: XCTestCase {
12 |
13 | override func setUpWithError() throws {
14 | // Put setup code here. This method is called before the invocation of each test method in the class.
15 |
16 | // In UI tests it is usually best to stop immediately when a failure occurs.
17 | continueAfterFailure = false
18 |
19 | // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this.
20 | }
21 |
22 | override func tearDownWithError() throws {
23 | // Put teardown code here. This method is called after the invocation of each test method in the class.
24 | }
25 |
26 | func testExample() throws {
27 | // UI tests must launch the application that they test.
28 | let app = XCUIApplication()
29 | app.launch()
30 |
31 | // Use recording to get started writing UI tests.
32 | // Use XCTAssert and related functions to verify your tests produce the correct results.
33 | }
34 |
35 | func testLaunchPerformance() throws {
36 | if #available(macOS 10.15, iOS 13.0, tvOS 13.0, *) {
37 | // This measures how long it takes to launch your application.
38 | measure(metrics: [XCTApplicationLaunchMetric()]) {
39 | XCUIApplication().launch()
40 | }
41 | }
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/Demo/iOS/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE)
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 | LSRequiresIPhoneOS
22 |
23 | UIApplicationSceneManifest
24 |
25 | UIApplicationSupportsMultipleScenes
26 |
27 |
28 | UIApplicationSupportsIndirectInputEvents
29 |
30 | UILaunchScreen
31 |
32 | UIRequiredDeviceCapabilities
33 |
34 | armv7
35 |
36 | UISupportedInterfaceOrientations
37 |
38 | UIInterfaceOrientationPortrait
39 | UIInterfaceOrientationLandscapeLeft
40 | UIInterfaceOrientationLandscapeRight
41 |
42 | UISupportedInterfaceOrientations~ipad
43 |
44 | UIInterfaceOrientationPortrait
45 | UIInterfaceOrientationPortraitUpsideDown
46 | UIInterfaceOrientationLandscapeLeft
47 | UIInterfaceOrientationLandscapeRight
48 |
49 |
50 |
51 |
--------------------------------------------------------------------------------
/Demo/macOS/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIconFile
10 |
11 | CFBundleIdentifier
12 | $(PRODUCT_BUNDLE_IDENTIFIER)
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | $(PRODUCT_NAME)
17 | CFBundlePackageType
18 | $(PRODUCT_BUNDLE_PACKAGE_TYPE)
19 | CFBundleShortVersionString
20 | 1.0
21 | CFBundleVersion
22 | 1
23 | LSMinimumSystemVersion
24 | $(MACOSX_DEPLOYMENT_TARGET)
25 |
26 |
27 |
--------------------------------------------------------------------------------
/Demo/macOS/macOS.entitlements:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | com.apple.security.app-sandbox
6 |
7 | com.apple.security.files.user-selected.read-only
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 Astemir Eleev
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 |
--------------------------------------------------------------------------------
/Package.swift:
--------------------------------------------------------------------------------
1 | // swift-tools-version:5.3
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: "GridCompositionalLayout",
8 | platforms: [
9 | .iOS(.v14),
10 | .macOS(.v10_16)
11 | ],
12 | products: [
13 | // Products define the executables and libraries a package produces, and make them visible to other packages.
14 | .library(
15 | name: "GridCompositionalLayout",
16 | targets: ["GridCompositionalLayout"]),
17 | ],
18 | dependencies: [
19 | // Dependencies declare other packages that this package depends on.
20 | // .package(url: /* package url */, from: "1.0.0"),
21 | ],
22 | targets: [
23 | // Targets are the basic building blocks of a package. A target can define a module or a test suite.
24 | // Targets can depend on other targets in this package, and on products in packages this package depends on.GridCompositionalLayout
25 | .target(name: "GridCompositionalLayout",
26 | dependencies: [],
27 | exclude: [
28 | "Assets",
29 | "Demo",
30 | "logo.jpg"
31 | ]),
32 | .testTarget(
33 | name: "GridCompositionalLayoutTests",
34 | dependencies: ["GridCompositionalLayout"]),
35 | ]
36 | )
37 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # grid-compositional-layout [](https://github.com/sindresorhus/awesome)
2 |
3 | []()
4 | []()
5 | []()
6 | []()
7 | []()
8 | []()
9 |
10 | **Last Update: 27/June/2020.**
11 |
12 | 
13 |
14 | ### If you like the project, please give it a star ⭐ It will show the creator your appreciation and help others to discover the repo.
15 |
16 | # ✍️ About
17 | 🧲 `Grid Compositional Layout` is a `SwiftUI` view that lays out the supplied views in a grid. Easily configurable and lazily retained [`Swift 5.3`, `iOS 14.0+`, `iPadOS 14.0+`, `macOS 11.0(10.16)+`].
18 |
19 | # 📚 Contents
20 | Please wait while the `.gif` files are loading (there are `9` files, that weight around `43Mb`)...
21 |
22 | | | | |
23 | :-------------------------:|:-------------------------:|:-------------------------:
24 |  |  | 
25 |  |  | 
26 |  |  | 
27 |
28 | # 📦 Installation
29 | There are no dependencies as well as any package managers involved. The repo contains both: the Swift Package and a demo Xcode project.
30 |
31 | ## Swift Package Manager
32 | Please note that the package and demo project have the minimum deplyment target for `iOS/iPadOS 14.0+` and `macOS 11.0(10.16)+`.
33 |
34 | ### Xcode 11+
35 |
36 | 1. Open `MenuBar` → `File` → `Swift Packages` → `Add Package Dependency...`
37 | 2. Paste the package repository url `https://github.com/jVirus/extensions-kit` and hit `Next`.
38 | 3. Select the installment rules.
39 |
40 | After specifying which version do you want to install, the package will be downloaded and attached to your project.
41 |
42 | ### Package.swift
43 | If you already have a `Package.swift` or you are building your own package simply add a new dependency:
44 |
45 | ```swift
46 | dependencies: [
47 | .package(url: "https://github.com/jVirus/grid-compositional-layout/", from: "1.0.0")
48 | ]
49 | ```
50 | ## Manual
51 | You can always use `copy-paste` the sources method 😄.
52 |
53 | # ✈️ Usage and APIs
54 | The `API` layer is thin and currently has a single compositional grid variant for vertical alignment. That means, under the hood the `LazyVGrid` is used to layout the supplied views. However, the future versions will support the `LazyHGrid` and their combination, which will allow to easly describe `orthogonal` compositional layouts, just as in `UIKit` with `UICollectionViewCompositionalLayout`.
55 |
56 | ## Code
57 | To create a layout you need to import the framework:
58 |
59 | ```swift
60 | import GridCompositionalLayout
61 | ```
62 |
63 | Then, instantiate an instance of `GridCompositionalView` type:
64 |
65 | ```swift
66 | var body: some View {
67 | GridCompositionalView(navigationTitle: "Your navigation title, if any",
68 | items: 20,
69 | columns: columns) { index -> AnyView in
70 | gridCellView(for: index)
71 | }
72 | }
73 | ```
74 |
75 | the `items` parameter describes the total number of views to be rendered by the view and `columns` is an input argument of type `[GridItem]`. It specifies how an item should be treated by the layout system. For example, if you specify the following:
76 |
77 | ```swift
78 | let columns = [GridItem](repeating: GridItem(.flexible(), spacing: interItemSpacing), count: 2),
79 | [GridItem](repeating: GridItem(.flexible(), spacing: interItemSpacing), count: 6),
80 | [GridItem](repeating: GridItem(.flexible(), spacing: interItemSpacing), count: 4)
81 | ```
82 | And then pass it as an input parameter to `GridCompositionalView` instance, you will get a grid, where the first `row` contains, evenly positioned `two` elements, the second row contains evenly positioned `six` elements and the `third` row contains `four` elements. Then, if there is a `fifth` row, it will use the first grid item description e.g. evenly positioned `two` columns of items.
83 |
84 | By combining and experimenting with differnet grid item configurations, you can customize the layout of the supplied views.
85 |
86 | # ⚠️ Warning
87 | The assets used in this project were taken from the `Web`. Do not use them for commertial purposes and proprietary projects. They are used just for demostration only.
88 |
89 | # 👨💻 Author
90 | [Astemir Eleev](https://github.com/jVirus)
91 |
92 | # 🔖 Licence
93 | The project is available under [MIT Licence](https://github.com/jVirus/grid-compositional-layout/blob/main/LICENSE)
94 |
--------------------------------------------------------------------------------
/Sources/GridCompositionalLayout/CompositionalGridLayout.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CompositionalGridLayout.swift
3 | // GridCompositionalLayout
4 | //
5 | // Created by Astemir Eleev on 24.06.2020.
6 | // Copyright © 2020 Astemir Eleev, Inc. All rights reserved.
7 | //
8 |
9 | import SwiftUI
10 |
11 | public protocol CompositionalGridLayout {
12 |
13 | // MARK: - Properties
14 |
15 | var items: Int { get }
16 | var indexManager: IndexManager { get }
17 | var columns: [[GridItem]] { get }
18 | var incrementedContent: AnyView { get }
19 |
20 | // MARK: - Methods
21 |
22 | func contentLenght() -> Int
23 | }
24 |
25 | public extension CompositionalGridLayout {
26 | func contentLenght() -> Int {
27 | let lenght = columns
28 | .compactMap { $0.count }
29 | .reduce(0) { $0 + $1 }
30 | return (items / lenght) + (items % lenght > 0 ? 1 : 0)
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/Sources/GridCompositionalLayout/GridCompositionalLayout.swift:
--------------------------------------------------------------------------------
1 | //
2 | // GridCompositionalView.swift
3 | // GridCompositionalLayout
4 | //
5 | // Created by Astemir Eleev on 24.06.2020.
6 | // Copyright © 2020 Astemir Eleev, Inc. All rights reserved.
7 | //
8 |
9 | import SwiftUI
10 |
11 | public struct GridCompositionalView: View, CompositionalGridLayout {
12 |
13 | @StateObject public var indexManager = IndexManager()
14 |
15 | public var incrementedContent: AnyView {
16 | guard indexManager.increment(cap: items) else {
17 | return AnyView(EmptyView())
18 | }
19 | return AnyView(content(indexManager.index))
20 | }
21 |
22 | public let navigationTitle: String
23 | public let items: Int
24 | public let itemInsets: CGSize
25 | public let padding: (edgeInsets: Edge.Set, lenght: CGFloat)
26 |
27 | public var columns: [[GridItem]]
28 | public let content: (_ index: Int) -> AnyView
29 |
30 | public init(navigationTitle: String,
31 | items: Int,
32 | itemInsets: CGSize = .init(width: 16, height: 16),
33 | padding: (edgeInsets: Edge.Set, lenght: CGFloat) = (.all, 16),
34 | columns: [[GridItem]],
35 | @ViewBuilder content: @escaping (_ index: Int) -> AnyView) {
36 | self.navigationTitle = navigationTitle
37 | self.items = items
38 | self.itemInsets = itemInsets
39 | self.padding = padding
40 | self.columns = columns
41 | self.content = content
42 | }
43 |
44 | public var body: some View {
45 | ScrollView() {
46 | ForEach(0.. some View {
57 | func items() -> some View {
58 | ForEach(0.. Bool {
20 | guard index < cap - 1 else { return false }
21 | index += 1
22 | return true
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/Tests/GridCompositionalLayoutTests/GridCompositionalLayoutTests.swift:
--------------------------------------------------------------------------------
1 | import XCTest
2 | @testable import GridCompositionalLayout
3 |
4 | final class GridCompositionalLayoutTests: XCTestCase {
5 | func testExample() {
6 | // This is an example of a functional test case.
7 | // Use XCTAssert and related functions to verify your tests produce the correct
8 | // results.
9 | }
10 |
11 | static var allTests = [
12 | ("testExample", testExample),
13 | ]
14 | }
15 |
--------------------------------------------------------------------------------
/Tests/GridCompositionalLayoutTests/XCTestManifests.swift:
--------------------------------------------------------------------------------
1 | import XCTest
2 |
3 | #if !canImport(ObjectiveC)
4 | public func allTests() -> [XCTestCaseEntry] {
5 | return [
6 | testCase(GridCompositionalLayoutTests.allTests),
7 | ]
8 | }
9 | #endif
10 |
--------------------------------------------------------------------------------
/Tests/LinuxMain.swift:
--------------------------------------------------------------------------------
1 | import XCTest
2 |
3 | import GridCompositionalLayoutTests
4 |
5 | var tests = [XCTestCaseEntry]()
6 | tests += GridCompositionalLayoutTests.allTests()
7 | XCTMain(tests)
8 |
--------------------------------------------------------------------------------
/logo.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eleev/grid-compositional-layout/831e171557ac1bf10de30fb8238e3830fde9adcb/logo.jpg
--------------------------------------------------------------------------------