diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0051490..1b8c864 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -35,16 +35,18 @@ jobs: path: .build/derivedData/**/Logs/Test/*.xcresult pod-lint: name: Lint Pod - runs-on: macOS-12 + runs-on: macOS-14 steps: + - name: List Simulators + run: xcrun simctl list - name: Checkout Repo uses: actions/checkout@v4 - name: Bundle Install run: bundle install - name: Select Xcode Version - run: sudo xcode-select --switch /Applications/Xcode_14.1.app/Contents/Developer + run: sudo xcode-select --switch /Applications/Xcode_15.3.app/Contents/Developer - name: Lint Podspec - run: bundle exec pod lib lint --verbose --fail-fast + run: bundle exec pod lib lint --verbose --fail-fast --swift-version=5.9 spm: name: SPM Build runs-on: macOS-12 diff --git a/Example/Packages/RealityKitContent/Package.realitycomposerpro/ProjectData/main.json b/Example/Packages/RealityKitContent/Package.realitycomposerpro/ProjectData/main.json new file mode 100644 index 0000000..4a8c74b --- /dev/null +++ b/Example/Packages/RealityKitContent/Package.realitycomposerpro/ProjectData/main.json @@ -0,0 +1,11 @@ +{ + "pathsToIds" : { + "\/RealityKitContent\/Sources\/RealityKitContent\/RealityKitContent.rkassets\/GridMaterial.usda" : "440DE5B4-E4E4-459B-AABF-9ACE96319272", + "\/RealityKitContent\/Sources\/RealityKitContent\/RealityKitContent.rkassets\/procedural_sphere_grid.usda" : "34C460AE-CA1B-4348-BD05-621ACBDFFE97", + "\/RealityKitContent\/Sources\/RealityKitContent\/RealityKitContent.rkassets\/Scene.usda" : "0A9B4653-B11E-4D6A-850E-C6FCB621626C", + "\/RealityKitContent\/Sources\/RealityKitContent\/RealityKitContent.rkassets\/Untitled Scene.usda" : "03E02005-EFA6-48D6-8A76-05B2822A74E9", + "RealityKitContent\/Sources\/RealityKitContent\/RealityKitContent.rkassets\/GridMaterial.usda" : "FBD8436F-6B8B-4B82-99B5-995D538B4704", + "RealityKitContent\/Sources\/RealityKitContent\/RealityKitContent.rkassets\/procedural_sphere_grid.usda" : "1CBF3893-ABFD-408C-8B91-045BFD257808", + "RealityKitContent\/Sources\/RealityKitContent\/RealityKitContent.rkassets\/Scene.usda" : "26DBAE76-5DD8-47B6-A085-1B4ADA111097" + } +} \ No newline at end of file diff --git a/Example/Packages/RealityKitContent/Package.realitycomposerpro/WorkspaceData/SceneMetadataList.json b/Example/Packages/RealityKitContent/Package.realitycomposerpro/WorkspaceData/SceneMetadataList.json new file mode 100644 index 0000000..1d84a75 --- /dev/null +++ b/Example/Packages/RealityKitContent/Package.realitycomposerpro/WorkspaceData/SceneMetadataList.json @@ -0,0 +1,209 @@ +{ + "0A9B4653-B11E-4D6A-850E-C6FCB621626C" : { + "cameraTransform" : [ + 0.9807314, + -1.9820146e-10, + -0.195361, + 0, + -0.10051192, + 0.85749435, + -0.5045798, + 0, + 0.16752096, + 0.51449335, + 0.84097165, + 0, + 0.09084191, + 0.05849296, + 0.13903293, + 1 + ], + "objectMetadataList" : [ + [ + "0A9B4653-B11E-4D6A-850E-C6FCB621626C", + "Root" + ], + { + "isExpanded" : true, + "isLocked" : false + }, + [ + "0A9B4653-B11E-4D6A-850E-C6FCB621626C", + "Root", + "GridMaterial" + ], + { + "isExpanded" : true, + "isLocked" : false + }, + [ + "0A9B4653-B11E-4D6A-850E-C6FCB621626C", + "Root", + "Sphere" + ], + { + "isExpanded" : true, + "isLocked" : false + } + ] + }, + "1CBF3893-ABFD-408C-8B91-045BFD257808" : { + "cameraTransform" : [ + 0.99999994, + 0, + -0, + 0, + -0, + 0.8660255, + -0.49999988, + 0, + 0, + 0.49999988, + 0.8660255, + 0, + 0, + 0.27093542, + 0.46927398, + 1 + ], + "objectMetadataList" : [ + + ] + }, + "03E02005-EFA6-48D6-8A76-05B2822A74E9" : { + "cameraTransform" : [ + 0.99999994, + 0, + -0, + 0, + -0, + 0.8660254, + -0.49999994, + 0, + 0, + 0.49999994, + 0.8660254, + 0, + 0, + 0.5981957, + 1.0361054, + 1 + ], + "objectMetadataList" : [ + + ] + }, + "26DBAE76-5DD8-47B6-A085-1B4ADA111097" : { + "cameraTransform" : [ + 1, + 0, + -0, + 0, + -0, + 0.7071069, + -0.7071067, + 0, + 0, + 0.7071067, + 0.7071069, + 0, + 0, + 0.2681068, + 0.26850593, + 1 + ], + "objectMetadataList" : [ + [ + "26DBAE76-5DD8-47B6-A085-1B4ADA111097", + "Root" + ], + { + "isExpanded" : true, + "isLocked" : false + } + ] + }, + "34C460AE-CA1B-4348-BD05-621ACBDFFE97" : { + "cameraTransform" : [ + 0.99999994, + 0, + -0, + 0, + -0, + 0.8660255, + -0.49999988, + 0, + 0, + 0.49999988, + 0.8660255, + 0, + 0, + 0.27093542, + 0.46927398, + 1 + ], + "objectMetadataList" : [ + + ] + }, + "440DE5B4-E4E4-459B-AABF-9ACE96319272" : { + "cameraTransform" : [ + 0.99999994, + 0, + -0, + 0, + -0, + 0.8660254, + -0.49999994, + 0, + 0, + 0.49999994, + 0.8660254, + 0, + 0, + 0.5981957, + 1.0361054, + 1 + ], + "objectMetadataList" : [ + [ + "440DE5B4-E4E4-459B-AABF-9ACE96319272", + "Root" + ], + { + "isExpanded" : true, + "isLocked" : false + } + ] + }, + "FBD8436F-6B8B-4B82-99B5-995D538B4704" : { + "cameraTransform" : [ + 0.99999994, + 0, + -0, + 0, + -0, + 0.8660254, + -0.49999994, + 0, + 0, + 0.49999994, + 0.8660254, + 0, + 0, + 0.5981957, + 1.0361054, + 1 + ], + "objectMetadataList" : [ + [ + "FBD8436F-6B8B-4B82-99B5-995D538B4704", + "Root" + ], + { + "isExpanded" : true, + "isLocked" : false + } + ] + } +} \ No newline at end of file diff --git a/Example/Packages/RealityKitContent/Package.realitycomposerpro/WorkspaceData/Settings.rcprojectdata b/Example/Packages/RealityKitContent/Package.realitycomposerpro/WorkspaceData/Settings.rcprojectdata new file mode 100644 index 0000000..6dea95c --- /dev/null +++ b/Example/Packages/RealityKitContent/Package.realitycomposerpro/WorkspaceData/Settings.rcprojectdata @@ -0,0 +1,17 @@ +{ + "cameraPresets" : { + + }, + "secondaryToolbarData" : { + "isGridVisible" : true, + "sceneReverbPreset" : -1 + }, + "unitDefaults" : { + "°" : "°", + "kg" : "g", + "m" : "cm", + "m\/s" : "m\/s", + "m\/s²" : "m\/s²", + "s" : "s" + } +} \ No newline at end of file diff --git a/Example/Packages/RealityKitContent/Package.swift b/Example/Packages/RealityKitContent/Package.swift new file mode 100644 index 0000000..d043ae1 --- /dev/null +++ b/Example/Packages/RealityKitContent/Package.swift @@ -0,0 +1,25 @@ +// swift-tools-version:5.9 +// The swift-tools-version declares the minimum version of Swift required to build this package. + +import PackageDescription + +let package = Package( + name: "RealityKitContent", + products: [ + // Products define the executables and libraries a package produces, and make them visible to other packages. + .library( + name: "RealityKitContent", + targets: ["RealityKitContent"]), + ], + dependencies: [ + // Dependencies declare other packages that this package depends on. + // .package(url: /* package url */, from: "1.0.0"), + ], + targets: [ + // Targets are the basic building blocks of a package. A target can define a module or a test suite. + // Targets can depend on other targets in this package, and on products in packages this package depends on. + .target( + name: "RealityKitContent", + dependencies: []), + ] +) \ No newline at end of file diff --git a/Example/Packages/RealityKitContent/README.md b/Example/Packages/RealityKitContent/README.md new file mode 100644 index 0000000..486b575 --- /dev/null +++ b/Example/Packages/RealityKitContent/README.md @@ -0,0 +1,3 @@ +# RealityKitContent + +A description of this package. \ No newline at end of file diff --git a/Example/Packages/RealityKitContent/Sources/RealityKitContent/RealityKitContent.rkassets/Materials/GridMaterial.usda b/Example/Packages/RealityKitContent/Sources/RealityKitContent/RealityKitContent.rkassets/Materials/GridMaterial.usda new file mode 100644 index 0000000..b7afd02 --- /dev/null +++ b/Example/Packages/RealityKitContent/Sources/RealityKitContent/RealityKitContent.rkassets/Materials/GridMaterial.usda @@ -0,0 +1,216 @@ +#usda 1.0 +( + defaultPrim = "Root" + metersPerUnit = 1 + upAxis = "Y" +) + +def Xform "Root" +{ + def Material "GridMaterial" + { + reorder nameChildren = ["", "", "", "", "", "", "", "", "", "", "", "", "", "", "DefaultSurfaceShader", "MaterialXPreviewSurface", "Texcoord", "Add", "Multiply", "Fractional", "LineCounts", "Multiply_1", "Separate2", "Separate2_1", "Ifgreater", "Ifgreater_1", "Max", "Background_Color"] + token outputs:mtlx:surface.connect = + token outputs:realitykit:vertex + token outputs:surface + float2 ui:nodegraph:realitykit:subgraphOutputs:pos = (2222, 300.5) + float2 ui:nodegraph:realitykit:subgraphOutputs:size = (182, 89) + int ui:nodegraph:realitykit:subgraphOutputs:stackingOrder = 749 + + def Shader "DefaultSurfaceShader" + { + uniform token info:id = "UsdPreviewSurface" + color3f inputs:diffuseColor = (1, 1, 1) + float inputs:roughness = 0.75 + token outputs:surface + } + + def Shader "MaterialXPreviewSurface" + { + uniform token info:id = "ND_UsdPreviewSurface_surfaceshader" + float inputs:clearcoat + float inputs:clearcoatRoughness + color3f inputs:diffuseColor.connect = + color3f inputs:emissiveColor + float inputs:ior + float inputs:metallic = 0.15 + float3 inputs:normal + float inputs:occlusion + float inputs:opacity + float inputs:opacityThreshold + float inputs:roughness = 0.5 + token outputs:out + float2 ui:nodegraph:node:pos = (1967, 300.5) + float2 ui:nodegraph:node:size = (208, 297) + int ui:nodegraph:node:stackingOrder = 870 + string[] ui:nodegraph:realitykit:node:attributesShowingChildren = ["Advanced"] + } + + def Shader "Texcoord" + { + uniform token info:id = "ND_texcoord_vector2" + float2 outputs:out + float2 ui:nodegraph:node:pos = (94.14453, 35.29297) + float2 ui:nodegraph:node:size = (182, 43) + int ui:nodegraph:node:stackingOrder = 1358 + } + + def Shader "Multiply" + { + uniform token info:id = "ND_multiply_vector2" + float2 inputs:in1.connect = + float2 inputs:in2 = (32, 15) + float2 inputs:in2.connect = + float2 outputs:out + float2 ui:nodegraph:node:pos = (275.64453, 47.29297) + float2 ui:nodegraph:node:size = (61, 36) + int ui:nodegraph:node:stackingOrder = 1348 + string[] ui:nodegraph:realitykit:node:attributesShowingChildren = ["inputs:in2"] + } + + def Shader "Fractional" + { + uniform token info:id = "ND_realitykit_fractional_vector2" + float2 inputs:in.connect = + float2 outputs:out + float2 ui:nodegraph:node:pos = (440.5, 49.5) + float2 ui:nodegraph:node:size = (155, 99) + int ui:nodegraph:node:stackingOrder = 1345 + } + + def Shader "BaseColor" + { + uniform token info:id = "ND_constant_color3" + color3f inputs:value = (0.89737034, 0.89737034, 0.89737034) ( + colorSpace = "Input - Texture - sRGB - sRGB" + ) + color3f inputs:value.connect = None + color3f outputs:out + float2 ui:nodegraph:node:pos = (1537.5977, 363.07812) + float2 ui:nodegraph:node:size = (150, 43) + int ui:nodegraph:node:stackingOrder = 1353 + } + + def Shader "LineColor" + { + uniform token info:id = "ND_constant_color3" + color3f inputs:value = (0.55945957, 0.55945957, 0.55945957) ( + colorSpace = "Input - Texture - sRGB - sRGB" + ) + color3f inputs:value.connect = None + color3f outputs:out + float2 ui:nodegraph:node:pos = (1536.9844, 287.86328) + float2 ui:nodegraph:node:size = (146, 43) + int ui:nodegraph:node:stackingOrder = 1355 + } + + def Shader "LineWidths" + { + uniform token info:id = "ND_combine2_vector2" + float inputs:in1 = 0.1 + float inputs:in2 = 0.1 + float2 outputs:out + float2 ui:nodegraph:node:pos = (443.64453, 233.79297) + float2 ui:nodegraph:node:size = (151, 43) + int ui:nodegraph:node:stackingOrder = 1361 + } + + def Shader "LineCounts" + { + uniform token info:id = "ND_combine2_vector2" + float inputs:in1 = 24 + float inputs:in2 = 12 + float2 outputs:out + float2 ui:nodegraph:node:pos = (94.14453, 138.29297) + float2 ui:nodegraph:node:size = (153, 43) + int ui:nodegraph:node:stackingOrder = 1359 + } + + def Shader "Remap" + { + uniform token info:id = "ND_remap_color3" + color3f inputs:in.connect = + color3f inputs:inhigh.connect = None + color3f inputs:inlow.connect = None + color3f inputs:outhigh.connect = + color3f inputs:outlow.connect = + color3f outputs:out + float2 ui:nodegraph:node:pos = (1755.5, 300.5) + float2 ui:nodegraph:node:size = (95, 171) + int ui:nodegraph:node:stackingOrder = 1282 + string[] ui:nodegraph:realitykit:node:attributesShowingChildren = ["inputs:outlow"] + } + + def Shader "Separate2" + { + uniform token info:id = "ND_separate2_vector2" + float2 inputs:in.connect = + float outputs:outx + float outputs:outy + float2 ui:nodegraph:node:pos = (1212.6445, 128.91797) + float2 ui:nodegraph:node:size = (116, 117) + int ui:nodegraph:node:stackingOrder = 1363 + } + + def Shader "Combine3" + { + uniform token info:id = "ND_combine3_color3" + float inputs:in1.connect = + float inputs:in2.connect = + float inputs:in3.connect = + color3f outputs:out + float2 ui:nodegraph:node:pos = (1578.1445, 128.91797) + float2 ui:nodegraph:node:size = (146, 54) + int ui:nodegraph:node:stackingOrder = 1348 + } + + def Shader "Range" + { + uniform token info:id = "ND_range_vector2" + bool inputs:doclamp = 1 + float2 inputs:gamma = (2, 2) + float2 inputs:in.connect = + float2 inputs:inhigh.connect = + float2 inputs:inlow = (0.02, 0.02) + float2 inputs:outhigh + float2 inputs:outlow + float2 outputs:out + float2 ui:nodegraph:node:pos = (990.64453, 128.91797) + float2 ui:nodegraph:node:size = (98, 207) + int ui:nodegraph:node:stackingOrder = 1364 + } + + def Shader "Subtract" + { + uniform token info:id = "ND_subtract_vector2" + float2 inputs:in1.connect = + float2 inputs:in2.connect = + float2 outputs:out + float2 ui:nodegraph:node:pos = (612.64453, 87.04297) + float2 ui:nodegraph:node:size = (63, 36) + int ui:nodegraph:node:stackingOrder = 1348 + } + + def Shader "Absval" + { + uniform token info:id = "ND_absval_vector2" + float2 inputs:in.connect = + float2 outputs:out + float2 ui:nodegraph:node:pos = (765.64453, 87.04297) + float2 ui:nodegraph:node:size = (123, 43) + int ui:nodegraph:node:stackingOrder = 1348 + } + + def Shader "Min" + { + uniform token info:id = "ND_min_float" + float inputs:in1.connect = + float inputs:in2.connect = + float outputs:out + float2 ui:nodegraph:node:pos = (1388.1445, 128.91797) + float2 ui:nodegraph:node:size = (114, 36) + int ui:nodegraph:node:stackingOrder = 1363 + } + } +} + diff --git a/Example/Packages/RealityKitContent/Sources/RealityKitContent/RealityKitContent.rkassets/Scene.usda b/Example/Packages/RealityKitContent/Sources/RealityKitContent/RealityKitContent.rkassets/Scene.usda new file mode 100644 index 0000000..4cb070b --- /dev/null +++ b/Example/Packages/RealityKitContent/Sources/RealityKitContent/RealityKitContent.rkassets/Scene.usda @@ -0,0 +1,59 @@ +#usda 1.0 +( + defaultPrim = "Root" + metersPerUnit = 1 + upAxis = "Y" +) + +def Xform "Root" +{ + reorder nameChildren = ["GridMaterial", "Sphere"] + rel material:binding = None ( + bindMaterialAs = "weakerThanDescendants" + ) + + def Sphere "Sphere" ( + active = true + prepend apiSchemas = ["MaterialBindingAPI"] + ) + { + rel material:binding = ( + bindMaterialAs = "weakerThanDescendants" + ) + double radius = 0.05 + quatf xformOp:orient = (1, 0, 0, 0) + float3 xformOp:scale = (1, 1, 1) + float3 xformOp:translate = (0, 0, 0.0004) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + + def RealityKitComponent "Collider" + { + uint group = 1 + uniform token info:id = "RealityKit.Collider" + uint mask = 4294967295 + token type = "Default" + + def RealityKitStruct "Shape" + { + float3 extent = (0.2, 0.2, 0.2) + float radius = 0.05 + token shapeType = "Sphere" + } + } + + def RealityKitComponent "InputTarget" + { + uniform token info:id = "RealityKit.InputTarget" + } + } + + def "GridMaterial" ( + active = true + prepend references = @Materials/GridMaterial.usda@ + ) + { + float3 xformOp:scale = (1, 1, 1) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + } +} + diff --git a/Example/Packages/RealityKitContent/Sources/RealityKitContent/RealityKitContent.swift b/Example/Packages/RealityKitContent/Sources/RealityKitContent/RealityKitContent.swift new file mode 100644 index 0000000..5caba4e --- /dev/null +++ b/Example/Packages/RealityKitContent/Sources/RealityKitContent/RealityKitContent.swift @@ -0,0 +1,4 @@ +import Foundation + +/// Bundle for the RealityKitContent project +public let realityKitContentBundle = Bundle.module diff --git a/Example/ParalayoutDemo.xcodeproj/project.pbxproj b/Example/ParalayoutDemo.xcodeproj/project.pbxproj index 3484bfd..8ff620e 100644 --- a/Example/ParalayoutDemo.xcodeproj/project.pbxproj +++ b/Example/ParalayoutDemo.xcodeproj/project.pbxproj @@ -17,6 +17,13 @@ 3D0BEEBB26047F6600C728FA /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 3D0BEEB926047F6600C728FA /* LaunchScreen.storyboard */; }; 3D0BEED42604854C00C728FA /* ViewDistributionSnapshotTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D0BEED32604854C00C728FA /* ViewDistributionSnapshotTests.swift */; }; 3D0BEEF22605598500C728FA /* SnapshotTestCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D0BEEF12605598500C728FA /* SnapshotTestCase.swift */; }; + 3DC24B062B64D7E500F3FADB /* RealityKitContent in Frameworks */ = {isa = PBXBuildFile; productRef = 3DC24B052B64D7E500F3FADB /* RealityKitContent */; }; + 3DC24B082B64D7E500F3FADB /* ParalayoutVisionDemoApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3DC24B072B64D7E500F3FADB /* ParalayoutVisionDemoApp.swift */; }; + 3DC24B0A2B64D7E500F3FADB /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3DC24B092B64D7E500F3FADB /* ContentView.swift */; }; + 3DC24B0C2B64D7E600F3FADB /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 3DC24B0B2B64D7E600F3FADB /* Assets.xcassets */; }; + 3DC24B0F2B64D7E600F3FADB /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 3DC24B0E2B64D7E600F3FADB /* Preview Assets.xcassets */; }; + 3DC24B152B64DA9E00F3FADB /* UIKitContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3DC24B142B64DA9E00F3FADB /* UIKitContentView.swift */; }; + AB37C692BE369C5BBF1B11C1 /* Pods_ParalayoutVisionDemo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 677C56ECD27566D4C3881E4C /* Pods_ParalayoutVisionDemo.framework */; }; BE56DECC24CB86EBC45FB81B /* Pods_ParalayoutDemo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2B4977CFAD5319FFF0258BF8 /* Pods_ParalayoutDemo.framework */; }; /* End PBXBuildFile section */ @@ -46,9 +53,20 @@ 3D0BEED32604854C00C728FA /* ViewDistributionSnapshotTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewDistributionSnapshotTests.swift; sourceTree = ""; }; 3D0BEED52604854C00C728FA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 3D0BEEF12605598500C728FA /* SnapshotTestCase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SnapshotTestCase.swift; sourceTree = ""; }; + 3DC24B012B64D7E500F3FADB /* ParalayoutVisionDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ParalayoutVisionDemo.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 3DC24B042B64D7E500F3FADB /* RealityKitContent */ = {isa = PBXFileReference; lastKnownFileType = wrapper; path = RealityKitContent; sourceTree = ""; }; + 3DC24B072B64D7E500F3FADB /* ParalayoutVisionDemoApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ParalayoutVisionDemoApp.swift; sourceTree = ""; }; + 3DC24B092B64D7E500F3FADB /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; }; + 3DC24B0B2B64D7E600F3FADB /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 3DC24B0E2B64D7E600F3FADB /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; + 3DC24B102B64D7E600F3FADB /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 3DC24B142B64DA9E00F3FADB /* UIKitContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIKitContentView.swift; sourceTree = ""; }; + 3ED911B2B4BC9DC23A40E453 /* Pods-ParalayoutVisionDemo.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ParalayoutVisionDemo.release.xcconfig"; path = "Target Support Files/Pods-ParalayoutVisionDemo/Pods-ParalayoutVisionDemo.release.xcconfig"; sourceTree = ""; }; 56BC1C4B5B8050608972ED18 /* Pods_ParalayoutDemo_ParalayoutSnapshotTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_ParalayoutDemo_ParalayoutSnapshotTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 66DA0A22B6BAC3A9DB54080E /* Pods-ParalayoutDemo-ParalayoutSnapshotTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ParalayoutDemo-ParalayoutSnapshotTests.release.xcconfig"; path = "Target Support Files/Pods-ParalayoutDemo-ParalayoutSnapshotTests/Pods-ParalayoutDemo-ParalayoutSnapshotTests.release.xcconfig"; sourceTree = ""; }; + 677C56ECD27566D4C3881E4C /* Pods_ParalayoutVisionDemo.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_ParalayoutVisionDemo.framework; sourceTree = BUILT_PRODUCTS_DIR; }; A103ABF2C8967E513AA8A2A1 /* Pods-ParalayoutDemo.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ParalayoutDemo.debug.xcconfig"; path = "Target Support Files/Pods-ParalayoutDemo/Pods-ParalayoutDemo.debug.xcconfig"; sourceTree = ""; }; + B3D736C30B36A20847ACD43B /* Pods-ParalayoutVisionDemo.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ParalayoutVisionDemo.debug.xcconfig"; path = "Target Support Files/Pods-ParalayoutVisionDemo/Pods-ParalayoutVisionDemo.debug.xcconfig"; sourceTree = ""; }; F0EE39C2249F3A3CBAE7BE68 /* Pods-ParalayoutDemo-ParalayoutSnapshotTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ParalayoutDemo-ParalayoutSnapshotTests.debug.xcconfig"; path = "Target Support Files/Pods-ParalayoutDemo-ParalayoutSnapshotTests/Pods-ParalayoutDemo-ParalayoutSnapshotTests.debug.xcconfig"; sourceTree = ""; }; /* End PBXFileReference section */ @@ -69,6 +87,15 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 3DC24AFE2B64D7E500F3FADB /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 3DC24B062B64D7E500F3FADB /* RealityKitContent in Frameworks */, + AB37C692BE369C5BBF1B11C1 /* Pods_ParalayoutVisionDemo.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ @@ -77,6 +104,8 @@ children = ( 3D0BEEAD26047F6400C728FA /* ParalayoutDemo */, 3D0BEED22604854C00C728FA /* ParalayoutSnapshotTests */, + 3DC24B022B64D7E500F3FADB /* ParalayoutVisionDemo */, + 3DC24B032B64D7E500F3FADB /* Packages */, 3D0BEEAC26047F6400C728FA /* Products */, 7E0941CD49D94306CE8399B6 /* Pods */, A2A4EAD12583EFDA5AA16EAC /* Frameworks */, @@ -88,6 +117,7 @@ children = ( 3D0BEEAB26047F6400C728FA /* ParalayoutDemo.app */, 3D0BEED12604854C00C728FA /* ParalayoutSnapshotTests.xctest */, + 3DC24B012B64D7E500F3FADB /* ParalayoutVisionDemo.app */, ); name = Products; sourceTree = ""; @@ -117,6 +147,35 @@ path = ParalayoutSnapshotTests; sourceTree = ""; }; + 3DC24B022B64D7E500F3FADB /* ParalayoutVisionDemo */ = { + isa = PBXGroup; + children = ( + 3DC24B072B64D7E500F3FADB /* ParalayoutVisionDemoApp.swift */, + 3DC24B092B64D7E500F3FADB /* ContentView.swift */, + 3DC24B142B64DA9E00F3FADB /* UIKitContentView.swift */, + 3DC24B0B2B64D7E600F3FADB /* Assets.xcassets */, + 3DC24B102B64D7E600F3FADB /* Info.plist */, + 3DC24B0D2B64D7E600F3FADB /* Preview Content */, + ); + path = ParalayoutVisionDemo; + sourceTree = ""; + }; + 3DC24B032B64D7E500F3FADB /* Packages */ = { + isa = PBXGroup; + children = ( + 3DC24B042B64D7E500F3FADB /* RealityKitContent */, + ); + path = Packages; + sourceTree = ""; + }; + 3DC24B0D2B64D7E600F3FADB /* Preview Content */ = { + isa = PBXGroup; + children = ( + 3DC24B0E2B64D7E600F3FADB /* Preview Assets.xcassets */, + ); + path = "Preview Content"; + sourceTree = ""; + }; 7E0941CD49D94306CE8399B6 /* Pods */ = { isa = PBXGroup; children = ( @@ -124,6 +183,8 @@ 098A230C2918ED70E7FB0FC5 /* Pods-ParalayoutDemo.release.xcconfig */, F0EE39C2249F3A3CBAE7BE68 /* Pods-ParalayoutDemo-ParalayoutSnapshotTests.debug.xcconfig */, 66DA0A22B6BAC3A9DB54080E /* Pods-ParalayoutDemo-ParalayoutSnapshotTests.release.xcconfig */, + B3D736C30B36A20847ACD43B /* Pods-ParalayoutVisionDemo.debug.xcconfig */, + 3ED911B2B4BC9DC23A40E453 /* Pods-ParalayoutVisionDemo.release.xcconfig */, ); path = Pods; sourceTree = ""; @@ -133,6 +194,7 @@ children = ( 2B4977CFAD5319FFF0258BF8 /* Pods_ParalayoutDemo.framework */, 56BC1C4B5B8050608972ED18 /* Pods_ParalayoutDemo_ParalayoutSnapshotTests.framework */, + 677C56ECD27566D4C3881E4C /* Pods_ParalayoutVisionDemo.framework */, ); name = Frameworks; sourceTree = ""; @@ -179,6 +241,28 @@ productReference = 3D0BEED12604854C00C728FA /* ParalayoutSnapshotTests.xctest */; productType = "com.apple.product-type.bundle.unit-test"; }; + 3DC24B002B64D7E500F3FADB /* ParalayoutVisionDemo */ = { + isa = PBXNativeTarget; + buildConfigurationList = 3DC24B112B64D7E600F3FADB /* Build configuration list for PBXNativeTarget "ParalayoutVisionDemo" */; + buildPhases = ( + 55384290183EBEB21495FC4D /* [CP] Check Pods Manifest.lock */, + 3DC24AFD2B64D7E500F3FADB /* Sources */, + 3DC24AFE2B64D7E500F3FADB /* Frameworks */, + 3DC24AFF2B64D7E500F3FADB /* Resources */, + 954DC931173487C6787A7F41 /* [CP] Embed Pods Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = ParalayoutVisionDemo; + packageProductDependencies = ( + 3DC24B052B64D7E500F3FADB /* RealityKitContent */, + ); + productName = ParalayoutVisionDemo; + productReference = 3DC24B012B64D7E500F3FADB /* ParalayoutVisionDemo.app */; + productType = "com.apple.product-type.application"; + }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ @@ -195,6 +279,9 @@ CreatedOnToolsVersion = 12.4; TestTargetID = 3D0BEEAA26047F6400C728FA; }; + 3DC24B002B64D7E500F3FADB = { + CreatedOnToolsVersion = 15.2; + }; }; }; buildConfigurationList = 3D0BEEA626047F6400C728FA /* Build configuration list for PBXProject "ParalayoutDemo" */; @@ -212,6 +299,7 @@ targets = ( 3D0BEEAA26047F6400C728FA /* ParalayoutDemo */, 3D0BEED02604854C00C728FA /* ParalayoutSnapshotTests */, + 3DC24B002B64D7E500F3FADB /* ParalayoutVisionDemo */, ); }; /* End PBXProject section */ @@ -233,6 +321,15 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 3DC24AFF2B64D7E500F3FADB /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 3DC24B0F2B64D7E600F3FADB /* Preview Assets.xcassets in Resources */, + 3DC24B0C2B64D7E600F3FADB /* Assets.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ @@ -270,6 +367,45 @@ shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-ParalayoutDemo-ParalayoutSnapshotTests/Pods-ParalayoutDemo-ParalayoutSnapshotTests-frameworks.sh\"\n"; showEnvVarsInLog = 0; }; + 55384290183EBEB21495FC4D /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-ParalayoutVisionDemo-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + 954DC931173487C6787A7F41 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-ParalayoutVisionDemo/Pods-ParalayoutVisionDemo-frameworks-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Embed Pods Frameworks"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-ParalayoutVisionDemo/Pods-ParalayoutVisionDemo-frameworks-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-ParalayoutVisionDemo/Pods-ParalayoutVisionDemo-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; F763318CE664BA5D8B464D85 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; @@ -338,6 +474,16 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 3DC24AFD2B64D7E500F3FADB /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 3DC24B0A2B64D7E500F3FADB /* ContentView.swift in Sources */, + 3DC24B152B64DA9E00F3FADB /* UIKitContentView.swift in Sources */, + 3DC24B082B64D7E500F3FADB /* ParalayoutVisionDemoApp.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ @@ -556,6 +702,73 @@ }; name = Release; }; + 3DC24B122B64D7E600F3FADB /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = B3D736C30B36A20847ACD43B /* Pods-ParalayoutVisionDemo.debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_ASSET_PATHS = "\"ParalayoutVisionDemo/Preview Content\""; + ENABLE_PREVIEWS = YES; + ENABLE_USER_SCRIPT_SANDBOXING = NO; + GCC_C_LANGUAGE_STANDARD = gnu17; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = "$(TARGET_NAME)/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.squareup.ParalayoutVisionDemo; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = xros; + SUPPORTED_PLATFORMS = "xros xrsimulator"; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)"; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2,7"; + XROS_DEPLOYMENT_TARGET = 1.0; + }; + name = Debug; + }; + 3DC24B132B64D7E600F3FADB /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 3ED911B2B4BC9DC23A40E453 /* Pods-ParalayoutVisionDemo.release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_ASSET_PATHS = "\"ParalayoutVisionDemo/Preview Content\""; + ENABLE_PREVIEWS = YES; + ENABLE_USER_SCRIPT_SANDBOXING = NO; + GCC_C_LANGUAGE_STANDARD = gnu17; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = "$(TARGET_NAME)/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.squareup.ParalayoutVisionDemo; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = xros; + SUPPORTED_PLATFORMS = "xros xrsimulator"; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2,7"; + XROS_DEPLOYMENT_TARGET = 1.0; + }; + name = Release; + }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ @@ -586,7 +799,23 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + 3DC24B112B64D7E600F3FADB /* Build configuration list for PBXNativeTarget "ParalayoutVisionDemo" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 3DC24B122B64D7E600F3FADB /* Debug */, + 3DC24B132B64D7E600F3FADB /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; /* End XCConfigurationList section */ + +/* Begin XCSwiftPackageProductDependency section */ + 3DC24B052B64D7E500F3FADB /* RealityKitContent */ = { + isa = XCSwiftPackageProductDependency; + productName = RealityKitContent; + }; +/* End XCSwiftPackageProductDependency section */ }; rootObject = 3D0BEEA326047F6400C728FA /* Project object */; } diff --git a/Example/ParalayoutVisionDemo/Assets.xcassets/AppIcon.solidimagestack/Back.solidimagestacklayer/Content.imageset/Contents.json b/Example/ParalayoutVisionDemo/Assets.xcassets/AppIcon.solidimagestack/Back.solidimagestacklayer/Content.imageset/Contents.json new file mode 100644 index 0000000..04056a5 --- /dev/null +++ b/Example/ParalayoutVisionDemo/Assets.xcassets/AppIcon.solidimagestack/Back.solidimagestacklayer/Content.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "idiom" : "vision", + "scale" : "2x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Example/ParalayoutVisionDemo/Assets.xcassets/AppIcon.solidimagestack/Back.solidimagestacklayer/Contents.json b/Example/ParalayoutVisionDemo/Assets.xcassets/AppIcon.solidimagestack/Back.solidimagestacklayer/Contents.json new file mode 100644 index 0000000..73c0059 --- /dev/null +++ b/Example/ParalayoutVisionDemo/Assets.xcassets/AppIcon.solidimagestack/Back.solidimagestacklayer/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Example/ParalayoutVisionDemo/Assets.xcassets/AppIcon.solidimagestack/Contents.json b/Example/ParalayoutVisionDemo/Assets.xcassets/AppIcon.solidimagestack/Contents.json new file mode 100644 index 0000000..950af4d --- /dev/null +++ b/Example/ParalayoutVisionDemo/Assets.xcassets/AppIcon.solidimagestack/Contents.json @@ -0,0 +1,17 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + }, + "layers" : [ + { + "filename" : "Front.solidimagestacklayer" + }, + { + "filename" : "Middle.solidimagestacklayer" + }, + { + "filename" : "Back.solidimagestacklayer" + } + ] +} diff --git a/Example/ParalayoutVisionDemo/Assets.xcassets/AppIcon.solidimagestack/Front.solidimagestacklayer/Content.imageset/Contents.json b/Example/ParalayoutVisionDemo/Assets.xcassets/AppIcon.solidimagestack/Front.solidimagestacklayer/Content.imageset/Contents.json new file mode 100644 index 0000000..04056a5 --- /dev/null +++ b/Example/ParalayoutVisionDemo/Assets.xcassets/AppIcon.solidimagestack/Front.solidimagestacklayer/Content.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "idiom" : "vision", + "scale" : "2x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Example/ParalayoutVisionDemo/Assets.xcassets/AppIcon.solidimagestack/Front.solidimagestacklayer/Contents.json b/Example/ParalayoutVisionDemo/Assets.xcassets/AppIcon.solidimagestack/Front.solidimagestacklayer/Contents.json new file mode 100644 index 0000000..73c0059 --- /dev/null +++ b/Example/ParalayoutVisionDemo/Assets.xcassets/AppIcon.solidimagestack/Front.solidimagestacklayer/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Example/ParalayoutVisionDemo/Assets.xcassets/AppIcon.solidimagestack/Middle.solidimagestacklayer/Content.imageset/Contents.json b/Example/ParalayoutVisionDemo/Assets.xcassets/AppIcon.solidimagestack/Middle.solidimagestacklayer/Content.imageset/Contents.json new file mode 100644 index 0000000..04056a5 --- /dev/null +++ b/Example/ParalayoutVisionDemo/Assets.xcassets/AppIcon.solidimagestack/Middle.solidimagestacklayer/Content.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "idiom" : "vision", + "scale" : "2x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Example/ParalayoutVisionDemo/Assets.xcassets/AppIcon.solidimagestack/Middle.solidimagestacklayer/Contents.json b/Example/ParalayoutVisionDemo/Assets.xcassets/AppIcon.solidimagestack/Middle.solidimagestacklayer/Contents.json new file mode 100644 index 0000000..73c0059 --- /dev/null +++ b/Example/ParalayoutVisionDemo/Assets.xcassets/AppIcon.solidimagestack/Middle.solidimagestacklayer/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Example/ParalayoutVisionDemo/Assets.xcassets/Contents.json b/Example/ParalayoutVisionDemo/Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/Example/ParalayoutVisionDemo/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Example/ParalayoutVisionDemo/ContentView.swift b/Example/ParalayoutVisionDemo/ContentView.swift new file mode 100644 index 0000000..8313abb --- /dev/null +++ b/Example/ParalayoutVisionDemo/ContentView.swift @@ -0,0 +1,27 @@ +// +// ContentView.swift +// ParalayoutVisionDemo +// +// Created by Nicholas Entin on 1/26/24. +// + +import SwiftUI +import RealityKit +import RealityKitContent +import UIKit + +struct ContentView: View { + var body: some View { + VStack { + Model3D(named: "Scene", bundle: realityKitContentBundle) + .padding(.bottom, 50) + + UIKitContentView() + } + .padding() + } +} + +#Preview(windowStyle: .automatic) { + ContentView() +} diff --git a/Example/ParalayoutVisionDemo/Info.plist b/Example/ParalayoutVisionDemo/Info.plist new file mode 100644 index 0000000..20f75e2 --- /dev/null +++ b/Example/ParalayoutVisionDemo/Info.plist @@ -0,0 +1,15 @@ + + + + + UIApplicationSceneManifest + + UIApplicationPreferredDefaultSceneSessionRole + UIWindowSceneSessionRoleApplication + UIApplicationSupportsMultipleScenes + + UISceneConfigurations + + + + diff --git a/Example/ParalayoutVisionDemo/ParalayoutVisionDemoApp.swift b/Example/ParalayoutVisionDemo/ParalayoutVisionDemoApp.swift new file mode 100644 index 0000000..c19683f --- /dev/null +++ b/Example/ParalayoutVisionDemo/ParalayoutVisionDemoApp.swift @@ -0,0 +1,17 @@ +// +// ParalayoutVisionDemoApp.swift +// ParalayoutVisionDemo +// +// Created by Nicholas Entin on 1/26/24. +// + +import SwiftUI + +@main +struct ParalayoutVisionDemoApp: App { + var body: some Scene { + WindowGroup { + ContentView() + } + } +} diff --git a/Example/ParalayoutVisionDemo/Preview Content/Preview Assets.xcassets/Contents.json b/Example/ParalayoutVisionDemo/Preview Content/Preview Assets.xcassets/Contents.json new file mode 100644 index 0000000..73c0059 --- /dev/null +++ b/Example/ParalayoutVisionDemo/Preview Content/Preview Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Example/ParalayoutVisionDemo/UIKitContentView.swift b/Example/ParalayoutVisionDemo/UIKitContentView.swift new file mode 100644 index 0000000..25fdbd5 --- /dev/null +++ b/Example/ParalayoutVisionDemo/UIKitContentView.swift @@ -0,0 +1,56 @@ +// +// UIKitContentView.swift +// ParalayoutVisionDemo +// +// Created by Nicholas Entin on 1/26/24. +// + +import Paralayout +import SwiftUI +import UIKit + +struct UIKitContentView: UIViewRepresentable { + + typealias UIViewType = CustomView + + func makeUIView(context: Context) -> CustomView { + return CustomView() + } + + func updateUIView(_ uiView: CustomView, context: Context) { + // No-op. + } + +} + +final class CustomView: UIView { + + // MARK: - Life Cycle + + override init(frame: CGRect) { + super.init(frame: frame) + + label.text = "Hello, TV" + label.textColor = .black + addSubview(label) + + backgroundColor = .white + } + + @available(*, unavailable) + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + // MARK: - Private Properties + + private let label: UILabel = .init() + + // MARK: - UIView + + override func layoutSubviews() { + label.sizeToFit() + label.align(withSuperview: .center) + } + +} diff --git a/Example/Podfile b/Example/Podfile index deeb8d5..54c14bd 100644 --- a/Example/Podfile +++ b/Example/Podfile @@ -9,3 +9,10 @@ target 'ParalayoutDemo' do pod 'SnapshotTesting', '~> 1.8' end end + +target 'ParalayoutVisionDemo' do + platform :visionos, '1.0' + use_frameworks! + + pod 'Paralayout', :path => '../Paralayout.podspec', :testspecs => ['Tests'] +end diff --git a/Example/Podfile.lock b/Example/Podfile.lock index 307671d..9737ca6 100644 --- a/Example/Podfile.lock +++ b/Example/Podfile.lock @@ -17,9 +17,9 @@ EXTERNAL SOURCES: :path: "../Paralayout.podspec" SPEC CHECKSUMS: - Paralayout: 63a087763d2c7a1b9c55843064e889aa27bdb56a + Paralayout: bec281b53f366b75f6cee850cdbeef938a98209f SnapshotTesting: 38947050d13960d57a4a9c166fcf51bca7d56970 -PODFILE CHECKSUM: f0cdc6633e8d65e479af433fa427d7c0ce7c72b1 +PODFILE CHECKSUM: ccd5bea90fc4594ec9092187c997b2c87d11c02c -COCOAPODS: 1.11.3 +COCOAPODS: 1.15.2 diff --git a/Gemfile.lock b/Gemfile.lock index 3115da4..a2d4f60 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,9 +1,11 @@ GEM remote: https://rubygems.org/ specs: - CFPropertyList (3.0.6) + CFPropertyList (3.0.7) + base64 + nkf rexml - activesupport (7.1.3) + activesupport (7.1.3.2) base64 bigdecimal concurrent-ruby (~> 1.0, >= 1.0.2) @@ -20,12 +22,12 @@ GEM json (>= 1.5.1) atomos (0.1.3) base64 (0.2.0) - bigdecimal (3.1.6) + bigdecimal (3.1.7) claide (1.1.0) - cocoapods (1.14.3) + cocoapods (1.15.2) addressable (~> 2.8) claide (>= 1.0.2, < 2.0) - cocoapods-core (= 1.14.3) + cocoapods-core (= 1.15.2) cocoapods-deintegrate (>= 1.0.3, < 2.0) cocoapods-downloader (>= 2.1, < 3.0) cocoapods-plugins (>= 1.0.0, < 2.0) @@ -40,7 +42,7 @@ GEM nap (~> 1.0) ruby-macho (>= 2.3.0, < 3.0) xcodeproj (>= 1.23.0, < 2.0) - cocoapods-core (1.14.3) + cocoapods-core (1.15.2) activesupport (>= 5.0, < 8) addressable (~> 2.8) algoliasearch (~> 1.0) @@ -62,8 +64,7 @@ GEM colored2 (3.1.2) concurrent-ruby (1.2.3) connection_pool (2.4.1) - drb (2.2.0) - ruby2_keywords + drb (2.2.1) escape (0.0.4) ethon (0.16.0) ffi (>= 1.15.0) @@ -72,24 +73,24 @@ GEM fuzzy_match (2.0.4) gh_inspector (1.1.3) httpclient (2.8.3) - i18n (1.14.1) + i18n (1.14.4) concurrent-ruby (~> 1.0) - json (2.7.1) - minitest (5.21.2) + json (2.7.2) + minitest (5.22.3) molinillo (0.8.0) mutex_m (0.2.0) nanaimo (0.3.0) nap (1.1.0) netrc (0.11.0) + nkf (0.2.0) public_suffix (4.0.7) rexml (3.2.6) ruby-macho (2.5.1) - ruby2_keywords (0.0.5) typhoeus (1.4.1) ethon (>= 0.9.0) tzinfo (2.0.6) concurrent-ruby (~> 1.0) - xcodeproj (1.23.0) + xcodeproj (1.24.0) CFPropertyList (>= 2.3.3, < 4.0) atomos (~> 0.1.3) claide (>= 1.0.2, < 2.0) diff --git a/Paralayout.podspec b/Paralayout.podspec index 86e21ce..2bda82e 100644 --- a/Paralayout.podspec +++ b/Paralayout.podspec @@ -8,7 +8,8 @@ Pod::Spec.new do |s| s.source = { :git => 'https://github.com/square/Paralayout.git', :tag => s.version } s.source_files = 'Paralayout/*.{swift}' s.ios.deployment_target = '12.0' - s.swift_version = '5.0' + s.visionos.deployment_target = '1.0' + s.swift_version = '5.9' s.test_spec 'Tests' do |test_spec| test_spec.source_files = 'ParalayoutTests/*{.swift}' diff --git a/Paralayout/PixelRounding.swift b/Paralayout/PixelRounding.swift index 3ac4f17..5df3cc8 100644 --- a/Paralayout/PixelRounding.swift +++ b/Paralayout/PixelRounding.swift @@ -23,6 +23,8 @@ public protocol ScaleFactorProviding { } +#if os(iOS) || os(tvOS) + extension UIScreen: ScaleFactorProviding { public var pixelsPerPoint: CGFloat { @@ -31,6 +33,8 @@ extension UIScreen: ScaleFactorProviding { } +#endif + extension UIView: ScaleFactorProviding { public var pixelsPerPoint: CGFloat { @@ -44,6 +48,10 @@ extension UIView: ScaleFactorProviding { #if os(iOS) return (window?.screen ?? UIScreen.main).pixelsPerPoint + #elseif os(visionOS) + // The Apple Vision Pro has a scale factor of 2, so use that as the default since that's currently the only + // visionOS device. + return 2 #endif } diff --git a/ParalayoutTests/PixelRoundingTests.swift b/ParalayoutTests/PixelRoundingTests.swift index d1f90e1..eae1f62 100644 --- a/ParalayoutTests/PixelRoundingTests.swift +++ b/ParalayoutTests/PixelRoundingTests.swift @@ -39,22 +39,22 @@ final class PixelRoundingTests: XCTestCase { func testFloatPixelRounding() { XCTAssertEqual(CGFloat(1.75).flooredToPixel(in: 0), 1.75) - XCTAssertEqual(CGFloat(1.75).flooredToPixel(in: TestScreen.at1x), 1) - XCTAssertEqual(CGFloat(1.75).flooredToPixel(in: TestScreen.at2x), 1.5) - XCTAssertEqual(CGFloat(1.75).flooredToPixel(in: TestScreen.at3x), CGFloat(2) - 1 / 3) - XCTAssertEqual(CGFloat(-1.6).flooredToPixel(in: TestScreen.at2x), -2) + XCTAssertEqual(CGFloat(1.75).flooredToPixel(in: 1), 1) + XCTAssertEqual(CGFloat(1.75).flooredToPixel(in: 2), 1.5) + XCTAssertEqual(CGFloat(1.75).flooredToPixel(in: 3), CGFloat(2) - 1 / 3) + XCTAssertEqual(CGFloat(-1.6).flooredToPixel(in: 2), -2) XCTAssertEqual(CGFloat(1.75).roundedToPixel(in: 0), 1.75) - XCTAssertEqual(CGFloat(1.75).roundedToPixel(in: TestScreen.at1x), 2) - XCTAssertEqual(CGFloat(1.75).roundedToPixel(in: TestScreen.at2x), 2) - XCTAssertEqual(CGFloat(1.75).roundedToPixel(in: TestScreen.at3x), CGFloat(2) - 1 / 3) - XCTAssertEqual(CGFloat(-1.6).roundedToPixel(in: TestScreen.at3x), CGFloat(-2) + 1 / 3) + XCTAssertEqual(CGFloat(1.75).roundedToPixel(in: 1), 2) + XCTAssertEqual(CGFloat(1.75).roundedToPixel(in: 2), 2) + XCTAssertEqual(CGFloat(1.75).roundedToPixel(in: 3), CGFloat(2) - 1 / 3) + XCTAssertEqual(CGFloat(-1.6).roundedToPixel(in: 3), CGFloat(-2) + 1 / 3) XCTAssertEqual(CGFloat(1.25).ceiledToPixel(in: 0), 1.25) - XCTAssertEqual(CGFloat(1.25).ceiledToPixel(in: TestScreen.at1x), 2) - XCTAssertEqual(CGFloat(1.25).ceiledToPixel(in: TestScreen.at2x), 1.5) - XCTAssertEqual(CGFloat(1.25).ceiledToPixel(in: TestScreen.at3x), CGFloat(1) + 1 / 3) - XCTAssertEqual(CGFloat(-1.75).ceiledToPixel(in: TestScreen.at2x), -1.5) + XCTAssertEqual(CGFloat(1.25).ceiledToPixel(in: 1), 2) + XCTAssertEqual(CGFloat(1.25).ceiledToPixel(in: 2), 1.5) + XCTAssertEqual(CGFloat(1.25).ceiledToPixel(in: 3), CGFloat(1) + 1 / 3) + XCTAssertEqual(CGFloat(-1.75).ceiledToPixel(in: 2), -1.5) } func testPointPixelRounding() { @@ -87,20 +87,20 @@ final class PixelRoundingTests: XCTestCase { func testRectPixelRounding() { XCTAssertEqual( - CGRect(left: 10.6, top: 10.4, right: 50.6, bottom: 50.6).expandedToPixel(in: TestScreen.at2x), + CGRect(left: 10.6, top: 10.4, right: 50.6, bottom: 50.6).expandedToPixel(in: 2), CGRect(left: 10.5, top: 10.0, right: 51, bottom: 51) ) XCTAssertEqual( - CGRect(left: 10.7, top: 10.4, right: 50.5, bottom: 50.7).expandedToPixel(in: TestScreen.at3x), + CGRect(left: 10.7, top: 10.4, right: 50.5, bottom: 50.7).expandedToPixel(in: 3), CGRect(left: CGFloat(10) + 2 / 3, top: CGFloat(10) + 1 / 3, right: CGFloat(50) + 2 / 3, bottom: 51) ) XCTAssertEqual( - CGRect(left: 10.6, top: 10.4, right: 50.6, bottom: 50.6).contractedToPixel(in: TestScreen.at2x), + CGRect(left: 10.6, top: 10.4, right: 50.6, bottom: 50.6).contractedToPixel(in: 2), CGRect(left: 11, top: 10.5, right: 50.5, bottom: 50.5) ) XCTAssertEqual( - CGRect(left: 10.7, top: 10.4, right: 50.5, bottom: 50.7).contractedToPixel(in: TestScreen.at3x), + CGRect(left: 10.7, top: 10.4, right: 50.5, bottom: 50.7).contractedToPixel(in: 3), CGRect(left: 11, top: CGFloat(10) + 2 / 3, right: CGFloat(50) + 1 / 3, bottom: CGFloat(50) + 2 / 3) ) } @@ -108,27 +108,32 @@ final class PixelRoundingTests: XCTestCase { // MARK: - Tests - Scale Factor func testViewScaleFactor() { - // A view should inherit the scale factor of its parent screen. - for screen in screensToTest() { - Samples.window.screen = screen - XCTAssertEqual(Samples.view.pixelsPerPoint, screen.pixelsPerPoint) - } + let viewController = UIViewController() - // With no superview, the main screen's scale should be used. - Samples.view.removeFromSuperview() - XCTAssert(Samples.view.pixelsPerPoint == UIScreen.main.pixelsPerPoint) - } + #if os(iOS) + XCTAssertEqual(viewController.view.pixelsPerPoint, UIScreen.main.pixelsPerPoint) + #elseif os(visionOS) + XCTAssertEqual(viewController.view.pixelsPerPoint, 2) + #endif + + let parentViewController = UIViewController() + parentViewController.addChild(viewController) + parentViewController.view.addSubview(viewController.view) + + let window = UIWindow() + window.makeKeyAndVisible() + window.rootViewController = parentViewController - // MARK: - Private Methods + for scale in Array([1, 2, 3]) { + if #available(iOS 17.0, visionOS 1.0, *) { + parentViewController.traitOverrides.displayScale = scale + } else { + parentViewController.setOverrideTraitCollection(.init(displayScale: scale), forChild: viewController) + } - private func screensToTest() -> [UIScreen] { - if #available(iOS 13, *) { - // In iOS 13 and later, there is a bug around setting `UIWindow.screen` that prevents us from testing - // multiple screens (FB8674601). - return [.main] + RunLoop.current.run(until: Date()) - } else { - return TestScreen.all + XCTAssertEqual(viewController.view.pixelsPerPoint, scale) } } diff --git a/ParalayoutTests/TestSamples.swift b/ParalayoutTests/TestSamples.swift deleted file mode 100644 index aeec158..0000000 --- a/ParalayoutTests/TestSamples.swift +++ /dev/null @@ -1,45 +0,0 @@ -// -// Copyright © 2017 Square, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -//    http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -import Paralayout -import UIKit - -final class TestScreen: UIScreen { - static let at1x = TestScreen(testScaleFactor: 1) - static let at2x = TestScreen(testScaleFactor: 2) - static let at3x = TestScreen(testScaleFactor: 3) - - static var all: [UIScreen] { - return [ UIScreen.main, TestScreen.at1x, TestScreen.at2x, TestScreen.at3x ] - } - - let testScaleFactor: CGFloat - - init(testScaleFactor: CGFloat) { - self.testScaleFactor = testScaleFactor - super.init() - } - - override var scale: CGFloat { - return testScaleFactor - } - - override var traitCollection: UITraitCollection { - // By default, `UIScreen` returns an invalid trait collection. Use the main screen's trait collection here - // instead since we know that should be valid. - return UIScreen.main.traitCollection - } -}