Add Examples for Day 93

This commit is contained in:
CypherPoet 2020-01-24 23:13:51 -06:00
parent e93da24434
commit 013ce270c0
9 changed files with 530 additions and 0 deletions

View File

@ -15,6 +15,12 @@
F331C40823DA77110061925E /* RootView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F331C40723DA77110061925E /* RootView.swift */; };
F331C41823DAB9700061925E /* AlignmentAndGuidesExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = F331C41723DAB9700061925E /* AlignmentAndGuidesExample.swift */; };
F331C41A23DABDA70061925E /* CustomAlignmentGuidesExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = F331C41923DABDA70061925E /* CustomAlignmentGuidesExample.swift */; };
F331C41D23DAC8E30061925E /* AbsolutePositioningExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = F331C41C23DAC8E30061925E /* AbsolutePositioningExample.swift */; };
F331C42123DBCC5A0061925E /* GeometryReaderAndCoordinatesExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = F331C42023DBCC5A0061925E /* GeometryReaderAndCoordinatesExample.swift */; };
F331C42623DBDD610061925E /* SpinningHelixView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F331C42523DBDD610061925E /* SpinningHelixView.swift */; };
F331C42823DBE2CB0061925E /* NestedGeometryReadersHelixExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = F331C42723DBE2CB0061925E /* NestedGeometryReadersHelixExample.swift */; };
F331C42A23DBE2F90061925E /* NestedGeometryReadersCoverFlowExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = F331C42923DBE2F90061925E /* NestedGeometryReadersCoverFlowExample.swift */; };
F331C42C23DC056F0061925E /* SideScrollingRectangleFlowView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F331C42B23DC056F0061925E /* SideScrollingRectangleFlowView.swift */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
@ -28,6 +34,12 @@
F331C40723DA77110061925E /* RootView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RootView.swift; sourceTree = "<group>"; };
F331C41723DAB9700061925E /* AlignmentAndGuidesExample.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlignmentAndGuidesExample.swift; sourceTree = "<group>"; };
F331C41923DABDA70061925E /* CustomAlignmentGuidesExample.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomAlignmentGuidesExample.swift; sourceTree = "<group>"; };
F331C41C23DAC8E30061925E /* AbsolutePositioningExample.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AbsolutePositioningExample.swift; sourceTree = "<group>"; };
F331C42023DBCC5A0061925E /* GeometryReaderAndCoordinatesExample.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GeometryReaderAndCoordinatesExample.swift; sourceTree = "<group>"; };
F331C42523DBDD610061925E /* SpinningHelixView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SpinningHelixView.swift; sourceTree = "<group>"; };
F331C42723DBE2CB0061925E /* NestedGeometryReadersHelixExample.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NestedGeometryReadersHelixExample.swift; sourceTree = "<group>"; };
F331C42923DBE2F90061925E /* NestedGeometryReadersCoverFlowExample.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NestedGeometryReadersCoverFlowExample.swift; sourceTree = "<group>"; };
F331C42B23DC056F0061925E /* SideScrollingRectangleFlowView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SideScrollingRectangleFlowView.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@ -91,6 +103,7 @@
isa = PBXGroup;
children = (
F331C40723DA77110061925E /* RootView.swift */,
F331C41B23DAC8D60061925E /* Day 93 */,
F331C41623DAB9640061925E /* Day 92 */,
);
path = Scenes;
@ -99,6 +112,7 @@
F331C40523DA76B60061925E /* Reusables */ = {
isa = PBXGroup;
children = (
F331C42423DBDD560061925E /* Views */,
);
path = Reusables;
sourceTree = "<group>";
@ -121,6 +135,26 @@
path = "Day 92";
sourceTree = "<group>";
};
F331C41B23DAC8D60061925E /* Day 93 */ = {
isa = PBXGroup;
children = (
F331C42723DBE2CB0061925E /* NestedGeometryReadersHelixExample.swift */,
F331C41C23DAC8E30061925E /* AbsolutePositioningExample.swift */,
F331C42023DBCC5A0061925E /* GeometryReaderAndCoordinatesExample.swift */,
F331C42923DBE2F90061925E /* NestedGeometryReadersCoverFlowExample.swift */,
);
path = "Day 93";
sourceTree = "<group>";
};
F331C42423DBDD560061925E /* Views */ = {
isa = PBXGroup;
children = (
F331C42523DBDD610061925E /* SpinningHelixView.swift */,
F331C42B23DC056F0061925E /* SideScrollingRectangleFlowView.swift */,
);
path = Views;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
@ -192,10 +226,16 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
F331C42A23DBE2F90061925E /* NestedGeometryReadersCoverFlowExample.swift in Sources */,
F331C3F023DA76390061925E /* AppDelegate.swift in Sources */,
F331C42C23DC056F0061925E /* SideScrollingRectangleFlowView.swift in Sources */,
F331C42623DBDD610061925E /* SpinningHelixView.swift in Sources */,
F331C41823DAB9700061925E /* AlignmentAndGuidesExample.swift in Sources */,
F331C42123DBCC5A0061925E /* GeometryReaderAndCoordinatesExample.swift in Sources */,
F331C42823DBE2CB0061925E /* NestedGeometryReadersHelixExample.swift in Sources */,
F331C3F223DA76390061925E /* SceneDelegate.swift in Sources */,
F331C40823DA77110061925E /* RootView.swift in Sources */,
F331C41D23DAC8E30061925E /* AbsolutePositioningExample.swift in Sources */,
F331C41A23DABDA70061925E /* CustomAlignmentGuidesExample.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;

View File

@ -0,0 +1,78 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1130"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "F331C3EB23DA76390061925E"
BuildableName = "Project18Concepts.app"
BlueprintName = "Project18Concepts"
ReferencedContainer = "container:Project18Concepts.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "F331C3EB23DA76390061925E"
BuildableName = "Project18Concepts.app"
BlueprintName = "Project18Concepts"
ReferencedContainer = "container:Project18Concepts.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "F331C3EB23DA76390061925E"
BuildableName = "Project18Concepts.app"
BlueprintName = "Project18Concepts"
ReferencedContainer = "container:Project18Concepts.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View File

@ -0,0 +1,66 @@
//
// SideScrollingRectangleFlowView.swift
// Project18Concepts
//
// Created by CypherPoet on 1/24/20.
//
//
import SwiftUI
struct SideScrollingRectangleFlowView {
private let colors: [Color] = [.red, .green, .blue, .orange, .pink, .purple, .yellow]
let container: GeometryProxy
}
// MARK: - View
extension SideScrollingRectangleFlowView: View {
var body: some View {
HStack {
ForEach(0 ..< 50) { index in
GeometryReader { geometry in
Rectangle()
.fill(self.colors[index % self.colors.count])
.frame(height: 150)
.rotation3DEffect(
self.rotation(forRectWith: geometry),
axis: (x: 0, y: 1, z: 0)
)
}
.frame(width: 150)
}
}
.padding(.horizontal, (container.size.width - 150) / 2)
}
}
// MARK: - Private Helpers
private extension SideScrollingRectangleFlowView {
func rotation(forRectWith geometry: GeometryProxy) -> Angle {
let screenMidX = Double(geometry.frame(in: .global).midX)
let containerHalfWidth = Double(container.size.width / 2)
return .radians(
-1 * ((screenMidX - containerHalfWidth) / 10 / 180) * Double.pi
)
}
}
// MARK: - Preview
struct SideScrollingRectangleFlowView_Previews: PreviewProvider {
static var previews: some View {
GeometryReader { geometry in
ScrollView(.horizontal, showsIndicators: false) {
SideScrollingRectangleFlowView(container: geometry)
}
}
.edgesIgnoringSafeArea(.all)
}
}

View File

@ -0,0 +1,76 @@
//
// SpinningHelixView.swift
// Project18Concepts
//
// Created by CypherPoet on 1/24/20.
//
//
import SwiftUI
struct SpinningHelixView {
private let colors: [Color] = [.red, .green, .blue, .orange, .pink, .purple, .yellow]
var container: GeometryProxy
}
// MARK: - View
extension SpinningHelixView: View {
var body: some View {
ForEach(0..<50) { row in
GeometryReader { geometry in
Text("Row \(row)")
.font(.largeTitle)
.frame(width: self.container.size.width)
.background(self.colors[row % self.colors.count])
.rotation3DEffect(
self.rotation(forRowWith: geometry),
axis: (x: 0, y: 1, z: 0)
)
}
.frame(height: 40)
}
}
}
// MARK: - Computeds
extension SpinningHelixView {
}
// MARK: - View Variables
extension SpinningHelixView {
}
// MARK: - Private Helpers
private extension SpinningHelixView {
func rotation(forRowWith geometry: GeometryProxy) -> Angle {
let screenHeight = Double(geometry.frame(in: .global).minY)
let containerMidHeight = Double(container.size.height) / 2.0
return .radians(
((screenHeight / 4 / 180) * Double.pi) - containerMidHeight
)
}
}
// MARK: - Preview
struct SpinningHelixView_Previews: PreviewProvider {
static var previews: some View {
GeometryReader { geometry in
ScrollView(.vertical) {
SpinningHelixView(container: geometry)
}
}
}
}

View File

@ -0,0 +1,70 @@
//
// AbsolutePositioningExample.swift
// Project18Concepts
//
// Created by CypherPoet on 1/24/20.
//
//
import SwiftUI
struct AbsolutePositioningExample {
}
// MARK: - View
extension AbsolutePositioningExample: View {
var body: some View {
VStack {
Text(/*@START_MENU_TOKEN@*/"Hello World!"/*@END_MENU_TOKEN@*/)
.background(Color.red)
.position(x: 100, y: 100)
// 📝 When we use the offset() modifier, were changing the location where a view should be
// rendered without actually changing its underlying geometry.
//
// This means when we apply background() afterwards it uses the original position of the
// text, not its offset.
//
// If you move the modifier order so that background() comes before
// offset() then things work more like you might have expected, showing
// once again that modifier order matters.
Text("Hello World!")
.offset(x: 100, y: -100)
.background(Color.blue)
Text("Hello World!")
.background(Color.purple)
.offset(x: 100, y: -100)
}
}
}
// MARK: - Computeds
extension AbsolutePositioningExample {
}
// MARK: - View Variables
extension AbsolutePositioningExample {
}
// MARK: - Private Helpers
private extension AbsolutePositioningExample {
}
// MARK: - Preview
struct AbsolutePositioningExample_Previews: PreviewProvider {
static var previews: some View {
AbsolutePositioningExample()
}
}

View File

@ -0,0 +1,77 @@
//
// GeometryReaderAndCoordinatesExample.swift
// Project18Concepts
//
// Created by CypherPoet on 1/24/20.
//
//
import SwiftUI
struct GeometryReaderAndCoordinatesExample {
enum CoordinateSpaceName {
static let custom = "Custom"
}
}
// MARK: - View
extension GeometryReaderAndCoordinatesExample: View {
var body: some View {
VStack {
Text("Top")
innerStack
.background(Color.gray)
Text("Bottom")
}
.background(Color.pink)
.coordinateSpace(name: CoordinateSpaceName.custom)
}
}
// MARK: - Computeds
extension GeometryReaderAndCoordinatesExample {
}
// MARK: - View Variables
extension GeometryReaderAndCoordinatesExample {
private var innerStack: some View {
HStack {
Text("Left")
GeometryReader { geometry in
Text("Center")
.background(Color.blue)
.onTapGesture {
print("Global center: \(geometry.frame(in: .global).midX) x \(geometry.frame(in: .global).midY)")
print("Custom center: \(geometry.frame(in: .named(CoordinateSpaceName.custom)).midX) x \(geometry.frame(in: .named(CoordinateSpaceName.custom)).midY)")
print("Local center: \(geometry.frame(in: .local).midX) x \(geometry.frame(in: .local).midY)")
}
}
.background(Color.purple)
Text("Right")
}
}
}
// MARK: - Private Helpers
private extension GeometryReaderAndCoordinatesExample {
}
// MARK: - Preview
struct GeometryReaderAndCoordinatesExample_Previews: PreviewProvider {
static var previews: some View {
GeometryReaderAndCoordinatesExample()
}
}

View File

@ -0,0 +1,53 @@
//
// NestedGeometryReadersCoverFlowExample.swift
// Project18Concepts
//
// Created by CypherPoet on 1/24/20.
//
//
import SwiftUI
struct NestedGeometryReadersCoverFlowExample {
}
// MARK: - View
extension NestedGeometryReadersCoverFlowExample: View {
var body: some View {
GeometryReader { geometry in
ScrollView(.horizontal, showsIndicators: false) {
SideScrollingRectangleFlowView(container: geometry)
}
}
.edgesIgnoringSafeArea(.all)
}
}
// MARK: - Computeds
extension NestedGeometryReadersCoverFlowExample {
}
// MARK: - View Variables
extension NestedGeometryReadersCoverFlowExample {
}
// MARK: - Private Helpers
private extension NestedGeometryReadersCoverFlowExample {
}
// MARK: - Preview
struct NestedGeometryReadersCoverFlowExample_Previews: PreviewProvider {
static var previews: some View {
NestedGeometryReadersCoverFlowExample()
}
}

View File

@ -0,0 +1,51 @@
//
// NestedGeometryReadersHelixExample.swift
// Project18Concepts
//
// Created by CypherPoet on 1/24/20.
//
//
import SwiftUI
struct NestedGeometryReadersHelixExample {
}
// MARK: - View
extension NestedGeometryReadersHelixExample: View {
var body: some View {
GeometryReader { geometry in
ScrollView(.vertical) {
SpinningHelixView(container: geometry)
}
}
}
}
// MARK: - Computeds
extension NestedGeometryReadersHelixExample {
}
// MARK: - View Variables
extension NestedGeometryReadersHelixExample {
}
// MARK: - Private Helpers
private extension NestedGeometryReadersHelixExample {
}
// MARK: - Preview
struct GeometryReaderScrollViewExample_Previews: PreviewProvider {
static var previews: some View {
NestedGeometryReadersHelixExample()
}
}

View File

@ -30,6 +30,25 @@ extension RootView: View {
destination: CustomAlignmentGuidesExample()
)
}
Section(header: Text("Day 93").font(.headline)) {
NavigationLink(
"Absolute Positioning",
destination: AbsolutePositioningExample()
)
NavigationLink(
"GeometryReader & Coordinate Spaces",
destination: GeometryReaderAndCoordinatesExample()
)
NavigationLink(
"Scroll View Effects with GeometryReaders (1)",
destination: NestedGeometryReadersHelixExample()
)
NavigationLink(
"Scroll View Effects with GeometryReaders (2)",
destination: NestedGeometryReadersCoverFlowExample()
)
}
}
.navigationBarTitle("Geometry & Layout")
}