├── .gitignore
├── .swiftpm
└── xcode
│ └── package.xcworkspace
│ └── contents.xcworkspacedata
├── Example-iOS-SwiftUI
├── Example-iOS-SwiftUI.xcodeproj
│ └── project.pbxproj
└── Example-iOS-SwiftUI
│ ├── Assets.xcassets
│ ├── AccentColor.colorset
│ │ └── Contents.json
│ ├── AppIcon.appiconset
│ │ └── Contents.json
│ ├── Contents.json
│ └── test_images
│ │ ├── 0.imageset
│ │ ├── Contents.json
│ │ └── zelda.png
│ │ ├── 1.imageset
│ │ ├── Contents.json
│ │ └── arctichare.png
│ │ ├── 10.imageset
│ │ ├── Contents.json
│ │ └── monarch.png
│ │ ├── 11.imageset
│ │ ├── Contents.json
│ │ └── mountain.png
│ │ ├── 12.imageset
│ │ ├── Contents.json
│ │ └── peppers.png
│ │ ├── 13.imageset
│ │ ├── Contents.json
│ │ └── pool.png
│ │ ├── 14.imageset
│ │ ├── Contents.json
│ │ └── sails.png
│ │ ├── 15.imageset
│ │ ├── Contents.json
│ │ └── serrano.png
│ │ ├── 16.imageset
│ │ ├── Contents.json
│ │ └── tulips.png
│ │ ├── 17.imageset
│ │ ├── Contents.json
│ │ └── watch.png
│ │ ├── 2.imageset
│ │ ├── Contents.json
│ │ └── baboon.png
│ │ ├── 3.imageset
│ │ ├── Contents.json
│ │ └── barbara.png
│ │ ├── 4.imageset
│ │ ├── Contents.json
│ │ └── boat.png
│ │ ├── 5.imageset
│ │ ├── Contents.json
│ │ └── cat.png
│ │ ├── 6.imageset
│ │ ├── Contents.json
│ │ └── fruits.png
│ │ ├── 7.imageset
│ │ ├── Contents.json
│ │ └── frymire.png
│ │ ├── 8.imageset
│ │ ├── Contents.json
│ │ └── goldhill.png
│ │ ├── 9.imageset
│ │ ├── Contents.json
│ │ └── lena.png
│ │ └── Contents.json
│ ├── Example_iOS_SwiftUIApp.swift
│ ├── ImagesView.swift
│ ├── Info.plist
│ └── Preview Content
│ └── Preview Assets.xcassets
│ └── Contents.json
├── Example-iOS
├── Example-iOS.xcodeproj
│ └── project.pbxproj
└── Example-iOS
│ ├── AppDelegate.swift
│ ├── Assets.xcassets
│ ├── AccentColor.colorset
│ │ └── Contents.json
│ ├── AppIcon.appiconset
│ │ └── Contents.json
│ ├── Contents.json
│ └── test_images
│ │ ├── 0.imageset
│ │ ├── Contents.json
│ │ └── zelda.png
│ │ ├── 1.imageset
│ │ ├── Contents.json
│ │ └── arctichare.png
│ │ ├── 10.imageset
│ │ ├── Contents.json
│ │ └── monarch.png
│ │ ├── 11.imageset
│ │ ├── Contents.json
│ │ └── mountain.png
│ │ ├── 12.imageset
│ │ ├── Contents.json
│ │ └── peppers.png
│ │ ├── 13.imageset
│ │ ├── Contents.json
│ │ └── pool.png
│ │ ├── 14.imageset
│ │ ├── Contents.json
│ │ └── sails.png
│ │ ├── 15.imageset
│ │ ├── Contents.json
│ │ └── serrano.png
│ │ ├── 16.imageset
│ │ ├── Contents.json
│ │ └── tulips.png
│ │ ├── 17.imageset
│ │ ├── Contents.json
│ │ └── watch.png
│ │ ├── 2.imageset
│ │ ├── Contents.json
│ │ └── baboon.png
│ │ ├── 3.imageset
│ │ ├── Contents.json
│ │ └── barbara.png
│ │ ├── 4.imageset
│ │ ├── Contents.json
│ │ └── boat.png
│ │ ├── 5.imageset
│ │ ├── Contents.json
│ │ └── cat.png
│ │ ├── 6.imageset
│ │ ├── Contents.json
│ │ └── fruits.png
│ │ ├── 7.imageset
│ │ ├── Contents.json
│ │ └── frymire.png
│ │ ├── 8.imageset
│ │ ├── Contents.json
│ │ └── goldhill.png
│ │ ├── 9.imageset
│ │ ├── Contents.json
│ │ └── lena.png
│ │ └── Contents.json
│ ├── Base.lproj
│ ├── LaunchScreen.storyboard
│ └── Main.storyboard
│ ├── CollectionViewCell.swift
│ ├── ImageCollectionViewCell.swift
│ ├── ImagesViewController.swift
│ ├── Info.plist
│ ├── SceneDelegate.swift
│ └── ViewController.swift
├── LICENSE
├── Package.swift
├── README.md
├── Screenshots
├── positioning.gif
├── screenshot_01.png
├── screenshot_02.png
└── scrolling.gif
├── Source
├── Info.plist
└── WatchLayout.swift
├── SwiftUI
├── Info.plist
├── WatchLayoutAttributes.swift
├── WatchLayoutUIPresentable.swift
└── WatchLayoutView.swift
├── WatchLayout-SwiftUI.podspec
├── WatchLayout.podspec
├── WatchLayout.xcodeproj
└── project.pbxproj
└── WatchLayout.xcworkspace
├── contents.xcworkspacedata
└── xcshareddata
└── IDEWorkspaceChecks.plist
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | /.build
3 | /Packages
4 | xcuserdata/
5 |
6 |
7 | # Xcode
8 | #
9 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
10 |
11 | ## User settings
12 | xcuserdata/
13 |
14 | ## compatibility with Xcode 8 and earlier (ignoring not required starting Xcode 9)
15 | *.xcscmblueprint
16 | *.xccheckout
17 |
18 | ## compatibility with Xcode 3 and earlier (ignoring not required starting Xcode 4)
19 | build/
20 | DerivedData/
21 | *.moved-aside
22 | *.pbxuser
23 | !default.pbxuser
24 | *.mode1v3
25 | !default.mode1v3
26 | *.mode2v3
27 | !default.mode2v3
28 | *.perspectivev3
29 | !default.perspectivev3
30 |
31 | ## Obj-C/Swift specific
32 | *.hmap
33 |
34 | ## App packaging
35 | *.ipa
36 | *.dSYM.zip
37 | *.dSYM
38 |
39 | ## Playgrounds
40 | timeline.xctimeline
41 | playground.xcworkspace
42 |
43 | # Swift Package Manager
44 | #
45 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies.
46 | # Packages/
47 | # Package.pins
48 | # Package.resolved
49 | # *.xcodeproj
50 | #
51 | # Xcode automatically generates this directory with a .xcworkspacedata file and xcuserdata
52 | # hence it is not needed unless you have added a package configuration file to your project
53 | # .swiftpm
54 |
55 | .build/
56 |
57 | # CocoaPods
58 | #
59 | # We recommend against adding the Pods directory to your .gitignore. However
60 | # you should judge for yourself, the pros and cons are mentioned at:
61 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
62 | #
63 | # Pods/
64 | #
65 | # Add this line if you want to avoid checking in source code from the Xcode workspace
66 | # *.xcworkspace
67 |
68 | # Carthage
69 | #
70 | # Add this line if you want to avoid checking in source code from Carthage dependencies.
71 | # Carthage/Checkouts
72 |
73 | Carthage/Build/
74 |
75 | # Accio dependency management
76 | Dependencies/
77 | .accio/
78 |
79 | # fastlane
80 | #
81 | # It is recommended to not store the screenshots in the git repo.
82 | # Instead, use fastlane to re-generate the screenshots whenever they are needed.
83 | # For more information about the recommended setup visit:
84 | # https://docs.fastlane.tools/best-practices/source-control/#source-control
85 |
86 | fastlane/report.xml
87 | fastlane/Preview.html
88 | fastlane/screenshots/**/*.png
89 | fastlane/test_output
90 |
91 | # Code Injection
92 | #
93 | # After new code Injection tools there's a generated folder /iOSInjectionProject
94 | # https://github.com/johnno1962/injectionforxcode
95 |
96 | iOSInjectionProject/
97 |
--------------------------------------------------------------------------------
/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Example-iOS-SwiftUI/Example-iOS-SwiftUI.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 50;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 156311B5261037D60033FFF8 /* Example_iOS_SwiftUIApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 156311B4261037D60033FFF8 /* Example_iOS_SwiftUIApp.swift */; };
11 | 156311B9261037D70033FFF8 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 156311B8261037D70033FFF8 /* Assets.xcassets */; };
12 | 156311BC261037D70033FFF8 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 156311BB261037D70033FFF8 /* Preview Assets.xcassets */; };
13 | 4B02529128F414FE00EC67AA /* WatchLayout_SwiftUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B02528D28F3DEBF00EC67AA /* WatchLayout_SwiftUI.framework */; };
14 | 4B02529228F414FE00EC67AA /* WatchLayout_SwiftUI.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 4B02528D28F3DEBF00EC67AA /* WatchLayout_SwiftUI.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
15 | 4B0BF09F28F93F21007CFB54 /* ImagesView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B0BF09E28F93F21007CFB54 /* ImagesView.swift */; };
16 | /* End PBXBuildFile section */
17 |
18 | /* Begin PBXContainerItemProxy section */
19 | 156311CD261038750033FFF8 /* PBXContainerItemProxy */ = {
20 | isa = PBXContainerItemProxy;
21 | containerPortal = 156311C8261038740033FFF8 /* WatchLayout.xcodeproj */;
22 | proxyType = 2;
23 | remoteGlobalIDString = 156311632610331E0033FFF8;
24 | remoteInfo = WatchLayout;
25 | };
26 | 4B02528C28F3DEBF00EC67AA /* PBXContainerItemProxy */ = {
27 | isa = PBXContainerItemProxy;
28 | containerPortal = 156311C8261038740033FFF8 /* WatchLayout.xcodeproj */;
29 | proxyType = 2;
30 | remoteGlobalIDString = 4B02527E28F3DE8700EC67AA;
31 | remoteInfo = "WatchLayout-SwiftUI";
32 | };
33 | /* End PBXContainerItemProxy section */
34 |
35 | /* Begin PBXCopyFilesBuildPhase section */
36 | 4B02529328F414FE00EC67AA /* Embed Frameworks */ = {
37 | isa = PBXCopyFilesBuildPhase;
38 | buildActionMask = 2147483647;
39 | dstPath = "";
40 | dstSubfolderSpec = 10;
41 | files = (
42 | 4B02529228F414FE00EC67AA /* WatchLayout_SwiftUI.framework in Embed Frameworks */,
43 | );
44 | name = "Embed Frameworks";
45 | runOnlyForDeploymentPostprocessing = 0;
46 | };
47 | /* End PBXCopyFilesBuildPhase section */
48 |
49 | /* Begin PBXFileReference section */
50 | 156311B1261037D60033FFF8 /* Example-iOS-SwiftUI.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Example-iOS-SwiftUI.app"; sourceTree = BUILT_PRODUCTS_DIR; };
51 | 156311B4261037D60033FFF8 /* Example_iOS_SwiftUIApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Example_iOS_SwiftUIApp.swift; sourceTree = ""; };
52 | 156311B8261037D70033FFF8 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
53 | 156311BB261037D70033FFF8 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; };
54 | 156311BD261037D70033FFF8 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
55 | 156311C8261038740033FFF8 /* WatchLayout.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = WatchLayout.xcodeproj; path = ../WatchLayout.xcodeproj; sourceTree = ""; };
56 | 4B0BF09E28F93F21007CFB54 /* ImagesView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImagesView.swift; sourceTree = ""; };
57 | /* End PBXFileReference section */
58 |
59 | /* Begin PBXFrameworksBuildPhase section */
60 | 156311AE261037D60033FFF8 /* Frameworks */ = {
61 | isa = PBXFrameworksBuildPhase;
62 | buildActionMask = 2147483647;
63 | files = (
64 | 4B02529128F414FE00EC67AA /* WatchLayout_SwiftUI.framework in Frameworks */,
65 | );
66 | runOnlyForDeploymentPostprocessing = 0;
67 | };
68 | /* End PBXFrameworksBuildPhase section */
69 |
70 | /* Begin PBXGroup section */
71 | 156311A8261037D60033FFF8 = {
72 | isa = PBXGroup;
73 | children = (
74 | 156311C8261038740033FFF8 /* WatchLayout.xcodeproj */,
75 | 156311B3261037D60033FFF8 /* Example-iOS-SwiftUI */,
76 | 156311B2261037D60033FFF8 /* Products */,
77 | 156311D2261038930033FFF8 /* Frameworks */,
78 | );
79 | sourceTree = "";
80 | };
81 | 156311B2261037D60033FFF8 /* Products */ = {
82 | isa = PBXGroup;
83 | children = (
84 | 156311B1261037D60033FFF8 /* Example-iOS-SwiftUI.app */,
85 | );
86 | name = Products;
87 | sourceTree = "";
88 | };
89 | 156311B3261037D60033FFF8 /* Example-iOS-SwiftUI */ = {
90 | isa = PBXGroup;
91 | children = (
92 | 156311B4261037D60033FFF8 /* Example_iOS_SwiftUIApp.swift */,
93 | 4B0BF09E28F93F21007CFB54 /* ImagesView.swift */,
94 | 156311B8261037D70033FFF8 /* Assets.xcassets */,
95 | 156311BD261037D70033FFF8 /* Info.plist */,
96 | 156311BA261037D70033FFF8 /* Preview Content */,
97 | );
98 | path = "Example-iOS-SwiftUI";
99 | sourceTree = "";
100 | };
101 | 156311BA261037D70033FFF8 /* Preview Content */ = {
102 | isa = PBXGroup;
103 | children = (
104 | 156311BB261037D70033FFF8 /* Preview Assets.xcassets */,
105 | );
106 | path = "Preview Content";
107 | sourceTree = "";
108 | };
109 | 156311C9261038740033FFF8 /* Products */ = {
110 | isa = PBXGroup;
111 | children = (
112 | 156311CE261038750033FFF8 /* WatchLayout.framework */,
113 | 4B02528D28F3DEBF00EC67AA /* WatchLayout_SwiftUI.framework */,
114 | );
115 | name = Products;
116 | sourceTree = "";
117 | };
118 | 156311D2261038930033FFF8 /* Frameworks */ = {
119 | isa = PBXGroup;
120 | children = (
121 | );
122 | name = Frameworks;
123 | sourceTree = "";
124 | };
125 | /* End PBXGroup section */
126 |
127 | /* Begin PBXNativeTarget section */
128 | 156311B0261037D60033FFF8 /* Example-iOS-SwiftUI */ = {
129 | isa = PBXNativeTarget;
130 | buildConfigurationList = 156311C0261037D70033FFF8 /* Build configuration list for PBXNativeTarget "Example-iOS-SwiftUI" */;
131 | buildPhases = (
132 | 156311AD261037D60033FFF8 /* Sources */,
133 | 156311AE261037D60033FFF8 /* Frameworks */,
134 | 156311AF261037D60033FFF8 /* Resources */,
135 | 4B02529328F414FE00EC67AA /* Embed Frameworks */,
136 | );
137 | buildRules = (
138 | );
139 | dependencies = (
140 | );
141 | name = "Example-iOS-SwiftUI";
142 | productName = "Example-iOS-SwiftUI";
143 | productReference = 156311B1261037D60033FFF8 /* Example-iOS-SwiftUI.app */;
144 | productType = "com.apple.product-type.application";
145 | };
146 | /* End PBXNativeTarget section */
147 |
148 | /* Begin PBXProject section */
149 | 156311A9261037D60033FFF8 /* Project object */ = {
150 | isa = PBXProject;
151 | attributes = {
152 | LastSwiftUpdateCheck = 1240;
153 | LastUpgradeCheck = 1240;
154 | TargetAttributes = {
155 | 156311B0261037D60033FFF8 = {
156 | CreatedOnToolsVersion = 12.4;
157 | };
158 | };
159 | };
160 | buildConfigurationList = 156311AC261037D60033FFF8 /* Build configuration list for PBXProject "Example-iOS-SwiftUI" */;
161 | compatibilityVersion = "Xcode 9.3";
162 | developmentRegion = en;
163 | hasScannedForEncodings = 0;
164 | knownRegions = (
165 | en,
166 | Base,
167 | );
168 | mainGroup = 156311A8261037D60033FFF8;
169 | productRefGroup = 156311B2261037D60033FFF8 /* Products */;
170 | projectDirPath = "";
171 | projectReferences = (
172 | {
173 | ProductGroup = 156311C9261038740033FFF8 /* Products */;
174 | ProjectRef = 156311C8261038740033FFF8 /* WatchLayout.xcodeproj */;
175 | },
176 | );
177 | projectRoot = "";
178 | targets = (
179 | 156311B0261037D60033FFF8 /* Example-iOS-SwiftUI */,
180 | );
181 | };
182 | /* End PBXProject section */
183 |
184 | /* Begin PBXReferenceProxy section */
185 | 156311CE261038750033FFF8 /* WatchLayout.framework */ = {
186 | isa = PBXReferenceProxy;
187 | fileType = wrapper.framework;
188 | path = WatchLayout.framework;
189 | remoteRef = 156311CD261038750033FFF8 /* PBXContainerItemProxy */;
190 | sourceTree = BUILT_PRODUCTS_DIR;
191 | };
192 | 4B02528D28F3DEBF00EC67AA /* WatchLayout_SwiftUI.framework */ = {
193 | isa = PBXReferenceProxy;
194 | fileType = wrapper.framework;
195 | path = WatchLayout_SwiftUI.framework;
196 | remoteRef = 4B02528C28F3DEBF00EC67AA /* PBXContainerItemProxy */;
197 | sourceTree = BUILT_PRODUCTS_DIR;
198 | };
199 | /* End PBXReferenceProxy section */
200 |
201 | /* Begin PBXResourcesBuildPhase section */
202 | 156311AF261037D60033FFF8 /* Resources */ = {
203 | isa = PBXResourcesBuildPhase;
204 | buildActionMask = 2147483647;
205 | files = (
206 | 156311BC261037D70033FFF8 /* Preview Assets.xcassets in Resources */,
207 | 156311B9261037D70033FFF8 /* Assets.xcassets in Resources */,
208 | );
209 | runOnlyForDeploymentPostprocessing = 0;
210 | };
211 | /* End PBXResourcesBuildPhase section */
212 |
213 | /* Begin PBXSourcesBuildPhase section */
214 | 156311AD261037D60033FFF8 /* Sources */ = {
215 | isa = PBXSourcesBuildPhase;
216 | buildActionMask = 2147483647;
217 | files = (
218 | 4B0BF09F28F93F21007CFB54 /* ImagesView.swift in Sources */,
219 | 156311B5261037D60033FFF8 /* Example_iOS_SwiftUIApp.swift in Sources */,
220 | );
221 | runOnlyForDeploymentPostprocessing = 0;
222 | };
223 | /* End PBXSourcesBuildPhase section */
224 |
225 | /* Begin XCBuildConfiguration section */
226 | 156311BE261037D70033FFF8 /* Debug */ = {
227 | isa = XCBuildConfiguration;
228 | buildSettings = {
229 | ALWAYS_SEARCH_USER_PATHS = NO;
230 | CLANG_ANALYZER_NONNULL = YES;
231 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
232 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
233 | CLANG_CXX_LIBRARY = "libc++";
234 | CLANG_ENABLE_MODULES = YES;
235 | CLANG_ENABLE_OBJC_ARC = YES;
236 | CLANG_ENABLE_OBJC_WEAK = YES;
237 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
238 | CLANG_WARN_BOOL_CONVERSION = YES;
239 | CLANG_WARN_COMMA = YES;
240 | CLANG_WARN_CONSTANT_CONVERSION = YES;
241 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
242 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
243 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
244 | CLANG_WARN_EMPTY_BODY = YES;
245 | CLANG_WARN_ENUM_CONVERSION = YES;
246 | CLANG_WARN_INFINITE_RECURSION = YES;
247 | CLANG_WARN_INT_CONVERSION = YES;
248 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
249 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
250 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
251 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
252 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
253 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
254 | CLANG_WARN_STRICT_PROTOTYPES = YES;
255 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
256 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
257 | CLANG_WARN_UNREACHABLE_CODE = YES;
258 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
259 | COPY_PHASE_STRIP = NO;
260 | DEBUG_INFORMATION_FORMAT = dwarf;
261 | ENABLE_STRICT_OBJC_MSGSEND = YES;
262 | ENABLE_TESTABILITY = YES;
263 | GCC_C_LANGUAGE_STANDARD = gnu11;
264 | GCC_DYNAMIC_NO_PIC = NO;
265 | GCC_NO_COMMON_BLOCKS = YES;
266 | GCC_OPTIMIZATION_LEVEL = 0;
267 | GCC_PREPROCESSOR_DEFINITIONS = (
268 | "DEBUG=1",
269 | "$(inherited)",
270 | );
271 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
272 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
273 | GCC_WARN_UNDECLARED_SELECTOR = YES;
274 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
275 | GCC_WARN_UNUSED_FUNCTION = YES;
276 | GCC_WARN_UNUSED_VARIABLE = YES;
277 | IPHONEOS_DEPLOYMENT_TARGET = 14.4;
278 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
279 | MTL_FAST_MATH = YES;
280 | ONLY_ACTIVE_ARCH = YES;
281 | SDKROOT = iphoneos;
282 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
283 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
284 | };
285 | name = Debug;
286 | };
287 | 156311BF261037D70033FFF8 /* Release */ = {
288 | isa = XCBuildConfiguration;
289 | buildSettings = {
290 | ALWAYS_SEARCH_USER_PATHS = NO;
291 | CLANG_ANALYZER_NONNULL = YES;
292 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
293 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
294 | CLANG_CXX_LIBRARY = "libc++";
295 | CLANG_ENABLE_MODULES = YES;
296 | CLANG_ENABLE_OBJC_ARC = YES;
297 | CLANG_ENABLE_OBJC_WEAK = YES;
298 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
299 | CLANG_WARN_BOOL_CONVERSION = YES;
300 | CLANG_WARN_COMMA = YES;
301 | CLANG_WARN_CONSTANT_CONVERSION = YES;
302 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
303 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
304 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
305 | CLANG_WARN_EMPTY_BODY = YES;
306 | CLANG_WARN_ENUM_CONVERSION = YES;
307 | CLANG_WARN_INFINITE_RECURSION = YES;
308 | CLANG_WARN_INT_CONVERSION = YES;
309 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
310 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
311 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
312 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
313 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
314 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
315 | CLANG_WARN_STRICT_PROTOTYPES = YES;
316 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
317 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
318 | CLANG_WARN_UNREACHABLE_CODE = YES;
319 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
320 | COPY_PHASE_STRIP = NO;
321 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
322 | ENABLE_NS_ASSERTIONS = NO;
323 | ENABLE_STRICT_OBJC_MSGSEND = YES;
324 | GCC_C_LANGUAGE_STANDARD = gnu11;
325 | GCC_NO_COMMON_BLOCKS = YES;
326 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
327 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
328 | GCC_WARN_UNDECLARED_SELECTOR = YES;
329 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
330 | GCC_WARN_UNUSED_FUNCTION = YES;
331 | GCC_WARN_UNUSED_VARIABLE = YES;
332 | IPHONEOS_DEPLOYMENT_TARGET = 14.4;
333 | MTL_ENABLE_DEBUG_INFO = NO;
334 | MTL_FAST_MATH = YES;
335 | SDKROOT = iphoneos;
336 | SWIFT_COMPILATION_MODE = wholemodule;
337 | SWIFT_OPTIMIZATION_LEVEL = "-O";
338 | VALIDATE_PRODUCT = YES;
339 | };
340 | name = Release;
341 | };
342 | 156311C1261037D70033FFF8 /* Debug */ = {
343 | isa = XCBuildConfiguration;
344 | buildSettings = {
345 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
346 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
347 | CODE_SIGN_STYLE = Automatic;
348 | DEVELOPMENT_ASSET_PATHS = "\"Example-iOS-SwiftUI/Preview Content\"";
349 | ENABLE_PREVIEWS = YES;
350 | INFOPLIST_FILE = "Example-iOS-SwiftUI/Info.plist";
351 | IPHONEOS_DEPLOYMENT_TARGET = 14.0;
352 | LD_RUNPATH_SEARCH_PATHS = (
353 | "$(inherited)",
354 | "@executable_path/Frameworks",
355 | );
356 | PRODUCT_BUNDLE_IDENTIFIER = "Hoc-Tran.Example-iOS-SwiftUI";
357 | PRODUCT_NAME = "$(TARGET_NAME)";
358 | SWIFT_VERSION = 5.0;
359 | TARGETED_DEVICE_FAMILY = "1,2";
360 | };
361 | name = Debug;
362 | };
363 | 156311C2261037D70033FFF8 /* Release */ = {
364 | isa = XCBuildConfiguration;
365 | buildSettings = {
366 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
367 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
368 | CODE_SIGN_STYLE = Automatic;
369 | DEVELOPMENT_ASSET_PATHS = "\"Example-iOS-SwiftUI/Preview Content\"";
370 | ENABLE_PREVIEWS = YES;
371 | INFOPLIST_FILE = "Example-iOS-SwiftUI/Info.plist";
372 | IPHONEOS_DEPLOYMENT_TARGET = 14.0;
373 | LD_RUNPATH_SEARCH_PATHS = (
374 | "$(inherited)",
375 | "@executable_path/Frameworks",
376 | );
377 | PRODUCT_BUNDLE_IDENTIFIER = "Hoc-Tran.Example-iOS-SwiftUI";
378 | PRODUCT_NAME = "$(TARGET_NAME)";
379 | SWIFT_VERSION = 5.0;
380 | TARGETED_DEVICE_FAMILY = "1,2";
381 | };
382 | name = Release;
383 | };
384 | /* End XCBuildConfiguration section */
385 |
386 | /* Begin XCConfigurationList section */
387 | 156311AC261037D60033FFF8 /* Build configuration list for PBXProject "Example-iOS-SwiftUI" */ = {
388 | isa = XCConfigurationList;
389 | buildConfigurations = (
390 | 156311BE261037D70033FFF8 /* Debug */,
391 | 156311BF261037D70033FFF8 /* Release */,
392 | );
393 | defaultConfigurationIsVisible = 0;
394 | defaultConfigurationName = Release;
395 | };
396 | 156311C0261037D70033FFF8 /* Build configuration list for PBXNativeTarget "Example-iOS-SwiftUI" */ = {
397 | isa = XCConfigurationList;
398 | buildConfigurations = (
399 | 156311C1261037D70033FFF8 /* Debug */,
400 | 156311C2261037D70033FFF8 /* Release */,
401 | );
402 | defaultConfigurationIsVisible = 0;
403 | defaultConfigurationName = Release;
404 | };
405 | /* End XCConfigurationList section */
406 | };
407 | rootObject = 156311A9261037D60033FFF8 /* Project object */;
408 | }
409 |
--------------------------------------------------------------------------------
/Example-iOS-SwiftUI/Example-iOS-SwiftUI/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 |
--------------------------------------------------------------------------------
/Example-iOS-SwiftUI/Example-iOS-SwiftUI/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 | "info" : {
95 | "author" : "xcode",
96 | "version" : 1
97 | }
98 | }
99 |
--------------------------------------------------------------------------------
/Example-iOS-SwiftUI/Example-iOS-SwiftUI/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/Example-iOS-SwiftUI/Example-iOS-SwiftUI/Assets.xcassets/test_images/0.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "filename" : "zelda.png",
5 | "idiom" : "universal",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "author" : "xcode",
19 | "version" : 1
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/Example-iOS-SwiftUI/Example-iOS-SwiftUI/Assets.xcassets/test_images/0.imageset/zelda.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HocTran/WatchLayout/1eee90826452e1f3d3d8c4488ed65de63f0e90bc/Example-iOS-SwiftUI/Example-iOS-SwiftUI/Assets.xcassets/test_images/0.imageset/zelda.png
--------------------------------------------------------------------------------
/Example-iOS-SwiftUI/Example-iOS-SwiftUI/Assets.xcassets/test_images/1.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "filename" : "arctichare.png",
5 | "idiom" : "universal",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "author" : "xcode",
19 | "version" : 1
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/Example-iOS-SwiftUI/Example-iOS-SwiftUI/Assets.xcassets/test_images/1.imageset/arctichare.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HocTran/WatchLayout/1eee90826452e1f3d3d8c4488ed65de63f0e90bc/Example-iOS-SwiftUI/Example-iOS-SwiftUI/Assets.xcassets/test_images/1.imageset/arctichare.png
--------------------------------------------------------------------------------
/Example-iOS-SwiftUI/Example-iOS-SwiftUI/Assets.xcassets/test_images/10.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "filename" : "monarch.png",
5 | "idiom" : "universal",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "author" : "xcode",
19 | "version" : 1
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/Example-iOS-SwiftUI/Example-iOS-SwiftUI/Assets.xcassets/test_images/10.imageset/monarch.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HocTran/WatchLayout/1eee90826452e1f3d3d8c4488ed65de63f0e90bc/Example-iOS-SwiftUI/Example-iOS-SwiftUI/Assets.xcassets/test_images/10.imageset/monarch.png
--------------------------------------------------------------------------------
/Example-iOS-SwiftUI/Example-iOS-SwiftUI/Assets.xcassets/test_images/11.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "filename" : "mountain.png",
5 | "idiom" : "universal",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "author" : "xcode",
19 | "version" : 1
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/Example-iOS-SwiftUI/Example-iOS-SwiftUI/Assets.xcassets/test_images/11.imageset/mountain.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HocTran/WatchLayout/1eee90826452e1f3d3d8c4488ed65de63f0e90bc/Example-iOS-SwiftUI/Example-iOS-SwiftUI/Assets.xcassets/test_images/11.imageset/mountain.png
--------------------------------------------------------------------------------
/Example-iOS-SwiftUI/Example-iOS-SwiftUI/Assets.xcassets/test_images/12.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "filename" : "peppers.png",
5 | "idiom" : "universal",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "author" : "xcode",
19 | "version" : 1
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/Example-iOS-SwiftUI/Example-iOS-SwiftUI/Assets.xcassets/test_images/12.imageset/peppers.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HocTran/WatchLayout/1eee90826452e1f3d3d8c4488ed65de63f0e90bc/Example-iOS-SwiftUI/Example-iOS-SwiftUI/Assets.xcassets/test_images/12.imageset/peppers.png
--------------------------------------------------------------------------------
/Example-iOS-SwiftUI/Example-iOS-SwiftUI/Assets.xcassets/test_images/13.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "filename" : "pool.png",
5 | "idiom" : "universal",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "author" : "xcode",
19 | "version" : 1
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/Example-iOS-SwiftUI/Example-iOS-SwiftUI/Assets.xcassets/test_images/13.imageset/pool.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HocTran/WatchLayout/1eee90826452e1f3d3d8c4488ed65de63f0e90bc/Example-iOS-SwiftUI/Example-iOS-SwiftUI/Assets.xcassets/test_images/13.imageset/pool.png
--------------------------------------------------------------------------------
/Example-iOS-SwiftUI/Example-iOS-SwiftUI/Assets.xcassets/test_images/14.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "filename" : "sails.png",
5 | "idiom" : "universal",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "author" : "xcode",
19 | "version" : 1
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/Example-iOS-SwiftUI/Example-iOS-SwiftUI/Assets.xcassets/test_images/14.imageset/sails.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HocTran/WatchLayout/1eee90826452e1f3d3d8c4488ed65de63f0e90bc/Example-iOS-SwiftUI/Example-iOS-SwiftUI/Assets.xcassets/test_images/14.imageset/sails.png
--------------------------------------------------------------------------------
/Example-iOS-SwiftUI/Example-iOS-SwiftUI/Assets.xcassets/test_images/15.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "filename" : "serrano.png",
5 | "idiom" : "universal",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "author" : "xcode",
19 | "version" : 1
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/Example-iOS-SwiftUI/Example-iOS-SwiftUI/Assets.xcassets/test_images/15.imageset/serrano.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HocTran/WatchLayout/1eee90826452e1f3d3d8c4488ed65de63f0e90bc/Example-iOS-SwiftUI/Example-iOS-SwiftUI/Assets.xcassets/test_images/15.imageset/serrano.png
--------------------------------------------------------------------------------
/Example-iOS-SwiftUI/Example-iOS-SwiftUI/Assets.xcassets/test_images/16.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "filename" : "tulips.png",
5 | "idiom" : "universal",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "author" : "xcode",
19 | "version" : 1
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/Example-iOS-SwiftUI/Example-iOS-SwiftUI/Assets.xcassets/test_images/16.imageset/tulips.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HocTran/WatchLayout/1eee90826452e1f3d3d8c4488ed65de63f0e90bc/Example-iOS-SwiftUI/Example-iOS-SwiftUI/Assets.xcassets/test_images/16.imageset/tulips.png
--------------------------------------------------------------------------------
/Example-iOS-SwiftUI/Example-iOS-SwiftUI/Assets.xcassets/test_images/17.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "filename" : "watch.png",
5 | "idiom" : "universal",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "author" : "xcode",
19 | "version" : 1
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/Example-iOS-SwiftUI/Example-iOS-SwiftUI/Assets.xcassets/test_images/17.imageset/watch.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HocTran/WatchLayout/1eee90826452e1f3d3d8c4488ed65de63f0e90bc/Example-iOS-SwiftUI/Example-iOS-SwiftUI/Assets.xcassets/test_images/17.imageset/watch.png
--------------------------------------------------------------------------------
/Example-iOS-SwiftUI/Example-iOS-SwiftUI/Assets.xcassets/test_images/2.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "filename" : "baboon.png",
5 | "idiom" : "universal",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "author" : "xcode",
19 | "version" : 1
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/Example-iOS-SwiftUI/Example-iOS-SwiftUI/Assets.xcassets/test_images/2.imageset/baboon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HocTran/WatchLayout/1eee90826452e1f3d3d8c4488ed65de63f0e90bc/Example-iOS-SwiftUI/Example-iOS-SwiftUI/Assets.xcassets/test_images/2.imageset/baboon.png
--------------------------------------------------------------------------------
/Example-iOS-SwiftUI/Example-iOS-SwiftUI/Assets.xcassets/test_images/3.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "filename" : "barbara.png",
5 | "idiom" : "universal",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "author" : "xcode",
19 | "version" : 1
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/Example-iOS-SwiftUI/Example-iOS-SwiftUI/Assets.xcassets/test_images/3.imageset/barbara.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HocTran/WatchLayout/1eee90826452e1f3d3d8c4488ed65de63f0e90bc/Example-iOS-SwiftUI/Example-iOS-SwiftUI/Assets.xcassets/test_images/3.imageset/barbara.png
--------------------------------------------------------------------------------
/Example-iOS-SwiftUI/Example-iOS-SwiftUI/Assets.xcassets/test_images/4.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "filename" : "boat.png",
5 | "idiom" : "universal",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "author" : "xcode",
19 | "version" : 1
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/Example-iOS-SwiftUI/Example-iOS-SwiftUI/Assets.xcassets/test_images/4.imageset/boat.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HocTran/WatchLayout/1eee90826452e1f3d3d8c4488ed65de63f0e90bc/Example-iOS-SwiftUI/Example-iOS-SwiftUI/Assets.xcassets/test_images/4.imageset/boat.png
--------------------------------------------------------------------------------
/Example-iOS-SwiftUI/Example-iOS-SwiftUI/Assets.xcassets/test_images/5.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "filename" : "cat.png",
5 | "idiom" : "universal",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "author" : "xcode",
19 | "version" : 1
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/Example-iOS-SwiftUI/Example-iOS-SwiftUI/Assets.xcassets/test_images/5.imageset/cat.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HocTran/WatchLayout/1eee90826452e1f3d3d8c4488ed65de63f0e90bc/Example-iOS-SwiftUI/Example-iOS-SwiftUI/Assets.xcassets/test_images/5.imageset/cat.png
--------------------------------------------------------------------------------
/Example-iOS-SwiftUI/Example-iOS-SwiftUI/Assets.xcassets/test_images/6.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "filename" : "fruits.png",
5 | "idiom" : "universal",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "author" : "xcode",
19 | "version" : 1
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/Example-iOS-SwiftUI/Example-iOS-SwiftUI/Assets.xcassets/test_images/6.imageset/fruits.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HocTran/WatchLayout/1eee90826452e1f3d3d8c4488ed65de63f0e90bc/Example-iOS-SwiftUI/Example-iOS-SwiftUI/Assets.xcassets/test_images/6.imageset/fruits.png
--------------------------------------------------------------------------------
/Example-iOS-SwiftUI/Example-iOS-SwiftUI/Assets.xcassets/test_images/7.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "filename" : "frymire.png",
5 | "idiom" : "universal",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "author" : "xcode",
19 | "version" : 1
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/Example-iOS-SwiftUI/Example-iOS-SwiftUI/Assets.xcassets/test_images/7.imageset/frymire.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HocTran/WatchLayout/1eee90826452e1f3d3d8c4488ed65de63f0e90bc/Example-iOS-SwiftUI/Example-iOS-SwiftUI/Assets.xcassets/test_images/7.imageset/frymire.png
--------------------------------------------------------------------------------
/Example-iOS-SwiftUI/Example-iOS-SwiftUI/Assets.xcassets/test_images/8.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "filename" : "goldhill.png",
5 | "idiom" : "universal",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "author" : "xcode",
19 | "version" : 1
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/Example-iOS-SwiftUI/Example-iOS-SwiftUI/Assets.xcassets/test_images/8.imageset/goldhill.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HocTran/WatchLayout/1eee90826452e1f3d3d8c4488ed65de63f0e90bc/Example-iOS-SwiftUI/Example-iOS-SwiftUI/Assets.xcassets/test_images/8.imageset/goldhill.png
--------------------------------------------------------------------------------
/Example-iOS-SwiftUI/Example-iOS-SwiftUI/Assets.xcassets/test_images/9.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "filename" : "lena.png",
5 | "idiom" : "universal",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "author" : "xcode",
19 | "version" : 1
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/Example-iOS-SwiftUI/Example-iOS-SwiftUI/Assets.xcassets/test_images/9.imageset/lena.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HocTran/WatchLayout/1eee90826452e1f3d3d8c4488ed65de63f0e90bc/Example-iOS-SwiftUI/Example-iOS-SwiftUI/Assets.xcassets/test_images/9.imageset/lena.png
--------------------------------------------------------------------------------
/Example-iOS-SwiftUI/Example-iOS-SwiftUI/Assets.xcassets/test_images/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/Example-iOS-SwiftUI/Example-iOS-SwiftUI/Example_iOS_SwiftUIApp.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) 2021 Hoc Tran (https://hoctran.com/)
3 | //
4 | // Permission is hereby granted, free of charge, to any person obtaining a copy
5 | // of this software and associated documentation files (the "Software"), to deal
6 | // in the Software without restriction, including without limitation the rights
7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | // copies of the Software, and to permit persons to whom the Software is
9 | // furnished to do so, subject to the following conditions:
10 | //
11 | // The above copyright notice and this permission notice shall be included in
12 | // all copies or substantial portions of the Software.
13 | //
14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | // THE SOFTWARE.
21 | //
22 |
23 | import SwiftUI
24 | import WatchLayout_SwiftUI
25 |
26 | @main
27 | struct Example_iOS_SwiftUIApp: App {
28 | @State var layout = WatchLayoutAttributes(
29 | itemSize: 120,
30 | spacing: 16,
31 | minScale: 0.2,
32 | nextItemScale: 0.6
33 | )
34 |
35 | @State var centeredIndex: Int? = 0
36 |
37 | @State var data = (0..<1000).map { CellItem(id: $0) }
38 |
39 | var body: some Scene {
40 | WindowGroup {
41 | NavigationView {
42 | VStack {
43 |
44 | WatchLayoutView(layoutAttributes: layout, data: data, centeredIndex: $centeredIndex) { i in
45 | Text("\(i.id)")
46 | .frame(maxWidth: .infinity, maxHeight: .infinity)
47 | .background(i.color)
48 | .clipShape(Circle())
49 | }
50 | .ignoresSafeArea()
51 | .onChange(of: centeredIndex) { newValue in
52 | print(newValue)
53 | }
54 |
55 |
56 | VStack(spacing: 16) {
57 |
58 | Text("Selected item: \(centeredIndex ?? -1)")
59 |
60 | Button("Change data") {
61 | data = (0..<(1000..<1500).randomElement()!).map { CellItem(id: $0) }
62 | }
63 |
64 | Button("Change center") {
65 | centeredIndex = (0..
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 |
--------------------------------------------------------------------------------
/Example-iOS-SwiftUI/Example-iOS-SwiftUI/Preview Content/Preview Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/Example-iOS/Example-iOS.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 50;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 151C593A25D04C39002CF5BE /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 151C593925D04C39002CF5BE /* AppDelegate.swift */; };
11 | 151C593C25D04C39002CF5BE /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 151C593B25D04C39002CF5BE /* SceneDelegate.swift */; };
12 | 151C593E25D04C39002CF5BE /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 151C593D25D04C39002CF5BE /* ViewController.swift */; };
13 | 151C594125D04C39002CF5BE /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 151C593F25D04C39002CF5BE /* Main.storyboard */; };
14 | 151C594325D04C3B002CF5BE /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 151C594225D04C3B002CF5BE /* Assets.xcassets */; };
15 | 151C594625D04C3B002CF5BE /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 151C594425D04C3B002CF5BE /* LaunchScreen.storyboard */; };
16 | 151C595825D04CAA002CF5BE /* CollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 151C595725D04CAA002CF5BE /* CollectionViewCell.swift */; };
17 | 156311772610341D0033FFF8 /* WatchLayout.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 15F3A3DB25D0D5AB00637820 /* WatchLayout.framework */; };
18 | 156311782610341D0033FFF8 /* WatchLayout.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 15F3A3DB25D0D5AB00637820 /* WatchLayout.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
19 | 15F3A3E625D0E4FE00637820 /* ImagesViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 15F3A3E525D0E4FE00637820 /* ImagesViewController.swift */; };
20 | 15F3A3EA25D0E5F100637820 /* ImageCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 15F3A3E925D0E5F100637820 /* ImageCollectionViewCell.swift */; };
21 | /* End PBXBuildFile section */
22 |
23 | /* Begin PBXContainerItemProxy section */
24 | 1563120526105ED70033FFF8 /* PBXContainerItemProxy */ = {
25 | isa = PBXContainerItemProxy;
26 | containerPortal = 1563120126105ED70033FFF8 /* WatchLayout.xcodeproj */;
27 | proxyType = 2;
28 | remoteGlobalIDString = 156311E626105E710033FFF8;
29 | remoteInfo = WatchLayout;
30 | };
31 | /* End PBXContainerItemProxy section */
32 |
33 | /* Begin PBXCopyFilesBuildPhase section */
34 | 156311792610341D0033FFF8 /* Embed Frameworks */ = {
35 | isa = PBXCopyFilesBuildPhase;
36 | buildActionMask = 2147483647;
37 | dstPath = "";
38 | dstSubfolderSpec = 10;
39 | files = (
40 | 156311782610341D0033FFF8 /* WatchLayout.framework in Embed Frameworks */,
41 | );
42 | name = "Embed Frameworks";
43 | runOnlyForDeploymentPostprocessing = 0;
44 | };
45 | /* End PBXCopyFilesBuildPhase section */
46 |
47 | /* Begin PBXFileReference section */
48 | 151C593625D04C39002CF5BE /* Example-iOS.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Example-iOS.app"; sourceTree = BUILT_PRODUCTS_DIR; };
49 | 151C593925D04C39002CF5BE /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
50 | 151C593B25D04C39002CF5BE /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; };
51 | 151C593D25D04C39002CF5BE /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; };
52 | 151C594025D04C39002CF5BE /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
53 | 151C594225D04C3B002CF5BE /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
54 | 151C594525D04C3B002CF5BE /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; };
55 | 151C594725D04C3B002CF5BE /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
56 | 151C595725D04CAA002CF5BE /* CollectionViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CollectionViewCell.swift; sourceTree = ""; };
57 | 1563120126105ED70033FFF8 /* WatchLayout.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = WatchLayout.xcodeproj; path = ../WatchLayout.xcodeproj; sourceTree = ""; };
58 | 15F3A3E525D0E4FE00637820 /* ImagesViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImagesViewController.swift; sourceTree = ""; };
59 | 15F3A3E925D0E5F100637820 /* ImageCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageCollectionViewCell.swift; sourceTree = ""; };
60 | /* End PBXFileReference section */
61 |
62 | /* Begin PBXFrameworksBuildPhase section */
63 | 151C593325D04C39002CF5BE /* Frameworks */ = {
64 | isa = PBXFrameworksBuildPhase;
65 | buildActionMask = 2147483647;
66 | files = (
67 | 156311772610341D0033FFF8 /* WatchLayout.framework in Frameworks */,
68 | );
69 | runOnlyForDeploymentPostprocessing = 0;
70 | };
71 | /* End PBXFrameworksBuildPhase section */
72 |
73 | /* Begin PBXGroup section */
74 | 151C592D25D04C39002CF5BE = {
75 | isa = PBXGroup;
76 | children = (
77 | 1563120126105ED70033FFF8 /* WatchLayout.xcodeproj */,
78 | 151C593825D04C39002CF5BE /* Example-iOS */,
79 | 151C593725D04C39002CF5BE /* Products */,
80 | 15F3A3D625D0D5AB00637820 /* WatchLayout.xcodeproj */,
81 | 156311752610341D0033FFF8 /* Frameworks */,
82 | );
83 | sourceTree = "";
84 | };
85 | 151C593725D04C39002CF5BE /* Products */ = {
86 | isa = PBXGroup;
87 | children = (
88 | 151C593625D04C39002CF5BE /* Example-iOS.app */,
89 | );
90 | name = Products;
91 | sourceTree = "";
92 | };
93 | 151C593825D04C39002CF5BE /* Example-iOS */ = {
94 | isa = PBXGroup;
95 | children = (
96 | 151C593925D04C39002CF5BE /* AppDelegate.swift */,
97 | 151C593B25D04C39002CF5BE /* SceneDelegate.swift */,
98 | 151C593D25D04C39002CF5BE /* ViewController.swift */,
99 | 15F3A3E525D0E4FE00637820 /* ImagesViewController.swift */,
100 | 151C595725D04CAA002CF5BE /* CollectionViewCell.swift */,
101 | 15F3A3E925D0E5F100637820 /* ImageCollectionViewCell.swift */,
102 | 151C593F25D04C39002CF5BE /* Main.storyboard */,
103 | 151C594225D04C3B002CF5BE /* Assets.xcassets */,
104 | 151C594425D04C3B002CF5BE /* LaunchScreen.storyboard */,
105 | 151C594725D04C3B002CF5BE /* Info.plist */,
106 | );
107 | path = "Example-iOS";
108 | sourceTree = "";
109 | };
110 | 156311752610341D0033FFF8 /* Frameworks */ = {
111 | isa = PBXGroup;
112 | children = (
113 | );
114 | name = Frameworks;
115 | sourceTree = "";
116 | };
117 | 15F3A3D725D0D5AB00637820 /* Products */ = {
118 | isa = PBXGroup;
119 | children = (
120 | 1563120626105ED70033FFF8 /* WatchLayout.framework */,
121 | );
122 | name = Products;
123 | sourceTree = "";
124 | };
125 | 1563120926105EED0033FFF8 /* Frameworks */ = {
126 | isa = PBXGroup;
127 | children = (
128 | );
129 | name = Frameworks;
130 | sourceTree = "";
131 | };
132 | /* End PBXGroup section */
133 |
134 | /* Begin PBXNativeTarget section */
135 | 151C593525D04C39002CF5BE /* Example-iOS */ = {
136 | isa = PBXNativeTarget;
137 | buildConfigurationList = 151C594A25D04C3B002CF5BE /* Build configuration list for PBXNativeTarget "Example-iOS" */;
138 | buildPhases = (
139 | 151C593225D04C39002CF5BE /* Sources */,
140 | 151C593325D04C39002CF5BE /* Frameworks */,
141 | 151C593425D04C39002CF5BE /* Resources */,
142 | 156311792610341D0033FFF8 /* Embed Frameworks */,
143 | );
144 | buildRules = (
145 | );
146 | dependencies = (
147 | );
148 | name = "Example-iOS";
149 | productName = "Example-iOS";
150 | productReference = 151C593625D04C39002CF5BE /* Example-iOS.app */;
151 | productType = "com.apple.product-type.application";
152 | };
153 | /* End PBXNativeTarget section */
154 |
155 | /* Begin PBXProject section */
156 | 151C592E25D04C39002CF5BE /* Project object */ = {
157 | isa = PBXProject;
158 | attributes = {
159 | LastSwiftUpdateCheck = 1240;
160 | LastUpgradeCheck = 1240;
161 | TargetAttributes = {
162 | 151C593525D04C39002CF5BE = {
163 | CreatedOnToolsVersion = 12.4;
164 | };
165 | };
166 | };
167 | buildConfigurationList = 151C593125D04C39002CF5BE /* Build configuration list for PBXProject "Example-iOS" */;
168 | compatibilityVersion = "Xcode 9.3";
169 | developmentRegion = en;
170 | hasScannedForEncodings = 0;
171 | knownRegions = (
172 | en,
173 | Base,
174 | );
175 | mainGroup = 151C592D25D04C39002CF5BE;
176 | productRefGroup = 151C593725D04C39002CF5BE /* Products */;
177 | projectDirPath = "";
178 | projectReferences = (
179 | {
180 | ProductGroup = 1563120226105ED70033FFF8 /* Products */;
181 | ProjectRef = 1563120126105ED70033FFF8 /* WatchLayout.xcodeproj */;
182 | },
183 | );
184 | projectRoot = "";
185 | targets = (
186 | 151C593525D04C39002CF5BE /* Example-iOS */,
187 | );
188 | };
189 | /* End PBXProject section */
190 |
191 | /* Begin PBXReferenceProxy section */
192 | 1563120626105ED70033FFF8 /* WatchLayout.framework */ = {
193 | isa = PBXReferenceProxy;
194 | fileType = wrapper.framework;
195 | path = WatchLayout.framework;
196 | remoteRef = 1563120526105ED70033FFF8 /* PBXContainerItemProxy */;
197 | sourceTree = BUILT_PRODUCTS_DIR;
198 | };
199 | /* End PBXReferenceProxy section */
200 |
201 | /* Begin PBXResourcesBuildPhase section */
202 | 151C593425D04C39002CF5BE /* Resources */ = {
203 | isa = PBXResourcesBuildPhase;
204 | buildActionMask = 2147483647;
205 | files = (
206 | 151C594625D04C3B002CF5BE /* LaunchScreen.storyboard in Resources */,
207 | 151C594325D04C3B002CF5BE /* Assets.xcassets in Resources */,
208 | 151C594125D04C39002CF5BE /* Main.storyboard in Resources */,
209 | );
210 | runOnlyForDeploymentPostprocessing = 0;
211 | };
212 | /* End PBXResourcesBuildPhase section */
213 |
214 | /* Begin PBXSourcesBuildPhase section */
215 | 151C593225D04C39002CF5BE /* Sources */ = {
216 | isa = PBXSourcesBuildPhase;
217 | buildActionMask = 2147483647;
218 | files = (
219 | 151C593E25D04C39002CF5BE /* ViewController.swift in Sources */,
220 | 151C593A25D04C39002CF5BE /* AppDelegate.swift in Sources */,
221 | 15F3A3EA25D0E5F100637820 /* ImageCollectionViewCell.swift in Sources */,
222 | 15F3A3E625D0E4FE00637820 /* ImagesViewController.swift in Sources */,
223 | 151C595825D04CAA002CF5BE /* CollectionViewCell.swift in Sources */,
224 | 151C593C25D04C39002CF5BE /* SceneDelegate.swift in Sources */,
225 | );
226 | runOnlyForDeploymentPostprocessing = 0;
227 | };
228 | /* End PBXSourcesBuildPhase section */
229 |
230 | /* Begin PBXVariantGroup section */
231 | 151C593F25D04C39002CF5BE /* Main.storyboard */ = {
232 | isa = PBXVariantGroup;
233 | children = (
234 | 151C594025D04C39002CF5BE /* Base */,
235 | );
236 | name = Main.storyboard;
237 | sourceTree = "";
238 | };
239 | 151C594425D04C3B002CF5BE /* LaunchScreen.storyboard */ = {
240 | isa = PBXVariantGroup;
241 | children = (
242 | 151C594525D04C3B002CF5BE /* Base */,
243 | );
244 | name = LaunchScreen.storyboard;
245 | sourceTree = "";
246 | };
247 | /* End PBXVariantGroup section */
248 |
249 | /* Begin XCBuildConfiguration section */
250 | 151C594825D04C3B002CF5BE /* Debug */ = {
251 | isa = XCBuildConfiguration;
252 | buildSettings = {
253 | ALWAYS_SEARCH_USER_PATHS = NO;
254 | CLANG_ANALYZER_NONNULL = YES;
255 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
256 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
257 | CLANG_CXX_LIBRARY = "libc++";
258 | CLANG_ENABLE_MODULES = YES;
259 | CLANG_ENABLE_OBJC_ARC = YES;
260 | CLANG_ENABLE_OBJC_WEAK = YES;
261 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
262 | CLANG_WARN_BOOL_CONVERSION = YES;
263 | CLANG_WARN_COMMA = YES;
264 | CLANG_WARN_CONSTANT_CONVERSION = YES;
265 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
266 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
267 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
268 | CLANG_WARN_EMPTY_BODY = YES;
269 | CLANG_WARN_ENUM_CONVERSION = YES;
270 | CLANG_WARN_INFINITE_RECURSION = YES;
271 | CLANG_WARN_INT_CONVERSION = YES;
272 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
273 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
274 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
275 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
276 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
277 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
278 | CLANG_WARN_STRICT_PROTOTYPES = YES;
279 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
280 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
281 | CLANG_WARN_UNREACHABLE_CODE = YES;
282 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
283 | COPY_PHASE_STRIP = NO;
284 | DEBUG_INFORMATION_FORMAT = dwarf;
285 | ENABLE_STRICT_OBJC_MSGSEND = YES;
286 | ENABLE_TESTABILITY = YES;
287 | GCC_C_LANGUAGE_STANDARD = gnu11;
288 | GCC_DYNAMIC_NO_PIC = NO;
289 | GCC_NO_COMMON_BLOCKS = YES;
290 | GCC_OPTIMIZATION_LEVEL = 0;
291 | GCC_PREPROCESSOR_DEFINITIONS = (
292 | "DEBUG=1",
293 | "$(inherited)",
294 | );
295 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
296 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
297 | GCC_WARN_UNDECLARED_SELECTOR = YES;
298 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
299 | GCC_WARN_UNUSED_FUNCTION = YES;
300 | GCC_WARN_UNUSED_VARIABLE = YES;
301 | IPHONEOS_DEPLOYMENT_TARGET = 14.4;
302 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
303 | MTL_FAST_MATH = YES;
304 | ONLY_ACTIVE_ARCH = YES;
305 | SDKROOT = iphoneos;
306 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
307 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
308 | };
309 | name = Debug;
310 | };
311 | 151C594925D04C3B002CF5BE /* Release */ = {
312 | isa = XCBuildConfiguration;
313 | buildSettings = {
314 | ALWAYS_SEARCH_USER_PATHS = NO;
315 | CLANG_ANALYZER_NONNULL = YES;
316 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
317 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
318 | CLANG_CXX_LIBRARY = "libc++";
319 | CLANG_ENABLE_MODULES = YES;
320 | CLANG_ENABLE_OBJC_ARC = YES;
321 | CLANG_ENABLE_OBJC_WEAK = YES;
322 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
323 | CLANG_WARN_BOOL_CONVERSION = YES;
324 | CLANG_WARN_COMMA = YES;
325 | CLANG_WARN_CONSTANT_CONVERSION = YES;
326 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
327 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
328 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
329 | CLANG_WARN_EMPTY_BODY = YES;
330 | CLANG_WARN_ENUM_CONVERSION = YES;
331 | CLANG_WARN_INFINITE_RECURSION = YES;
332 | CLANG_WARN_INT_CONVERSION = YES;
333 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
334 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
335 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
336 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
337 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
338 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
339 | CLANG_WARN_STRICT_PROTOTYPES = YES;
340 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
341 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
342 | CLANG_WARN_UNREACHABLE_CODE = YES;
343 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
344 | COPY_PHASE_STRIP = NO;
345 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
346 | ENABLE_NS_ASSERTIONS = NO;
347 | ENABLE_STRICT_OBJC_MSGSEND = YES;
348 | GCC_C_LANGUAGE_STANDARD = gnu11;
349 | GCC_NO_COMMON_BLOCKS = YES;
350 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
351 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
352 | GCC_WARN_UNDECLARED_SELECTOR = YES;
353 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
354 | GCC_WARN_UNUSED_FUNCTION = YES;
355 | GCC_WARN_UNUSED_VARIABLE = YES;
356 | IPHONEOS_DEPLOYMENT_TARGET = 14.4;
357 | MTL_ENABLE_DEBUG_INFO = NO;
358 | MTL_FAST_MATH = YES;
359 | SDKROOT = iphoneos;
360 | SWIFT_COMPILATION_MODE = wholemodule;
361 | SWIFT_OPTIMIZATION_LEVEL = "-O";
362 | VALIDATE_PRODUCT = YES;
363 | };
364 | name = Release;
365 | };
366 | 151C594B25D04C3B002CF5BE /* Debug */ = {
367 | isa = XCBuildConfiguration;
368 | buildSettings = {
369 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
370 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
371 | CODE_SIGN_STYLE = Automatic;
372 | INFOPLIST_FILE = "Example-iOS/Info.plist";
373 | LD_RUNPATH_SEARCH_PATHS = (
374 | "$(inherited)",
375 | "@executable_path/Frameworks",
376 | );
377 | PRODUCT_BUNDLE_IDENTIFIER = "Hoc-Tran.Example-iOS";
378 | PRODUCT_NAME = "$(TARGET_NAME)";
379 | SWIFT_VERSION = 5.0;
380 | TARGETED_DEVICE_FAMILY = "1,2";
381 | };
382 | name = Debug;
383 | };
384 | 151C594C25D04C3B002CF5BE /* Release */ = {
385 | isa = XCBuildConfiguration;
386 | buildSettings = {
387 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
388 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
389 | CODE_SIGN_STYLE = Automatic;
390 | INFOPLIST_FILE = "Example-iOS/Info.plist";
391 | LD_RUNPATH_SEARCH_PATHS = (
392 | "$(inherited)",
393 | "@executable_path/Frameworks",
394 | );
395 | PRODUCT_BUNDLE_IDENTIFIER = "Hoc-Tran.Example-iOS";
396 | PRODUCT_NAME = "$(TARGET_NAME)";
397 | SWIFT_VERSION = 5.0;
398 | TARGETED_DEVICE_FAMILY = "1,2";
399 | };
400 | name = Release;
401 | };
402 | /* End XCBuildConfiguration section */
403 |
404 | /* Begin XCConfigurationList section */
405 | 151C593125D04C39002CF5BE /* Build configuration list for PBXProject "Example-iOS" */ = {
406 | isa = XCConfigurationList;
407 | buildConfigurations = (
408 | 151C594825D04C3B002CF5BE /* Debug */,
409 | 151C594925D04C3B002CF5BE /* Release */,
410 | );
411 | defaultConfigurationIsVisible = 0;
412 | defaultConfigurationName = Release;
413 | };
414 | 151C594A25D04C3B002CF5BE /* Build configuration list for PBXNativeTarget "Example-iOS" */ = {
415 | isa = XCConfigurationList;
416 | buildConfigurations = (
417 | 151C594B25D04C3B002CF5BE /* Debug */,
418 | 151C594C25D04C3B002CF5BE /* Release */,
419 | );
420 | defaultConfigurationIsVisible = 0;
421 | defaultConfigurationName = Release;
422 | };
423 | /* End XCConfigurationList section */
424 | };
425 | rootObject = 151C592E25D04C39002CF5BE /* Project object */;
426 | }
427 |
--------------------------------------------------------------------------------
/Example-iOS/Example-iOS/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) 2021 Hoc Tran (https://hoctran.com/)
3 | //
4 | // Permission is hereby granted, free of charge, to any person obtaining a copy
5 | // of this software and associated documentation files (the "Software"), to deal
6 | // in the Software without restriction, including without limitation the rights
7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | // copies of the Software, and to permit persons to whom the Software is
9 | // furnished to do so, subject to the following conditions:
10 | //
11 | // The above copyright notice and this permission notice shall be included in
12 | // all copies or substantial portions of the Software.
13 | //
14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | // THE SOFTWARE.
21 | //
22 |
23 | import UIKit
24 |
25 | @main
26 | class AppDelegate: UIResponder, UIApplicationDelegate {
27 |
28 |
29 |
30 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
31 | // Override point for customization after application launch.
32 | return true
33 | }
34 |
35 | // MARK: UISceneSession Lifecycle
36 |
37 | func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
38 | // Called when a new scene session is being created.
39 | // Use this method to select a configuration to create the new scene with.
40 | return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
41 | }
42 |
43 | func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) {
44 | // Called when the user discards a scene session.
45 | // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
46 | // Use this method to release any resources that were specific to the discarded scenes, as they will not return.
47 | }
48 |
49 |
50 | }
51 |
52 |
--------------------------------------------------------------------------------
/Example-iOS/Example-iOS/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 |
--------------------------------------------------------------------------------
/Example-iOS/Example-iOS/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 | "info" : {
95 | "author" : "xcode",
96 | "version" : 1
97 | }
98 | }
99 |
--------------------------------------------------------------------------------
/Example-iOS/Example-iOS/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/Example-iOS/Example-iOS/Assets.xcassets/test_images/0.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "filename" : "zelda.png",
5 | "idiom" : "universal",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "author" : "xcode",
19 | "version" : 1
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/Example-iOS/Example-iOS/Assets.xcassets/test_images/0.imageset/zelda.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HocTran/WatchLayout/1eee90826452e1f3d3d8c4488ed65de63f0e90bc/Example-iOS/Example-iOS/Assets.xcassets/test_images/0.imageset/zelda.png
--------------------------------------------------------------------------------
/Example-iOS/Example-iOS/Assets.xcassets/test_images/1.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "filename" : "arctichare.png",
5 | "idiom" : "universal",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "author" : "xcode",
19 | "version" : 1
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/Example-iOS/Example-iOS/Assets.xcassets/test_images/1.imageset/arctichare.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HocTran/WatchLayout/1eee90826452e1f3d3d8c4488ed65de63f0e90bc/Example-iOS/Example-iOS/Assets.xcassets/test_images/1.imageset/arctichare.png
--------------------------------------------------------------------------------
/Example-iOS/Example-iOS/Assets.xcassets/test_images/10.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "filename" : "monarch.png",
5 | "idiom" : "universal",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "author" : "xcode",
19 | "version" : 1
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/Example-iOS/Example-iOS/Assets.xcassets/test_images/10.imageset/monarch.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HocTran/WatchLayout/1eee90826452e1f3d3d8c4488ed65de63f0e90bc/Example-iOS/Example-iOS/Assets.xcassets/test_images/10.imageset/monarch.png
--------------------------------------------------------------------------------
/Example-iOS/Example-iOS/Assets.xcassets/test_images/11.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "filename" : "mountain.png",
5 | "idiom" : "universal",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "author" : "xcode",
19 | "version" : 1
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/Example-iOS/Example-iOS/Assets.xcassets/test_images/11.imageset/mountain.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HocTran/WatchLayout/1eee90826452e1f3d3d8c4488ed65de63f0e90bc/Example-iOS/Example-iOS/Assets.xcassets/test_images/11.imageset/mountain.png
--------------------------------------------------------------------------------
/Example-iOS/Example-iOS/Assets.xcassets/test_images/12.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "filename" : "peppers.png",
5 | "idiom" : "universal",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "author" : "xcode",
19 | "version" : 1
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/Example-iOS/Example-iOS/Assets.xcassets/test_images/12.imageset/peppers.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HocTran/WatchLayout/1eee90826452e1f3d3d8c4488ed65de63f0e90bc/Example-iOS/Example-iOS/Assets.xcassets/test_images/12.imageset/peppers.png
--------------------------------------------------------------------------------
/Example-iOS/Example-iOS/Assets.xcassets/test_images/13.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "filename" : "pool.png",
5 | "idiom" : "universal",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "author" : "xcode",
19 | "version" : 1
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/Example-iOS/Example-iOS/Assets.xcassets/test_images/13.imageset/pool.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HocTran/WatchLayout/1eee90826452e1f3d3d8c4488ed65de63f0e90bc/Example-iOS/Example-iOS/Assets.xcassets/test_images/13.imageset/pool.png
--------------------------------------------------------------------------------
/Example-iOS/Example-iOS/Assets.xcassets/test_images/14.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "filename" : "sails.png",
5 | "idiom" : "universal",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "author" : "xcode",
19 | "version" : 1
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/Example-iOS/Example-iOS/Assets.xcassets/test_images/14.imageset/sails.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HocTran/WatchLayout/1eee90826452e1f3d3d8c4488ed65de63f0e90bc/Example-iOS/Example-iOS/Assets.xcassets/test_images/14.imageset/sails.png
--------------------------------------------------------------------------------
/Example-iOS/Example-iOS/Assets.xcassets/test_images/15.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "filename" : "serrano.png",
5 | "idiom" : "universal",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "author" : "xcode",
19 | "version" : 1
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/Example-iOS/Example-iOS/Assets.xcassets/test_images/15.imageset/serrano.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HocTran/WatchLayout/1eee90826452e1f3d3d8c4488ed65de63f0e90bc/Example-iOS/Example-iOS/Assets.xcassets/test_images/15.imageset/serrano.png
--------------------------------------------------------------------------------
/Example-iOS/Example-iOS/Assets.xcassets/test_images/16.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "filename" : "tulips.png",
5 | "idiom" : "universal",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "author" : "xcode",
19 | "version" : 1
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/Example-iOS/Example-iOS/Assets.xcassets/test_images/16.imageset/tulips.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HocTran/WatchLayout/1eee90826452e1f3d3d8c4488ed65de63f0e90bc/Example-iOS/Example-iOS/Assets.xcassets/test_images/16.imageset/tulips.png
--------------------------------------------------------------------------------
/Example-iOS/Example-iOS/Assets.xcassets/test_images/17.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "filename" : "watch.png",
5 | "idiom" : "universal",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "author" : "xcode",
19 | "version" : 1
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/Example-iOS/Example-iOS/Assets.xcassets/test_images/17.imageset/watch.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HocTran/WatchLayout/1eee90826452e1f3d3d8c4488ed65de63f0e90bc/Example-iOS/Example-iOS/Assets.xcassets/test_images/17.imageset/watch.png
--------------------------------------------------------------------------------
/Example-iOS/Example-iOS/Assets.xcassets/test_images/2.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "filename" : "baboon.png",
5 | "idiom" : "universal",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "author" : "xcode",
19 | "version" : 1
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/Example-iOS/Example-iOS/Assets.xcassets/test_images/2.imageset/baboon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HocTran/WatchLayout/1eee90826452e1f3d3d8c4488ed65de63f0e90bc/Example-iOS/Example-iOS/Assets.xcassets/test_images/2.imageset/baboon.png
--------------------------------------------------------------------------------
/Example-iOS/Example-iOS/Assets.xcassets/test_images/3.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "filename" : "barbara.png",
5 | "idiom" : "universal",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "author" : "xcode",
19 | "version" : 1
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/Example-iOS/Example-iOS/Assets.xcassets/test_images/3.imageset/barbara.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HocTran/WatchLayout/1eee90826452e1f3d3d8c4488ed65de63f0e90bc/Example-iOS/Example-iOS/Assets.xcassets/test_images/3.imageset/barbara.png
--------------------------------------------------------------------------------
/Example-iOS/Example-iOS/Assets.xcassets/test_images/4.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "filename" : "boat.png",
5 | "idiom" : "universal",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "author" : "xcode",
19 | "version" : 1
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/Example-iOS/Example-iOS/Assets.xcassets/test_images/4.imageset/boat.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HocTran/WatchLayout/1eee90826452e1f3d3d8c4488ed65de63f0e90bc/Example-iOS/Example-iOS/Assets.xcassets/test_images/4.imageset/boat.png
--------------------------------------------------------------------------------
/Example-iOS/Example-iOS/Assets.xcassets/test_images/5.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "filename" : "cat.png",
5 | "idiom" : "universal",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "author" : "xcode",
19 | "version" : 1
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/Example-iOS/Example-iOS/Assets.xcassets/test_images/5.imageset/cat.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HocTran/WatchLayout/1eee90826452e1f3d3d8c4488ed65de63f0e90bc/Example-iOS/Example-iOS/Assets.xcassets/test_images/5.imageset/cat.png
--------------------------------------------------------------------------------
/Example-iOS/Example-iOS/Assets.xcassets/test_images/6.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "filename" : "fruits.png",
5 | "idiom" : "universal",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "author" : "xcode",
19 | "version" : 1
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/Example-iOS/Example-iOS/Assets.xcassets/test_images/6.imageset/fruits.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HocTran/WatchLayout/1eee90826452e1f3d3d8c4488ed65de63f0e90bc/Example-iOS/Example-iOS/Assets.xcassets/test_images/6.imageset/fruits.png
--------------------------------------------------------------------------------
/Example-iOS/Example-iOS/Assets.xcassets/test_images/7.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "filename" : "frymire.png",
5 | "idiom" : "universal",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "author" : "xcode",
19 | "version" : 1
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/Example-iOS/Example-iOS/Assets.xcassets/test_images/7.imageset/frymire.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HocTran/WatchLayout/1eee90826452e1f3d3d8c4488ed65de63f0e90bc/Example-iOS/Example-iOS/Assets.xcassets/test_images/7.imageset/frymire.png
--------------------------------------------------------------------------------
/Example-iOS/Example-iOS/Assets.xcassets/test_images/8.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "filename" : "goldhill.png",
5 | "idiom" : "universal",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "author" : "xcode",
19 | "version" : 1
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/Example-iOS/Example-iOS/Assets.xcassets/test_images/8.imageset/goldhill.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HocTran/WatchLayout/1eee90826452e1f3d3d8c4488ed65de63f0e90bc/Example-iOS/Example-iOS/Assets.xcassets/test_images/8.imageset/goldhill.png
--------------------------------------------------------------------------------
/Example-iOS/Example-iOS/Assets.xcassets/test_images/9.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "filename" : "lena.png",
5 | "idiom" : "universal",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "author" : "xcode",
19 | "version" : 1
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/Example-iOS/Example-iOS/Assets.xcassets/test_images/9.imageset/lena.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HocTran/WatchLayout/1eee90826452e1f3d3d8c4488ed65de63f0e90bc/Example-iOS/Example-iOS/Assets.xcassets/test_images/9.imageset/lena.png
--------------------------------------------------------------------------------
/Example-iOS/Example-iOS/Assets.xcassets/test_images/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/Example-iOS/Example-iOS/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 |
--------------------------------------------------------------------------------
/Example-iOS/Example-iOS/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
--------------------------------------------------------------------------------
/Example-iOS/Example-iOS/CollectionViewCell.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) 2021 Hoc Tran (https://hoctran.com/)
3 | //
4 | // Permission is hereby granted, free of charge, to any person obtaining a copy
5 | // of this software and associated documentation files (the "Software"), to deal
6 | // in the Software without restriction, including without limitation the rights
7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | // copies of the Software, and to permit persons to whom the Software is
9 | // furnished to do so, subject to the following conditions:
10 | //
11 | // The above copyright notice and this permission notice shall be included in
12 | // all copies or substantial portions of the Software.
13 | //
14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | // THE SOFTWARE.
21 | //
22 |
23 | import UIKit
24 |
25 | class CollectionViewCell: UICollectionViewCell {
26 | @IBOutlet var label: UILabel!
27 |
28 | override func layoutSubviews() {
29 | super.layoutSubviews()
30 | clipsToBounds = true
31 | layer.cornerRadius = bounds.height * 0.5
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/Example-iOS/Example-iOS/ImageCollectionViewCell.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) 2021 Hoc Tran (https://hoctran.com/)
3 | //
4 | // Permission is hereby granted, free of charge, to any person obtaining a copy
5 | // of this software and associated documentation files (the "Software"), to deal
6 | // in the Software without restriction, including without limitation the rights
7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | // copies of the Software, and to permit persons to whom the Software is
9 | // furnished to do so, subject to the following conditions:
10 | //
11 | // The above copyright notice and this permission notice shall be included in
12 | // all copies or substantial portions of the Software.
13 | //
14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | // THE SOFTWARE.
21 | //
22 |
23 | import UIKit
24 |
25 | class ImageCollectionViewCell: UICollectionViewCell {
26 | @IBOutlet var imgView: UIImageView!
27 |
28 | override func prepareForReuse() {
29 | super.prepareForReuse()
30 | imgView.image = nil
31 | }
32 |
33 | override func layoutSubviews() {
34 | super.layoutSubviews()
35 | clipsToBounds = true
36 | layer.cornerRadius = bounds.height * 0.5
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/Example-iOS/Example-iOS/ImagesViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) 2021 Hoc Tran (https://hoctran.com/)
3 | //
4 | // Permission is hereby granted, free of charge, to any person obtaining a copy
5 | // of this software and associated documentation files (the "Software"), to deal
6 | // in the Software without restriction, including without limitation the rights
7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | // copies of the Software, and to permit persons to whom the Software is
9 | // furnished to do so, subject to the following conditions:
10 | //
11 | // The above copyright notice and this permission notice shall be included in
12 | // all copies or substantial portions of the Software.
13 | //
14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | // THE SOFTWARE.
21 | //
22 |
23 | import UIKit
24 | import WatchLayout
25 |
26 | class ImagesViewController: UIViewController, UICollectionViewDataSource {
27 |
28 | @IBOutlet var collectionView: UICollectionView!
29 | private var items = [String]()
30 |
31 |
32 | override func viewDidLoad() {
33 | super.viewDidLoad()
34 |
35 | items = (0...17).map { "\($0)"}
36 |
37 | let layout = WatchLayout()
38 | layout.itemSize = 200
39 | layout.spacing = -40
40 | layout.minScale = 0.2
41 | layout.nextItemScale = 0.4
42 |
43 | collectionView.collectionViewLayout = layout
44 |
45 | DispatchQueue.main.async {
46 | self.collectionView.setContentOffset(layout.centeredOffsetForItem(indexPath: IndexPath(item: 0, section: 0)), animated: true)
47 | }
48 | }
49 |
50 | override func didReceiveMemoryWarning() {
51 | super.didReceiveMemoryWarning()
52 | // Dispose of any resources that can be recreated.
53 | }
54 |
55 | func numberOfSections(in collectionView: UICollectionView) -> Int {
56 | return 1
57 | }
58 |
59 | func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
60 | return items.count
61 | }
62 |
63 | func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
64 | let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! ImageCollectionViewCell
65 | cell.imgView.image = UIImage(named: items[indexPath.item])
66 | return cell
67 | }
68 | }
69 |
70 |
--------------------------------------------------------------------------------
/Example-iOS/Example-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 | UISceneConfigurations
28 |
29 | UIWindowSceneSessionRoleApplication
30 |
31 |
32 | UISceneConfigurationName
33 | Default Configuration
34 | UISceneDelegateClassName
35 | $(PRODUCT_MODULE_NAME).SceneDelegate
36 | UISceneStoryboardFile
37 | Main
38 |
39 |
40 |
41 |
42 | UIApplicationSupportsIndirectInputEvents
43 |
44 | UILaunchStoryboardName
45 | LaunchScreen
46 | UIMainStoryboardFile
47 | Main
48 | UIRequiredDeviceCapabilities
49 |
50 | armv7
51 |
52 | UISupportedInterfaceOrientations
53 |
54 | UIInterfaceOrientationPortrait
55 | UIInterfaceOrientationLandscapeLeft
56 | UIInterfaceOrientationLandscapeRight
57 |
58 | UISupportedInterfaceOrientations~ipad
59 |
60 | UIInterfaceOrientationPortrait
61 | UIInterfaceOrientationPortraitUpsideDown
62 | UIInterfaceOrientationLandscapeLeft
63 | UIInterfaceOrientationLandscapeRight
64 |
65 |
66 |
67 |
--------------------------------------------------------------------------------
/Example-iOS/Example-iOS/SceneDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) 2021 Hoc Tran (https://hoctran.com/)
3 | //
4 | // Permission is hereby granted, free of charge, to any person obtaining a copy
5 | // of this software and associated documentation files (the "Software"), to deal
6 | // in the Software without restriction, including without limitation the rights
7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | // copies of the Software, and to permit persons to whom the Software is
9 | // furnished to do so, subject to the following conditions:
10 | //
11 | // The above copyright notice and this permission notice shall be included in
12 | // all copies or substantial portions of the Software.
13 | //
14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | // THE SOFTWARE.
21 | //
22 |
23 | import UIKit
24 |
25 | class SceneDelegate: UIResponder, UIWindowSceneDelegate {
26 |
27 | var window: UIWindow?
28 |
29 |
30 | func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
31 | // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
32 | // If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
33 | // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
34 | guard let _ = (scene as? UIWindowScene) else { return }
35 | }
36 |
37 | func sceneDidDisconnect(_ scene: UIScene) {
38 | // Called as the scene is being released by the system.
39 | // This occurs shortly after the scene enters the background, or when its session is discarded.
40 | // Release any resources associated with this scene that can be re-created the next time the scene connects.
41 | // The scene may re-connect later, as its session was not necessarily discarded (see `application:didDiscardSceneSessions` instead).
42 | }
43 |
44 | func sceneDidBecomeActive(_ scene: UIScene) {
45 | // Called when the scene has moved from an inactive state to an active state.
46 | // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive.
47 | }
48 |
49 | func sceneWillResignActive(_ scene: UIScene) {
50 | // Called when the scene will move from an active state to an inactive state.
51 | // This may occur due to temporary interruptions (ex. an incoming phone call).
52 | }
53 |
54 | func sceneWillEnterForeground(_ scene: UIScene) {
55 | // Called as the scene transitions from the background to the foreground.
56 | // Use this method to undo the changes made on entering the background.
57 | }
58 |
59 | func sceneDidEnterBackground(_ scene: UIScene) {
60 | // Called as the scene transitions from the foreground to the background.
61 | // Use this method to save data, release shared resources, and store enough scene-specific state information
62 | // to restore the scene back to its current state.
63 | }
64 |
65 |
66 | }
67 |
68 |
--------------------------------------------------------------------------------
/Example-iOS/Example-iOS/ViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) 2021 Hoc Tran (https://hoctran.com/)
3 | //
4 | // Permission is hereby granted, free of charge, to any person obtaining a copy
5 | // of this software and associated documentation files (the "Software"), to deal
6 | // in the Software without restriction, including without limitation the rights
7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | // copies of the Software, and to permit persons to whom the Software is
9 | // furnished to do so, subject to the following conditions:
10 | //
11 | // The above copyright notice and this permission notice shall be included in
12 | // all copies or substantial portions of the Software.
13 | //
14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | // THE SOFTWARE.
21 | //
22 |
23 | import UIKit
24 | import WatchLayout
25 |
26 | class ViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate {
27 |
28 | @IBOutlet var collectionView: UICollectionView!
29 | private var items = [UIColor]()
30 |
31 |
32 | override func viewDidLoad() {
33 | super.viewDidLoad()
34 |
35 | let r: Range = 0..<1
36 | items = (0..<100).map { i -> UIColor in
37 | UIColor(
38 | red: CGFloat.random(in: r),
39 | green: CGFloat.random(in: r),
40 | blue: CGFloat.random(in: r),
41 | alpha: 1)
42 | }
43 |
44 | let layout = WatchLayout()
45 | layout.itemSize = 129
46 | layout.spacing = 16
47 | layout.minScale = 0.2
48 | layout.nextItemScale = 0.6
49 |
50 | collectionView.collectionViewLayout = layout
51 | collectionView.delegate = self
52 |
53 | DispatchQueue.main.async {
54 | self.collectionView.setContentOffset(layout.centeredOffsetForItem(indexPath: IndexPath(item: 0, section: 0)), animated: true)
55 | }
56 | }
57 |
58 | override func didReceiveMemoryWarning() {
59 | super.didReceiveMemoryWarning()
60 | // Dispose of any resources that can be recreated.
61 | }
62 |
63 | func numberOfSections(in collectionView: UICollectionView) -> Int {
64 | return 1
65 | }
66 |
67 | func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
68 | return items.count
69 | }
70 |
71 | func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
72 | let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! CollectionViewCell
73 | cell.backgroundColor = items[indexPath.item]
74 | cell.label.text = "\(indexPath.item)"
75 | return cell
76 | }
77 |
78 | func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
79 | print((collectionView.collectionViewLayout as! WatchLayout).centeredIndexPath)
80 | }
81 | }
82 |
83 | extension ViewController {
84 |
85 | }
86 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2021 Hoc Tran
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy
4 | of this software and associated documentation files (the "Software"), to deal
5 | in the Software without restriction, including without limitation the rights
6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 | copies of the Software, and to permit persons to whom the Software is
8 | furnished to do so, subject to the following conditions:
9 |
10 | The above copyright notice and this permission notice shall be included in
11 | all copies or substantial portions of the Software.
12 |
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 | THE SOFTWARE.
20 |
--------------------------------------------------------------------------------
/Package.swift:
--------------------------------------------------------------------------------
1 | // swift-tools-version:5.3
2 | //
3 | // Package.swift
4 | //
5 | // Copyright (c) 2021 Hoc Tran (https://hoctran.com/)
6 | //
7 | // Permission is hereby granted, free of charge, to any person obtaining a copy
8 | // of this software and associated documentation files (the "Software"), to deal
9 | // in the Software without restriction, including without limitation the rights
10 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 | // copies of the Software, and to permit persons to whom the Software is
12 | // furnished to do so, subject to the following conditions:
13 | //
14 | // The above copyright notice and this permission notice shall be included in
15 | // all copies or substantial portions of the Software.
16 | //
17 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 | // THE SOFTWARE.
24 | //
25 |
26 | import PackageDescription
27 |
28 | let package = Package(
29 | name: "WatchLayout",
30 | platforms: [.iOS(.v13)],
31 | products: [
32 | .library(
33 | name: "WatchLayout",
34 | targets: ["WatchLayout"]
35 | ),
36 | .library(
37 | name: "WatchLayout-SwiftUI",
38 | targets: ["WatchLayout-SwiftUI"]
39 | )
40 | ],
41 | targets: [
42 | .target(
43 | name: "WatchLayout",
44 | path: "Source"
45 | ),
46 | .target(
47 | name: "WatchLayout-SwiftUI",
48 | dependencies: ["WatchLayout"],
49 | path: "SwiftUI"
50 | )
51 | ],
52 | swiftLanguageVersions: [.v5]
53 | )
54 |
55 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # WatchLayout
2 |
3 | [](https://cocoapods.org/pods/WatchLayout)
4 | [](https://cocoapods.org/pods/WatchLayout)
5 | [](https://cocoapods.org/pods/WatchLayout)
6 |
7 | ## Requirements
8 |
9 | iOS 13+
10 |
11 | ## Installation
12 |
13 | ### Cocoapods
14 | WatchLayout is available through [CocoaPods](https://cocoapods.org). To install
15 | it, simply add the following line to your Podfile:
16 |
17 | UIKit | SwiftUI
18 | :-------------:|:-------------:
19 | | `pod 'WatchLayout'` | `pod 'WatchLayout-SwiftUI'` |
20 |
21 |
22 | ### Swift Package Manager
23 |
24 | ```swift
25 | dependencies: [
26 | .package(url: "https://github.com/HocTran/WatchLayout.git", .upToNextMajor(from: "1.1.0"))
27 | ]
28 | ```
29 |
30 | ## Usage
31 |
32 | ### UIKit
33 |
34 | ```swift
35 | let layout = WatchLayout()
36 | ```
37 |
38 | **Support configurations**
39 |
40 | Set the item size for collection view cell.
41 | ```swift
42 | layout.itemSize = 200
43 | ```
44 |
45 | Set the cell item spacing. Minus means the items can be overlapped. Default value 0.
46 | ```swift
47 | layout.spacing = -40
48 | ```
49 |
50 | Set the scaling for item next to the item in the center. Default value 0.4
51 | ```swift
52 | layout.nextItemScale = 0.4
53 | ```
54 |
55 | Set the minimum scaling for item depending on the distance to the center. Default value 0.2
56 | ```swift
57 | layout.minScale = 0.2
58 | ```
59 |
60 | Assign the custom layout to UICollectionView
61 | ```swift
62 | collectionView.collectionViewLayout = layout
63 | ```
64 |
65 | Scroll to an item at the index path
66 | ```swift
67 | self.collectionView.setContentOffset(layout.centeredOffsetForItem(indexPath: IndexPath(item: 0, section: 0)), animated: true)
68 | ```
69 |
70 | Get the current centered index
71 | ```swift
72 | layout.centeredIndexPath
73 | ```
74 |
75 | ### SwiftUI
76 |
77 | SwiftUI version is built on top of `UIViewRepresentable` of `WatchLayout`.
78 |
79 | Declare a layout attributes (See the detail of each param in the UIKit usage above).
80 |
81 | ```swift
82 | @State var layout = WatchLayoutAttributes(
83 | itemSize: 120,
84 | spacing: 16,
85 | minScale: 0.2,
86 | nextItemScale: 0.6
87 | )
88 | ```
89 |
90 | Create and assign layout attributes to the view
91 |
92 | * data: *RandomAccessCollection* (or *Binding*) for computing the collection.
93 |
94 | * centeredIndex: **(Optional)** A binding to indentify the centered index of the collection.
95 |
96 | ```swift
97 | WatchLayoutView(
98 | layoutAttributes: layout,
99 | data: data,
100 | centeredIndex: $centeredIndex,
101 | cellContent: ({ dataElement in
102 | // Build up your cell content here
103 | Text(dataElement.description)
104 | .frame(maxWidth: .infinity, maxHeight: .infinity)
105 | .background(dataElement.color)
106 | .clipShape(Circle())
107 | })
108 | ```
109 |
110 | If **data** element is *hashable*, the centered binding can be a data element.
111 |
112 | ```swift
113 | WatchLayoutView(
114 | layoutAttributes: layout,
115 | data: data,
116 | centeredItem: $centeredItem,
117 | cellContent: ({ dataElement in
118 | // Build up your cell content here
119 | Text(dataElement.description)
120 | .frame(maxWidth: .infinity, maxHeight: .infinity)
121 | .background(dataElement.color)
122 | .clipShape(Circle())
123 | })
124 | ```
125 |
126 | ## Screenshots
127 |
128 | Positioning | Scrolling
129 | :-------------:|:-------------:
130 |  | 
131 |
132 |
133 | Example 01 | Example 02
134 | :-------------:|:-------------:
135 |  | 
136 |
137 |
138 | ## Example
139 |
140 | To run the example project, clone the repo, open `WatchLayout.xcworkspace`.
141 |
142 | ### UIKit
143 |
144 | * Select scheme `WatchLayout`, **Cmd+B** to build the framework.
145 |
146 | * Select scheme `Example-iOS`, and run the example.
147 |
148 | ### SwiftUI
149 |
150 | * Select scheme `WatchLayout`, **Cmd+B** to build the framework.
151 |
152 | * Select scheme `WatchLayout-SwiftUI`, **Cmd+B** to build the framework.
153 |
154 | * Select scheme `Example-iOS`, and run the example.
155 |
156 |
157 | ## Author
158 |
159 | HocTran, tranhoc78@gmail.com
160 |
161 | ## License
162 |
163 | WatchLayout is available under the MIT license. See the [LICENSE file](LICENSE) for more info.
164 |
--------------------------------------------------------------------------------
/Screenshots/positioning.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HocTran/WatchLayout/1eee90826452e1f3d3d8c4488ed65de63f0e90bc/Screenshots/positioning.gif
--------------------------------------------------------------------------------
/Screenshots/screenshot_01.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HocTran/WatchLayout/1eee90826452e1f3d3d8c4488ed65de63f0e90bc/Screenshots/screenshot_01.png
--------------------------------------------------------------------------------
/Screenshots/screenshot_02.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HocTran/WatchLayout/1eee90826452e1f3d3d8c4488ed65de63f0e90bc/Screenshots/screenshot_02.png
--------------------------------------------------------------------------------
/Screenshots/scrolling.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HocTran/WatchLayout/1eee90826452e1f3d3d8c4488ed65de63f0e90bc/Screenshots/scrolling.gif
--------------------------------------------------------------------------------
/Source/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 | $(CURRENT_PROJECT_VERSION)
21 |
22 |
23 |
--------------------------------------------------------------------------------
/Source/WatchLayout.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) 2021 Hoc Tran (https://hoctran.com/)
3 | //
4 | // Permission is hereby granted, free of charge, to any person obtaining a copy
5 | // of this software and associated documentation files (the "Software"), to deal
6 | // in the Software without restriction, including without limitation the rights
7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | // copies of the Software, and to permit persons to whom the Software is
9 | // furnished to do so, subject to the following conditions:
10 | //
11 | // The above copyright notice and this permission notice shall be included in
12 | // all copies or substantial portions of the Software.
13 | //
14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | // THE SOFTWARE.
21 | //
22 |
23 | import UIKit
24 |
25 | final public class WatchLayout: UICollectionViewLayout {
26 |
27 | @objc public var itemSize: CGFloat = 100 {
28 | didSet {
29 | invalidateLayout()
30 | }
31 | }
32 |
33 | @objc public var spacing: CGFloat = 0 {
34 | didSet {
35 | invalidateLayout()
36 | }
37 | }
38 |
39 | private var _minScale: CGFloat = 0.2 {
40 | didSet {
41 | invalidateLayout()
42 | }
43 | }
44 |
45 | @objc public var minScale: CGFloat {
46 | get {
47 | return _minScale
48 | }
49 | set {
50 | _minScale = min(max(newValue, 0), 1)
51 | }
52 | }
53 |
54 | private var _nextItemScale: CGFloat = 0.4 {
55 | didSet {
56 | invalidateLayout()
57 | }
58 | }
59 |
60 | @objc public var nextItemScale: CGFloat {
61 | get {
62 | return _nextItemScale
63 | }
64 | set {
65 | _nextItemScale = min(max(newValue, 0), 1)
66 | }
67 | }
68 |
69 | @objc public func centeredOffsetForItem(indexPath: IndexPath) -> CGPoint {
70 | guard let collectionView = self.collectionView else {
71 | return .zero
72 | }
73 |
74 | guard attributes.indices.contains(indexPath.item) else {
75 | return .zero
76 | }
77 |
78 | let attr = attributes[indexPath.item]
79 | return CGPoint(
80 | x: attr.center.x - collectionView.bounds.width * 0.5,
81 | y: attr.center.y - collectionView.bounds.height * 0.5
82 | )
83 | }
84 |
85 | @objc public private(set) var centeredIndexPath: IndexPath?
86 |
87 | private var attributes = [UICollectionViewLayoutAttributes]()
88 | private var layers = 1
89 |
90 | public override var collectionViewContentSize: CGSize {
91 | guard let collectionView = self.collectionView else {
92 | return .zero
93 | }
94 |
95 | let size = CGFloat(layers) * (itemSize + spacing) * 2 - (itemSize + spacing)
96 | let inset = collectionView.contentInset
97 | return CGSize(width: size + collectionView.bounds.width + inset.left + inset.right,
98 | height: size + collectionView.bounds.height + inset.top + inset.bottom)
99 | }
100 |
101 | public override class var layoutAttributesClass: AnyClass {
102 | return UICollectionViewLayoutAttributes.self
103 | }
104 |
105 | public override func prepare() {
106 |
107 | super.prepare()
108 |
109 | guard let collectionView = self.collectionView else {
110 | return
111 | }
112 |
113 | let N = collectionView.numberOfItems(inSection: 0)
114 |
115 | if attributes.count == N {
116 | return
117 | }
118 |
119 | if N == 0 {
120 | attributes.removeAll()
121 | centeredIndexPath = nil
122 | return
123 | }
124 |
125 | let center = CGPoint.zero
126 |
127 | var i = 0
128 | var layer = 0
129 |
130 | attributes.removeAll()
131 | centeredIndexPath = nil//IndexPath(item: 0, section: 0)
132 |
133 | while i < N {
134 |
135 | if layer == 0 {
136 | let attr = UICollectionViewLayoutAttributes(forCellWith: IndexPath(item: i, section: 0))
137 | attr.size = CGSize(width: itemSize, height: itemSize)
138 | attr.center = center
139 | attributes.append(attr)
140 |
141 | i += 1
142 | } else {
143 |
144 | let radius = CGFloat(layer) * (itemSize + spacing)
145 | let hexagon = Multagon(6, center: center, radius: radius)
146 |
147 | for j in 0 ..< layer {
148 |
149 | let vertexes = hexagon.midVertex(slice: layer, slideIndex: j)
150 | for vertex in vertexes {
151 | let attr = UICollectionViewLayoutAttributes(forCellWith: IndexPath(item: i, section: 0))
152 | attr.size = CGSize(width: itemSize, height: itemSize)
153 | attr.center = vertex
154 |
155 | attributes.append(attr)
156 | i += 1
157 | if i >= N {
158 | break
159 | }
160 | }
161 |
162 | if i >= N {
163 | break
164 | }
165 | }
166 | }
167 |
168 | layer += 1
169 | }
170 |
171 | layers = max(layer, 1)
172 |
173 | // move all to center
174 | let size = CGFloat(layers) * (itemSize + spacing) * 2 - (itemSize + spacing)
175 | let inset = collectionView.contentInset
176 |
177 | attributes.forEach { attr in
178 | attr.center = CGPoint(
179 | x: attr.center.x + size * 0.5 + inset.left + collectionView.bounds.width * 0.5,
180 | y: attr.center.y + size * 0.5 + inset.top + collectionView.bounds.height * 0.5
181 | )
182 | }
183 | }
184 |
185 | public override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
186 |
187 | guard let collectionView = self.collectionView else {
188 | return nil
189 | }
190 |
191 | let center = CGPoint(x: collectionView.bounds.midX, y: collectionView.bounds.midY)
192 | let result = attributes.filter { rect.intersects($0.frame) }
193 | result.forEach { attr in
194 | let distance = CGPoint.distance(center, attr.center)
195 |
196 | var scale = 1 - (1 - nextItemScale) * distance / itemSize // 0.8 is scale at 1 itemsize distance
197 | scale = min(max(scale, minScale), 1)
198 | attr.transform = CGAffineTransform(scaleX: scale, y: scale)
199 | }
200 | return result
201 | }
202 |
203 | // public override func layoutAttributesForItem(at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? {
204 | // guard let collectionView = self.collectionView else {
205 | // return nil
206 | // }
207 | // }
208 |
209 | public override func shouldInvalidateLayout(forBoundsChange newBounds: CGRect) -> Bool {
210 | return true
211 | }
212 |
213 | //auto snap to center of item
214 | public override func targetContentOffset(forProposedContentOffset proposedContentOffset: CGPoint, withScrollingVelocity velocity: CGPoint) -> CGPoint {
215 | guard let collectionView = self.collectionView else {
216 | return proposedContentOffset
217 | }
218 |
219 | let proposedCenter = CGPoint(x: proposedContentOffset.x + collectionView.bounds.width * 0.5,
220 | y: proposedContentOffset.y + collectionView.bounds.height * 0.5)
221 |
222 | let closestAttr = attributes.min { (attr1, attr2) -> Bool in
223 | return CGPoint.distance(attr1.center, proposedCenter) < CGPoint.distance(attr2.center, proposedCenter)
224 |
225 | }
226 |
227 | if let attr = closestAttr {
228 | centeredIndexPath = attr.indexPath
229 |
230 | let expectedOffset = CGPoint(x: attr.center.x - proposedCenter.x + proposedContentOffset.x,
231 | y: attr.center.y - proposedCenter.y + proposedContentOffset.y)
232 | return expectedOffset
233 | } else {
234 | return proposedContentOffset
235 | }
236 | }
237 | }
238 |
239 | // Helper
240 | private extension CGPoint {
241 | static func distance(_ p1: CGPoint, _ p2: CGPoint) -> CGFloat {
242 | return sqrt((p1.x - p2.x) * (p1.x - p2.x) + (p1.y - p2.y) * (p1.y - p2.y))
243 | }
244 | }
245 |
246 | private struct Multagon {
247 |
248 | let vertexes: [CGPoint]
249 |
250 | init(_ numberOfVertex: Int, center: CGPoint, radius: CGFloat) {
251 | let step = CGFloat.pi / (CGFloat(numberOfVertex) * 0.5)
252 | vertexes = (0.. [CGPoint] {
261 | if slice == 0 {
262 | return []
263 | }
264 | if slice == 1 || slideIndex == 0 || slideIndex == slice {
265 | return vertexes
266 | }
267 |
268 | let i = CGFloat(slideIndex)
269 | let s = CGFloat(slice)
270 |
271 | var shifted = vertexes
272 | let first = shifted.remove(at: 0)
273 | shifted.append(first)
274 |
275 | return zip(vertexes, shifted).map { (a, b) -> CGPoint in
276 | CGPoint(x: a.x + (b.x - a.x) / s * i, y: a.y + (b.y - a.y) / s * i)
277 | }
278 | }
279 | }
280 |
--------------------------------------------------------------------------------
/SwiftUI/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 | $(CURRENT_PROJECT_VERSION)
21 |
22 |
23 |
--------------------------------------------------------------------------------
/SwiftUI/WatchLayoutAttributes.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) 2021 Hoc Tran (https://hoctran.com/)
3 | //
4 | // Permission is hereby granted, free of charge, to any person obtaining a copy
5 | // of this software and associated documentation files (the "Software"), to deal
6 | // in the Software without restriction, including without limitation the rights
7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | // copies of the Software, and to permit persons to whom the Software is
9 | // furnished to do so, subject to the following conditions:
10 | //
11 | // The above copyright notice and this permission notice shall be included in
12 | // all copies or substantial portions of the Software.
13 | //
14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | // THE SOFTWARE.
21 | //
22 |
23 | import UIKit
24 | import WatchLayout
25 |
26 | public struct WatchLayoutAttributes: Equatable {
27 | public let itemSize: CGFloat
28 | public let spacing: CGFloat
29 | public let minScale: CGFloat
30 | public let nextItemScale: CGFloat
31 |
32 | public init(
33 | itemSize: CGFloat = 100,
34 | spacing: CGFloat = 0,
35 | minScale: CGFloat = 0.2,
36 | nextItemScale: CGFloat = 0.4
37 | ) {
38 | self.itemSize = itemSize
39 | self.spacing = spacing
40 | self.minScale = min(max(minScale, 0), 1)
41 | self.nextItemScale = min(max(nextItemScale, 0), 1)
42 | }
43 | }
44 |
45 | public extension WatchLayout {
46 | func withAttributes(_ layoutAttributes: WatchLayoutAttributes) -> WatchLayout {
47 | let r = WatchLayout()
48 | r.itemSize = layoutAttributes.itemSize
49 | r.spacing = layoutAttributes.spacing
50 | r.minScale = layoutAttributes.minScale
51 | r.nextItemScale = layoutAttributes.nextItemScale
52 | return r
53 | }
54 |
55 | var layoutAttributes: WatchLayoutAttributes {
56 | WatchLayoutAttributes(itemSize: itemSize,
57 | spacing: spacing,
58 | minScale: minScale,
59 | nextItemScale: nextItemScale)
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/SwiftUI/WatchLayoutUIPresentable.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) 2021 Hoc Tran (https://hoctran.com/)
3 | //
4 | // Permission is hereby granted, free of charge, to any person obtaining a copy
5 | // of this software and associated documentation files (the "Software"), to deal
6 | // in the Software without restriction, including without limitation the rights
7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | // copies of the Software, and to permit persons to whom the Software is
9 | // furnished to do so, subject to the following conditions:
10 | //
11 | // The above copyright notice and this permission notice shall be included in
12 | // all copies or substantial portions of the Software.
13 | //
14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | // THE SOFTWARE.
21 | //
22 |
23 | import SwiftUI
24 | import UIKit
25 | import WatchLayout
26 |
27 | class WatchLayoutItemCell: UICollectionViewCell {
28 |
29 | private var hostingViewController: UIHostingController?
30 |
31 | func updateContent(_ content: AnyView) {
32 | if let hostingViewController = hostingViewController {
33 | hostingViewController.view.removeFromSuperview()
34 | hostingViewController.rootView = content
35 | } else {
36 | hostingViewController = UIHostingController(rootView: content)
37 | }
38 |
39 | fitting()
40 | }
41 |
42 | private func fitting() {
43 | guard let view = hostingViewController?.view else {
44 | return
45 | }
46 |
47 | view.backgroundColor = .clear
48 | view.translatesAutoresizingMaskIntoConstraints = false
49 | contentView.addSubview(view)
50 |
51 | NSLayoutConstraint.activate([
52 | view.topAnchor.constraint(equalTo: contentView.topAnchor),
53 | view.leadingAnchor.constraint(equalTo: contentView.leadingAnchor),
54 | view.bottomAnchor.constraint(equalTo: contentView.bottomAnchor),
55 | view.trailingAnchor.constraint(equalTo: contentView.trailingAnchor),
56 | ])
57 | }
58 | }
59 |
60 | public class WatchLayoutCoordinator: NSObject, UICollectionViewDataSource, UICollectionViewDelegate {
61 |
62 | let collectionView: UICollectionView
63 | private let cellId = "cell"
64 | private var items: [T] = []
65 | private let cellContent: (T) -> Content
66 |
67 | init(layoutAtributes: WatchLayoutAttributes, @ViewBuilder cellContent: @escaping (T) -> Content) {
68 |
69 | self.collectionView = UICollectionView(frame: .zero, collectionViewLayout: WatchLayout().withAttributes(layoutAtributes))
70 | self.cellContent = cellContent
71 |
72 | super.init()
73 |
74 | self.collectionView.register(WatchLayoutItemCell.self, forCellWithReuseIdentifier: cellId)
75 | self.collectionView.dataSource = self
76 | self.collectionView.delegate = self
77 | }
78 |
79 |
80 | func reloadData(_ data: [T], layoutAttributes: WatchLayoutAttributes) {
81 |
82 | let shouldReCenter = items.isEmpty && !data.isEmpty
83 |
84 | items = data
85 |
86 | if let layout = self.collectionView.collectionViewLayout as? WatchLayout,
87 | layout.layoutAttributes != layoutAttributes {
88 | collectionView.collectionViewLayout = WatchLayout().withAttributes(layoutAttributes)
89 | }
90 | collectionView.reloadData()
91 |
92 | if shouldReCenter {
93 | centerToIndexPath(IndexPath(item: 0, section: 0))
94 | }
95 | }
96 |
97 | func centerToIndexPath(_ idx: IndexPath) {
98 |
99 | guard !items.isEmpty else {
100 | return
101 | }
102 |
103 | let indexPath: IndexPath
104 |
105 | if (0.. Int {
123 | return items.count
124 | }
125 |
126 | public func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
127 | let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath) as! WatchLayoutItemCell
128 |
129 | let ct = cellContent(items[indexPath.item])
130 | if #available(iOS 14, *) {
131 | cell.updateContent(AnyView(ct.ignoresSafeArea()))
132 | } else {
133 | cell.updateContent(AnyView(ct))
134 | }
135 |
136 | return cell
137 | }
138 | }
139 |
140 |
--------------------------------------------------------------------------------
/SwiftUI/WatchLayoutView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) 2021 Hoc Tran (https://hoctran.com/)
3 | //
4 | // Permission is hereby granted, free of charge, to any person obtaining a copy
5 | // of this software and associated documentation files (the "Software"), to deal
6 | // in the Software without restriction, including without limitation the rights
7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | // copies of the Software, and to permit persons to whom the Software is
9 | // furnished to do so, subject to the following conditions:
10 | //
11 | // The above copyright notice and this permission notice shall be included in
12 | // all copies or substantial portions of the Software.
13 | //
14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | // THE SOFTWARE.
21 | //
22 |
23 | import SwiftUI
24 | import WatchLayout
25 |
26 | public struct WatchLayoutView: UIViewRepresentable
27 | where Data: RandomAccessCollection, Content: View {
28 |
29 | private let layoutAttributes: WatchLayoutAttributes
30 |
31 | private let data: Binding
32 | private let centeredIndex: Binding?
33 |
34 | private let cellContent: (Data.Element) -> Content
35 |
36 | public func updateUIView(_ uiView: UICollectionView, context: Context) {
37 | context.coordinator.reloadData(Array(data.wrappedValue), layoutAttributes: layoutAttributes)
38 | if let centeredIndex = centeredIndex?.wrappedValue {
39 | context.coordinator.centerToIndexPath(IndexPath(item: data.wrappedValue.distance(from: data.wrappedValue.startIndex, to: centeredIndex), section: 0))
40 | }
41 | }
42 |
43 | public func makeCoordinator() -> WatchLayoutCoordinator {
44 | WatchLayoutCoordinator(layoutAtributes: layoutAttributes, cellContent: cellContent)
45 | }
46 |
47 | public func makeUIView(context: Context) -> UICollectionView {
48 | context.coordinator.collectionView
49 | }
50 |
51 | /// Creates a view that computes its cells on demand from an underlying
52 | /// collection of data, optionally allowing users to select centered index.
53 | ///
54 | /// - Parameters:
55 | /// - layoutAttributes: WatchLayout configuration.
56 | /// - data: The data for computing the collection.
57 | /// - centeredIndex: A binding to indentify the centered index of the collection
58 | /// - cellContent: A view builder that creates the view for a single cell of the collection.
59 | public init(layoutAttributes: WatchLayoutAttributes = WatchLayoutAttributes(),
60 | data: Binding,
61 | centeredIndex: Binding = .constant(nil),
62 | @ViewBuilder cellContent: @escaping (Data.Element) -> Content) {
63 | self.layoutAttributes = layoutAttributes
64 | self.centeredIndex = centeredIndex
65 | self.data = data
66 | self.cellContent = cellContent
67 | }
68 | }
69 |
70 |
71 | // MARK: - Listing bound Data
72 |
73 | extension WatchLayoutView where Data.Element: Hashable {
74 |
75 | /// Creates a view that computes its cells on demand from an underlying
76 | /// collection of hashable data, optionally allowing users to select centered item.
77 | ///
78 | /// - Parameters:
79 | /// - layoutAttributes: WatchLayout configuration.
80 | /// - data: The data for computing the collection.
81 | /// - centeredItem: A binding to indentify the centered item of the collection
82 | /// - cellContent: A view builder that creates the view for a single cell of the collection.
83 | public init(layoutAttributes: WatchLayoutAttributes = WatchLayoutAttributes(),
84 | data: Binding,
85 | centeredItem: Binding = .constant(nil),
86 | @ViewBuilder cellContent: @escaping (Data.Element) -> Content) {
87 | let centeredIndex: Binding
88 | if let center = centeredItem.wrappedValue, let idx = data.wrappedValue.firstIndex(of: center) {
89 | centeredIndex = .constant(idx)
90 | } else {
91 | centeredIndex = .constant(nil)
92 | }
93 |
94 | self = .init(layoutAttributes: layoutAttributes, data: data, centeredIndex: centeredIndex, cellContent: cellContent)
95 | }
96 | }
97 |
98 |
99 | // MARK: - Listing Data
100 |
101 | extension WatchLayoutView {
102 |
103 | /// Creates a view that computes its cells on demand from an underlying
104 | /// collection of data, optionally allowing users to select centered item.
105 | ///
106 | /// - Parameters:
107 | /// - layoutAttributes: WatchLayout configuration.
108 | /// - data: The data for computing the collection.
109 | /// - centeredItem: A binding to indentify the centered item of the collection
110 | /// - cellContent: A view builder that creates the view for a single cell of the collection.
111 | public init(layoutAttributes: WatchLayoutAttributes = WatchLayoutAttributes(),
112 | data: Data,
113 | centeredIndex: Binding = .constant(nil),
114 | @ViewBuilder cellContent: @escaping (Data.Element) -> Content) {
115 | self = .init(layoutAttributes: layoutAttributes, data: .constant(data), centeredIndex: centeredIndex, cellContent: cellContent)
116 | }
117 | }
118 |
119 | extension WatchLayoutView where Data.Element: Hashable {
120 |
121 | /// Creates a view that computes its cells on demand from an underlying
122 | /// collection of hashable data, optionally allowing users to select centered item.
123 | ///
124 | /// - Parameters:
125 | /// - layoutAttributes: WatchLayout configuration.
126 | /// - data: The data for computing the collection.
127 | /// - centeredItem: A binding to indentify the centered item of the collection
128 | /// - cellContent: A view builder that creates the view for a single cell of the collection.
129 | public init(layoutAttributes: WatchLayoutAttributes = WatchLayoutAttributes(),
130 | data: Data,
131 | centeredItem: Binding,
132 | @ViewBuilder cellContent: @escaping (Data.Element) -> Content) {
133 | self = .init(layoutAttributes: layoutAttributes, data: .constant(data), centeredItem: centeredItem, cellContent: cellContent)
134 | }
135 | }
136 |
--------------------------------------------------------------------------------
/WatchLayout-SwiftUI.podspec:
--------------------------------------------------------------------------------
1 | Pod::Spec.new do |s|
2 | s.name = 'WatchLayout-SwiftUI'
3 | s.version = '1.1.0'
4 | s.license = { :type => 'MIT', :file => 'LICENSE' }
5 | s.summary = 'A bubble watch-like like out for UICollectionView'
6 | s.homepage = 'https://github.com/HocTran/WatchLayout'
7 | s.author = { 'Hoc Tran' => 'tranhoc78@gmail.com' }
8 | s.source = { :git => 'https://github.com/HocTran/WatchLayout.git', :tag => s.version.to_s }
9 |
10 | s.ios.deployment_target = '13.0'
11 |
12 | s.source_files = 'SwiftUI/*.swift'
13 |
14 | s.swift_versions = ['5']
15 |
16 | s.dependency 'WatchLayout', '1.1.0'
17 | end
18 |
--------------------------------------------------------------------------------
/WatchLayout.podspec:
--------------------------------------------------------------------------------
1 | Pod::Spec.new do |s|
2 | s.name = 'WatchLayout'
3 | s.version = '1.1.0'
4 | s.license = { :type => 'MIT', :file => 'LICENSE' }
5 | s.summary = 'A bubble watch-like like out for UICollectionView'
6 | s.homepage = 'https://github.com/HocTran/WatchLayout'
7 | s.author = { 'Hoc Tran' => 'tranhoc78@gmail.com' }
8 | s.source = { :git => 'https://github.com/HocTran/WatchLayout.git', :tag => s.version.to_s }
9 |
10 | s.ios.deployment_target = '13.0'
11 |
12 | s.source_files = 'Source/*.swift'
13 |
14 | s.swift_versions = ['5']
15 |
16 | end
17 |
--------------------------------------------------------------------------------
/WatchLayout.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 50;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 156311F826105E9E0033FFF8 /* WatchLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 156311F626105E9E0033FFF8 /* WatchLayout.swift */; };
11 | 4B02528828F3DE9800EC67AA /* WatchLayoutView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B02528628F3DE9800EC67AA /* WatchLayoutView.swift */; };
12 | 4B02528A28F3DE9D00EC67AA /* WatchLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 156311F626105E9E0033FFF8 /* WatchLayout.swift */; };
13 | 4BD9DAB3290A5E4300023B17 /* WatchLayoutAttributes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BD9DAB2290A5E4300023B17 /* WatchLayoutAttributes.swift */; };
14 | 4BD9DAB5290A5EA000023B17 /* WatchLayoutUIPresentable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BD9DAB4290A5EA000023B17 /* WatchLayoutUIPresentable.swift */; };
15 | /* End PBXBuildFile section */
16 |
17 | /* Begin PBXFileReference section */
18 | 156311E626105E710033FFF8 /* WatchLayout.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = WatchLayout.framework; sourceTree = BUILT_PRODUCTS_DIR; };
19 | 156311F626105E9E0033FFF8 /* WatchLayout.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WatchLayout.swift; sourceTree = ""; };
20 | 156311F726105E9E0033FFF8 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
21 | 156311FB26105EB10033FFF8 /* WatchLayout.podspec */ = {isa = PBXFileReference; lastKnownFileType = text; path = WatchLayout.podspec; sourceTree = ""; };
22 | 156311FC26105EB10033FFF8 /* LICENSE */ = {isa = PBXFileReference; lastKnownFileType = text; path = LICENSE; sourceTree = ""; };
23 | 156311FD26105EB10033FFF8 /* Screenshots */ = {isa = PBXFileReference; lastKnownFileType = folder; path = Screenshots; sourceTree = ""; };
24 | 156311FE26105EB10033FFF8 /* Package.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Package.swift; sourceTree = ""; };
25 | 156311FF26105EB10033FFF8 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; };
26 | 4B02527E28F3DE8700EC67AA /* WatchLayout_SwiftUI.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = WatchLayout_SwiftUI.framework; sourceTree = BUILT_PRODUCTS_DIR; };
27 | 4B02528628F3DE9800EC67AA /* WatchLayoutView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WatchLayoutView.swift; sourceTree = ""; };
28 | 4B02528728F3DE9800EC67AA /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
29 | 4B0BF0A228F951A9007CFB54 /* WatchLayout-SwiftUI.podspec */ = {isa = PBXFileReference; lastKnownFileType = text; path = "WatchLayout-SwiftUI.podspec"; sourceTree = ""; };
30 | 4BD9DAB2290A5E4300023B17 /* WatchLayoutAttributes.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WatchLayoutAttributes.swift; sourceTree = ""; };
31 | 4BD9DAB4290A5EA000023B17 /* WatchLayoutUIPresentable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WatchLayoutUIPresentable.swift; sourceTree = ""; };
32 | /* End PBXFileReference section */
33 |
34 | /* Begin PBXFrameworksBuildPhase section */
35 | 156311E326105E710033FFF8 /* Frameworks */ = {
36 | isa = PBXFrameworksBuildPhase;
37 | buildActionMask = 2147483647;
38 | files = (
39 | );
40 | runOnlyForDeploymentPostprocessing = 0;
41 | };
42 | 4B02527B28F3DE8700EC67AA /* Frameworks */ = {
43 | isa = PBXFrameworksBuildPhase;
44 | buildActionMask = 2147483647;
45 | files = (
46 | );
47 | runOnlyForDeploymentPostprocessing = 0;
48 | };
49 | /* End PBXFrameworksBuildPhase section */
50 |
51 | /* Begin PBXGroup section */
52 | 156311DC26105E710033FFF8 = {
53 | isa = PBXGroup;
54 | children = (
55 | 156311FC26105EB10033FFF8 /* LICENSE */,
56 | 156311FE26105EB10033FFF8 /* Package.swift */,
57 | 156311FF26105EB10033FFF8 /* README.md */,
58 | 156311FD26105EB10033FFF8 /* Screenshots */,
59 | 156311FB26105EB10033FFF8 /* WatchLayout.podspec */,
60 | 4B0BF0A228F951A9007CFB54 /* WatchLayout-SwiftUI.podspec */,
61 | 156311F526105E9E0033FFF8 /* Source */,
62 | 4B02528528F3DE9800EC67AA /* SwiftUI */,
63 | 156311E726105E710033FFF8 /* Products */,
64 | );
65 | sourceTree = "";
66 | };
67 | 156311E726105E710033FFF8 /* Products */ = {
68 | isa = PBXGroup;
69 | children = (
70 | 156311E626105E710033FFF8 /* WatchLayout.framework */,
71 | 4B02527E28F3DE8700EC67AA /* WatchLayout_SwiftUI.framework */,
72 | );
73 | name = Products;
74 | sourceTree = "";
75 | };
76 | 156311F526105E9E0033FFF8 /* Source */ = {
77 | isa = PBXGroup;
78 | children = (
79 | 156311F626105E9E0033FFF8 /* WatchLayout.swift */,
80 | 156311F726105E9E0033FFF8 /* Info.plist */,
81 | );
82 | path = Source;
83 | sourceTree = "";
84 | };
85 | 4B02528528F3DE9800EC67AA /* SwiftUI */ = {
86 | isa = PBXGroup;
87 | children = (
88 | 4BD9DAB2290A5E4300023B17 /* WatchLayoutAttributes.swift */,
89 | 4BD9DAB4290A5EA000023B17 /* WatchLayoutUIPresentable.swift */,
90 | 4B02528628F3DE9800EC67AA /* WatchLayoutView.swift */,
91 | 4B02528728F3DE9800EC67AA /* Info.plist */,
92 | );
93 | path = SwiftUI;
94 | sourceTree = "";
95 | };
96 | /* End PBXGroup section */
97 |
98 | /* Begin PBXHeadersBuildPhase section */
99 | 156311E126105E710033FFF8 /* Headers */ = {
100 | isa = PBXHeadersBuildPhase;
101 | buildActionMask = 2147483647;
102 | files = (
103 | );
104 | runOnlyForDeploymentPostprocessing = 0;
105 | };
106 | 4B02527928F3DE8700EC67AA /* Headers */ = {
107 | isa = PBXHeadersBuildPhase;
108 | buildActionMask = 2147483647;
109 | files = (
110 | );
111 | runOnlyForDeploymentPostprocessing = 0;
112 | };
113 | /* End PBXHeadersBuildPhase section */
114 |
115 | /* Begin PBXNativeTarget section */
116 | 156311E526105E710033FFF8 /* WatchLayout */ = {
117 | isa = PBXNativeTarget;
118 | buildConfigurationList = 156311EE26105E710033FFF8 /* Build configuration list for PBXNativeTarget "WatchLayout" */;
119 | buildPhases = (
120 | 156311E126105E710033FFF8 /* Headers */,
121 | 156311E226105E710033FFF8 /* Sources */,
122 | 156311E326105E710033FFF8 /* Frameworks */,
123 | 156311E426105E710033FFF8 /* Resources */,
124 | );
125 | buildRules = (
126 | );
127 | dependencies = (
128 | );
129 | name = WatchLayout;
130 | productName = WatchLayout;
131 | productReference = 156311E626105E710033FFF8 /* WatchLayout.framework */;
132 | productType = "com.apple.product-type.framework";
133 | };
134 | 4B02527D28F3DE8700EC67AA /* WatchLayout-SwiftUI */ = {
135 | isa = PBXNativeTarget;
136 | buildConfigurationList = 4B02528428F3DE8700EC67AA /* Build configuration list for PBXNativeTarget "WatchLayout-SwiftUI" */;
137 | buildPhases = (
138 | 4B02527928F3DE8700EC67AA /* Headers */,
139 | 4B02527A28F3DE8700EC67AA /* Sources */,
140 | 4B02527B28F3DE8700EC67AA /* Frameworks */,
141 | 4B02527C28F3DE8700EC67AA /* Resources */,
142 | );
143 | buildRules = (
144 | );
145 | dependencies = (
146 | );
147 | name = "WatchLayout-SwiftUI";
148 | productName = "WatchLayout-SwiftUI";
149 | productReference = 4B02527E28F3DE8700EC67AA /* WatchLayout_SwiftUI.framework */;
150 | productType = "com.apple.product-type.framework";
151 | };
152 | /* End PBXNativeTarget section */
153 |
154 | /* Begin PBXProject section */
155 | 156311DD26105E710033FFF8 /* Project object */ = {
156 | isa = PBXProject;
157 | attributes = {
158 | LastUpgradeCheck = 1240;
159 | TargetAttributes = {
160 | 156311E526105E710033FFF8 = {
161 | CreatedOnToolsVersion = 12.4;
162 | };
163 | 4B02527D28F3DE8700EC67AA = {
164 | CreatedOnToolsVersion = 13.4.1;
165 | };
166 | };
167 | };
168 | buildConfigurationList = 156311E026105E710033FFF8 /* Build configuration list for PBXProject "WatchLayout" */;
169 | compatibilityVersion = "Xcode 9.3";
170 | developmentRegion = en;
171 | hasScannedForEncodings = 0;
172 | knownRegions = (
173 | en,
174 | Base,
175 | );
176 | mainGroup = 156311DC26105E710033FFF8;
177 | productRefGroup = 156311E726105E710033FFF8 /* Products */;
178 | projectDirPath = "";
179 | projectRoot = "";
180 | targets = (
181 | 156311E526105E710033FFF8 /* WatchLayout */,
182 | 4B02527D28F3DE8700EC67AA /* WatchLayout-SwiftUI */,
183 | );
184 | };
185 | /* End PBXProject section */
186 |
187 | /* Begin PBXResourcesBuildPhase section */
188 | 156311E426105E710033FFF8 /* Resources */ = {
189 | isa = PBXResourcesBuildPhase;
190 | buildActionMask = 2147483647;
191 | files = (
192 | );
193 | runOnlyForDeploymentPostprocessing = 0;
194 | };
195 | 4B02527C28F3DE8700EC67AA /* Resources */ = {
196 | isa = PBXResourcesBuildPhase;
197 | buildActionMask = 2147483647;
198 | files = (
199 | );
200 | runOnlyForDeploymentPostprocessing = 0;
201 | };
202 | /* End PBXResourcesBuildPhase section */
203 |
204 | /* Begin PBXSourcesBuildPhase section */
205 | 156311E226105E710033FFF8 /* Sources */ = {
206 | isa = PBXSourcesBuildPhase;
207 | buildActionMask = 2147483647;
208 | files = (
209 | 156311F826105E9E0033FFF8 /* WatchLayout.swift in Sources */,
210 | );
211 | runOnlyForDeploymentPostprocessing = 0;
212 | };
213 | 4B02527A28F3DE8700EC67AA /* Sources */ = {
214 | isa = PBXSourcesBuildPhase;
215 | buildActionMask = 2147483647;
216 | files = (
217 | 4B02528828F3DE9800EC67AA /* WatchLayoutView.swift in Sources */,
218 | 4BD9DAB5290A5EA000023B17 /* WatchLayoutUIPresentable.swift in Sources */,
219 | 4BD9DAB3290A5E4300023B17 /* WatchLayoutAttributes.swift in Sources */,
220 | 4B02528A28F3DE9D00EC67AA /* WatchLayout.swift in Sources */,
221 | );
222 | runOnlyForDeploymentPostprocessing = 0;
223 | };
224 | /* End PBXSourcesBuildPhase section */
225 |
226 | /* Begin XCBuildConfiguration section */
227 | 156311EC26105E710033FFF8 /* Debug */ = {
228 | isa = XCBuildConfiguration;
229 | buildSettings = {
230 | ALWAYS_SEARCH_USER_PATHS = NO;
231 | CLANG_ANALYZER_NONNULL = YES;
232 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
233 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
234 | CLANG_CXX_LIBRARY = "libc++";
235 | CLANG_ENABLE_MODULES = YES;
236 | CLANG_ENABLE_OBJC_ARC = YES;
237 | CLANG_ENABLE_OBJC_WEAK = YES;
238 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
239 | CLANG_WARN_BOOL_CONVERSION = YES;
240 | CLANG_WARN_COMMA = YES;
241 | CLANG_WARN_CONSTANT_CONVERSION = YES;
242 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
243 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
244 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
245 | CLANG_WARN_EMPTY_BODY = YES;
246 | CLANG_WARN_ENUM_CONVERSION = YES;
247 | CLANG_WARN_INFINITE_RECURSION = YES;
248 | CLANG_WARN_INT_CONVERSION = YES;
249 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
250 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
251 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
252 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
253 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
254 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
255 | CLANG_WARN_STRICT_PROTOTYPES = YES;
256 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
257 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
258 | CLANG_WARN_UNREACHABLE_CODE = YES;
259 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
260 | COPY_PHASE_STRIP = NO;
261 | CURRENT_PROJECT_VERSION = 1;
262 | DEBUG_INFORMATION_FORMAT = dwarf;
263 | ENABLE_STRICT_OBJC_MSGSEND = YES;
264 | ENABLE_TESTABILITY = YES;
265 | GCC_C_LANGUAGE_STANDARD = gnu11;
266 | GCC_DYNAMIC_NO_PIC = NO;
267 | GCC_NO_COMMON_BLOCKS = YES;
268 | GCC_OPTIMIZATION_LEVEL = 0;
269 | GCC_PREPROCESSOR_DEFINITIONS = (
270 | "DEBUG=1",
271 | "$(inherited)",
272 | );
273 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
274 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
275 | GCC_WARN_UNDECLARED_SELECTOR = YES;
276 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
277 | GCC_WARN_UNUSED_FUNCTION = YES;
278 | GCC_WARN_UNUSED_VARIABLE = YES;
279 | IPHONEOS_DEPLOYMENT_TARGET = 14.4;
280 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
281 | MTL_FAST_MATH = YES;
282 | ONLY_ACTIVE_ARCH = YES;
283 | SDKROOT = iphoneos;
284 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
285 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
286 | VERSIONING_SYSTEM = "apple-generic";
287 | VERSION_INFO_PREFIX = "";
288 | };
289 | name = Debug;
290 | };
291 | 156311ED26105E710033FFF8 /* Release */ = {
292 | isa = XCBuildConfiguration;
293 | buildSettings = {
294 | ALWAYS_SEARCH_USER_PATHS = NO;
295 | CLANG_ANALYZER_NONNULL = YES;
296 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
297 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
298 | CLANG_CXX_LIBRARY = "libc++";
299 | CLANG_ENABLE_MODULES = YES;
300 | CLANG_ENABLE_OBJC_ARC = YES;
301 | CLANG_ENABLE_OBJC_WEAK = YES;
302 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
303 | CLANG_WARN_BOOL_CONVERSION = YES;
304 | CLANG_WARN_COMMA = YES;
305 | CLANG_WARN_CONSTANT_CONVERSION = YES;
306 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
307 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
308 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
309 | CLANG_WARN_EMPTY_BODY = YES;
310 | CLANG_WARN_ENUM_CONVERSION = YES;
311 | CLANG_WARN_INFINITE_RECURSION = YES;
312 | CLANG_WARN_INT_CONVERSION = YES;
313 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
314 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
315 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
316 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
317 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
318 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
319 | CLANG_WARN_STRICT_PROTOTYPES = YES;
320 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
321 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
322 | CLANG_WARN_UNREACHABLE_CODE = YES;
323 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
324 | COPY_PHASE_STRIP = NO;
325 | CURRENT_PROJECT_VERSION = 1;
326 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
327 | ENABLE_NS_ASSERTIONS = NO;
328 | ENABLE_STRICT_OBJC_MSGSEND = YES;
329 | GCC_C_LANGUAGE_STANDARD = gnu11;
330 | GCC_NO_COMMON_BLOCKS = YES;
331 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
332 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
333 | GCC_WARN_UNDECLARED_SELECTOR = YES;
334 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
335 | GCC_WARN_UNUSED_FUNCTION = YES;
336 | GCC_WARN_UNUSED_VARIABLE = YES;
337 | IPHONEOS_DEPLOYMENT_TARGET = 14.4;
338 | MTL_ENABLE_DEBUG_INFO = NO;
339 | MTL_FAST_MATH = YES;
340 | SDKROOT = iphoneos;
341 | SWIFT_COMPILATION_MODE = wholemodule;
342 | SWIFT_OPTIMIZATION_LEVEL = "-O";
343 | VALIDATE_PRODUCT = YES;
344 | VERSIONING_SYSTEM = "apple-generic";
345 | VERSION_INFO_PREFIX = "";
346 | };
347 | name = Release;
348 | };
349 | 156311EF26105E710033FFF8 /* Debug */ = {
350 | isa = XCBuildConfiguration;
351 | buildSettings = {
352 | CODE_SIGN_STYLE = Automatic;
353 | DEFINES_MODULE = YES;
354 | DYLIB_COMPATIBILITY_VERSION = 1;
355 | DYLIB_CURRENT_VERSION = 1;
356 | DYLIB_INSTALL_NAME_BASE = "@rpath";
357 | INFOPLIST_FILE = Source/Info.plist;
358 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
359 | IPHONEOS_DEPLOYMENT_TARGET = 13.0;
360 | LD_RUNPATH_SEARCH_PATHS = (
361 | "$(inherited)",
362 | "@executable_path/Frameworks",
363 | "@loader_path/Frameworks",
364 | );
365 | PRODUCT_BUNDLE_IDENTIFIER = "Hoc-Tran.WatchLayout";
366 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
367 | SKIP_INSTALL = YES;
368 | SWIFT_VERSION = 5.0;
369 | TARGETED_DEVICE_FAMILY = "1,2";
370 | };
371 | name = Debug;
372 | };
373 | 156311F026105E710033FFF8 /* Release */ = {
374 | isa = XCBuildConfiguration;
375 | buildSettings = {
376 | CODE_SIGN_STYLE = Automatic;
377 | DEFINES_MODULE = YES;
378 | DYLIB_COMPATIBILITY_VERSION = 1;
379 | DYLIB_CURRENT_VERSION = 1;
380 | DYLIB_INSTALL_NAME_BASE = "@rpath";
381 | INFOPLIST_FILE = Source/Info.plist;
382 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
383 | IPHONEOS_DEPLOYMENT_TARGET = 13.0;
384 | LD_RUNPATH_SEARCH_PATHS = (
385 | "$(inherited)",
386 | "@executable_path/Frameworks",
387 | "@loader_path/Frameworks",
388 | );
389 | PRODUCT_BUNDLE_IDENTIFIER = "Hoc-Tran.WatchLayout";
390 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
391 | SKIP_INSTALL = YES;
392 | SWIFT_VERSION = 5.0;
393 | TARGETED_DEVICE_FAMILY = "1,2";
394 | };
395 | name = Release;
396 | };
397 | 4B02528228F3DE8700EC67AA /* Debug */ = {
398 | isa = XCBuildConfiguration;
399 | buildSettings = {
400 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
401 | CODE_SIGN_STYLE = Automatic;
402 | CURRENT_PROJECT_VERSION = 1;
403 | DEFINES_MODULE = YES;
404 | DYLIB_COMPATIBILITY_VERSION = 1;
405 | DYLIB_CURRENT_VERSION = 1;
406 | DYLIB_INSTALL_NAME_BASE = "@rpath";
407 | GENERATE_INFOPLIST_FILE = YES;
408 | INFOPLIST_KEY_NSHumanReadableCopyright = "";
409 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
410 | IPHONEOS_DEPLOYMENT_TARGET = 13.0;
411 | LD_RUNPATH_SEARCH_PATHS = (
412 | "$(inherited)",
413 | "@executable_path/Frameworks",
414 | "@loader_path/Frameworks",
415 | );
416 | MARKETING_VERSION = 1.0;
417 | PRODUCT_BUNDLE_IDENTIFIER = "dev.ht.WatchLayout-SwiftUI";
418 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
419 | SKIP_INSTALL = YES;
420 | SWIFT_EMIT_LOC_STRINGS = YES;
421 | SWIFT_VERSION = 5.0;
422 | TARGETED_DEVICE_FAMILY = "1,2";
423 | };
424 | name = Debug;
425 | };
426 | 4B02528328F3DE8700EC67AA /* Release */ = {
427 | isa = XCBuildConfiguration;
428 | buildSettings = {
429 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
430 | CODE_SIGN_STYLE = Automatic;
431 | CURRENT_PROJECT_VERSION = 1;
432 | DEFINES_MODULE = YES;
433 | DYLIB_COMPATIBILITY_VERSION = 1;
434 | DYLIB_CURRENT_VERSION = 1;
435 | DYLIB_INSTALL_NAME_BASE = "@rpath";
436 | GENERATE_INFOPLIST_FILE = YES;
437 | INFOPLIST_KEY_NSHumanReadableCopyright = "";
438 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
439 | IPHONEOS_DEPLOYMENT_TARGET = 13.0;
440 | LD_RUNPATH_SEARCH_PATHS = (
441 | "$(inherited)",
442 | "@executable_path/Frameworks",
443 | "@loader_path/Frameworks",
444 | );
445 | MARKETING_VERSION = 1.0;
446 | PRODUCT_BUNDLE_IDENTIFIER = "dev.ht.WatchLayout-SwiftUI";
447 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
448 | SKIP_INSTALL = YES;
449 | SWIFT_EMIT_LOC_STRINGS = YES;
450 | SWIFT_VERSION = 5.0;
451 | TARGETED_DEVICE_FAMILY = "1,2";
452 | };
453 | name = Release;
454 | };
455 | /* End XCBuildConfiguration section */
456 |
457 | /* Begin XCConfigurationList section */
458 | 156311E026105E710033FFF8 /* Build configuration list for PBXProject "WatchLayout" */ = {
459 | isa = XCConfigurationList;
460 | buildConfigurations = (
461 | 156311EC26105E710033FFF8 /* Debug */,
462 | 156311ED26105E710033FFF8 /* Release */,
463 | );
464 | defaultConfigurationIsVisible = 0;
465 | defaultConfigurationName = Release;
466 | };
467 | 156311EE26105E710033FFF8 /* Build configuration list for PBXNativeTarget "WatchLayout" */ = {
468 | isa = XCConfigurationList;
469 | buildConfigurations = (
470 | 156311EF26105E710033FFF8 /* Debug */,
471 | 156311F026105E710033FFF8 /* Release */,
472 | );
473 | defaultConfigurationIsVisible = 0;
474 | defaultConfigurationName = Release;
475 | };
476 | 4B02528428F3DE8700EC67AA /* Build configuration list for PBXNativeTarget "WatchLayout-SwiftUI" */ = {
477 | isa = XCConfigurationList;
478 | buildConfigurations = (
479 | 4B02528228F3DE8700EC67AA /* Debug */,
480 | 4B02528328F3DE8700EC67AA /* Release */,
481 | );
482 | defaultConfigurationIsVisible = 0;
483 | defaultConfigurationName = Release;
484 | };
485 | /* End XCConfigurationList section */
486 | };
487 | rootObject = 156311DD26105E710033FFF8 /* Project object */;
488 | }
489 |
--------------------------------------------------------------------------------
/WatchLayout.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
9 |
10 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/WatchLayout.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------