commit 3470c7e360f16a080c5547a57e268cab756ace0f Author: Sriram K Date: Tue Jan 25 13:52:52 2022 +0530 base code commit from windows system diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..faf7c5d --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,128 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +We as members, contributors, and leaders pledge to make participation in our +community a harassment-free experience for everyone, regardless of age, body +size, visible or invisible disability, ethnicity, sex characteristics, gender +identity and expression, level of experience, education, socio-economic status, +nationality, personal appearance, race, religion, or sexual identity +and orientation. + +We pledge to act and interact in ways that contribute to an open, welcoming, +diverse, inclusive, and healthy community. + +## Our Standards + +Examples of behavior that contributes to a positive environment for our +community include: + +* Demonstrating empathy and kindness toward other people +* Being respectful of differing opinions, viewpoints, and experiences +* Giving and gracefully accepting constructive feedback +* Accepting responsibility and apologizing to those affected by our mistakes, + and learning from the experience +* Focusing on what is best not just for us as individuals, but for the + overall community + +Examples of unacceptable behavior include: + +* The use of sexualized language or imagery, and sexual attention or + advances of any kind +* Trolling, insulting or derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or email + address, without their explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Enforcement Responsibilities + +Community leaders are responsible for clarifying and enforcing our standards of +acceptable behavior and will take appropriate and fair corrective action in +response to any behavior that they deem inappropriate, threatening, offensive, +or harmful. + +Community leaders have the right and responsibility to remove, edit, or reject +comments, commits, code, wiki edits, issues, and other contributions that are +not aligned to this Code of Conduct, and will communicate reasons for moderation +decisions when appropriate. + +## Scope + +This Code of Conduct applies within all community spaces, and also applies when +an individual is officially representing the community in public spaces. +Examples of representing our community include using an official e-mail address, +posting via an official social media account, or acting as an appointed +representative at an online or offline event. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported to the community leaders responsible for enforcement at +hello@ivanvorobei.by. +All complaints will be reviewed and investigated promptly and fairly. + +All community leaders are obligated to respect the privacy and security of the +reporter of any incident. + +## Enforcement Guidelines + +Community leaders will follow these Community Impact Guidelines in determining +the consequences for any action they deem in violation of this Code of Conduct: + +### 1. Correction + +**Community Impact**: Use of inappropriate language or other behavior deemed +unprofessional or unwelcome in the community. + +**Consequence**: A private, written warning from community leaders, providing +clarity around the nature of the violation and an explanation of why the +behavior was inappropriate. A public apology may be requested. + +### 2. Warning + +**Community Impact**: A violation through a single incident or series +of actions. + +**Consequence**: A warning with consequences for continued behavior. No +interaction with the people involved, including unsolicited interaction with +those enforcing the Code of Conduct, for a specified period of time. This +includes avoiding interactions in community spaces as well as external channels +like social media. Violating these terms may lead to a temporary or +permanent ban. + +### 3. Temporary Ban + +**Community Impact**: A serious violation of community standards, including +sustained inappropriate behavior. + +**Consequence**: A temporary ban from any sort of interaction or public +communication with the community for a specified period of time. No public or +private interaction with the people involved, including unsolicited interaction +with those enforcing the Code of Conduct, is allowed during this period. +Violating these terms may lead to a permanent ban. + +### 4. Permanent Ban + +**Community Impact**: Demonstrating a pattern of violation of community +standards, including sustained inappropriate behavior, harassment of an +individual, or aggression toward or disparagement of classes of individuals. + +**Consequence**: A permanent ban from any sort of public interaction within +the community. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], +version 2.0, available at +https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. + +Community Impact Guidelines were inspired by [Mozilla's code of conduct +enforcement ladder](https://github.com/mozilla/diversity). + +[homepage]: https://www.contributor-covenant.org + +For answers to common questions about this code of conduct, see the FAQ at +https://www.contributor-covenant.org/faq. Translations are available at +https://www.contributor-covenant.org/translations. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..64b8cb6 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,28 @@ +# Contributing + +Here provided more info about project, contribution process and recomended changes. +Please, read it before pull request or create issue. + +## Codestyle + +### Marks + +For clean struct code good is using marks. + +```swift +class Example { + + // MARK: - Init + + init() {} +} +``` + +Here you find all which using in project: + +- // MARK: - Init +- // MARK: - Lifecycle +- // MARK: - Layout +- // MARK: - Helpers + +If you can't find valid, add new to codestyle agreements please. Other can be use if class is large and need struct it even without adding to codestyle agreements. diff --git a/Examples.xcworkspace/contents.xcworkspacedata b/Examples.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..9ab944b --- /dev/null +++ b/Examples.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,82 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Examples.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/Examples.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/Examples.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/Files/AnimatableCards.swift b/Files/AnimatableCards.swift new file mode 100644 index 0000000..df87a10 --- /dev/null +++ b/Files/AnimatableCards.swift @@ -0,0 +1,122 @@ +// The MIT License (MIT) +// Copyright © 2019 Ivan Varabei (varabeis@icloud.com) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +import SwiftUI + +struct ContentView: View { + + @GestureState var dragState = DragState.inactive + + var body: some View { + + let dragGester = DragGesture() + .updating($dragState) { (value, state, transaction) in + state = .dragging(translation: value.translation) + } + + return ZStack { + Card(title: "Third card") + .rotation3DEffect(Angle(degrees: dragState.isActive ? 0 : 60), axis: (x: 10.0, y: 10.0, z: 10.0)) + .blendMode(.hardLight) + .padding(dragState.isActive ? 32 : 64) + .padding(.bottom, dragState.isActive ? 32 : 64) + .animation(.spring()) + Card(title: "Second Card") + .rotation3DEffect(Angle(degrees: dragState.isActive ? 0 : 30), axis: (x: 10.0, y: 10.0, z: 10.0)) + .blendMode(.hardLight) + .padding(dragState.isActive ? 16 : 32) + .padding(.bottom, dragState.isActive ? 0 : 32) + .animation(.spring()) + MainCard(title: "Main Card") + .offset( + x: dragState.translation.width, + y: dragState.translation.height + ) + .rotationEffect(Angle(degrees: Double(dragState.translation.width / 10))) + .shadow(radius: dragState.isActive ? 8 : 0) + .animation(.spring()) + .gesture(dragGester) + } + + } + + enum DragState { + + case inactive + case dragging(translation: CGSize) + + var translation: CGSize { + switch self { + case .inactive: + return .zero + case .dragging(let translation): + return translation + } + } + + var isActive: Bool { + switch self { + case .inactive: + return false + case .dragging: + return true + } + } + } +} + +struct Card: View { + + var title: String + + var body: some View { + ZStack { + Rectangle() + .fill(Color(red: 68 / 255, green: 41 / 255, blue: 182 / 255)) + .frame(height: 230) + .cornerRadius(10) + .padding(16) + Text(title) + .color(.white) + .font(.title) + .bold() + } + } +} + +struct MainCard: View { + + var title: String + + var body: some View { + ZStack { + Rectangle() + .fill(Color.black) + .frame(height: 230) + .cornerRadius(10) + .padding(16) + Text(title) + .color(.white) + .font(.largeTitle) + .bold() + } + } +} diff --git a/Files/AreaToCard.swift b/Files/AreaToCard.swift new file mode 100644 index 0000000..2a9d4b3 --- /dev/null +++ b/Files/AreaToCard.swift @@ -0,0 +1,79 @@ +// The MIT License (MIT) +// Copyright © 2019 Ivan Varabei (varabeis@icloud.com) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +import SwiftUI + +struct ContentView : View { + @State var show = false + + var body: some View { + VStack() { + Text("Card in SwiftUI") + .foregroundColor(.white) + .fontWeight(.bold) + .font(.largeTitle) + .padding(.top, show ? 30 : 20) + .padding(.bottom, show ? 20 : 0) + + Text("Animatable cards with Spring, custom frame and some paddings. Also use SFSymbol for icon in the bottom button. Tap to button fo see fill style of this icon.") + .foregroundColor(.white) + .multilineTextAlignment(.center) + .animation(.spring()) + .cornerRadius(0) + .lineLimit(.none) + + Spacer() + + Button(action: { + self.show.toggle() + }) { + HStack { + Image(systemName: show ? "slash.circle.fill" : "slash.circle") + .foregroundColor(Color(hue: 0.498, saturation: 0.609, brightness: 1.0)) + .font(Font.title.weight(.semibold)) + .imageScale(.small) + Text(show ? "to Card" : "to Area") + .foregroundColor(Color(hue: 0.498, saturation: 0.609, brightness: 1.0)) + .fontWeight(.bold) + .font(.title) + .cornerRadius(0) + } + } + .padding(.bottom, show ? 20 : 15) + + } + .padding() + .padding(.top, 15) + .frame(width: show ? 350 : 290, height: show ? 420 : 260) + .background(Color.blue) + .cornerRadius(30) + .animation(.spring()) + } +} + +#if DEBUG +struct ContentView_Previews : PreviewProvider { + static var previews: some View { + ContentView() + } +} +#endif + diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..8f7a3fa --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright © 2020 Ivan Vorobei + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/Other Projects/2048 Game/LICENSE b/Other Projects/2048 Game/LICENSE new file mode 100644 index 0000000..e69de29 diff --git a/Other Projects/2048 Game/Screenshot.png b/Other Projects/2048 Game/Screenshot.png new file mode 100644 index 0000000..e69de29 diff --git a/Other Projects/2048 Game/SwiftUI2048.xcodeproj/project.pbxproj b/Other Projects/2048 Game/SwiftUI2048.xcodeproj/project.pbxproj new file mode 100644 index 0000000..b32c81b --- /dev/null +++ b/Other Projects/2048 Game/SwiftUI2048.xcodeproj/project.pbxproj @@ -0,0 +1,407 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 50; + objects = { + +/* Begin PBXBuildFile section */ + FA132EFA22A94D9400BD9743 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = FA132EF922A94D9400BD9743 /* MainMenu.xib */; }; + FA633E1F22A77D1C00DE6288 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA633E1E22A77D1C00DE6288 /* AppDelegate.swift */; }; + FA633E2522A77D1D00DE6288 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = FA633E2422A77D1D00DE6288 /* Assets.xcassets */; }; + FA633E2822A77D1D00DE6288 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = FA633E2722A77D1D00DE6288 /* Preview Assets.xcassets */; }; + FA633E2B22A77D1D00DE6288 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = FA633E2922A77D1D00DE6288 /* LaunchScreen.storyboard */; }; + FA633E3422A77D5700DE6288 /* BlockView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA633E3322A77D5700DE6288 /* BlockView.swift */; }; + FA633E3722A7928500DE6288 /* BlockMatrix.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA633E3622A7928400DE6288 /* BlockMatrix.swift */; }; + FA633E3922A79AFA00DE6288 /* GameLogic.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA633E3822A79AFA00DE6288 /* GameLogic.swift */; }; + FA633E3B22A79B1200DE6288 /* GameView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA633E3A22A79B1200DE6288 /* GameView.swift */; }; + FA633E3D22A79B3C00DE6288 /* BlockGridView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA633E3C22A79B3C00DE6288 /* BlockGridView.swift */; }; + FA633E3F22A7BDBB00DE6288 /* IdentifiedBlock.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA633E3E22A7BDBB00DE6288 /* IdentifiedBlock.swift */; }; + FA633E4622A800AB00DE6288 /* Screenshot.png in Resources */ = {isa = PBXBuildFile; fileRef = FA633E4522A800AB00DE6288 /* Screenshot.png */; }; + FA633E4822A8019D00DE6288 /* LICENSE in Resources */ = {isa = PBXBuildFile; fileRef = FA633E4722A8019D00DE6288 /* LICENSE */; }; + FA6F2B2122A81832009C2D3B /* FunctionalUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA6F2B2022A81832009C2D3B /* FunctionalUtils.swift */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + FA132EF822A90EFD00BD9743 /* SwiftUI2048.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = SwiftUI2048.entitlements; sourceTree = ""; }; + FA132EF922A94D9400BD9743 /* MainMenu.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = MainMenu.xib; sourceTree = ""; }; + FA633E1B22A77D1C00DE6288 /* 2048.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = 2048.app; sourceTree = BUILT_PRODUCTS_DIR; }; + FA633E1E22A77D1C00DE6288 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + FA633E2422A77D1D00DE6288 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + FA633E2722A77D1D00DE6288 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; + FA633E2A22A77D1D00DE6288 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + FA633E2C22A77D1D00DE6288 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + FA633E3322A77D5700DE6288 /* BlockView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BlockView.swift; sourceTree = ""; }; + FA633E3622A7928400DE6288 /* BlockMatrix.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BlockMatrix.swift; sourceTree = ""; }; + FA633E3822A79AFA00DE6288 /* GameLogic.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GameLogic.swift; sourceTree = ""; }; + FA633E3A22A79B1200DE6288 /* GameView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GameView.swift; sourceTree = ""; }; + FA633E3C22A79B3C00DE6288 /* BlockGridView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BlockGridView.swift; sourceTree = ""; }; + FA633E3E22A7BDBB00DE6288 /* IdentifiedBlock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IdentifiedBlock.swift; sourceTree = ""; }; + FA633E4222A7FFD000DE6288 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; + FA633E4522A800AB00DE6288 /* Screenshot.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Screenshot.png; sourceTree = ""; }; + FA633E4722A8019D00DE6288 /* LICENSE */ = {isa = PBXFileReference; lastKnownFileType = text; path = LICENSE; sourceTree = ""; }; + FA6F2B2022A81832009C2D3B /* FunctionalUtils.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FunctionalUtils.swift; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + FA633E1822A77D1C00DE6288 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + FA633E1222A77D1C00DE6288 = { + isa = PBXGroup; + children = ( + FA633E4722A8019D00DE6288 /* LICENSE */, + FA633E4222A7FFD000DE6288 /* README.md */, + FA633E4522A800AB00DE6288 /* Screenshot.png */, + FA633E1D22A77D1C00DE6288 /* SwiftUI2048 */, + FA633E1C22A77D1C00DE6288 /* Products */, + ); + sourceTree = ""; + }; + FA633E1C22A77D1C00DE6288 /* Products */ = { + isa = PBXGroup; + children = ( + FA633E1B22A77D1C00DE6288 /* 2048.app */, + ); + name = Products; + sourceTree = ""; + }; + FA633E1D22A77D1C00DE6288 /* SwiftUI2048 */ = { + isa = PBXGroup; + children = ( + FA132EF822A90EFD00BD9743 /* SwiftUI2048.entitlements */, + FA6F2B2022A81832009C2D3B /* FunctionalUtils.swift */, + FA633E3522A7926200DE6288 /* Models */, + FA633E3222A77D3400DE6288 /* Views */, + FA633E1E22A77D1C00DE6288 /* AppDelegate.swift */, + FA633E2422A77D1D00DE6288 /* Assets.xcassets */, + FA633E2922A77D1D00DE6288 /* LaunchScreen.storyboard */, + FA132EF922A94D9400BD9743 /* MainMenu.xib */, + FA633E2C22A77D1D00DE6288 /* Info.plist */, + FA633E2622A77D1D00DE6288 /* Preview Content */, + ); + path = SwiftUI2048; + sourceTree = ""; + }; + FA633E2622A77D1D00DE6288 /* Preview Content */ = { + isa = PBXGroup; + children = ( + FA633E2722A77D1D00DE6288 /* Preview Assets.xcassets */, + ); + path = "Preview Content"; + sourceTree = ""; + }; + FA633E3222A77D3400DE6288 /* Views */ = { + isa = PBXGroup; + children = ( + FA633E3322A77D5700DE6288 /* BlockView.swift */, + FA633E3C22A79B3C00DE6288 /* BlockGridView.swift */, + FA633E3A22A79B1200DE6288 /* GameView.swift */, + ); + path = Views; + sourceTree = ""; + }; + FA633E3522A7926200DE6288 /* Models */ = { + isa = PBXGroup; + children = ( + FA633E3622A7928400DE6288 /* BlockMatrix.swift */, + FA633E3822A79AFA00DE6288 /* GameLogic.swift */, + FA633E3E22A7BDBB00DE6288 /* IdentifiedBlock.swift */, + ); + path = Models; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + FA633E1A22A77D1C00DE6288 /* 2048 */ = { + isa = PBXNativeTarget; + buildConfigurationList = FA633E2F22A77D1D00DE6288 /* Build configuration list for PBXNativeTarget "2048" */; + buildPhases = ( + FA633E1722A77D1C00DE6288 /* Sources */, + FA633E1822A77D1C00DE6288 /* Frameworks */, + FA633E1922A77D1C00DE6288 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = 2048; + productName = SwiftUI2048; + productReference = FA633E1B22A77D1C00DE6288 /* 2048.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + FA633E1322A77D1C00DE6288 /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 1100; + LastUpgradeCheck = 1100; + ORGANIZATIONNAME = Cyandev; + TargetAttributes = { + FA633E1A22A77D1C00DE6288 = { + CreatedOnToolsVersion = 11.0; + }; + }; + }; + buildConfigurationList = FA633E1622A77D1C00DE6288 /* Build configuration list for PBXProject "SwiftUI2048" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = FA633E1222A77D1C00DE6288; + productRefGroup = FA633E1C22A77D1C00DE6288 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + FA633E1A22A77D1C00DE6288 /* 2048 */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + FA633E1922A77D1C00DE6288 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + FA633E2B22A77D1D00DE6288 /* LaunchScreen.storyboard in Resources */, + FA633E2822A77D1D00DE6288 /* Preview Assets.xcassets in Resources */, + FA633E2522A77D1D00DE6288 /* Assets.xcassets in Resources */, + FA633E4622A800AB00DE6288 /* Screenshot.png in Resources */, + FA633E4822A8019D00DE6288 /* LICENSE in Resources */, + FA132EFA22A94D9400BD9743 /* MainMenu.xib in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + FA633E1722A77D1C00DE6288 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + FA633E3F22A7BDBB00DE6288 /* IdentifiedBlock.swift in Sources */, + FA6F2B2122A81832009C2D3B /* FunctionalUtils.swift in Sources */, + FA633E3922A79AFA00DE6288 /* GameLogic.swift in Sources */, + FA633E3422A77D5700DE6288 /* BlockView.swift in Sources */, + FA633E3D22A79B3C00DE6288 /* BlockGridView.swift in Sources */, + FA633E1F22A77D1C00DE6288 /* AppDelegate.swift in Sources */, + FA633E3722A7928500DE6288 /* BlockMatrix.swift in Sources */, + FA633E3B22A79B1200DE6288 /* GameView.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + FA633E2922A77D1D00DE6288 /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + FA633E2A22A77D1D00DE6288 /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + FA633E2D22A77D1D00DE6288 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + FA633E2E22A77D1D00DE6288 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + FA633E3022A77D1D00DE6288 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_ENTITLEMENTS = SwiftUI2048/SwiftUI2048.entitlements; + "CODE_SIGN_IDENTITY[sdk=*]" = ""; + CODE_SIGN_STYLE = Automatic; + DERIVE_UIKITFORMAC_PRODUCT_BUNDLE_IDENTIFIER = YES; + DEVELOPMENT_ASSET_PATHS = "SwiftUI2048/Preview\\ Content"; + DEVELOPMENT_TEAM = 9ZS3K56XF5; + ENABLE_PREVIEWS = YES; + INFOPLIST_FILE = SwiftUI2048/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.cyandev.SwiftUI2048; + PRODUCT_NAME = "$(TARGET_NAME)"; + SUPPORTS_UIKITFORMAC = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + FA633E3122A77D1D00DE6288 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_ENTITLEMENTS = SwiftUI2048/SwiftUI2048.entitlements; + "CODE_SIGN_IDENTITY[sdk=*]" = ""; + CODE_SIGN_STYLE = Automatic; + DERIVE_UIKITFORMAC_PRODUCT_BUNDLE_IDENTIFIER = YES; + DEVELOPMENT_ASSET_PATHS = "SwiftUI2048/Preview\\ Content"; + DEVELOPMENT_TEAM = 9ZS3K56XF5; + ENABLE_PREVIEWS = YES; + INFOPLIST_FILE = SwiftUI2048/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.cyandev.SwiftUI2048; + PRODUCT_NAME = "$(TARGET_NAME)"; + SUPPORTS_UIKITFORMAC = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + FA633E1622A77D1C00DE6288 /* Build configuration list for PBXProject "SwiftUI2048" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + FA633E2D22A77D1D00DE6288 /* Debug */, + FA633E2E22A77D1D00DE6288 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + FA633E2F22A77D1D00DE6288 /* Build configuration list for PBXNativeTarget "2048" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + FA633E3022A77D1D00DE6288 /* Debug */, + FA633E3122A77D1D00DE6288 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = FA633E1322A77D1C00DE6288 /* Project object */; +} diff --git a/Other Projects/2048 Game/SwiftUI2048.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/Other Projects/2048 Game/SwiftUI2048.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..df46ccf --- /dev/null +++ b/Other Projects/2048 Game/SwiftUI2048.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/Other Projects/2048 Game/SwiftUI2048.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/Other Projects/2048 Game/SwiftUI2048.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/Other Projects/2048 Game/SwiftUI2048.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/Other Projects/2048 Game/SwiftUI2048/AppDelegate.swift b/Other Projects/2048 Game/SwiftUI2048/AppDelegate.swift new file mode 100644 index 0000000..8cfeec7 --- /dev/null +++ b/Other Projects/2048 Game/SwiftUI2048/AppDelegate.swift @@ -0,0 +1,58 @@ +// +// AppDelegate.swift +// SwiftUI2048 +// +// Created by Hongyu on 6/5/19. +// Copyright © 2019 Cyandev. All rights reserved. +// + +import UIKit +import SwiftUI + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + + var gameLogic: GameLogic! + var window: UIWindow? + + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { + + gameLogic = GameLogic() + + window = UIWindow(frame: UIScreen.main.bounds) + window!.rootViewController = UIHostingController(rootView: + GameView().environmentObject(gameLogic) + ) + window!.makeKeyAndVisible() + + self.becomeFirstResponder() + + return true + } + + func applicationWillTerminate(_ application: UIApplication) { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. + } + + @objc func newGame(_ sender: AnyObject?) { + gameLogic.newGame() + } + + override func buildMenu(with builder: UIMenuBuilder) { + builder.remove(menu: .edit) + builder.remove(menu: .format) + builder.remove(menu: .view) + + builder.replaceChildren(ofMenu: .file) { oldChildren in + var newChildren = oldChildren + let newGameItem = UIKeyCommand(input: "N", + modifierFlags: .command, + action: #selector(newGame(_:))) + newGameItem.title = "New Game" + newChildren.insert(newGameItem, at: 0) + return newChildren + } + } + +} + diff --git a/Other Projects/2048 Game/SwiftUI2048/Assets.xcassets/AppIcon.appiconset/Contents.json b/Other Projects/2048 Game/SwiftUI2048/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..d8db8d6 --- /dev/null +++ b/Other Projects/2048 Game/SwiftUI2048/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,98 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "83.5x83.5", + "scale" : "2x" + }, + { + "idiom" : "ios-marketing", + "size" : "1024x1024", + "scale" : "1x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/2048 Game/SwiftUI2048/Assets.xcassets/Contents.json b/Other Projects/2048 Game/SwiftUI2048/Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/Other Projects/2048 Game/SwiftUI2048/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/2048 Game/SwiftUI2048/Base.lproj/LaunchScreen.storyboard b/Other Projects/2048 Game/SwiftUI2048/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000..8ca4785 --- /dev/null +++ b/Other Projects/2048 Game/SwiftUI2048/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Other Projects/2048 Game/SwiftUI2048/FunctionalUtils.swift b/Other Projects/2048 Game/SwiftUI2048/FunctionalUtils.swift new file mode 100644 index 0000000..c2ffdf4 --- /dev/null +++ b/Other Projects/2048 Game/SwiftUI2048/FunctionalUtils.swift @@ -0,0 +1,13 @@ +// +// FunctionalUtils.swift +// SwiftUI2048 +// +// Created by Hongyu on 6/5/19. +// Copyright © 2019 Cyandev. All rights reserved. +// + +import Foundation + +func bind(_ x: T, _ closure: (T) -> U) -> U { + return closure(x) +} diff --git a/Other Projects/2048 Game/SwiftUI2048/Info.plist b/Other Projects/2048 Game/SwiftUI2048/Info.plist new file mode 100644 index 0000000..bd0f804 --- /dev/null +++ b/Other Projects/2048 Game/SwiftUI2048/Info.plist @@ -0,0 +1,45 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleDisplayName + 2048 + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + $(PRODUCT_BUNDLE_PACKAGE_TYPE) + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/Other Projects/2048 Game/SwiftUI2048/MainMenu.xib b/Other Projects/2048 Game/SwiftUI2048/MainMenu.xib new file mode 100644 index 0000000..2bc8a16 --- /dev/null +++ b/Other Projects/2048 Game/SwiftUI2048/MainMenu.xib @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/Other Projects/2048 Game/SwiftUI2048/Models/BlockMatrix.swift b/Other Projects/2048 Game/SwiftUI2048/Models/BlockMatrix.swift new file mode 100644 index 0000000..e4d3c62 --- /dev/null +++ b/Other Projects/2048 Game/SwiftUI2048/Models/BlockMatrix.swift @@ -0,0 +1,127 @@ +// +// BlockMatrix.swift +// SwiftUI2048 +// +// Created by Hongyu on 6/5/19. +// Copyright © 2019 Cyandev. All rights reserved. +// + +import Foundation + +protocol Block { + + associatedtype Value + + var number: Value { get set } + +} + +struct IndexedBlock { + + let index: (Int, Int) + let item: T? + +} + +struct BlockMatrix : CustomDebugStringConvertible where T: Block { + + typealias Index = (Int, Int) + + fileprivate var matrix: [[T?]] + + init() { + matrix = [[T?]]() + for _ in 0..<4 { + var row = [T?]() + for _ in 0..<4 { + row.append(nil) + } + matrix.append(row) + } + } + + var debugDescription: String { + matrix.map { row -> String in + row.map { + if $0 == nil { + return " " + } else { + return String(describing: $0!.number) + } + }.joined(separator: "\t") + }.joined(separator: "\n") + } + + var flatten: [IndexedBlock] { + return self.matrix.enumerated().flatMap { (y: Int, element: [T?]) in + element.enumerated().map { (x: Int, element: T?) in + return IndexedBlock(index: (x, y), item: element) + } + } + } + + subscript(index: Self.Index) -> T? { + guard isIndexValid(index) else { + return nil + } + + return matrix[index.1][index.0] + } + + /// Move the block to specific location and leave the original location blank. + /// - Parameter from: Source location + /// - Parameter to: Destination location + mutating func move(from: Self.Index, to: Self.Index) { + guard isIndexValid(from) && isIndexValid(to) else { + // TODO: Throw an error? + return + } + + guard let source = self[from] else { + return + } + + matrix[to.1][to.0] = source + matrix[from.1][from.0] = nil + } + + /// Move the block to specific location, change its value and leave the original location blank. + /// - Parameter from: Source location + /// - Parameter to: Destination location + /// - Parameter newValue: The new value + mutating func move(from: Self.Index, to: Self.Index, with newValue: T.Value) { + guard isIndexValid(from) && isIndexValid(to) else { + // TODO: Throw an error? + return + } + + guard var source = self[from] else { + return + } + + source.number = newValue + + matrix[to.1][to.0] = source + matrix[from.1][from.0] = nil + } + + /// Place a block to specific location. + /// - Parameter block: The block to place + /// - Parameter to: Destination location + mutating func place(_ block: T?, to: Self.Index) { + matrix[to.1][to.0] = block + } + + fileprivate func isIndexValid(_ index: Self.Index) -> Bool { + guard index.0 >= 0 && index.0 < 4 else { + return false + } + + guard index.1 >= 0 && index.1 < 4 else { + return false + } + + return true + } + +} diff --git a/Other Projects/2048 Game/SwiftUI2048/Models/GameLogic.swift b/Other Projects/2048 Game/SwiftUI2048/Models/GameLogic.swift new file mode 100644 index 0000000..ae5ad1b --- /dev/null +++ b/Other Projects/2048 Game/SwiftUI2048/Models/GameLogic.swift @@ -0,0 +1,176 @@ +// +// GameLogic.swift +// SwiftUI2048 +// +// Created by Hongyu on 6/5/19. +// Copyright © 2019 Cyandev. All rights reserved. +// + +import Foundation +import SwiftUI +import Combine + +final class GameLogic : ObservableObject { + + enum Direction { + case left + case right + case up + case down + } + + typealias BlockMatrixType = BlockMatrix + + let objectWillChange = PassthroughSubject() + + fileprivate var _blockMatrix: BlockMatrixType! + var blockMatrix: BlockMatrixType { + return _blockMatrix + } + + fileprivate var _globalID = 0 + fileprivate var newGlobalID: Int { + _globalID += 1 + return _globalID + } + + init() { + newGame() + } + + func newGame() { + _blockMatrix = BlockMatrixType() + generateNewBlocks() + + objectWillChange.send(self) + } + + func move(_ direction: Direction) { + defer { + objectWillChange.send(self) + } + + var moved = false + + let axis = direction == .left || direction == .right + for row in 0..<4 { + var rowSnapshot = [IdentifiedBlock?]() + var compactRow = [IdentifiedBlock]() + for col in 0..<4 { + // Transpose if necessary. + if let block = _blockMatrix[axis ? (col, row) : (row, col)] { + rowSnapshot.append(block) + compactRow.append(block) + } + rowSnapshot.append(nil) + } + + merge(blocks: &compactRow, reverse: direction == .down || direction == .right) + + var newRow = [IdentifiedBlock?]() + compactRow.forEach { newRow.append($0) } + if compactRow.count < 4 { + for _ in 0..<(4 - compactRow.count) { + if direction == .left || direction == .up { + newRow.append(nil) + } else { + newRow.insert(nil, at: 0) + } + } + } + + newRow.enumerated().forEach { + if rowSnapshot[$0]?.number != $1?.number { + moved = true + } + _blockMatrix.place($1, to: axis ? ($0, row) : (row, $0)) + } + } + + if moved { + generateNewBlocks() + } + } + + fileprivate func merge(blocks: inout [IdentifiedBlock], reverse: Bool) { + if reverse { + blocks = blocks.reversed() + } + + blocks = blocks + .map { (false, $0) } + .reduce([(Bool, IdentifiedBlock)]()) { acc, item in + if acc.last?.0 == false && acc.last?.1.number == item.1.number { + var accPrefix = Array(acc.dropLast()) + var mergedBlock = item.1 + mergedBlock.number *= 2 + accPrefix.append((true, mergedBlock)) + return accPrefix + } else { + var accTmp = acc + accTmp.append((false, item.1)) + return accTmp + } + } + .map { $0.1 } + + if reverse { + blocks = blocks.reversed() + } + } + + @discardableResult fileprivate func generateNewBlocks() -> Bool { + var blankLocations = [BlockMatrixType.Index]() + for rowIndex in 0..<4 { + for colIndex in 0..<4 { + let index = (colIndex, rowIndex) + if _blockMatrix[index] == nil { + blankLocations.append(index) + } + } + } + + guard blankLocations.count >= 2 else { + return false + } + + // Don't forget to sync data. + defer { + objectWillChange.send(self) + } + + // Place the first block. + var placeLocIndex = Int.random(in: 0.. ()) { +// var indices = (0..<4).map { $0 } +// if reversed { +// indices = indices.reversed() +// } +// +// for row in indices { +// for col in indices { +// if mode == .rowByRow { +// action((col, row)) +// } else { +// action((row, col)) // transpose +// } +// } +// } +// } + +} diff --git a/Other Projects/2048 Game/SwiftUI2048/Models/IdentifiedBlock.swift b/Other Projects/2048 Game/SwiftUI2048/Models/IdentifiedBlock.swift new file mode 100644 index 0000000..71d0f35 --- /dev/null +++ b/Other Projects/2048 Game/SwiftUI2048/Models/IdentifiedBlock.swift @@ -0,0 +1,16 @@ +// +// IdentifiedBlock.swift +// SwiftUI2048 +// +// Created by Hongyu on 6/5/19. +// Copyright © 2019 Cyandev. All rights reserved. +// + +import Foundation + +struct IdentifiedBlock: Block { + + let id: Int + var number: Int + +} diff --git a/Other Projects/2048 Game/SwiftUI2048/Preview Content/Preview Assets.xcassets/Contents.json b/Other Projects/2048 Game/SwiftUI2048/Preview Content/Preview Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/Other Projects/2048 Game/SwiftUI2048/Preview Content/Preview Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/2048 Game/SwiftUI2048/SwiftUI2048.entitlements b/Other Projects/2048 Game/SwiftUI2048/SwiftUI2048.entitlements new file mode 100644 index 0000000..ee95ab7 --- /dev/null +++ b/Other Projects/2048 Game/SwiftUI2048/SwiftUI2048.entitlements @@ -0,0 +1,10 @@ + + + + + com.apple.security.app-sandbox + + com.apple.security.network.client + + + diff --git a/Other Projects/2048 Game/SwiftUI2048/Views/BlockGridView.swift b/Other Projects/2048 Game/SwiftUI2048/Views/BlockGridView.swift new file mode 100644 index 0000000..d09e3b8 --- /dev/null +++ b/Other Projects/2048 Game/SwiftUI2048/Views/BlockGridView.swift @@ -0,0 +1,116 @@ +// +// BlockGridView.swift +// SwiftUI2048 +// +// Created by Hongyu on 6/5/19. +// Copyright © 2019 Cyandev. All rights reserved. +// + +import SwiftUI + +fileprivate struct IdentifiableIndexedBlock : Identifiable { + + typealias ID = String + typealias IdentifiedValue = IndexedBlock + + static var uniqueBlankId = 0 + + let indexedBlock: IndexedBlock + + var id: Self.ID { + if let id = indexedBlock.item?.id { + return "\(id)" + } + + // TODO: (Refactor) Don't mix two types of block views. + IdentifiableIndexedBlock.uniqueBlankId += 1 + return "Blank_\(IdentifiableIndexedBlock.uniqueBlankId)" + } + + var identifiedValue: Self.IdentifiedValue { + return indexedBlock + } + +} + +extension AnyTransition { + + static func blockAppear(from: Edge) -> AnyTransition { + return .asymmetric( + insertion: AnyTransition.opacity + .combined(with: .move(edge: from)), + removal: .identity) + } + +} + +struct BlockGridView : View { + + typealias SupportingMatrix = BlockMatrix + + let matrix: Self.SupportingMatrix + let blockEnterEdge: Edge + + func createBlock(_ block: IdentifiedBlock?) -> some View { + if let block = block { + return BlockView(number: block.number) + } + return BlockView.blank() + } + + // FIXME: This is existed as a workaround for a Swift compiler bug. + func zIndex(_ block: IdentifiedBlock?) -> Double { + if block == nil { + return 1 + } + return 1000 + } + + var body: some View { + ZStack { + ForEach( + self.matrix.flatten.map { IdentifiableIndexedBlock(indexedBlock: $0) } + ) { block in + self.createBlock(block.item) + .frame(width: 65, height: 65, alignment: .center) + .position(x: CGFloat(block.index.0) * (65 + 12) + 32.5 + 12, + y: CGFloat(block.index.1) * (65 + 12) + 32.5 + 12) + .zIndex(self.zIndex(block.item)) + .transition(.blockAppear(from: self.blockEnterEdge)) +// .animation(block.item == nil ? nil : .spring(mass: 1, stiffness: 400, damping: 56, initialVelocity: 0)) + } + } + .frame(width: 320, height: 320, alignment: .center) + .background( + Rectangle() + .fill(Color(red:0.72, green:0.66, blue:0.63, opacity:1.00)) + ) + .clipped() + .cornerRadius(6) + } + +} + +#if DEBUG +struct BlockGridView_Previews : PreviewProvider { + + static var matrix: BlockGridView.SupportingMatrix { + var _matrix = BlockGridView.SupportingMatrix() + _matrix.place(IdentifiedBlock(id: 1, number: 2), to: (2, 0)) + _matrix.place(IdentifiedBlock(id: 2, number: 2), to: (3, 0)) + _matrix.place(IdentifiedBlock(id: 3, number: 8), to: (1, 1)) + _matrix.place(IdentifiedBlock(id: 4, number: 4), to: (2, 1)) + _matrix.place(IdentifiedBlock(id: 5, number: 512), to: (3, 3)) + _matrix.place(IdentifiedBlock(id: 6, number: 1024), to: (2, 3)) + _matrix.place(IdentifiedBlock(id: 7, number: 16), to: (0, 3)) + _matrix.place(IdentifiedBlock(id: 8, number: 8), to: (1, 3)) + return _matrix + } + + static var previews: some View { + BlockGridView(matrix: matrix, blockEnterEdge: .top) + .previewLayout(.sizeThatFits) + } + +} +#endif diff --git a/Other Projects/2048 Game/SwiftUI2048/Views/BlockView.swift b/Other Projects/2048 Game/SwiftUI2048/Views/BlockView.swift new file mode 100644 index 0000000..fe12dfa --- /dev/null +++ b/Other Projects/2048 Game/SwiftUI2048/Views/BlockView.swift @@ -0,0 +1,118 @@ +// +// BlockView.swift +// SwiftUI2048 +// +// Created by Hongyu on 6/5/19. +// Copyright © 2019 Cyandev. All rights reserved. +// + +import SwiftUI + +struct BlockView : View { + + fileprivate let colorScheme: [(Color, Color)] = [ + // 2 + (Color(red:0.91, green:0.87, blue:0.83, opacity:1.00), Color(red:0.42, green:0.39, blue:0.35, opacity:1.00)), + // 4 + (Color(red:0.90, green:0.86, blue:0.76, opacity:1.00), Color(red:0.42, green:0.39, blue:0.35, opacity:1.00)), + // 8 + (Color(red:0.93, green:0.67, blue:0.46, opacity:1.00), Color.white), + // 16 + (Color(red:0.94, green:0.57, blue:0.38, opacity:1.00), Color.white), + // 32 + (Color(red:0.95, green:0.46, blue:0.33, opacity:1.00), Color.white), + // 64 + (Color(red:0.94, green:0.35, blue:0.23, opacity:1.00), Color.white), + // 128 + (Color(red:0.91, green:0.78, blue:0.43, opacity:1.00), Color.white), + // 256 + (Color(red:0.91, green:0.78, blue:0.37, opacity:1.00), Color.white), + // 512 + (Color(red:0.90, green:0.77, blue:0.31, opacity:1.00), Color.white), + // 1024 + (Color(red:0.91, green:0.75, blue:0.24, opacity:1.00), Color.white), + // 2048 + (Color(red:0.91, green:0.74, blue:0.18, opacity:1.00), Color.white), + ] + + fileprivate let number: Int? + + init(number: Int) { + self.number = number + } + + fileprivate init() { + self.number = nil + } + + static func blank() -> Self { + return self.init() + } + + fileprivate var numberText: String { + guard let number = number else { + return "" + } + return String(number) + } + + fileprivate var fontSize: CGFloat { + let textLength = numberText.count + if textLength < 3 { + return 32 + } else if textLength < 4 { + return 18 + } else { + return 12 + } + } + + fileprivate var colorPair: (Color, Color) { + guard let number = number else { + return (Color(red:0.78, green:0.73, blue:0.68, opacity:1.00), Color.black) + } + let index = Int(log2(Double(number))) - 1 + if index < 0 || index >= colorScheme.count { + fatalError("No color for such number") + } + return colorScheme[index] + } + + // MARK: Body + + var body: some View { + ZStack { + Rectangle().fill(colorPair.0) + + Text(numberText) + .font(Font.system(size: fontSize).bold()) + .foregroundColor(colorPair.1) + .id(numberText) + .transition(AnyTransition.scale(scale: 0.5, anchor: .center).combined(with: .opacity)) +// .animation(.fluidSpring()) + } + .clipped() + .cornerRadius(6) + } + +} + +// MARK: - Previews + +#if DEBUG +struct BlockView_Previews : PreviewProvider { + + static var previews: some View { + Group { + ForEach((1...11).map { Int(pow(2.0, Double($0))) }, id: \.self) { i in + BlockView(number: i) + .previewLayout(.sizeThatFits) + } + + BlockView.blank() + .previewLayout(.sizeThatFits) + } + } + +} +#endif diff --git a/Other Projects/2048 Game/SwiftUI2048/Views/GameView.swift b/Other Projects/2048 Game/SwiftUI2048/Views/GameView.swift new file mode 100644 index 0000000..a98113e --- /dev/null +++ b/Other Projects/2048 Game/SwiftUI2048/Views/GameView.swift @@ -0,0 +1,127 @@ +// +// GameView.swift +// SwiftUI2048 +// +// Created by Hongyu on 6/5/19. +// Copyright © 2019 Cyandev. All rights reserved. +// + +import SwiftUI + +extension Edge { + + static func from(_ from: GameLogic.Direction) -> Self { + switch from { + case .down: + return .top + case .up: + return .bottom + case .left: + return .trailing + case .right: + return .leading + } + } + +} + +struct GameView : View { + + @State var gestureStartLocation: CGPoint = .zero + @State var lastGestureDirection: GameLogic.Direction = .up + @EnvironmentObject var gameLogic: GameLogic + + fileprivate struct LayoutTraits { + let bannerOffset: CGSize + let containerAlignment: Alignment + } + + fileprivate func layoutTraits(`for` proxy: GeometryProxy) -> LayoutTraits { + let landscape = proxy.size.width > proxy.size.height + + return LayoutTraits( + bannerOffset: landscape + ? .init(width: proxy.safeAreaInsets.leading + 32, height: 0) + : .init(width: 0, height: proxy.safeAreaInsets.top + 32), + containerAlignment: landscape ? .leading : .top + ) + } + + var gesture: some Gesture { + let threshold: CGFloat = 44 + let drag = DragGesture() + .onChanged { v in + guard self.gestureStartLocation != v.startLocation else { return } + + withTransaction(Transaction()) { + self.gestureStartLocation = v.startLocation + + if v.translation.width > threshold { + // Move right + self.gameLogic.move(.right) + self.lastGestureDirection = .right + } else if v.translation.width < -threshold { + // Move left + self.gameLogic.move(.left) + self.lastGestureDirection = .left + } else if v.translation.height > threshold { + // Move down + self.gameLogic.move(.down) + self.lastGestureDirection = .down + } else if v.translation.height < -threshold { + // Move up + self.gameLogic.move(.up) + self.lastGestureDirection = .up + } else { + // Direction cannot be deduced, reset gesture state. + self.gestureStartLocation = .zero + } + } + + // After the scene is updated, reset the last gesture direction + // to make sure the animation is right when user starts a new + // game. + OperationQueue.main.addOperation { + self.lastGestureDirection = .up + } + } + return drag + } + + var body: some View { + GeometryReader { proxy in + bind(self.layoutTraits(for: proxy)) { layoutTraits in + ZStack(alignment: layoutTraits.containerAlignment) { + Text("2048") + .font(Font.system(size: 48).weight(.black)) + .foregroundColor(Color(red:0.47, green:0.43, blue:0.40, opacity:1.00)) + .offset(layoutTraits.bannerOffset) + + ZStack(alignment: .top) { + BlockGridView(matrix: self.gameLogic.blockMatrix, + blockEnterEdge: .from(self.lastGestureDirection)) + .gesture(self.gesture) + } + .frame(width: proxy.size.width, height: proxy.size.height, alignment: .center) + } + .frame(width: proxy.size.width, height: proxy.size.height, alignment: .center) + .background( + Rectangle().fill(Color(red:0.96, green:0.94, blue:0.90, opacity:1.00)) + ) + } + } + .edgesIgnoringSafeArea(.all) + } + +} + +#if DEBUG +struct GameView_Previews : PreviewProvider { + + static var previews: some View { + GameView() + .environmentObject(GameLogic()) + } + +} +#endif diff --git a/Other Projects/Animating Views And Transitions/Complete/.gitignore b/Other Projects/Animating Views And Transitions/Complete/.gitignore new file mode 100644 index 0000000..9e50718 --- /dev/null +++ b/Other Projects/Animating Views And Transitions/Complete/.gitignore @@ -0,0 +1,21 @@ +# See LICENSE folder for this sample’s licensing information. +# +# Apple sample code gitignore configuration. + +# Finder +.DS_Store + +# Xcode - User files +xcuserdata/ + +**/*.xcodeproj/project.xcworkspace/* +!**/*.xcodeproj/project.xcworkspace/xcshareddata + +**/*.xcodeproj/project.xcworkspace/xcshareddata/* +!**/*.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings + +**/*.playground/playground.xcworkspace/* +!**/*.playground/playground.xcworkspace/xcshareddata + +**/*.playground/playground.xcworkspace/xcshareddata/* +!**/*.playground/playground.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings diff --git a/Other Projects/Animating Views And Transitions/Complete/Configuration/SampleCode.xcconfig b/Other Projects/Animating Views And Transitions/Complete/Configuration/SampleCode.xcconfig new file mode 100644 index 0000000..db86c06 --- /dev/null +++ b/Other Projects/Animating Views And Transitions/Complete/Configuration/SampleCode.xcconfig @@ -0,0 +1,13 @@ +// +// See LICENSE folder for this sample’s licensing information. +// +// SampleCode.xcconfig +// + +// The `SAMPLE_CODE_DISAMBIGUATOR` configuration is to make it easier to build +// and run a sample code project. Once you set your project's development team, +// you'll have a unique bundle identifier. This is because the bundle identifier +// is derived based on the 'SAMPLE_CODE_DISAMBIGUATOR' value. Do not use this +// approach in your own projects—it's only useful for sample code projects because +// they are frequently downloaded and don't have a development team set. +SAMPLE_CODE_DISAMBIGUATOR=${DEVELOPMENT_TEAM} diff --git a/Other Projects/Animating Views And Transitions/Complete/LICENSE/LICENSE.txt b/Other Projects/Animating Views And Transitions/Complete/LICENSE/LICENSE.txt new file mode 100644 index 0000000..94e3d54 --- /dev/null +++ b/Other Projects/Animating Views And Transitions/Complete/LICENSE/LICENSE.txt @@ -0,0 +1,8 @@ +Copyright © 2019 Apple Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + diff --git a/Other Projects/Animating Views And Transitions/Complete/Landmarks/AnimatingViewsAndTransitions.xcodeproj/.xcodesamplecode.plist b/Other Projects/Animating Views And Transitions/Complete/Landmarks/AnimatingViewsAndTransitions.xcodeproj/.xcodesamplecode.plist new file mode 100644 index 0000000..5dd5da8 --- /dev/null +++ b/Other Projects/Animating Views And Transitions/Complete/Landmarks/AnimatingViewsAndTransitions.xcodeproj/.xcodesamplecode.plist @@ -0,0 +1,5 @@ + + + + + diff --git a/Other Projects/Animating Views And Transitions/Complete/Landmarks/AnimatingViewsAndTransitions.xcodeproj/project.pbxproj b/Other Projects/Animating Views And Transitions/Complete/Landmarks/AnimatingViewsAndTransitions.xcodeproj/project.pbxproj new file mode 100644 index 0000000..c1dabf0 --- /dev/null +++ b/Other Projects/Animating Views And Transitions/Complete/Landmarks/AnimatingViewsAndTransitions.xcodeproj/project.pbxproj @@ -0,0 +1,525 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 50; + objects = { + +/* Begin PBXBuildFile section */ + B7310DD1229F6839001079B9 /* HexagonParameters.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7310DD0229F6839001079B9 /* HexagonParameters.swift */; }; + B7310DD3229F6CA9001079B9 /* Badge.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7310DD2229F6CA9001079B9 /* Badge.swift */; }; + B7394866229F194000C47603 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7394865229F194000C47603 /* AppDelegate.swift */; }; + B7394868229F194000C47603 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7394867229F194000C47603 /* SceneDelegate.swift */; }; + B739486A229F194000C47603 /* LandmarkDetail.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7394869229F194000C47603 /* LandmarkDetail.swift */; }; + B739486C229F194200C47603 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B739486B229F194200C47603 /* Assets.xcassets */; }; + B739486F229F194200C47603 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B739486E229F194200C47603 /* Preview Assets.xcassets */; }; + B7394872229F194200C47603 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B7394870229F194200C47603 /* LaunchScreen.storyboard */; }; + B739487A229F1B3F00C47603 /* CircleImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7394879229F1B3F00C47603 /* CircleImage.swift */; }; + B739487C229F1B6800C47603 /* MapView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B739487B229F1B6800C47603 /* MapView.swift */; }; + B7394881229F28B900C47603 /* Landmark.swift in Sources */ = {isa = PBXBuildFile; fileRef = B739487F229F28B900C47603 /* Landmark.swift */; }; + B7394882229F28B900C47603 /* Data.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7394880229F28B900C47603 /* Data.swift */; }; + B7394891229F292F00C47603 /* rainbowlake.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B7394884229F292D00C47603 /* rainbowlake.jpg */; }; + B7394893229F292F00C47603 /* icybay.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B7394886229F292E00C47603 /* icybay.jpg */; }; + B7394894229F292F00C47603 /* lakemcdonald.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B7394887229F292E00C47603 /* lakemcdonald.jpg */; }; + B7394895229F292F00C47603 /* turtlerock.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B7394888229F292E00C47603 /* turtlerock.jpg */; }; + B7394896229F292F00C47603 /* umbagog.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B7394889229F292E00C47603 /* umbagog.jpg */; }; + B7394897229F292F00C47603 /* hiddenlake.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B739488A229F292E00C47603 /* hiddenlake.jpg */; }; + B7394898229F292F00C47603 /* stmarylake.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B739488B229F292E00C47603 /* stmarylake.jpg */; }; + B7394899229F292F00C47603 /* twinlake.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B739488C229F292E00C47603 /* twinlake.jpg */; }; + B739489A229F292F00C47603 /* silversalmoncreek.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B739488D229F292E00C47603 /* silversalmoncreek.jpg */; }; + B739489B229F292F00C47603 /* landmarkData.json in Resources */ = {isa = PBXBuildFile; fileRef = B739488E229F292E00C47603 /* landmarkData.json */; }; + B739489C229F292F00C47603 /* chincoteague.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B739488F229F292F00C47603 /* chincoteague.jpg */; }; + B739489D229F292F00C47603 /* chilkoottrail.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B7394890229F292F00C47603 /* chilkoottrail.jpg */; }; + B739489F229F2D9700C47603 /* LandmarkRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = B739489E229F2D9700C47603 /* LandmarkRow.swift */; }; + B73948A1229F2E1F00C47603 /* LandmarkList.swift in Sources */ = {isa = PBXBuildFile; fileRef = B73948A0229F2E1F00C47603 /* LandmarkList.swift */; }; + B73948A3229F3E2200C47603 /* charleyrivers.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B73948A2229F3E2200C47603 /* charleyrivers.jpg */; }; + B7D2AAC5229F4D7C0061E5F5 /* UserData.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7D2AAC4229F4D7C0061E5F5 /* UserData.swift */; }; + B7D587AE229F7382006E8DCF /* BadgeBackground.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7D587AD229F7382006E8DCF /* BadgeBackground.swift */; }; + B7D587B0229F73C1006E8DCF /* BadgeSymbol.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7D587AF229F73C1006E8DCF /* BadgeSymbol.swift */; }; + B7D587B2229F7406006E8DCF /* RotatedBadgeSymbol.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7D587B1229F7406006E8DCF /* RotatedBadgeSymbol.swift */; }; + B7D587B6229F825D006E8DCF /* HikeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7D587B5229F825D006E8DCF /* HikeView.swift */; }; + B7D587B8229F826D006E8DCF /* GraphCapsule.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7D587B7229F826D006E8DCF /* GraphCapsule.swift */; }; + B7D587BA229F8288006E8DCF /* Hike.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7D587B9229F8288006E8DCF /* Hike.swift */; }; + B7D587BC229F82EB006E8DCF /* HikeDetail.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7D587BB229F82EB006E8DCF /* HikeDetail.swift */; }; + B7D587BE229F82FF006E8DCF /* HikeGraph.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7D587BD229F82FF006E8DCF /* HikeGraph.swift */; }; + B7D587C0229F830B006E8DCF /* hikeData.json in Resources */ = {isa = PBXBuildFile; fileRef = B7D587BF229F830B006E8DCF /* hikeData.json */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 704D6530704D8B0000000001 /* SampleCode.xcconfig */ = {isa = PBXFileReference; name = SampleCode.xcconfig; path = ../Configuration/SampleCode.xcconfig; sourceTree = ""; }; + 7074FA407074F5C000000001 /* LICENSE.txt */ = {isa = PBXFileReference; includeInIndex = 1; path = LICENSE.txt; sourceTree = ""; }; + B7310DD0229F6839001079B9 /* HexagonParameters.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HexagonParameters.swift; sourceTree = ""; }; + B7310DD2229F6CA9001079B9 /* Badge.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Badge.swift; sourceTree = ""; }; + B7394862229F194000C47603 /* Landmarks.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Landmarks.app; sourceTree = BUILT_PRODUCTS_DIR; }; + B7394865229F194000C47603 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + B7394867229F194000C47603 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; + B7394869229F194000C47603 /* LandmarkDetail.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LandmarkDetail.swift; sourceTree = ""; }; + B739486B229F194200C47603 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + B739486E229F194200C47603 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; + B7394871229F194200C47603 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + B7394873229F194200C47603 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + B7394879229F1B3F00C47603 /* CircleImage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CircleImage.swift; sourceTree = ""; }; + B739487B229F1B6800C47603 /* MapView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapView.swift; sourceTree = ""; }; + B739487F229F28B900C47603 /* Landmark.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Landmark.swift; sourceTree = ""; }; + B7394880229F28B900C47603 /* Data.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Data.swift; sourceTree = ""; }; + B7394884229F292D00C47603 /* rainbowlake.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = rainbowlake.jpg; sourceTree = ""; }; + B7394886229F292E00C47603 /* icybay.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = icybay.jpg; sourceTree = ""; }; + B7394887229F292E00C47603 /* lakemcdonald.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = lakemcdonald.jpg; sourceTree = ""; }; + B7394888229F292E00C47603 /* turtlerock.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = turtlerock.jpg; sourceTree = ""; }; + B7394889229F292E00C47603 /* umbagog.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = umbagog.jpg; sourceTree = ""; }; + B739488A229F292E00C47603 /* hiddenlake.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = hiddenlake.jpg; sourceTree = ""; }; + B739488B229F292E00C47603 /* stmarylake.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = stmarylake.jpg; sourceTree = ""; }; + B739488C229F292E00C47603 /* twinlake.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = twinlake.jpg; sourceTree = ""; }; + B739488D229F292E00C47603 /* silversalmoncreek.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = silversalmoncreek.jpg; sourceTree = ""; }; + B739488E229F292E00C47603 /* landmarkData.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = landmarkData.json; sourceTree = ""; }; + B739488F229F292F00C47603 /* chincoteague.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = chincoteague.jpg; sourceTree = ""; }; + B7394890229F292F00C47603 /* chilkoottrail.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = chilkoottrail.jpg; sourceTree = ""; }; + B739489E229F2D9700C47603 /* LandmarkRow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = LandmarkRow.swift; path = "Supporting Views/LandmarkRow.swift"; sourceTree = ""; }; + B73948A0229F2E1F00C47603 /* LandmarkList.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LandmarkList.swift; sourceTree = ""; }; + B73948A2229F3E2200C47603 /* charleyrivers.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = charleyrivers.jpg; sourceTree = ""; }; + B7D2AAC4229F4D7C0061E5F5 /* UserData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserData.swift; sourceTree = ""; }; + B7D587AD229F7382006E8DCF /* BadgeBackground.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BadgeBackground.swift; sourceTree = ""; }; + B7D587AF229F73C1006E8DCF /* BadgeSymbol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BadgeSymbol.swift; sourceTree = ""; }; + B7D587B1229F7406006E8DCF /* RotatedBadgeSymbol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RotatedBadgeSymbol.swift; sourceTree = ""; }; + B7D587B5229F825D006E8DCF /* HikeView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HikeView.swift; sourceTree = ""; }; + B7D587B7229F826D006E8DCF /* GraphCapsule.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GraphCapsule.swift; sourceTree = ""; }; + B7D587B9229F8288006E8DCF /* Hike.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Hike.swift; sourceTree = ""; }; + B7D587BB229F82EB006E8DCF /* HikeDetail.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HikeDetail.swift; sourceTree = ""; }; + B7D587BD229F82FF006E8DCF /* HikeGraph.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HikeGraph.swift; sourceTree = ""; }; + B7D587BF229F830B006E8DCF /* hikeData.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = hikeData.json; sourceTree = ""; }; + C4E4AAA0C4E4035000000001 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; name = README.md; path = ../README.md; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + B739485F229F194000C47603 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 704E08B0704E8FD000000001 /* Configuration */ = { + isa = PBXGroup; + children = ( + 704D6530704D8B0000000001 /* SampleCode.xcconfig */, + ); + name = Configuration; + sourceTree = ""; + }; + 7074E3507074EFD000000001 /* LICENSE */ = { + isa = PBXGroup; + children = ( + 7074FA407074F5C000000001 /* LICENSE.txt */, + ); + name = LICENSE; + path = ../LICENSE; + sourceTree = ""; + }; + B7394859229F194000C47603 = { + isa = PBXGroup; + children = ( + C4E4AAA0C4E4035000000001 /* README.md */, + B7394864229F194000C47603 /* Landmarks */, + B7394863229F194000C47603 /* Products */, + 704E08B0704E8FD000000001 /* Configuration */, + 7074E3507074EFD000000001 /* LICENSE */, + ); + sourceTree = ""; + }; + B7394863229F194000C47603 /* Products */ = { + isa = PBXGroup; + children = ( + B7394862229F194000C47603 /* Landmarks.app */, + ); + name = Products; + sourceTree = ""; + }; + B7394864229F194000C47603 /* Landmarks */ = { + isa = PBXGroup; + children = ( + B739487E229F282200C47603 /* Models */, + B7394865229F194000C47603 /* AppDelegate.swift */, + B7394867229F194000C47603 /* SceneDelegate.swift */, + B73948A0229F2E1F00C47603 /* LandmarkList.swift */, + B739489E229F2D9700C47603 /* LandmarkRow.swift */, + B7394869229F194000C47603 /* LandmarkDetail.swift */, + B7D587B5229F825D006E8DCF /* HikeView.swift */, + B7D587BB229F82EB006E8DCF /* HikeDetail.swift */, + B7310DD0229F6839001079B9 /* HexagonParameters.swift */, + B739487D229F1C0100C47603 /* Supporting Views */, + B7394883229F291A00C47603 /* Resources */, + B739486B229F194200C47603 /* Assets.xcassets */, + B7394870229F194200C47603 /* LaunchScreen.storyboard */, + B7394873229F194200C47603 /* Info.plist */, + B739486D229F194200C47603 /* Preview Content */, + ); + path = Landmarks; + sourceTree = ""; + }; + B739486D229F194200C47603 /* Preview Content */ = { + isa = PBXGroup; + children = ( + B739486E229F194200C47603 /* Preview Assets.xcassets */, + ); + path = "Preview Content"; + sourceTree = ""; + }; + B739487D229F1C0100C47603 /* Supporting Views */ = { + isa = PBXGroup; + children = ( + B7394879229F1B3F00C47603 /* CircleImage.swift */, + B739487B229F1B6800C47603 /* MapView.swift */, + B7310DD2229F6CA9001079B9 /* Badge.swift */, + B7D587AF229F73C1006E8DCF /* BadgeSymbol.swift */, + B7D587B1229F7406006E8DCF /* RotatedBadgeSymbol.swift */, + B7D587AD229F7382006E8DCF /* BadgeBackground.swift */, + B7D587BD229F82FF006E8DCF /* HikeGraph.swift */, + B7D587B7229F826D006E8DCF /* GraphCapsule.swift */, + ); + path = "Supporting Views"; + sourceTree = ""; + }; + B739487E229F282200C47603 /* Models */ = { + isa = PBXGroup; + children = ( + B7394880229F28B900C47603 /* Data.swift */, + B739487F229F28B900C47603 /* Landmark.swift */, + B7D587B9229F8288006E8DCF /* Hike.swift */, + B7D2AAC4229F4D7C0061E5F5 /* UserData.swift */, + ); + path = Models; + sourceTree = ""; + }; + B7394883229F291A00C47603 /* Resources */ = { + isa = PBXGroup; + children = ( + B739488E229F292E00C47603 /* landmarkData.json */, + B7D587BF229F830B006E8DCF /* hikeData.json */, + B7394890229F292F00C47603 /* chilkoottrail.jpg */, + B739488F229F292F00C47603 /* chincoteague.jpg */, + B739488A229F292E00C47603 /* hiddenlake.jpg */, + B7394886229F292E00C47603 /* icybay.jpg */, + B7394887229F292E00C47603 /* lakemcdonald.jpg */, + B7394884229F292D00C47603 /* rainbowlake.jpg */, + B739488D229F292E00C47603 /* silversalmoncreek.jpg */, + B739488B229F292E00C47603 /* stmarylake.jpg */, + B7394888229F292E00C47603 /* turtlerock.jpg */, + B739488C229F292E00C47603 /* twinlake.jpg */, + B7394889229F292E00C47603 /* umbagog.jpg */, + B73948A2229F3E2200C47603 /* charleyrivers.jpg */, + ); + path = Resources; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + B7394861229F194000C47603 /* Landmarks */ = { + isa = PBXNativeTarget; + buildConfigurationList = B7394876229F194200C47603 /* Build configuration list for PBXNativeTarget "Landmarks" */; + buildPhases = ( + B739485E229F194000C47603 /* Sources */, + B739485F229F194000C47603 /* Frameworks */, + B7394860229F194000C47603 /* Resources */, + C602AC70C605937000000001, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Landmarks; + productName = Landmarks; + productReference = B7394862229F194000C47603 /* Landmarks.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + B739485A229F194000C47603 /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 1100; + LastUpgradeCheck = 1100; + ORGANIZATIONNAME = Apple; + TargetAttributes = { + B7394861229F194000C47603 = { + CreatedOnToolsVersion = 11.0; + }; + }; + }; + buildConfigurationList = B739485D229F194000C47603 /* Build configuration list for PBXProject "AnimatingViewsAndTransitions" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = B7394859229F194000C47603; + productRefGroup = B7394863229F194000C47603 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + B7394861229F194000C47603 /* Landmarks */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + B7394860229F194000C47603 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + B739489A229F292F00C47603 /* silversalmoncreek.jpg in Resources */, + B7394894229F292F00C47603 /* lakemcdonald.jpg in Resources */, + B7D587C0229F830B006E8DCF /* hikeData.json in Resources */, + B7394872229F194200C47603 /* LaunchScreen.storyboard in Resources */, + B73948A3229F3E2200C47603 /* charleyrivers.jpg in Resources */, + B7394891229F292F00C47603 /* rainbowlake.jpg in Resources */, + B739486F229F194200C47603 /* Preview Assets.xcassets in Resources */, + B7394895229F292F00C47603 /* turtlerock.jpg in Resources */, + B739486C229F194200C47603 /* Assets.xcassets in Resources */, + B7394899229F292F00C47603 /* twinlake.jpg in Resources */, + B7394896229F292F00C47603 /* umbagog.jpg in Resources */, + B739489D229F292F00C47603 /* chilkoottrail.jpg in Resources */, + B739489C229F292F00C47603 /* chincoteague.jpg in Resources */, + B739489B229F292F00C47603 /* landmarkData.json in Resources */, + B7394893229F292F00C47603 /* icybay.jpg in Resources */, + B7394897229F292F00C47603 /* hiddenlake.jpg in Resources */, + B7394898229F292F00C47603 /* stmarylake.jpg in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + B739485E229F194000C47603 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + B7394882229F28B900C47603 /* Data.swift in Sources */, + B7310DD3229F6CA9001079B9 /* Badge.swift in Sources */, + B7394866229F194000C47603 /* AppDelegate.swift in Sources */, + B7D587B8229F826D006E8DCF /* GraphCapsule.swift in Sources */, + B739487A229F1B3F00C47603 /* CircleImage.swift in Sources */, + B739487C229F1B6800C47603 /* MapView.swift in Sources */, + B7D587BA229F8288006E8DCF /* Hike.swift in Sources */, + B7D587BC229F82EB006E8DCF /* HikeDetail.swift in Sources */, + B7D587B6229F825D006E8DCF /* HikeView.swift in Sources */, + B7310DD1229F6839001079B9 /* HexagonParameters.swift in Sources */, + B73948A1229F2E1F00C47603 /* LandmarkList.swift in Sources */, + B7D587B0229F73C1006E8DCF /* BadgeSymbol.swift in Sources */, + B7D587B2229F7406006E8DCF /* RotatedBadgeSymbol.swift in Sources */, + B7D587BE229F82FF006E8DCF /* HikeGraph.swift in Sources */, + B7394868229F194000C47603 /* SceneDelegate.swift in Sources */, + B7D587AE229F7382006E8DCF /* BadgeBackground.swift in Sources */, + B739486A229F194000C47603 /* LandmarkDetail.swift in Sources */, + B739489F229F2D9700C47603 /* LandmarkRow.swift in Sources */, + B7D2AAC5229F4D7C0061E5F5 /* UserData.swift in Sources */, + B7394881229F28B900C47603 /* Landmark.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + B7394870229F194200C47603 /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + B7394871229F194200C47603 /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + B7394874229F194200C47603 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 704D6530704D8B0000000001 /* SampleCode.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + B7394875229F194200C47603 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 704D6530704D8B0000000001 /* SampleCode.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + B7394877229F194200C47603 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 704D6530704D8B0000000001 /* SampleCode.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_ASSET_PATHS = "Landmarks/Preview\\ Content"; + DEVELOPMENT_TEAM = ""; + ENABLE_PREVIEWS = YES; + INFOPLIST_FILE = Landmarks/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = "com.example.apple-samplecode.Landmarks${SAMPLE_CODE_DISAMBIGUATOR}"; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + B7394878229F194200C47603 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 704D6530704D8B0000000001 /* SampleCode.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_ASSET_PATHS = "Landmarks/Preview\\ Content"; + DEVELOPMENT_TEAM = ""; + ENABLE_PREVIEWS = YES; + INFOPLIST_FILE = Landmarks/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = "com.example.apple-samplecode.Landmarks${SAMPLE_CODE_DISAMBIGUATOR}"; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + B739485D229F194000C47603 /* Build configuration list for PBXProject "AnimatingViewsAndTransitions" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + B7394874229F194200C47603 /* Debug */, + B7394875229F194200C47603 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + B7394876229F194200C47603 /* Build configuration list for PBXNativeTarget "Landmarks" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + B7394877229F194200C47603 /* Debug */, + B7394878229F194200C47603 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = B739485A229F194000C47603 /* Project object */; +} diff --git a/Other Projects/Animating Views And Transitions/Complete/Landmarks/AnimatingViewsAndTransitions.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/Other Projects/Animating Views And Transitions/Complete/Landmarks/AnimatingViewsAndTransitions.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 0000000..3ddf867 --- /dev/null +++ b/Other Projects/Animating Views And Transitions/Complete/Landmarks/AnimatingViewsAndTransitions.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,8 @@ + + + + + BuildSystemType + Latest + + diff --git a/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/AppDelegate.swift b/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/AppDelegate.swift new file mode 100644 index 0000000..e22943b --- /dev/null +++ b/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/AppDelegate.swift @@ -0,0 +1,36 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +The application delegate. +*/ + +import UIKit + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { + // Override point for customization after application launch. + return true + } + + func applicationWillTerminate(_ application: UIApplication) { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. + } + + // MARK: UISceneSession Lifecycle + func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration { + // Called when a new scene session is being created. + // Use this method to select a configuration to create the new scene with. + return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role) + } + + func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) { + // Called when the user discards a scene session. + // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions. + // Use this method to release any resources that were specific to the discarded scenes, as they will not return. + } + +} + diff --git a/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/Contents.json b/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..fa0d2db --- /dev/null +++ b/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,113 @@ +{ + "images" : [ + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "landmark_app_icon_40x40.png", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "3x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "landmark_app_icon_58x58.png", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "landmark_app_icon_87x87.png", + "scale" : "3x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "landmark_app_icon_80x80.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "landmark_app_icon_120x120.png", + "scale" : "3x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "landmark_app_icon_120x120-1.png", + "scale" : "2x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "landmark_app_icon_180x180.png", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "1x" + }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "landmark_app_icon_40x40-1.png", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "landmark_app_icon_58x58-1.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "landmark_app_icon_40x40-2.png", + "scale" : "1x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "landmark_app_icon_80x80-1.png", + "scale" : "2x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "landmark_app_icon_76x76.png", + "scale" : "1x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "landmark_app_icon_152x152.png", + "scale" : "2x" + }, + { + "size" : "83.5x83.5", + "idiom" : "ipad", + "filename" : "landmark_app_icon_167x167.png", + "scale" : "2x" + }, + { + "size" : "1024x1024", + "idiom" : "ios-marketing", + "filename" : "landmark_app_icon_1024x1024.png", + "scale" : "1x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_1024x1024.png b/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_1024x1024.png new file mode 100644 index 0000000..00d81c1 Binary files /dev/null and b/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_1024x1024.png differ diff --git a/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_120x120-1.png b/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_120x120-1.png new file mode 100644 index 0000000..d382b8b Binary files /dev/null and b/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_120x120-1.png differ diff --git a/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_120x120.png b/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_120x120.png new file mode 100644 index 0000000..d382b8b Binary files /dev/null and b/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_120x120.png differ diff --git a/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_152x152.png b/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_152x152.png new file mode 100644 index 0000000..11057f8 Binary files /dev/null and b/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_152x152.png differ diff --git a/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_167x167.png b/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_167x167.png new file mode 100644 index 0000000..f73bc26 Binary files /dev/null and b/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_167x167.png differ diff --git a/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_180x180.png b/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_180x180.png new file mode 100644 index 0000000..b02738c Binary files /dev/null and b/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_180x180.png differ diff --git a/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40-1.png b/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40-1.png new file mode 100644 index 0000000..abaff0e Binary files /dev/null and b/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40-1.png differ diff --git a/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40-2.png b/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40-2.png new file mode 100644 index 0000000..abaff0e Binary files /dev/null and b/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40-2.png differ diff --git a/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40.png b/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40.png new file mode 100644 index 0000000..abaff0e Binary files /dev/null and b/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40.png differ diff --git a/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_58x58-1.png b/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_58x58-1.png new file mode 100644 index 0000000..cf7c73d Binary files /dev/null and b/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_58x58-1.png differ diff --git a/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_58x58.png b/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_58x58.png new file mode 100644 index 0000000..cf7c73d Binary files /dev/null and b/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_58x58.png differ diff --git a/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_76x76.png b/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_76x76.png new file mode 100644 index 0000000..3eff85b Binary files /dev/null and b/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_76x76.png differ diff --git a/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_80x80-1.png b/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_80x80-1.png new file mode 100644 index 0000000..6f33f66 Binary files /dev/null and b/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_80x80-1.png differ diff --git a/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_80x80.png b/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_80x80.png new file mode 100644 index 0000000..6f33f66 Binary files /dev/null and b/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_80x80.png differ diff --git a/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_87x87.png b/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_87x87.png new file mode 100644 index 0000000..9e1616c Binary files /dev/null and b/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_87x87.png differ diff --git a/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Assets.xcassets/Contents.json b/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Assets.xcassets/turtlerock.imageset/Contents.json b/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Assets.xcassets/turtlerock.imageset/Contents.json new file mode 100644 index 0000000..5bfd7bf --- /dev/null +++ b/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Assets.xcassets/turtlerock.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "turtlerock.jpg", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Assets.xcassets/turtlerock.imageset/turtlerock.jpg b/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Assets.xcassets/turtlerock.imageset/turtlerock.jpg new file mode 100644 index 0000000..68bcd3e Binary files /dev/null and b/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Assets.xcassets/turtlerock.imageset/turtlerock.jpg differ diff --git a/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Base.lproj/LaunchScreen.storyboard b/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000..865e932 --- /dev/null +++ b/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/HexagonParameters.swift b/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/HexagonParameters.swift new file mode 100644 index 0000000..8decba4 --- /dev/null +++ b/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/HexagonParameters.swift @@ -0,0 +1,57 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +Size, position, and other information used to draw a badge. +*/ + +import SwiftUI + +struct HexagonParameters { + struct Segment { + let useWidth: (CGFloat, CGFloat, CGFloat) + let xFactors: (CGFloat, CGFloat, CGFloat) + let useHeight: (CGFloat, CGFloat, CGFloat) + let yFactors: (CGFloat, CGFloat, CGFloat) + } + + static let adjustment: CGFloat = 0.085 + static let points = [ + Segment( + useWidth: (1.00, 1.00, 1.00), + xFactors: (0.60, 0.40, 0.50), + useHeight: (1.00, 1.00, 0.00), + yFactors: (0.05, 0.05, 0.00) + ), + Segment( + useWidth: (1.00, 1.00, 0.00), + xFactors: (0.05, 0.00, 0.00), + useHeight: (1.00, 1.00, 1.00), + yFactors: (0.20 + adjustment, 0.30 + adjustment, 0.25 + adjustment) + ), + Segment( + useWidth: (1.00, 1.00, 0.00), + xFactors: (0.00, 0.05, 0.00), + useHeight: (1.00, 1.00, 1.00), + yFactors: (0.70 - adjustment, 0.80 - adjustment, 0.75 - adjustment) + ), + Segment( + useWidth: (1.00, 1.00, 1.00), + xFactors: (0.40, 0.60, 0.50), + useHeight: (1.00, 1.00, 1.00), + yFactors: (0.95, 0.95, 1.00) + ), + Segment( + useWidth: (1.00, 1.00, 1.00), + xFactors: (0.95, 1.00, 1.00), + useHeight: (1.00, 1.00, 1.00), + yFactors: (0.80 - adjustment, 0.70 - adjustment, 0.75 - adjustment) + ), + Segment( + useWidth: (1.00, 1.00, 1.00), + xFactors: (1.00, 0.95, 1.00), + useHeight: (1.00, 1.00, 1.00), + yFactors: (0.30 + adjustment, 0.20 + adjustment, 0.25 + adjustment) + ) + ] +} diff --git a/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/HikeDetail.swift b/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/HikeDetail.swift new file mode 100644 index 0000000..1d63904 --- /dev/null +++ b/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/HikeDetail.swift @@ -0,0 +1,49 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A view showing the details for a hike. +*/ + +import SwiftUI + +struct HikeDetail: View { + let hike: Hike + @State var dataToShow = \Hike.Observation.elevation + + var buttons = [ + ("Elevation", \Hike.Observation.elevation), + ("Heart Rate", \Hike.Observation.heartRate), + ("Pace", \Hike.Observation.pace), + ] + + var body: some View { + return VStack { + HikeGraph(hike: hike, path: dataToShow) + .frame(height: 200, alignment: .center) + + HStack(spacing: 25) { + ForEach(buttons, id: \.0) { value in + Button(action: { + self.dataToShow = value.1 + }) { + Text(verbatim: value.0) + .font(.system(size: 15)) + .foregroundColor(value.1 == self.dataToShow + ? Color.gray + : Color.accentColor) + .animation(nil) + } + } + } + } + } +} + +#if DEBUG +struct HikeDetail_Previews: PreviewProvider { + static var previews: some View { + HikeDetail(hike: hikeData[0]) + } +} +#endif diff --git a/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/HikeView.swift b/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/HikeView.swift new file mode 100644 index 0000000..b9964c7 --- /dev/null +++ b/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/HikeView.swift @@ -0,0 +1,68 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A view displaying inforamtion about a hike, including an elevation graph. +*/ + +import SwiftUI + +struct HikeView: View { + var hike: Hike + @State private var showDetail = false + + var transition: AnyTransition { + let insertion = AnyTransition.move(edge: .trailing) + .combined(with: .opacity) + let removal = AnyTransition.scale(scale: 0.0) + .combined(with: .opacity) + return .asymmetric(insertion: insertion, removal: removal) + } + + var body: some View { + VStack { + HStack { + HikeGraph(hike: hike, path: \.elevation) + .frame(width: 50, height: 30) + .animation(nil) + + VStack(alignment: .leading) { + Text(verbatim: hike.name) + .font(.headline) + Text(verbatim: hike.distanceText) + } + + Spacer() + + Button(action: { + withAnimation { + self.showDetail.toggle() + } + }) { + Image(systemName: "chevron.right.circle") + .imageScale(.large) + .rotationEffect(.degrees(showDetail ? 90 : 0)) + .scaleEffect(showDetail ? 1.5 : 1) + .padding() + } + } + + if showDetail { + HikeDetail(hike: hike) + .transition(transition) + } + } + } +} + +#if DEBUG +struct HikeView_Previews: PreviewProvider { + static var previews: some View { + VStack { + HikeView(hike: hikeData[0]) + .padding() + Spacer() + } + } +} +#endif diff --git a/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Info.plist b/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Info.plist new file mode 100644 index 0000000..e8bb4c6 --- /dev/null +++ b/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Info.plist @@ -0,0 +1,62 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + $(PRODUCT_BUNDLE_PACKAGE_TYPE) + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UIApplicationSceneManifest + + UIApplicationSupportsMultipleScenes + + UISceneConfigurations + + UIWindowSceneSessionRoleApplication + + + UILaunchStoryboardName + LaunchScreen + UISceneConfigurationName + Default Configuration + UISceneDelegateClassName + $(PRODUCT_MODULE_NAME).SceneDelegate + + + + + UILaunchStoryboardName + LaunchScreen + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/LandmarkDetail.swift b/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/LandmarkDetail.swift new file mode 100644 index 0000000..6c290a3 --- /dev/null +++ b/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/LandmarkDetail.swift @@ -0,0 +1,71 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A view showing the details for a landmark. +*/ + +import SwiftUI + +struct LandmarkDetail: View { + @EnvironmentObject var userData: UserData + var landmark: Landmark + + var landmarkIndex: Int { + userData.landmarks.firstIndex(where: { $0.id == landmark.id })! + } + + var body: some View { + VStack { + MapView(coordinate: landmark.locationCoordinate) + .edgesIgnoringSafeArea(.top) + .frame(height: 300) + + CircleImage(image: landmark.image(forSize: 250)) + .offset(x: 0, y: -130) + .padding(.bottom, -130) + + VStack(alignment: .leading) { + HStack { + Text(verbatim: landmark.name) + .font(.title) + + Button(action: { + self.userData.landmarks[self.landmarkIndex] + .isFavorite.toggle() + }) { + if self.userData.landmarks[self.landmarkIndex] + .isFavorite { + Image(systemName: "star.fill") + .foregroundColor(Color.yellow) + } else { + Image(systemName: "star") + .foregroundColor(Color.gray) + } + } + } + + HStack(alignment: .top) { + Text(verbatim: landmark.park) + .font(.subheadline) + Spacer() + Text(verbatim: landmark.state) + .font(.subheadline) + } + } + .padding() + + Spacer() + } + } +} + +#if DEBUG +struct LandmarkDetail_Preview: PreviewProvider { + static var previews: some View { + let userData = UserData() + return LandmarkDetail(landmark: userData.landmarks[0]) + .environmentObject(userData) + } +} +#endif diff --git a/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/LandmarkList.swift b/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/LandmarkList.swift new file mode 100644 index 0000000..665a08e --- /dev/null +++ b/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/LandmarkList.swift @@ -0,0 +1,46 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A view showing a list of landmarks. +*/ + +import SwiftUI + +struct LandmarkList: View { + @EnvironmentObject private var userData: UserData + + var body: some View { + NavigationView { + List { + Toggle(isOn: $userData.showFavoritesOnly) { + Text("Show Favorites Only") + } + + ForEach(userData.landmarks) { landmark in + if !self.userData.showFavoritesOnly || landmark.isFavorite { + NavigationLink( + destination: LandmarkDetail(landmark: landmark) + .environmentObject(self.userData)) { + LandmarkRow(landmark: landmark) + } + } + } + } + .navigationBarTitle(Text("Landmarks"), displayMode: .large) + } + } +} + +#if DEBUG +struct LandmarksList_Previews: PreviewProvider { + static var previews: some View { + ForEach(["iPhone SE", "iPhone XS Max"], id: \.self) { deviceName in + LandmarkList() + .previewDevice(PreviewDevice(rawValue: deviceName)) + .previewDisplayName(deviceName) + } + .environmentObject(UserData()) + } +} +#endif diff --git a/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Models/Data.swift b/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Models/Data.swift new file mode 100644 index 0000000..cfe5a4a --- /dev/null +++ b/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Models/Data.swift @@ -0,0 +1,95 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +Helpers for loading images and data. +*/ + +import Foundation +import CoreLocation +import UIKit +import SwiftUI + +let landmarkData: [Landmark] = load("landmarkData.json") +let hikeData: [Hike] = load("hikeData.json") + +func load(_ filename: String, as type: T.Type = T.self) -> T { + let data: Data + + guard let file = Bundle.main.url(forResource: filename, withExtension: nil) + else { + fatalError("Couldn't find \(filename) in main bundle.") + } + + do { + data = try Data(contentsOf: file) + } catch { + fatalError("Couldn't load \(filename) from main bundle:\n\(error)") + } + + do { + let decoder = JSONDecoder() + return try decoder.decode(T.self, from: data) + } catch { + fatalError("Couldn't parse \(filename) as \(T.self):\n\(error)") + } +} + +final class ImageStore { + fileprivate typealias _ImageDictionary = [String: [Int: CGImage]] + fileprivate var images: _ImageDictionary = [:] + + fileprivate static var originalSize = 250 + fileprivate static var scale = 2 + + static var shared = ImageStore() + + func image(name: String, size: Int) -> Image { + let index = _guaranteeInitialImage(name: name) + + let sizedImage = images.values[index][size] + ?? _sizeImage(images.values[index][ImageStore.originalSize]!, to: size * ImageStore.scale) + images.values[index][size] = sizedImage + + return Image(sizedImage, scale: CGFloat(ImageStore.scale), label: Text(verbatim: name)) + } + + fileprivate func _guaranteeInitialImage(name: String) -> _ImageDictionary.Index { + if let index = images.index(forKey: name) { return index } + + guard + let url = Bundle.main.url(forResource: name, withExtension: "jpg"), + let imageSource = CGImageSourceCreateWithURL(url as NSURL, nil), + let image = CGImageSourceCreateImageAtIndex(imageSource, 0, nil) + else { + fatalError("Couldn't load image \(name).jpg from main bundle.") + } + + images[name] = [ImageStore.originalSize: image] + return images.index(forKey: name)! + } + + fileprivate func _sizeImage(_ image: CGImage, to size: Int) -> CGImage { + guard + let colorSpace = image.colorSpace, + let context = CGContext( + data: nil, + width: size, height: size, + bitsPerComponent: image.bitsPerComponent, + bytesPerRow: image.bytesPerRow, + space: colorSpace, + bitmapInfo: image.bitmapInfo.rawValue) + else { + fatalError("Couldn't create graphics context.") + } + context.interpolationQuality = .high + context.draw(image, in: CGRect(x: 0, y: 0, width: size, height: size)) + + if let sizedImage = context.makeImage() { + return sizedImage + } else { + fatalError("Couldn't resize image.") + } + } +} + diff --git a/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Models/Hike.swift b/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Models/Hike.swift new file mode 100644 index 0000000..dfd2bb8 --- /dev/null +++ b/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Models/Hike.swift @@ -0,0 +1,31 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +The model for a hike. +*/ + +import SwiftUI + +struct Hike: Codable, Hashable, Identifiable { + var name: String + var id: Int + var distance: Double + var difficulty: Int + var observations: [Observation] + + static var formatter = LengthFormatter() + + var distanceText: String { + return Hike.formatter + .string(fromValue: distance, unit: .kilometer) + } + + struct Observation: Codable, Hashable { + var distanceFromStart: Double + + var elevation: Range + var pace: Range + var heartRate: Range + } +} diff --git a/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Models/Landmark.swift b/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Models/Landmark.swift new file mode 100644 index 0000000..79b9aa4 --- /dev/null +++ b/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Models/Landmark.swift @@ -0,0 +1,42 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +The model for an individual landmark. +*/ + +import SwiftUI +import CoreLocation + +struct Landmark: Hashable, Codable, Identifiable { + var id: Int + var name: String + fileprivate var imageName: String + fileprivate var coordinates: Coordinates + var state: String + var park: String + var category: Category + var isFavorite: Bool + + var locationCoordinate: CLLocationCoordinate2D { + CLLocationCoordinate2D( + latitude: coordinates.latitude, + longitude: coordinates.longitude) + } + + func image(forSize size: Int) -> Image { + ImageStore.shared.image(name: imageName, size: size) + } + + enum Category: String, CaseIterable, Codable, Hashable { + case featured = "Featured" + case lakes = "Lakes" + case rivers = "Rivers" + case mountains = "Mountains" + } +} + +struct Coordinates: Hashable, Codable { + var latitude: Double + var longitude: Double +} diff --git a/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Models/UserData.swift b/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Models/UserData.swift new file mode 100644 index 0000000..afc2cca --- /dev/null +++ b/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Models/UserData.swift @@ -0,0 +1,15 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A model object that stores app data. +*/ + +import Combine +import SwiftUI + +final class UserData: ObservableObject { + @Published var showFavoritesOnly = false + + @Published var landmarks = landmarkData +} diff --git a/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Preview Content/Preview Assets.xcassets/Contents.json b/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Preview Content/Preview Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Preview Content/Preview Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Resources/charleyrivers.jpg b/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Resources/charleyrivers.jpg new file mode 100644 index 0000000..17ff44b Binary files /dev/null and b/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Resources/charleyrivers.jpg differ diff --git a/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Resources/chilkoottrail.jpg b/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Resources/chilkoottrail.jpg new file mode 100644 index 0000000..e7f805e Binary files /dev/null and b/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Resources/chilkoottrail.jpg differ diff --git a/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Resources/chincoteague.jpg b/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Resources/chincoteague.jpg new file mode 100644 index 0000000..5f47986 Binary files /dev/null and b/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Resources/chincoteague.jpg differ diff --git a/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Resources/hiddenlake.jpg b/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Resources/hiddenlake.jpg new file mode 100644 index 0000000..d8e804c Binary files /dev/null and b/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Resources/hiddenlake.jpg differ diff --git a/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Resources/hikeData.json b/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Resources/hikeData.json new file mode 100644 index 0000000..3fb1e96 --- /dev/null +++ b/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Resources/hikeData.json @@ -0,0 +1,1882 @@ +[ + { + "name":"Lonesome Ridge Trail", + "id":1001, + "distance":4.5, + "difficulty":3, + "observations":[ + { + "elevation":[ + 291.65263635636268, + 309.26016677925196 + ], + "pace":[ + 396.08716481908732, + 403.68937873525232 + ], + "heartRate":[ + 117.16351898665887, + 121.95815455919609 + ], + "distanceFromStart":0 + }, + { + "elevation":[ + 299.24001936628116, + 317.44584350790012 + ], + "pace":[ + 380.19020240756623, + 395.3978319010256 + ], + "heartRate":[ + 117.6410892152911, + 124.82185220506081 + ], + "distanceFromStart":0.375 + }, + { + "elevation":[ + 303.62145464574394, + 336.05569457646544 + ], + "pace":[ + 380.55927782266116, + 397.60789726832775 + ], + "heartRate":[ + 121.52696452049059, + 127.31525441110122 + ], + "distanceFromStart":0.75 + }, + { + "elevation":[ + 319.90393365162629, + 346.26966025518789 + ], + "pace":[ + 357.94116421258531, + 398.0750288648062 + ], + "heartRate":[ + 123.75908585923588, + 132.77069404486801 + ], + "distanceFromStart":1.125 + }, + { + "elevation":[ + 354.17104439267905, + 403.57031216972939 + ], + "pace":[ + 335.07385149392701, + 397.82674381875808 + ], + "heartRate":[ + 130.8235194572915, + 140.55700591418218 + ], + "distanceFromStart":1.5 + }, + { + "elevation":[ + 357.42992871175124, + 385.92155620623635 + ], + "pace":[ + 395.16168913839374, + 404.60294066527558 + ], + "heartRate":[ + 131.5456052446734, + 134.65984504627627 + ], + "distanceFromStart":1.875 + }, + { + "elevation":[ + 345.47736721935661, + 363.18776661379422 + ], + "pace":[ + 340.82303041339082, + 404.71689228682374 + ], + "heartRate":[ + 125.1949698433959, + 131.31354363122026 + ], + "distanceFromStart":2.25 + }, + { + "elevation":[ + 346.23343025200535, + 497.23376445462401 + ], + "pace":[ + 261.27629148816021, + 331.68516208719467 + ], + "heartRate":[ + 131.67810544238606, + 154.26779645311458 + ], + "distanceFromStart":2.625 + }, + { + "elevation":[ + 491.57378483134391, + 547.49535224251053 + ], + "pace":[ + 296.05298644112088, + 401.14092967732398 + ], + "heartRate":[ + 151.36398089694217, + 166.20454793289232 + ], + "distanceFromStart":3 + }, + { + "elevation":[ + 472.06803233416338, + 531.92570520228401 + ], + "pace":[ + 395.50830663514012, + 401.67837917543591 + ], + "heartRate":[ + 134.41798110234078, + 151.90886697564241 + ], + "distanceFromStart":3.375 + }, + { + "elevation":[ + 339.81419476005283, + 461.03832527824829 + ], + "pace":[ + 395.31160487975183, + 404.49550455974907 + ], + "heartRate":[ + 129.97753472415462, + 138.13531094848992 + ], + "distanceFromStart":3.75 + }, + { + "elevation":[ + 303.1495508565697, + 342.3532820173541 + ], + "pace":[ + 395.02844559698116, + 402.65878340653796 + ], + "heartRate":[ + 127.72304232462609, + 133.26322270764186 + ], + "distanceFromStart":4.125 + } + ] + }, + { + "name":"Lonesome Ridge Trail", + "id":1002, + "distance":4.5, + "difficulty":3, + "observations":[ + { + "elevation":[ + 291.65263635636268, + 309.26016677925196 + ], + "pace":[ + 396.08716481908732, + 403.68937873525232 + ], + "heartRate":[ + 117.16351898665887, + 121.95815455919609 + ], + "distanceFromStart":0 + }, + { + "elevation":[ + 299.24001936628116, + 317.44584350790012 + ], + "pace":[ + 380.19020240756623, + 395.3978319010256 + ], + "heartRate":[ + 117.6410892152911, + 124.82185220506081 + ], + "distanceFromStart":0.375 + }, + { + "elevation":[ + 303.62145464574394, + 336.05569457646544 + ], + "pace":[ + 380.55927782266116, + 397.60789726832775 + ], + "heartRate":[ + 121.52696452049059, + 127.31525441110122 + ], + "distanceFromStart":0.75 + }, + { + "elevation":[ + 319.90393365162629, + 346.26966025518789 + ], + "pace":[ + 357.94116421258531, + 398.0750288648062 + ], + "heartRate":[ + 123.75908585923588, + 132.77069404486801 + ], + "distanceFromStart":1.125 + }, + { + "elevation":[ + 354.17104439267905, + 403.57031216972939 + ], + "pace":[ + 335.07385149392701, + 397.82674381875808 + ], + "heartRate":[ + 130.8235194572915, + 140.55700591418218 + ], + "distanceFromStart":1.5 + }, + { + "elevation":[ + 357.42992871175124, + 385.92155620623635 + ], + "pace":[ + 395.16168913839374, + 404.60294066527558 + ], + "heartRate":[ + 131.5456052446734, + 134.65984504627627 + ], + "distanceFromStart":1.875 + }, + { + "elevation":[ + 345.47736721935661, + 363.18776661379422 + ], + "pace":[ + 340.82303041339082, + 404.71689228682374 + ], + "heartRate":[ + 125.1949698433959, + 131.31354363122026 + ], + "distanceFromStart":2.25 + }, + { + "elevation":[ + 346.23343025200535, + 497.23376445462401 + ], + "pace":[ + 261.27629148816021, + 331.68516208719467 + ], + "heartRate":[ + 131.67810544238606, + 154.26779645311458 + ], + "distanceFromStart":2.625 + }, + { + "elevation":[ + 491.57378483134391, + 547.49535224251053 + ], + "pace":[ + 296.05298644112088, + 401.14092967732398 + ], + "heartRate":[ + 151.36398089694217, + 166.20454793289232 + ], + "distanceFromStart":3 + }, + { + "elevation":[ + 472.06803233416338, + 531.92570520228401 + ], + "pace":[ + 395.50830663514012, + 401.67837917543591 + ], + "heartRate":[ + 134.41798110234078, + 151.90886697564241 + ], + "distanceFromStart":3.375 + }, + { + "elevation":[ + 339.81419476005283, + 461.03832527824829 + ], + "pace":[ + 395.31160487975183, + 404.49550455974907 + ], + "heartRate":[ + 129.97753472415462, + 138.13531094848992 + ], + "distanceFromStart":3.75 + }, + { + "elevation":[ + 303.1495508565697, + 342.3532820173541 + ], + "pace":[ + 395.02844559698116, + 402.65878340653796 + ], + "heartRate":[ + 127.72304232462609, + 133.26322270764186 + ], + "distanceFromStart":4.125 + } + ] + }, + { + "name":"Lonesome Ridge Trail", + "id":1003, + "distance":4.5, + "difficulty":3, + "observations":[ + { + "elevation":[ + 291.65263635636268, + 309.26016677925196 + ], + "pace":[ + 396.08716481908732, + 403.68937873525232 + ], + "heartRate":[ + 117.16351898665887, + 121.95815455919609 + ], + "distanceFromStart":0 + }, + { + "elevation":[ + 299.24001936628116, + 317.44584350790012 + ], + "pace":[ + 380.19020240756623, + 395.3978319010256 + ], + "heartRate":[ + 117.6410892152911, + 124.82185220506081 + ], + "distanceFromStart":0.375 + }, + { + "elevation":[ + 303.62145464574394, + 336.05569457646544 + ], + "pace":[ + 380.55927782266116, + 397.60789726832775 + ], + "heartRate":[ + 121.52696452049059, + 127.31525441110122 + ], + "distanceFromStart":0.75 + }, + { + "elevation":[ + 319.90393365162629, + 346.26966025518789 + ], + "pace":[ + 357.94116421258531, + 398.0750288648062 + ], + "heartRate":[ + 123.75908585923588, + 132.77069404486801 + ], + "distanceFromStart":1.125 + }, + { + "elevation":[ + 354.17104439267905, + 403.57031216972939 + ], + "pace":[ + 335.07385149392701, + 397.82674381875808 + ], + "heartRate":[ + 130.8235194572915, + 140.55700591418218 + ], + "distanceFromStart":1.5 + }, + { + "elevation":[ + 357.42992871175124, + 385.92155620623635 + ], + "pace":[ + 395.16168913839374, + 404.60294066527558 + ], + "heartRate":[ + 131.5456052446734, + 134.65984504627627 + ], + "distanceFromStart":1.875 + }, + { + "elevation":[ + 345.47736721935661, + 363.18776661379422 + ], + "pace":[ + 340.82303041339082, + 404.71689228682374 + ], + "heartRate":[ + 125.1949698433959, + 131.31354363122026 + ], + "distanceFromStart":2.25 + }, + { + "elevation":[ + 346.23343025200535, + 497.23376445462401 + ], + "pace":[ + 261.27629148816021, + 331.68516208719467 + ], + "heartRate":[ + 131.67810544238606, + 154.26779645311458 + ], + "distanceFromStart":2.625 + }, + { + "elevation":[ + 491.57378483134391, + 547.49535224251053 + ], + "pace":[ + 296.05298644112088, + 401.14092967732398 + ], + "heartRate":[ + 151.36398089694217, + 166.20454793289232 + ], + "distanceFromStart":3 + }, + { + "elevation":[ + 472.06803233416338, + 531.92570520228401 + ], + "pace":[ + 395.50830663514012, + 401.67837917543591 + ], + "heartRate":[ + 134.41798110234078, + 151.90886697564241 + ], + "distanceFromStart":3.375 + }, + { + "elevation":[ + 339.81419476005283, + 461.03832527824829 + ], + "pace":[ + 395.31160487975183, + 404.49550455974907 + ], + "heartRate":[ + 129.97753472415462, + 138.13531094848992 + ], + "distanceFromStart":3.75 + }, + { + "elevation":[ + 303.1495508565697, + 342.3532820173541 + ], + "pace":[ + 395.02844559698116, + 402.65878340653796 + ], + "heartRate":[ + 127.72304232462609, + 133.26322270764186 + ], + "distanceFromStart":4.125 + } + ] + }, + { + "name":"Lonesome Ridge Trail", + "id":1004, + "distance":4.5, + "difficulty":3, + "observations":[ + { + "elevation":[ + 291.65263635636268, + 309.26016677925196 + ], + "pace":[ + 396.08716481908732, + 403.68937873525232 + ], + "heartRate":[ + 117.16351898665887, + 121.95815455919609 + ], + "distanceFromStart":0 + }, + { + "elevation":[ + 299.24001936628116, + 317.44584350790012 + ], + "pace":[ + 380.19020240756623, + 395.3978319010256 + ], + "heartRate":[ + 117.6410892152911, + 124.82185220506081 + ], + "distanceFromStart":0.375 + }, + { + "elevation":[ + 303.62145464574394, + 336.05569457646544 + ], + "pace":[ + 380.55927782266116, + 397.60789726832775 + ], + "heartRate":[ + 121.52696452049059, + 127.31525441110122 + ], + "distanceFromStart":0.75 + }, + { + "elevation":[ + 319.90393365162629, + 346.26966025518789 + ], + "pace":[ + 357.94116421258531, + 398.0750288648062 + ], + "heartRate":[ + 123.75908585923588, + 132.77069404486801 + ], + "distanceFromStart":1.125 + }, + { + "elevation":[ + 354.17104439267905, + 403.57031216972939 + ], + "pace":[ + 335.07385149392701, + 397.82674381875808 + ], + "heartRate":[ + 130.8235194572915, + 140.55700591418218 + ], + "distanceFromStart":1.5 + }, + { + "elevation":[ + 357.42992871175124, + 385.92155620623635 + ], + "pace":[ + 395.16168913839374, + 404.60294066527558 + ], + "heartRate":[ + 131.5456052446734, + 134.65984504627627 + ], + "distanceFromStart":1.875 + }, + { + "elevation":[ + 345.47736721935661, + 363.18776661379422 + ], + "pace":[ + 340.82303041339082, + 404.71689228682374 + ], + "heartRate":[ + 125.1949698433959, + 131.31354363122026 + ], + "distanceFromStart":2.25 + }, + { + "elevation":[ + 346.23343025200535, + 497.23376445462401 + ], + "pace":[ + 261.27629148816021, + 331.68516208719467 + ], + "heartRate":[ + 131.67810544238606, + 154.26779645311458 + ], + "distanceFromStart":2.625 + }, + { + "elevation":[ + 491.57378483134391, + 547.49535224251053 + ], + "pace":[ + 296.05298644112088, + 401.14092967732398 + ], + "heartRate":[ + 151.36398089694217, + 166.20454793289232 + ], + "distanceFromStart":3 + }, + { + "elevation":[ + 472.06803233416338, + 531.92570520228401 + ], + "pace":[ + 395.50830663514012, + 401.67837917543591 + ], + "heartRate":[ + 134.41798110234078, + 151.90886697564241 + ], + "distanceFromStart":3.375 + }, + { + "elevation":[ + 339.81419476005283, + 461.03832527824829 + ], + "pace":[ + 395.31160487975183, + 404.49550455974907 + ], + "heartRate":[ + 129.97753472415462, + 138.13531094848992 + ], + "distanceFromStart":3.75 + }, + { + "elevation":[ + 303.1495508565697, + 342.3532820173541 + ], + "pace":[ + 395.02844559698116, + 402.65878340653796 + ], + "heartRate":[ + 127.72304232462609, + 133.26322270764186 + ], + "distanceFromStart":4.125 + } + ] + }, + { + "name":"Lonesome Ridge Trail", + "id":1005, + "distance":4.5, + "difficulty":3, + "observations":[ + { + "elevation":[ + 291.65263635636268, + 309.26016677925196 + ], + "pace":[ + 396.08716481908732, + 403.68937873525232 + ], + "heartRate":[ + 117.16351898665887, + 121.95815455919609 + ], + "distanceFromStart":0 + }, + { + "elevation":[ + 299.24001936628116, + 317.44584350790012 + ], + "pace":[ + 380.19020240756623, + 395.3978319010256 + ], + "heartRate":[ + 117.6410892152911, + 124.82185220506081 + ], + "distanceFromStart":0.375 + }, + { + "elevation":[ + 303.62145464574394, + 336.05569457646544 + ], + "pace":[ + 380.55927782266116, + 397.60789726832775 + ], + "heartRate":[ + 121.52696452049059, + 127.31525441110122 + ], + "distanceFromStart":0.75 + }, + { + "elevation":[ + 319.90393365162629, + 346.26966025518789 + ], + "pace":[ + 357.94116421258531, + 398.0750288648062 + ], + "heartRate":[ + 123.75908585923588, + 132.77069404486801 + ], + "distanceFromStart":1.125 + }, + { + "elevation":[ + 354.17104439267905, + 403.57031216972939 + ], + "pace":[ + 335.07385149392701, + 397.82674381875808 + ], + "heartRate":[ + 130.8235194572915, + 140.55700591418218 + ], + "distanceFromStart":1.5 + }, + { + "elevation":[ + 357.42992871175124, + 385.92155620623635 + ], + "pace":[ + 395.16168913839374, + 404.60294066527558 + ], + "heartRate":[ + 131.5456052446734, + 134.65984504627627 + ], + "distanceFromStart":1.875 + }, + { + "elevation":[ + 345.47736721935661, + 363.18776661379422 + ], + "pace":[ + 340.82303041339082, + 404.71689228682374 + ], + "heartRate":[ + 125.1949698433959, + 131.31354363122026 + ], + "distanceFromStart":2.25 + }, + { + "elevation":[ + 346.23343025200535, + 497.23376445462401 + ], + "pace":[ + 261.27629148816021, + 331.68516208719467 + ], + "heartRate":[ + 131.67810544238606, + 154.26779645311458 + ], + "distanceFromStart":2.625 + }, + { + "elevation":[ + 491.57378483134391, + 547.49535224251053 + ], + "pace":[ + 296.05298644112088, + 401.14092967732398 + ], + "heartRate":[ + 151.36398089694217, + 166.20454793289232 + ], + "distanceFromStart":3 + }, + { + "elevation":[ + 472.06803233416338, + 531.92570520228401 + ], + "pace":[ + 395.50830663514012, + 401.67837917543591 + ], + "heartRate":[ + 134.41798110234078, + 151.90886697564241 + ], + "distanceFromStart":3.375 + }, + { + "elevation":[ + 339.81419476005283, + 461.03832527824829 + ], + "pace":[ + 395.31160487975183, + 404.49550455974907 + ], + "heartRate":[ + 129.97753472415462, + 138.13531094848992 + ], + "distanceFromStart":3.75 + }, + { + "elevation":[ + 303.1495508565697, + 342.3532820173541 + ], + "pace":[ + 395.02844559698116, + 402.65878340653796 + ], + "heartRate":[ + 127.72304232462609, + 133.26322270764186 + ], + "distanceFromStart":4.125 + } + ] + }, + { + "name":"Lonesome Ridge Trail", + "id":1006, + "distance":4.5, + "difficulty":3, + "observations":[ + { + "elevation":[ + 291.65263635636268, + 309.26016677925196 + ], + "pace":[ + 396.08716481908732, + 403.68937873525232 + ], + "heartRate":[ + 117.16351898665887, + 121.95815455919609 + ], + "distanceFromStart":0 + }, + { + "elevation":[ + 299.24001936628116, + 317.44584350790012 + ], + "pace":[ + 380.19020240756623, + 395.3978319010256 + ], + "heartRate":[ + 117.6410892152911, + 124.82185220506081 + ], + "distanceFromStart":0.375 + }, + { + "elevation":[ + 303.62145464574394, + 336.05569457646544 + ], + "pace":[ + 380.55927782266116, + 397.60789726832775 + ], + "heartRate":[ + 121.52696452049059, + 127.31525441110122 + ], + "distanceFromStart":0.75 + }, + { + "elevation":[ + 319.90393365162629, + 346.26966025518789 + ], + "pace":[ + 357.94116421258531, + 398.0750288648062 + ], + "heartRate":[ + 123.75908585923588, + 132.77069404486801 + ], + "distanceFromStart":1.125 + }, + { + "elevation":[ + 354.17104439267905, + 403.57031216972939 + ], + "pace":[ + 335.07385149392701, + 397.82674381875808 + ], + "heartRate":[ + 130.8235194572915, + 140.55700591418218 + ], + "distanceFromStart":1.5 + }, + { + "elevation":[ + 357.42992871175124, + 385.92155620623635 + ], + "pace":[ + 395.16168913839374, + 404.60294066527558 + ], + "heartRate":[ + 131.5456052446734, + 134.65984504627627 + ], + "distanceFromStart":1.875 + }, + { + "elevation":[ + 345.47736721935661, + 363.18776661379422 + ], + "pace":[ + 340.82303041339082, + 404.71689228682374 + ], + "heartRate":[ + 125.1949698433959, + 131.31354363122026 + ], + "distanceFromStart":2.25 + }, + { + "elevation":[ + 346.23343025200535, + 497.23376445462401 + ], + "pace":[ + 261.27629148816021, + 331.68516208719467 + ], + "heartRate":[ + 131.67810544238606, + 154.26779645311458 + ], + "distanceFromStart":2.625 + }, + { + "elevation":[ + 491.57378483134391, + 547.49535224251053 + ], + "pace":[ + 296.05298644112088, + 401.14092967732398 + ], + "heartRate":[ + 151.36398089694217, + 166.20454793289232 + ], + "distanceFromStart":3 + }, + { + "elevation":[ + 472.06803233416338, + 531.92570520228401 + ], + "pace":[ + 395.50830663514012, + 401.67837917543591 + ], + "heartRate":[ + 134.41798110234078, + 151.90886697564241 + ], + "distanceFromStart":3.375 + }, + { + "elevation":[ + 339.81419476005283, + 461.03832527824829 + ], + "pace":[ + 395.31160487975183, + 404.49550455974907 + ], + "heartRate":[ + 129.97753472415462, + 138.13531094848992 + ], + "distanceFromStart":3.75 + }, + { + "elevation":[ + 303.1495508565697, + 342.3532820173541 + ], + "pace":[ + 395.02844559698116, + 402.65878340653796 + ], + "heartRate":[ + 127.72304232462609, + 133.26322270764186 + ], + "distanceFromStart":4.125 + } + ] + }, + { + "name":"Lonesome Ridge Trail", + "id":1007, + "distance":4.5, + "difficulty":3, + "observations":[ + { + "elevation":[ + 291.65263635636268, + 309.26016677925196 + ], + "pace":[ + 396.08716481908732, + 403.68937873525232 + ], + "heartRate":[ + 117.16351898665887, + 121.95815455919609 + ], + "distanceFromStart":0 + }, + { + "elevation":[ + 299.24001936628116, + 317.44584350790012 + ], + "pace":[ + 380.19020240756623, + 395.3978319010256 + ], + "heartRate":[ + 117.6410892152911, + 124.82185220506081 + ], + "distanceFromStart":0.375 + }, + { + "elevation":[ + 303.62145464574394, + 336.05569457646544 + ], + "pace":[ + 380.55927782266116, + 397.60789726832775 + ], + "heartRate":[ + 121.52696452049059, + 127.31525441110122 + ], + "distanceFromStart":0.75 + }, + { + "elevation":[ + 319.90393365162629, + 346.26966025518789 + ], + "pace":[ + 357.94116421258531, + 398.0750288648062 + ], + "heartRate":[ + 123.75908585923588, + 132.77069404486801 + ], + "distanceFromStart":1.125 + }, + { + "elevation":[ + 354.17104439267905, + 403.57031216972939 + ], + "pace":[ + 335.07385149392701, + 397.82674381875808 + ], + "heartRate":[ + 130.8235194572915, + 140.55700591418218 + ], + "distanceFromStart":1.5 + }, + { + "elevation":[ + 357.42992871175124, + 385.92155620623635 + ], + "pace":[ + 395.16168913839374, + 404.60294066527558 + ], + "heartRate":[ + 131.5456052446734, + 134.65984504627627 + ], + "distanceFromStart":1.875 + }, + { + "elevation":[ + 345.47736721935661, + 363.18776661379422 + ], + "pace":[ + 340.82303041339082, + 404.71689228682374 + ], + "heartRate":[ + 125.1949698433959, + 131.31354363122026 + ], + "distanceFromStart":2.25 + }, + { + "elevation":[ + 346.23343025200535, + 497.23376445462401 + ], + "pace":[ + 261.27629148816021, + 331.68516208719467 + ], + "heartRate":[ + 131.67810544238606, + 154.26779645311458 + ], + "distanceFromStart":2.625 + }, + { + "elevation":[ + 491.57378483134391, + 547.49535224251053 + ], + "pace":[ + 296.05298644112088, + 401.14092967732398 + ], + "heartRate":[ + 151.36398089694217, + 166.20454793289232 + ], + "distanceFromStart":3 + }, + { + "elevation":[ + 472.06803233416338, + 531.92570520228401 + ], + "pace":[ + 395.50830663514012, + 401.67837917543591 + ], + "heartRate":[ + 134.41798110234078, + 151.90886697564241 + ], + "distanceFromStart":3.375 + }, + { + "elevation":[ + 339.81419476005283, + 461.03832527824829 + ], + "pace":[ + 395.31160487975183, + 404.49550455974907 + ], + "heartRate":[ + 129.97753472415462, + 138.13531094848992 + ], + "distanceFromStart":3.75 + }, + { + "elevation":[ + 303.1495508565697, + 342.3532820173541 + ], + "pace":[ + 395.02844559698116, + 402.65878340653796 + ], + "heartRate":[ + 127.72304232462609, + 133.26322270764186 + ], + "distanceFromStart":4.125 + } + ] + }, + { + "name":"Lonesome Ridge Trail", + "id":1008, + "distance":4.5, + "difficulty":3, + "observations":[ + { + "elevation":[ + 291.65263635636268, + 309.26016677925196 + ], + "pace":[ + 396.08716481908732, + 403.68937873525232 + ], + "heartRate":[ + 117.16351898665887, + 121.95815455919609 + ], + "distanceFromStart":0 + }, + { + "elevation":[ + 299.24001936628116, + 317.44584350790012 + ], + "pace":[ + 380.19020240756623, + 395.3978319010256 + ], + "heartRate":[ + 117.6410892152911, + 124.82185220506081 + ], + "distanceFromStart":0.375 + }, + { + "elevation":[ + 303.62145464574394, + 336.05569457646544 + ], + "pace":[ + 380.55927782266116, + 397.60789726832775 + ], + "heartRate":[ + 121.52696452049059, + 127.31525441110122 + ], + "distanceFromStart":0.75 + }, + { + "elevation":[ + 319.90393365162629, + 346.26966025518789 + ], + "pace":[ + 357.94116421258531, + 398.0750288648062 + ], + "heartRate":[ + 123.75908585923588, + 132.77069404486801 + ], + "distanceFromStart":1.125 + }, + { + "elevation":[ + 354.17104439267905, + 403.57031216972939 + ], + "pace":[ + 335.07385149392701, + 397.82674381875808 + ], + "heartRate":[ + 130.8235194572915, + 140.55700591418218 + ], + "distanceFromStart":1.5 + }, + { + "elevation":[ + 357.42992871175124, + 385.92155620623635 + ], + "pace":[ + 395.16168913839374, + 404.60294066527558 + ], + "heartRate":[ + 131.5456052446734, + 134.65984504627627 + ], + "distanceFromStart":1.875 + }, + { + "elevation":[ + 345.47736721935661, + 363.18776661379422 + ], + "pace":[ + 340.82303041339082, + 404.71689228682374 + ], + "heartRate":[ + 125.1949698433959, + 131.31354363122026 + ], + "distanceFromStart":2.25 + }, + { + "elevation":[ + 346.23343025200535, + 497.23376445462401 + ], + "pace":[ + 261.27629148816021, + 331.68516208719467 + ], + "heartRate":[ + 131.67810544238606, + 154.26779645311458 + ], + "distanceFromStart":2.625 + }, + { + "elevation":[ + 491.57378483134391, + 547.49535224251053 + ], + "pace":[ + 296.05298644112088, + 401.14092967732398 + ], + "heartRate":[ + 151.36398089694217, + 166.20454793289232 + ], + "distanceFromStart":3 + }, + { + "elevation":[ + 472.06803233416338, + 531.92570520228401 + ], + "pace":[ + 395.50830663514012, + 401.67837917543591 + ], + "heartRate":[ + 134.41798110234078, + 151.90886697564241 + ], + "distanceFromStart":3.375 + }, + { + "elevation":[ + 339.81419476005283, + 461.03832527824829 + ], + "pace":[ + 395.31160487975183, + 404.49550455974907 + ], + "heartRate":[ + 129.97753472415462, + 138.13531094848992 + ], + "distanceFromStart":3.75 + }, + { + "elevation":[ + 303.1495508565697, + 342.3532820173541 + ], + "pace":[ + 395.02844559698116, + 402.65878340653796 + ], + "heartRate":[ + 127.72304232462609, + 133.26322270764186 + ], + "distanceFromStart":4.125 + } + ] + }, + { + "name":"Lonesome Ridge Trail", + "id":1009, + "distance":4.5, + "difficulty":3, + "observations":[ + { + "elevation":[ + 291.65263635636268, + 309.26016677925196 + ], + "pace":[ + 396.08716481908732, + 403.68937873525232 + ], + "heartRate":[ + 117.16351898665887, + 121.95815455919609 + ], + "distanceFromStart":0 + }, + { + "elevation":[ + 299.24001936628116, + 317.44584350790012 + ], + "pace":[ + 380.19020240756623, + 395.3978319010256 + ], + "heartRate":[ + 117.6410892152911, + 124.82185220506081 + ], + "distanceFromStart":0.375 + }, + { + "elevation":[ + 303.62145464574394, + 336.05569457646544 + ], + "pace":[ + 380.55927782266116, + 397.60789726832775 + ], + "heartRate":[ + 121.52696452049059, + 127.31525441110122 + ], + "distanceFromStart":0.75 + }, + { + "elevation":[ + 319.90393365162629, + 346.26966025518789 + ], + "pace":[ + 357.94116421258531, + 398.0750288648062 + ], + "heartRate":[ + 123.75908585923588, + 132.77069404486801 + ], + "distanceFromStart":1.125 + }, + { + "elevation":[ + 354.17104439267905, + 403.57031216972939 + ], + "pace":[ + 335.07385149392701, + 397.82674381875808 + ], + "heartRate":[ + 130.8235194572915, + 140.55700591418218 + ], + "distanceFromStart":1.5 + }, + { + "elevation":[ + 357.42992871175124, + 385.92155620623635 + ], + "pace":[ + 395.16168913839374, + 404.60294066527558 + ], + "heartRate":[ + 131.5456052446734, + 134.65984504627627 + ], + "distanceFromStart":1.875 + }, + { + "elevation":[ + 345.47736721935661, + 363.18776661379422 + ], + "pace":[ + 340.82303041339082, + 404.71689228682374 + ], + "heartRate":[ + 125.1949698433959, + 131.31354363122026 + ], + "distanceFromStart":2.25 + }, + { + "elevation":[ + 346.23343025200535, + 497.23376445462401 + ], + "pace":[ + 261.27629148816021, + 331.68516208719467 + ], + "heartRate":[ + 131.67810544238606, + 154.26779645311458 + ], + "distanceFromStart":2.625 + }, + { + "elevation":[ + 491.57378483134391, + 547.49535224251053 + ], + "pace":[ + 296.05298644112088, + 401.14092967732398 + ], + "heartRate":[ + 151.36398089694217, + 166.20454793289232 + ], + "distanceFromStart":3 + }, + { + "elevation":[ + 472.06803233416338, + 531.92570520228401 + ], + "pace":[ + 395.50830663514012, + 401.67837917543591 + ], + "heartRate":[ + 134.41798110234078, + 151.90886697564241 + ], + "distanceFromStart":3.375 + }, + { + "elevation":[ + 339.81419476005283, + 461.03832527824829 + ], + "pace":[ + 395.31160487975183, + 404.49550455974907 + ], + "heartRate":[ + 129.97753472415462, + 138.13531094848992 + ], + "distanceFromStart":3.75 + }, + { + "elevation":[ + 303.1495508565697, + 342.3532820173541 + ], + "pace":[ + 395.02844559698116, + 402.65878340653796 + ], + "heartRate":[ + 127.72304232462609, + 133.26322270764186 + ], + "distanceFromStart":4.125 + } + ] + }, + { + "name":"Lonesome Ridge Trail", + "id":1010, + "distance":4.5, + "difficulty":3, + "observations":[ + { + "elevation":[ + 291.65263635636268, + 309.26016677925196 + ], + "pace":[ + 396.08716481908732, + 403.68937873525232 + ], + "heartRate":[ + 117.16351898665887, + 121.95815455919609 + ], + "distanceFromStart":0 + }, + { + "elevation":[ + 299.24001936628116, + 317.44584350790012 + ], + "pace":[ + 380.19020240756623, + 395.3978319010256 + ], + "heartRate":[ + 117.6410892152911, + 124.82185220506081 + ], + "distanceFromStart":0.375 + }, + { + "elevation":[ + 303.62145464574394, + 336.05569457646544 + ], + "pace":[ + 380.55927782266116, + 397.60789726832775 + ], + "heartRate":[ + 121.52696452049059, + 127.31525441110122 + ], + "distanceFromStart":0.75 + }, + { + "elevation":[ + 319.90393365162629, + 346.26966025518789 + ], + "pace":[ + 357.94116421258531, + 398.0750288648062 + ], + "heartRate":[ + 123.75908585923588, + 132.77069404486801 + ], + "distanceFromStart":1.125 + }, + { + "elevation":[ + 354.17104439267905, + 403.57031216972939 + ], + "pace":[ + 335.07385149392701, + 397.82674381875808 + ], + "heartRate":[ + 130.8235194572915, + 140.55700591418218 + ], + "distanceFromStart":1.5 + }, + { + "elevation":[ + 357.42992871175124, + 385.92155620623635 + ], + "pace":[ + 395.16168913839374, + 404.60294066527558 + ], + "heartRate":[ + 131.5456052446734, + 134.65984504627627 + ], + "distanceFromStart":1.875 + }, + { + "elevation":[ + 345.47736721935661, + 363.18776661379422 + ], + "pace":[ + 340.82303041339082, + 404.71689228682374 + ], + "heartRate":[ + 125.1949698433959, + 131.31354363122026 + ], + "distanceFromStart":2.25 + }, + { + "elevation":[ + 346.23343025200535, + 497.23376445462401 + ], + "pace":[ + 261.27629148816021, + 331.68516208719467 + ], + "heartRate":[ + 131.67810544238606, + 154.26779645311458 + ], + "distanceFromStart":2.625 + }, + { + "elevation":[ + 491.57378483134391, + 547.49535224251053 + ], + "pace":[ + 296.05298644112088, + 401.14092967732398 + ], + "heartRate":[ + 151.36398089694217, + 166.20454793289232 + ], + "distanceFromStart":3 + }, + { + "elevation":[ + 472.06803233416338, + 531.92570520228401 + ], + "pace":[ + 395.50830663514012, + 401.67837917543591 + ], + "heartRate":[ + 134.41798110234078, + 151.90886697564241 + ], + "distanceFromStart":3.375 + }, + { + "elevation":[ + 339.81419476005283, + 461.03832527824829 + ], + "pace":[ + 395.31160487975183, + 404.49550455974907 + ], + "heartRate":[ + 129.97753472415462, + 138.13531094848992 + ], + "distanceFromStart":3.75 + }, + { + "elevation":[ + 303.1495508565697, + 342.3532820173541 + ], + "pace":[ + 395.02844559698116, + 402.65878340653796 + ], + "heartRate":[ + 127.72304232462609, + 133.26322270764186 + ], + "distanceFromStart":4.125 + } + ] + } +] diff --git a/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Resources/icybay.jpg b/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Resources/icybay.jpg new file mode 100644 index 0000000..feb1764 Binary files /dev/null and b/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Resources/icybay.jpg differ diff --git a/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Resources/lakemcdonald.jpg b/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Resources/lakemcdonald.jpg new file mode 100644 index 0000000..bd9d6b9 Binary files /dev/null and b/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Resources/lakemcdonald.jpg differ diff --git a/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Resources/landmarkData.json b/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Resources/landmarkData.json new file mode 100644 index 0000000..e5b14fc --- /dev/null +++ b/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Resources/landmarkData.json @@ -0,0 +1,182 @@ +[ + { + "name": "Turtle Rock", + "category": "Rivers", + "city": "Twentynine Palms", + "state": "California", + "id": 1001, + "isFeatured": true, + "isFavorite": true, + "park": "Joshua Tree National Park", + "coordinates": { + "longitude": -116.166868, + "latitude": 34.011286 + }, + "imageName": "turtlerock" + }, + { + "name": "Silver Salmon Creek", + "category": "Lakes", + "city": "Port Alsworth", + "state": "Alaska", + "id": 1002, + "isFeatured": false, + "isFavorite": false, + "park": "Lake Clark National Park and Preserve", + "coordinates": { + "longitude": -152.665167, + "latitude": 59.980167 + }, + "imageName": "silversalmoncreek" + }, + { + "name": "Chilkoot Trail", + "category": "Mountains", + "city": "Skagway", + "state": "Alaska", + "id": 1003, + "isFeatured": false, + "isFavorite": true, + "park": "Klondike Gold Rush National Historical Park", + "coordinates": { + "longitude": -135.334571, + "latitude": 59.560551 + }, + "imageName": "chilkoottrail" + }, + { + "name": "St. Mary Lake", + "category": "Lakes", + "city": "Browning", + "state": "Montana", + "id": 1004, + "isFeatured": true, + "isFavorite": true, + "park": "Glacier National Park", + "coordinates": { + "longitude": -113.536248, + "latitude": 48.69423 + }, + "imageName": "stmarylake" + }, + { + "name": "Twin Lake", + "category": "Lakes", + "city": "Twin Lakes", + "state": "Alaska", + "id": 1005, + "isFeatured": false, + "isFavorite": false, + "park": "Lake Clark National Park and Preserve", + "coordinates": { + "longitude": -153.849883, + "latitude": 60.641684 + }, + "imageName": "twinlake" + }, + { + "name": "Lake McDonald", + "category": "Mountains", + "city": "West Glacier", + "state": "Montana", + "id": 1006, + "isFeatured": false, + "isFavorite": false, + "park": "Glacier National Park", + "coordinates": { + "longitude": -113.934831, + "latitude": 48.56002 + }, + "imageName": "lakemcdonald" + }, + { + "name": "Charley Rivers", + "category": "Rivers", + "city": "Eaking", + "state": "Alaska", + "id": 1007, + "isFeatured": true, + "isFavorite": false, + "park": "Charley Rivers National Preserve", + "coordinates": { + "longitude": -143.122586, + "latitude": 65.350021 + }, + "imageName": "charleyrivers", + }, + { + "name": "Icy Bay", + "category": "Mountains", + "city": "Icy Bay", + "state": "Alaska", + "id": 1008, + "isFeatured": false, + "isFavorite": false, + "park": "Wrangell-St. Elias National Park and Preserve", + "coordinates": { + "longitude": -141.518167, + "latitude": 60.089917 + }, + "imageName": "icybay" + }, + { + "name": "Rainbow Lake", + "category": "Lakes", + "city": "Willow", + "state": "Alaska", + "id": 1009, + "isFeatured": false, + "isFavorite": false, + "park": "State Recreation Area", + "coordinates": { + "longitude": -150.086103, + "latitude": 61.694334 + }, + "imageName": "rainbowlake" + }, + { + "name": "Hidden Lake", + "category": "Lakes", + "city": "Newhalem", + "state": "Washington", + "id": 1010, + "isFeatured": false, + "isFavorite": false, + "park": "North Cascades National Park", + "coordinates": { + "longitude": -121.17799, + "latitude": 48.495442 + }, + "imageName": "hiddenlake" + }, + { + "name": "Chincoteague", + "category": "Rivers", + "city": "Chincoteague", + "state": "Virginia", + "id": 1011, + "isFeatured": false, + "isFavorite": false, + "park": "Chincoteague National Wildlife Refuge", + "coordinates": { + "longitude": -75.383212, + "latitude": 37.91531 + }, + "imageName": "chincoteague" + }, + { + "name": "Lake Umbagog", + "category": "Lakes", + "city": "Errol", + "state": "New Hampshire", + "id": 1012, + "isFeatured": true, + "isFavorite": false, + "park": "Umbagog National Wildlife Refuge", + "coordinates": { + "longitude": -71.056816, + "latitude": 44.747408 + }, + "imageName": "umbagog" + } +] diff --git a/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Resources/rainbowlake.jpg b/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Resources/rainbowlake.jpg new file mode 100644 index 0000000..6da43dd Binary files /dev/null and b/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Resources/rainbowlake.jpg differ diff --git a/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Resources/silversalmoncreek.jpg b/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Resources/silversalmoncreek.jpg new file mode 100644 index 0000000..f657532 Binary files /dev/null and b/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Resources/silversalmoncreek.jpg differ diff --git a/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Resources/stmarylake.jpg b/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Resources/stmarylake.jpg new file mode 100644 index 0000000..1c71de4 Binary files /dev/null and b/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Resources/stmarylake.jpg differ diff --git a/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Resources/turtlerock.jpg b/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Resources/turtlerock.jpg new file mode 100644 index 0000000..f7a6e6d Binary files /dev/null and b/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Resources/turtlerock.jpg differ diff --git a/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Resources/twinlake.jpg b/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Resources/twinlake.jpg new file mode 100644 index 0000000..3e7a57c Binary files /dev/null and b/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Resources/twinlake.jpg differ diff --git a/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Resources/umbagog.jpg b/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Resources/umbagog.jpg new file mode 100644 index 0000000..56291c6 Binary files /dev/null and b/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Resources/umbagog.jpg differ diff --git a/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/SceneDelegate.swift b/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/SceneDelegate.swift new file mode 100644 index 0000000..ef7f251 --- /dev/null +++ b/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/SceneDelegate.swift @@ -0,0 +1,58 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +The scene delegate. +*/ + +import UIKit +import SwiftUI + +class SceneDelegate: UIResponder, UIWindowSceneDelegate { + + var window: UIWindow? + + func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { + // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`. + // If using a storyboard, the `window` property will automatically be initialized and attached to the scene. + // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead). + + // Use a UIHostingController as window root view controller + if let windowScene = scene as? UIWindowScene { + let window = UIWindow(windowScene: windowScene) + window.rootViewController = UIHostingController(rootView: LandmarkList().environmentObject(UserData())) + self.window = window + window.makeKeyAndVisible() + } + } + + func sceneDidDisconnect(_ scene: UIScene) { + // Called as the scene is being released by the system. + // This occurs shortly after the scene enters the background, or when its session is discarded. + // Release any resources associated with this scene that can be re-created the next time the scene connects. + // The scene may re-connect later, as its session was not neccessarily discarded (see `application:didDiscardSceneSessions` instead). + } + + func sceneDidBecomeActive(_ scene: UIScene) { + // Called when the scene has moved from an inactive state to an active state. + // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive. + } + + func sceneWillResignActive(_ scene: UIScene) { + // Called when the scene will move from an active state to an inactive state. + // This may occur due to temporary interruptions (ex. an incoming phone call). + } + + func sceneWillEnterForeground(_ scene: UIScene) { + // Called as the scene transitions from the background to the foreground. + // Use this method to undo the changes made on entering the background. + } + + func sceneDidEnterBackground(_ scene: UIScene) { + // Called as the scene transitions from the foreground to the background. + // Use this method to save data, release shared resources, and store enough scene-specific state information + // to restore the scene back to its current state. + } + +} + diff --git a/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Supporting Views/Badge.swift b/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Supporting Views/Badge.swift new file mode 100644 index 0000000..59f03b2 --- /dev/null +++ b/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Supporting Views/Badge.swift @@ -0,0 +1,41 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A view that displays a badge. +*/ + +import SwiftUI + +struct Badge: View { + static let rotationCount = 8 + + var badgeSymbols: some View { + ForEach(0.. + var overallRange: Range + + var heightRatio: CGFloat { + max(CGFloat(magnitude(of: range) / magnitude(of: overallRange)), 0.15) + } + + var offsetRatio: CGFloat { + CGFloat((range.lowerBound - overallRange.lowerBound) / magnitude(of: overallRange)) + } + + var animation: Animation { + Animation.spring() + .speed(2) + .delay(0.03 * Double(index)) + } + + var body: some View { + Capsule() + .fill(Color.white) + .frame(height: height * heightRatio, alignment: .bottom) + .offset(x: 0, y: height * -offsetRatio) + .animation(animation) + } +} + +#if DEBUG +struct GraphCapsule_Previews: PreviewProvider { + static var previews: some View { + GraphCapsule(index: 0, height: 150, range: 10..<50, overallRange: 0..<100) + } +} +#endif diff --git a/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Supporting Views/HikeGraph.swift b/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Supporting Views/HikeGraph.swift new file mode 100644 index 0000000..2a4ff27 --- /dev/null +++ b/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Supporting Views/HikeGraph.swift @@ -0,0 +1,74 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +The elevation, heart rate, and pace of a hike plotted on a graph. +*/ + +import SwiftUI + +func rangeOfRanges(_ ranges: C) -> Range + where C.Element == Range { + guard !ranges.isEmpty else { return 0..<0 } + let low = ranges.lazy.map { $0.lowerBound }.min()! + let high = ranges.lazy.map { $0.upperBound }.max()! + return low..) -> Double { + return range.upperBound - range.lowerBound +} + +struct HikeGraph: View { + var hike: Hike + var path: KeyPath> + + var color: Color { + switch path { + case \.elevation: + return .gray + case \.heartRate: + return Color(hue: 0, saturation: 0.5, brightness: 0.7) + case \.pace: + return Color(hue: 0.7, saturation: 0.4, brightness: 0.7) + default: + return .black + } + } + + var body: some View { + let data = hike.observations + let overallRange = rangeOfRanges(data.lazy.map { $0[keyPath: self.path] }) + let maxMagnitude = data.map { magnitude(of: $0[keyPath: path]) }.max()! + let heightRatio = 1 - CGFloat(maxMagnitude / magnitude(of: overallRange)) + + return GeometryReader { proxy in + HStack(alignment: .bottom, spacing: proxy.size.width / 120) { + ForEach(data.indices) { index in + GraphCapsule( + index: index, + height: proxy.size.height, + range: data[index][keyPath: self.path], + overallRange: overallRange) + .colorMultiply(self.color) + } + .offset(x: 0, y: proxy.size.height * heightRatio) + } + } + } +} + +#if DEBUG +struct HikeGraph_Previews: PreviewProvider { + static var previews: some View { + Group { + HikeGraph(hike: hikeData[0], path: \.elevation) + .frame(height: 200) + HikeGraph(hike: hikeData[0], path: \.heartRate) + .frame(height: 200) + HikeGraph(hike: hikeData[0], path: \.pace) + .frame(height: 200) + } + } +} +#endif diff --git a/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Supporting Views/LandmarkRow.swift b/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Supporting Views/LandmarkRow.swift new file mode 100644 index 0000000..2f8110c --- /dev/null +++ b/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Supporting Views/LandmarkRow.swift @@ -0,0 +1,38 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A single row to be displayed in a list of landmarks. +*/ + +import SwiftUI + +struct LandmarkRow: View { + var landmark: Landmark + + var body: some View { + HStack { + landmark.image(forSize: 50) + Text(verbatim: landmark.name) + Spacer() + + if landmark.isFavorite { + Image(systemName: "star.fill") + .imageScale(.medium) + .foregroundColor(.yellow) + } + } + } +} + +#if DEBUG +struct LandmarkRow_Previews: PreviewProvider { + static var previews: some View { + Group { + LandmarkRow(landmark: landmarkData[0]) + LandmarkRow(landmark: landmarkData[1]) + } + .previewLayout(.fixed(width: 300, height: 70)) + } +} +#endif diff --git a/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Supporting Views/MapView.swift b/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Supporting Views/MapView.swift new file mode 100644 index 0000000..5a8c64b --- /dev/null +++ b/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Supporting Views/MapView.swift @@ -0,0 +1,31 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A view that hosts an `MKMapView`. +*/ + +import SwiftUI +import MapKit + +struct MapView: UIViewRepresentable { + var coordinate: CLLocationCoordinate2D + + func makeUIView(context: Context) -> MKMapView { + MKMapView(frame: .zero) + } + + func updateUIView(_ view: MKMapView, context: Context) { + let span = MKCoordinateSpan(latitudeDelta: 0.02, longitudeDelta: 0.02) + let region = MKCoordinateRegion(center: coordinate, span: span) + view.setRegion(region, animated: true) + } +} + +#if DEBUG +struct MapView_Previews: PreviewProvider { + static var previews: some View { + MapView(coordinate: landmarkData[0].locationCoordinate) + } +} +#endif diff --git a/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Supporting Views/RotatedBadgeSymbol.swift b/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Supporting Views/RotatedBadgeSymbol.swift new file mode 100644 index 0000000..a7e4b53 --- /dev/null +++ b/Other Projects/Animating Views And Transitions/Complete/Landmarks/Landmarks/Supporting Views/RotatedBadgeSymbol.swift @@ -0,0 +1,26 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A view that displays a rotated version of a badge symbol. +*/ + +import SwiftUI + +struct RotatedBadgeSymbol: View { + let angle: Angle + + var body: some View { + BadgeSymbol() + .padding(-60) + .rotationEffect(angle, anchor: .bottom) + } +} + +#if DEBUG +struct RotatedBadgeSymbol_Previews: PreviewProvider { + static var previews: some View { + RotatedBadgeSymbol(angle: .init(degrees: 5)) + } +} +#endif diff --git a/Other Projects/Animating Views And Transitions/Complete/README.md b/Other Projects/Animating Views And Transitions/Complete/README.md new file mode 100644 index 0000000..577767d --- /dev/null +++ b/Other Projects/Animating Views And Transitions/Complete/README.md @@ -0,0 +1,3 @@ +# Completed Project: Animating Views and Transitions + +Explore the completed project for the [Animating Views and Transitions](https://developer.apple.com/tutorials/swiftui/animating-views-and-transitions) tutorial. \ No newline at end of file diff --git a/Other Projects/Animating Views And Transitions/StartingPoint/.gitignore b/Other Projects/Animating Views And Transitions/StartingPoint/.gitignore new file mode 100644 index 0000000..9e50718 --- /dev/null +++ b/Other Projects/Animating Views And Transitions/StartingPoint/.gitignore @@ -0,0 +1,21 @@ +# See LICENSE folder for this sample’s licensing information. +# +# Apple sample code gitignore configuration. + +# Finder +.DS_Store + +# Xcode - User files +xcuserdata/ + +**/*.xcodeproj/project.xcworkspace/* +!**/*.xcodeproj/project.xcworkspace/xcshareddata + +**/*.xcodeproj/project.xcworkspace/xcshareddata/* +!**/*.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings + +**/*.playground/playground.xcworkspace/* +!**/*.playground/playground.xcworkspace/xcshareddata + +**/*.playground/playground.xcworkspace/xcshareddata/* +!**/*.playground/playground.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings diff --git a/Other Projects/Animating Views And Transitions/StartingPoint/Configuration/SampleCode.xcconfig b/Other Projects/Animating Views And Transitions/StartingPoint/Configuration/SampleCode.xcconfig new file mode 100644 index 0000000..db86c06 --- /dev/null +++ b/Other Projects/Animating Views And Transitions/StartingPoint/Configuration/SampleCode.xcconfig @@ -0,0 +1,13 @@ +// +// See LICENSE folder for this sample’s licensing information. +// +// SampleCode.xcconfig +// + +// The `SAMPLE_CODE_DISAMBIGUATOR` configuration is to make it easier to build +// and run a sample code project. Once you set your project's development team, +// you'll have a unique bundle identifier. This is because the bundle identifier +// is derived based on the 'SAMPLE_CODE_DISAMBIGUATOR' value. Do not use this +// approach in your own projects—it's only useful for sample code projects because +// they are frequently downloaded and don't have a development team set. +SAMPLE_CODE_DISAMBIGUATOR=${DEVELOPMENT_TEAM} diff --git a/Other Projects/Animating Views And Transitions/StartingPoint/LICENSE/LICENSE.txt b/Other Projects/Animating Views And Transitions/StartingPoint/LICENSE/LICENSE.txt new file mode 100644 index 0000000..94e3d54 --- /dev/null +++ b/Other Projects/Animating Views And Transitions/StartingPoint/LICENSE/LICENSE.txt @@ -0,0 +1,8 @@ +Copyright © 2019 Apple Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + diff --git a/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/AnimatingViewsAndTransitions.xcodeproj/.xcodesamplecode.plist b/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/AnimatingViewsAndTransitions.xcodeproj/.xcodesamplecode.plist new file mode 100644 index 0000000..5dd5da8 --- /dev/null +++ b/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/AnimatingViewsAndTransitions.xcodeproj/.xcodesamplecode.plist @@ -0,0 +1,5 @@ + + + + + diff --git a/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/AnimatingViewsAndTransitions.xcodeproj/project.pbxproj b/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/AnimatingViewsAndTransitions.xcodeproj/project.pbxproj new file mode 100644 index 0000000..94530de --- /dev/null +++ b/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/AnimatingViewsAndTransitions.xcodeproj/project.pbxproj @@ -0,0 +1,525 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 50; + objects = { + +/* Begin PBXBuildFile section */ + B7310DD1229F6839001079B9 /* HexagonParameters.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7310DD0229F6839001079B9 /* HexagonParameters.swift */; }; + B7310DD3229F6CA9001079B9 /* Badge.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7310DD2229F6CA9001079B9 /* Badge.swift */; }; + B7394866229F194000C47603 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7394865229F194000C47603 /* AppDelegate.swift */; }; + B7394868229F194000C47603 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7394867229F194000C47603 /* SceneDelegate.swift */; }; + B739486A229F194000C47603 /* LandmarkDetail.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7394869229F194000C47603 /* LandmarkDetail.swift */; }; + B739486C229F194200C47603 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B739486B229F194200C47603 /* Assets.xcassets */; }; + B739486F229F194200C47603 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B739486E229F194200C47603 /* Preview Assets.xcassets */; }; + B7394872229F194200C47603 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B7394870229F194200C47603 /* LaunchScreen.storyboard */; }; + B739487A229F1B3F00C47603 /* CircleImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7394879229F1B3F00C47603 /* CircleImage.swift */; }; + B739487C229F1B6800C47603 /* MapView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B739487B229F1B6800C47603 /* MapView.swift */; }; + B7394881229F28B900C47603 /* Landmark.swift in Sources */ = {isa = PBXBuildFile; fileRef = B739487F229F28B900C47603 /* Landmark.swift */; }; + B7394882229F28B900C47603 /* Data.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7394880229F28B900C47603 /* Data.swift */; }; + B7394891229F292F00C47603 /* rainbowlake.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B7394884229F292D00C47603 /* rainbowlake.jpg */; }; + B7394893229F292F00C47603 /* icybay.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B7394886229F292E00C47603 /* icybay.jpg */; }; + B7394894229F292F00C47603 /* lakemcdonald.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B7394887229F292E00C47603 /* lakemcdonald.jpg */; }; + B7394895229F292F00C47603 /* turtlerock.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B7394888229F292E00C47603 /* turtlerock.jpg */; }; + B7394896229F292F00C47603 /* umbagog.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B7394889229F292E00C47603 /* umbagog.jpg */; }; + B7394897229F292F00C47603 /* hiddenlake.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B739488A229F292E00C47603 /* hiddenlake.jpg */; }; + B7394898229F292F00C47603 /* stmarylake.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B739488B229F292E00C47603 /* stmarylake.jpg */; }; + B7394899229F292F00C47603 /* twinlake.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B739488C229F292E00C47603 /* twinlake.jpg */; }; + B739489A229F292F00C47603 /* silversalmoncreek.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B739488D229F292E00C47603 /* silversalmoncreek.jpg */; }; + B739489B229F292F00C47603 /* landmarkData.json in Resources */ = {isa = PBXBuildFile; fileRef = B739488E229F292E00C47603 /* landmarkData.json */; }; + B739489C229F292F00C47603 /* chincoteague.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B739488F229F292F00C47603 /* chincoteague.jpg */; }; + B739489D229F292F00C47603 /* chilkoottrail.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B7394890229F292F00C47603 /* chilkoottrail.jpg */; }; + B739489F229F2D9700C47603 /* LandmarkRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = B739489E229F2D9700C47603 /* LandmarkRow.swift */; }; + B73948A1229F2E1F00C47603 /* LandmarkList.swift in Sources */ = {isa = PBXBuildFile; fileRef = B73948A0229F2E1F00C47603 /* LandmarkList.swift */; }; + B73948A3229F3E2200C47603 /* charleyrivers.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B73948A2229F3E2200C47603 /* charleyrivers.jpg */; }; + B7D2AAC5229F4D7C0061E5F5 /* UserData.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7D2AAC4229F4D7C0061E5F5 /* UserData.swift */; }; + B7D587AE229F7382006E8DCF /* BadgeBackground.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7D587AD229F7382006E8DCF /* BadgeBackground.swift */; }; + B7D587B0229F73C1006E8DCF /* BadgeSymbol.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7D587AF229F73C1006E8DCF /* BadgeSymbol.swift */; }; + B7D587B2229F7406006E8DCF /* RotatedBadgeSymbol.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7D587B1229F7406006E8DCF /* RotatedBadgeSymbol.swift */; }; + B7D587B6229F825D006E8DCF /* HikeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7D587B5229F825D006E8DCF /* HikeView.swift */; }; + B7D587B8229F826D006E8DCF /* GraphCapsule.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7D587B7229F826D006E8DCF /* GraphCapsule.swift */; }; + B7D587BA229F8288006E8DCF /* Hike.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7D587B9229F8288006E8DCF /* Hike.swift */; }; + B7D587BC229F82EB006E8DCF /* HikeDetail.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7D587BB229F82EB006E8DCF /* HikeDetail.swift */; }; + B7D587BE229F82FF006E8DCF /* HikeGraph.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7D587BD229F82FF006E8DCF /* HikeGraph.swift */; }; + B7D587C0229F830B006E8DCF /* hikeData.json in Resources */ = {isa = PBXBuildFile; fileRef = B7D587BF229F830B006E8DCF /* hikeData.json */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + B7310DD0229F6839001079B9 /* HexagonParameters.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HexagonParameters.swift; sourceTree = ""; }; + B7310DD2229F6CA9001079B9 /* Badge.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Badge.swift; sourceTree = ""; }; + B7394862229F194000C47603 /* Landmarks.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Landmarks.app; sourceTree = BUILT_PRODUCTS_DIR; }; + B7394865229F194000C47603 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + B7394867229F194000C47603 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; + B7394869229F194000C47603 /* LandmarkDetail.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LandmarkDetail.swift; sourceTree = ""; }; + B739486B229F194200C47603 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + B739486E229F194200C47603 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; + B7394871229F194200C47603 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + B7394873229F194200C47603 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + B7394879229F1B3F00C47603 /* CircleImage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CircleImage.swift; sourceTree = ""; }; + B739487B229F1B6800C47603 /* MapView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapView.swift; sourceTree = ""; }; + B739487F229F28B900C47603 /* Landmark.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Landmark.swift; sourceTree = ""; }; + B7394880229F28B900C47603 /* Data.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Data.swift; sourceTree = ""; }; + B7394884229F292D00C47603 /* rainbowlake.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = rainbowlake.jpg; sourceTree = ""; }; + B7394886229F292E00C47603 /* icybay.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = icybay.jpg; sourceTree = ""; }; + B7394887229F292E00C47603 /* lakemcdonald.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = lakemcdonald.jpg; sourceTree = ""; }; + B7394888229F292E00C47603 /* turtlerock.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = turtlerock.jpg; sourceTree = ""; }; + B7394889229F292E00C47603 /* umbagog.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = umbagog.jpg; sourceTree = ""; }; + B739488A229F292E00C47603 /* hiddenlake.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = hiddenlake.jpg; sourceTree = ""; }; + B739488B229F292E00C47603 /* stmarylake.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = stmarylake.jpg; sourceTree = ""; }; + B739488C229F292E00C47603 /* twinlake.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = twinlake.jpg; sourceTree = ""; }; + B739488D229F292E00C47603 /* silversalmoncreek.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = silversalmoncreek.jpg; sourceTree = ""; }; + B739488E229F292E00C47603 /* landmarkData.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = landmarkData.json; sourceTree = ""; }; + B739488F229F292F00C47603 /* chincoteague.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = chincoteague.jpg; sourceTree = ""; }; + B7394890229F292F00C47603 /* chilkoottrail.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = chilkoottrail.jpg; sourceTree = ""; }; + B739489E229F2D9700C47603 /* LandmarkRow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = LandmarkRow.swift; path = "Supporting Views/LandmarkRow.swift"; sourceTree = ""; }; + B73948A0229F2E1F00C47603 /* LandmarkList.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LandmarkList.swift; sourceTree = ""; }; + B73948A2229F3E2200C47603 /* charleyrivers.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = charleyrivers.jpg; sourceTree = ""; }; + B7D2AAC4229F4D7C0061E5F5 /* UserData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserData.swift; sourceTree = ""; }; + B7D587AD229F7382006E8DCF /* BadgeBackground.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BadgeBackground.swift; sourceTree = ""; }; + B7D587AF229F73C1006E8DCF /* BadgeSymbol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BadgeSymbol.swift; sourceTree = ""; }; + B7D587B1229F7406006E8DCF /* RotatedBadgeSymbol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RotatedBadgeSymbol.swift; sourceTree = ""; }; + B7D587B5229F825D006E8DCF /* HikeView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HikeView.swift; sourceTree = ""; }; + B7D587B7229F826D006E8DCF /* GraphCapsule.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GraphCapsule.swift; sourceTree = ""; }; + B7D587B9229F8288006E8DCF /* Hike.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Hike.swift; sourceTree = ""; }; + B7D587BB229F82EB006E8DCF /* HikeDetail.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HikeDetail.swift; sourceTree = ""; }; + B7D587BD229F82FF006E8DCF /* HikeGraph.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HikeGraph.swift; sourceTree = ""; }; + B7D587BF229F830B006E8DCF /* hikeData.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = hikeData.json; sourceTree = ""; }; + C4E4AAA0C4E4035000000001 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; name = README.md; path = ../README.md; sourceTree = ""; }; + D4647A20D46497F000000001 /* SampleCode.xcconfig */ = {isa = PBXFileReference; name = SampleCode.xcconfig; path = ../Configuration/SampleCode.xcconfig; sourceTree = ""; }; + D4689770D468771000000001 /* LICENSE.txt */ = {isa = PBXFileReference; includeInIndex = 1; path = LICENSE.txt; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + B739485F229F194000C47603 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + B7394859229F194000C47603 = { + isa = PBXGroup; + children = ( + C4E4AAA0C4E4035000000001 /* README.md */, + B7394864229F194000C47603 /* Landmarks */, + B7394863229F194000C47603 /* Products */, + D46430F0D464341000000001 /* Configuration */, + D6574180D65753B000000001 /* LICENSE */, + ); + sourceTree = ""; + }; + B7394863229F194000C47603 /* Products */ = { + isa = PBXGroup; + children = ( + B7394862229F194000C47603 /* Landmarks.app */, + ); + name = Products; + sourceTree = ""; + }; + B7394864229F194000C47603 /* Landmarks */ = { + isa = PBXGroup; + children = ( + B739487E229F282200C47603 /* Models */, + B7394865229F194000C47603 /* AppDelegate.swift */, + B7394867229F194000C47603 /* SceneDelegate.swift */, + B73948A0229F2E1F00C47603 /* LandmarkList.swift */, + B739489E229F2D9700C47603 /* LandmarkRow.swift */, + B7394869229F194000C47603 /* LandmarkDetail.swift */, + B7D587B5229F825D006E8DCF /* HikeView.swift */, + B7D587BB229F82EB006E8DCF /* HikeDetail.swift */, + B7310DD0229F6839001079B9 /* HexagonParameters.swift */, + B739487D229F1C0100C47603 /* Supporting Views */, + B7394883229F291A00C47603 /* Resources */, + B739486B229F194200C47603 /* Assets.xcassets */, + B7394870229F194200C47603 /* LaunchScreen.storyboard */, + B7394873229F194200C47603 /* Info.plist */, + B739486D229F194200C47603 /* Preview Content */, + ); + path = Landmarks; + sourceTree = ""; + }; + B739486D229F194200C47603 /* Preview Content */ = { + isa = PBXGroup; + children = ( + B739486E229F194200C47603 /* Preview Assets.xcassets */, + ); + path = "Preview Content"; + sourceTree = ""; + }; + B739487D229F1C0100C47603 /* Supporting Views */ = { + isa = PBXGroup; + children = ( + B7394879229F1B3F00C47603 /* CircleImage.swift */, + B739487B229F1B6800C47603 /* MapView.swift */, + B7310DD2229F6CA9001079B9 /* Badge.swift */, + B7D587AF229F73C1006E8DCF /* BadgeSymbol.swift */, + B7D587B1229F7406006E8DCF /* RotatedBadgeSymbol.swift */, + B7D587AD229F7382006E8DCF /* BadgeBackground.swift */, + B7D587BD229F82FF006E8DCF /* HikeGraph.swift */, + B7D587B7229F826D006E8DCF /* GraphCapsule.swift */, + ); + path = "Supporting Views"; + sourceTree = ""; + }; + B739487E229F282200C47603 /* Models */ = { + isa = PBXGroup; + children = ( + B7394880229F28B900C47603 /* Data.swift */, + B739487F229F28B900C47603 /* Landmark.swift */, + B7D587B9229F8288006E8DCF /* Hike.swift */, + B7D2AAC4229F4D7C0061E5F5 /* UserData.swift */, + ); + path = Models; + sourceTree = ""; + }; + B7394883229F291A00C47603 /* Resources */ = { + isa = PBXGroup; + children = ( + B739488E229F292E00C47603 /* landmarkData.json */, + B7D587BF229F830B006E8DCF /* hikeData.json */, + B7394890229F292F00C47603 /* chilkoottrail.jpg */, + B739488F229F292F00C47603 /* chincoteague.jpg */, + B739488A229F292E00C47603 /* hiddenlake.jpg */, + B7394886229F292E00C47603 /* icybay.jpg */, + B7394887229F292E00C47603 /* lakemcdonald.jpg */, + B7394884229F292D00C47603 /* rainbowlake.jpg */, + B739488D229F292E00C47603 /* silversalmoncreek.jpg */, + B739488B229F292E00C47603 /* stmarylake.jpg */, + B7394888229F292E00C47603 /* turtlerock.jpg */, + B739488C229F292E00C47603 /* twinlake.jpg */, + B7394889229F292E00C47603 /* umbagog.jpg */, + B73948A2229F3E2200C47603 /* charleyrivers.jpg */, + ); + path = Resources; + sourceTree = ""; + }; + D46430F0D464341000000001 /* Configuration */ = { + isa = PBXGroup; + children = ( + D4647A20D46497F000000001 /* SampleCode.xcconfig */, + ); + name = Configuration; + sourceTree = ""; + }; + D6574180D65753B000000001 /* LICENSE */ = { + isa = PBXGroup; + children = ( + D4689770D468771000000001 /* LICENSE.txt */, + ); + name = LICENSE; + path = ../LICENSE; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + B7394861229F194000C47603 /* Landmarks */ = { + isa = PBXNativeTarget; + buildConfigurationList = B7394876229F194200C47603 /* Build configuration list for PBXNativeTarget "Landmarks" */; + buildPhases = ( + B739485E229F194000C47603 /* Sources */, + B739485F229F194000C47603 /* Frameworks */, + B7394860229F194000C47603 /* Resources */, + C602AC70C605937000000001, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Landmarks; + productName = Landmarks; + productReference = B7394862229F194000C47603 /* Landmarks.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + B739485A229F194000C47603 /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 1100; + LastUpgradeCheck = 1100; + ORGANIZATIONNAME = Apple; + TargetAttributes = { + B7394861229F194000C47603 = { + CreatedOnToolsVersion = 11.0; + }; + }; + }; + buildConfigurationList = B739485D229F194000C47603 /* Build configuration list for PBXProject "AnimatingViewsAndTransitions" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = B7394859229F194000C47603; + productRefGroup = B7394863229F194000C47603 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + B7394861229F194000C47603 /* Landmarks */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + B7394860229F194000C47603 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + B739489A229F292F00C47603 /* silversalmoncreek.jpg in Resources */, + B7394894229F292F00C47603 /* lakemcdonald.jpg in Resources */, + B7D587C0229F830B006E8DCF /* hikeData.json in Resources */, + B7394872229F194200C47603 /* LaunchScreen.storyboard in Resources */, + B73948A3229F3E2200C47603 /* charleyrivers.jpg in Resources */, + B7394891229F292F00C47603 /* rainbowlake.jpg in Resources */, + B739486F229F194200C47603 /* Preview Assets.xcassets in Resources */, + B7394895229F292F00C47603 /* turtlerock.jpg in Resources */, + B739486C229F194200C47603 /* Assets.xcassets in Resources */, + B7394899229F292F00C47603 /* twinlake.jpg in Resources */, + B7394896229F292F00C47603 /* umbagog.jpg in Resources */, + B739489D229F292F00C47603 /* chilkoottrail.jpg in Resources */, + B739489C229F292F00C47603 /* chincoteague.jpg in Resources */, + B739489B229F292F00C47603 /* landmarkData.json in Resources */, + B7394893229F292F00C47603 /* icybay.jpg in Resources */, + B7394897229F292F00C47603 /* hiddenlake.jpg in Resources */, + B7394898229F292F00C47603 /* stmarylake.jpg in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + B739485E229F194000C47603 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + B7394882229F28B900C47603 /* Data.swift in Sources */, + B7310DD3229F6CA9001079B9 /* Badge.swift in Sources */, + B7394866229F194000C47603 /* AppDelegate.swift in Sources */, + B7D587B8229F826D006E8DCF /* GraphCapsule.swift in Sources */, + B739487A229F1B3F00C47603 /* CircleImage.swift in Sources */, + B739487C229F1B6800C47603 /* MapView.swift in Sources */, + B7D587BA229F8288006E8DCF /* Hike.swift in Sources */, + B7D587BC229F82EB006E8DCF /* HikeDetail.swift in Sources */, + B7D587B6229F825D006E8DCF /* HikeView.swift in Sources */, + B7310DD1229F6839001079B9 /* HexagonParameters.swift in Sources */, + B73948A1229F2E1F00C47603 /* LandmarkList.swift in Sources */, + B7D587B0229F73C1006E8DCF /* BadgeSymbol.swift in Sources */, + B7D587B2229F7406006E8DCF /* RotatedBadgeSymbol.swift in Sources */, + B7D587BE229F82FF006E8DCF /* HikeGraph.swift in Sources */, + B7394868229F194000C47603 /* SceneDelegate.swift in Sources */, + B7D587AE229F7382006E8DCF /* BadgeBackground.swift in Sources */, + B739486A229F194000C47603 /* LandmarkDetail.swift in Sources */, + B739489F229F2D9700C47603 /* LandmarkRow.swift in Sources */, + B7D2AAC5229F4D7C0061E5F5 /* UserData.swift in Sources */, + B7394881229F28B900C47603 /* Landmark.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + B7394870229F194200C47603 /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + B7394871229F194200C47603 /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + B7394874229F194200C47603 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = D4647A20D46497F000000001 /* SampleCode.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + B7394875229F194200C47603 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = D4647A20D46497F000000001 /* SampleCode.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + B7394877229F194200C47603 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = D4647A20D46497F000000001 /* SampleCode.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_ASSET_PATHS = "Landmarks/Preview\\ Content"; + DEVELOPMENT_TEAM = ""; + ENABLE_PREVIEWS = YES; + INFOPLIST_FILE = Landmarks/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = "com.example.apple-samplecode.Landmarks${SAMPLE_CODE_DISAMBIGUATOR}"; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + B7394878229F194200C47603 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = D4647A20D46497F000000001 /* SampleCode.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_ASSET_PATHS = "Landmarks/Preview\\ Content"; + DEVELOPMENT_TEAM = ""; + ENABLE_PREVIEWS = YES; + INFOPLIST_FILE = Landmarks/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = "com.example.apple-samplecode.Landmarks${SAMPLE_CODE_DISAMBIGUATOR}"; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + B739485D229F194000C47603 /* Build configuration list for PBXProject "AnimatingViewsAndTransitions" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + B7394874229F194200C47603 /* Debug */, + B7394875229F194200C47603 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + B7394876229F194200C47603 /* Build configuration list for PBXNativeTarget "Landmarks" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + B7394877229F194200C47603 /* Debug */, + B7394878229F194200C47603 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = B739485A229F194000C47603 /* Project object */; +} diff --git a/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/AnimatingViewsAndTransitions.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/AnimatingViewsAndTransitions.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 0000000..3ddf867 --- /dev/null +++ b/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/AnimatingViewsAndTransitions.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,8 @@ + + + + + BuildSystemType + Latest + + diff --git a/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/AppDelegate.swift b/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/AppDelegate.swift new file mode 100644 index 0000000..e22943b --- /dev/null +++ b/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/AppDelegate.swift @@ -0,0 +1,36 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +The application delegate. +*/ + +import UIKit + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { + // Override point for customization after application launch. + return true + } + + func applicationWillTerminate(_ application: UIApplication) { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. + } + + // MARK: UISceneSession Lifecycle + func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration { + // Called when a new scene session is being created. + // Use this method to select a configuration to create the new scene with. + return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role) + } + + func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) { + // Called when the user discards a scene session. + // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions. + // Use this method to release any resources that were specific to the discarded scenes, as they will not return. + } + +} + diff --git a/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/Contents.json b/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..deeb2c6 --- /dev/null +++ b/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,113 @@ +{ + "images" : [ + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "landmark_app_icon_40x40.png", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "3x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "landmark_app_icon_58x58.png", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "landmark_app_icon_87x87.png", + "scale" : "3x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "landmark_app_icon_80x80-1.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "landmark_app_icon_120x120-1.png", + "scale" : "3x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "landmark_app_icon_120x120.png", + "scale" : "2x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "landmark_app_icon_180x180.png", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "1x" + }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "landmark_app_icon_40x40-2.png", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "landmark_app_icon_58x58-1.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "landmark_app_icon_40x40-1.png", + "scale" : "1x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "landmark_app_icon_80x80.png", + "scale" : "2x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "landmark_app_icon_76x76.png", + "scale" : "1x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "landmark_app_icon_152x152.png", + "scale" : "2x" + }, + { + "size" : "83.5x83.5", + "idiom" : "ipad", + "filename" : "landmark_app_icon_167x167.png", + "scale" : "2x" + }, + { + "size" : "1024x1024", + "idiom" : "ios-marketing", + "filename" : "landmark_app_icon_1024x1024.png", + "scale" : "1x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_1024x1024.png b/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_1024x1024.png new file mode 100644 index 0000000..00d81c1 Binary files /dev/null and b/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_1024x1024.png differ diff --git a/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_120x120-1.png b/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_120x120-1.png new file mode 100644 index 0000000..d382b8b Binary files /dev/null and b/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_120x120-1.png differ diff --git a/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_120x120.png b/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_120x120.png new file mode 100644 index 0000000..d382b8b Binary files /dev/null and b/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_120x120.png differ diff --git a/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_152x152.png b/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_152x152.png new file mode 100644 index 0000000..11057f8 Binary files /dev/null and b/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_152x152.png differ diff --git a/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_167x167.png b/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_167x167.png new file mode 100644 index 0000000..f73bc26 Binary files /dev/null and b/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_167x167.png differ diff --git a/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_180x180.png b/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_180x180.png new file mode 100644 index 0000000..b02738c Binary files /dev/null and b/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_180x180.png differ diff --git a/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40-1.png b/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40-1.png new file mode 100644 index 0000000..abaff0e Binary files /dev/null and b/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40-1.png differ diff --git a/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40-2.png b/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40-2.png new file mode 100644 index 0000000..abaff0e Binary files /dev/null and b/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40-2.png differ diff --git a/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40.png b/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40.png new file mode 100644 index 0000000..abaff0e Binary files /dev/null and b/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40.png differ diff --git a/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_58x58-1.png b/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_58x58-1.png new file mode 100644 index 0000000..cf7c73d Binary files /dev/null and b/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_58x58-1.png differ diff --git a/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_58x58.png b/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_58x58.png new file mode 100644 index 0000000..cf7c73d Binary files /dev/null and b/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_58x58.png differ diff --git a/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_76x76.png b/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_76x76.png new file mode 100644 index 0000000..3eff85b Binary files /dev/null and b/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_76x76.png differ diff --git a/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_80x80-1.png b/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_80x80-1.png new file mode 100644 index 0000000..6f33f66 Binary files /dev/null and b/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_80x80-1.png differ diff --git a/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_80x80.png b/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_80x80.png new file mode 100644 index 0000000..6f33f66 Binary files /dev/null and b/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_80x80.png differ diff --git a/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_87x87.png b/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_87x87.png new file mode 100644 index 0000000..9e1616c Binary files /dev/null and b/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_87x87.png differ diff --git a/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Assets.xcassets/Contents.json b/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Assets.xcassets/turtlerock.imageset/Contents.json b/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Assets.xcassets/turtlerock.imageset/Contents.json new file mode 100644 index 0000000..5bfd7bf --- /dev/null +++ b/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Assets.xcassets/turtlerock.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "turtlerock.jpg", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Assets.xcassets/turtlerock.imageset/turtlerock.jpg b/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Assets.xcassets/turtlerock.imageset/turtlerock.jpg new file mode 100644 index 0000000..68bcd3e Binary files /dev/null and b/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Assets.xcassets/turtlerock.imageset/turtlerock.jpg differ diff --git a/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Base.lproj/LaunchScreen.storyboard b/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000..865e932 --- /dev/null +++ b/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/HexagonParameters.swift b/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/HexagonParameters.swift new file mode 100644 index 0000000..8decba4 --- /dev/null +++ b/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/HexagonParameters.swift @@ -0,0 +1,57 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +Size, position, and other information used to draw a badge. +*/ + +import SwiftUI + +struct HexagonParameters { + struct Segment { + let useWidth: (CGFloat, CGFloat, CGFloat) + let xFactors: (CGFloat, CGFloat, CGFloat) + let useHeight: (CGFloat, CGFloat, CGFloat) + let yFactors: (CGFloat, CGFloat, CGFloat) + } + + static let adjustment: CGFloat = 0.085 + static let points = [ + Segment( + useWidth: (1.00, 1.00, 1.00), + xFactors: (0.60, 0.40, 0.50), + useHeight: (1.00, 1.00, 0.00), + yFactors: (0.05, 0.05, 0.00) + ), + Segment( + useWidth: (1.00, 1.00, 0.00), + xFactors: (0.05, 0.00, 0.00), + useHeight: (1.00, 1.00, 1.00), + yFactors: (0.20 + adjustment, 0.30 + adjustment, 0.25 + adjustment) + ), + Segment( + useWidth: (1.00, 1.00, 0.00), + xFactors: (0.00, 0.05, 0.00), + useHeight: (1.00, 1.00, 1.00), + yFactors: (0.70 - adjustment, 0.80 - adjustment, 0.75 - adjustment) + ), + Segment( + useWidth: (1.00, 1.00, 1.00), + xFactors: (0.40, 0.60, 0.50), + useHeight: (1.00, 1.00, 1.00), + yFactors: (0.95, 0.95, 1.00) + ), + Segment( + useWidth: (1.00, 1.00, 1.00), + xFactors: (0.95, 1.00, 1.00), + useHeight: (1.00, 1.00, 1.00), + yFactors: (0.80 - adjustment, 0.70 - adjustment, 0.75 - adjustment) + ), + Segment( + useWidth: (1.00, 1.00, 1.00), + xFactors: (1.00, 0.95, 1.00), + useHeight: (1.00, 1.00, 1.00), + yFactors: (0.30 + adjustment, 0.20 + adjustment, 0.25 + adjustment) + ) + ] +} diff --git a/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/HikeDetail.swift b/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/HikeDetail.swift new file mode 100644 index 0000000..3406a6d --- /dev/null +++ b/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/HikeDetail.swift @@ -0,0 +1,49 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A view showing the details for a hike. +*/ + +import SwiftUI + +struct HikeDetail: View { + let hike: Hike + @State var dataToShow = \Hike.Observation.elevation + + var buttons = [ + ("Elevation", \Hike.Observation.elevation), + ("Heart Rate", \Hike.Observation.heartRate), + ("Pace", \Hike.Observation.pace), + ] + + var body: some View { + return VStack { + HikeGraph(hike: hike, path: dataToShow) + .frame(height: 200, alignment: .center) + + HStack(spacing: 25) { + ForEach(buttons.identified(by: \.0)) { value in + Button(action: { + self.dataToShow = value.1 + }) { + Text(verbatim: value.0) + .font(.system(size: 15)) + .color(value.1 == self.dataToShow + ? Color.gray + : Color.accentColor) + .animation(nil) + } + } + } + } + } +} + +#if DEBUG +struct HikeDetail_Previews: PreviewProvider { + static var previews: some View { + HikeDetail(hike: hikeData[0]) + } +} +#endif diff --git a/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/HikeView.swift b/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/HikeView.swift new file mode 100644 index 0000000..ca1f218 --- /dev/null +++ b/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/HikeView.swift @@ -0,0 +1,56 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A view displaying inforamtion about a hike, including an elevation graph. +*/ + +import SwiftUI + +struct HikeView: View { + var hike: Hike + @State private var showDetail = false + + var body: some View { + VStack { + HStack { + HikeGraph(hike: hike, path: \.elevation) + .frame(width: 50, height: 30) + .animation(nil) + + VStack(alignment: .leading) { + Text(verbatim: hike.name) + .font(.headline) + Text(verbatim: hike.distanceText) + } + + Spacer() + + Button(action: { + self.showDetail.toggle() + }) { + Image(systemName: "chevron.right.circle") + .imageScale(.large) + .rotationEffect(.degrees(showDetail ? 90 : 0)) + .padding() + } + } + + if showDetail { + HikeDetail(hike: hike) + } + } + } +} + +#if DEBUG +struct HikeView_Previews: PreviewProvider { + static var previews: some View { + VStack { + HikeView(hike: hikeData[0]) + .padding() + Spacer() + } + } +} +#endif diff --git a/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Info.plist b/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Info.plist new file mode 100644 index 0000000..e8bb4c6 --- /dev/null +++ b/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Info.plist @@ -0,0 +1,62 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + $(PRODUCT_BUNDLE_PACKAGE_TYPE) + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UIApplicationSceneManifest + + UIApplicationSupportsMultipleScenes + + UISceneConfigurations + + UIWindowSceneSessionRoleApplication + + + UILaunchStoryboardName + LaunchScreen + UISceneConfigurationName + Default Configuration + UISceneDelegateClassName + $(PRODUCT_MODULE_NAME).SceneDelegate + + + + + UILaunchStoryboardName + LaunchScreen + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/LandmarkDetail.swift b/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/LandmarkDetail.swift new file mode 100644 index 0000000..6c290a3 --- /dev/null +++ b/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/LandmarkDetail.swift @@ -0,0 +1,71 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A view showing the details for a landmark. +*/ + +import SwiftUI + +struct LandmarkDetail: View { + @EnvironmentObject var userData: UserData + var landmark: Landmark + + var landmarkIndex: Int { + userData.landmarks.firstIndex(where: { $0.id == landmark.id })! + } + + var body: some View { + VStack { + MapView(coordinate: landmark.locationCoordinate) + .edgesIgnoringSafeArea(.top) + .frame(height: 300) + + CircleImage(image: landmark.image(forSize: 250)) + .offset(x: 0, y: -130) + .padding(.bottom, -130) + + VStack(alignment: .leading) { + HStack { + Text(verbatim: landmark.name) + .font(.title) + + Button(action: { + self.userData.landmarks[self.landmarkIndex] + .isFavorite.toggle() + }) { + if self.userData.landmarks[self.landmarkIndex] + .isFavorite { + Image(systemName: "star.fill") + .foregroundColor(Color.yellow) + } else { + Image(systemName: "star") + .foregroundColor(Color.gray) + } + } + } + + HStack(alignment: .top) { + Text(verbatim: landmark.park) + .font(.subheadline) + Spacer() + Text(verbatim: landmark.state) + .font(.subheadline) + } + } + .padding() + + Spacer() + } + } +} + +#if DEBUG +struct LandmarkDetail_Preview: PreviewProvider { + static var previews: some View { + let userData = UserData() + return LandmarkDetail(landmark: userData.landmarks[0]) + .environmentObject(userData) + } +} +#endif diff --git a/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/LandmarkList.swift b/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/LandmarkList.swift new file mode 100644 index 0000000..c17b5f3 --- /dev/null +++ b/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/LandmarkList.swift @@ -0,0 +1,45 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A view showing a list of landmarks. +*/ + +import SwiftUI + +struct LandmarkList: View { + @EnvironmentObject private var userData: UserData + + var body: some View { + NavigationView { + List { + Toggle(isOn: $userData.showFavoritesOnly) { + Text("Show Favorites Only") + } + + ForEach(userData.landmarks) { landmark in + if !self.userData.showFavoritesOnly || landmark.isFavorite { + NavigationButton( + destination: LandmarkDetail(landmark: landmark)) { + LandmarkRow(landmark: landmark) + } + } + } + } + .navigationBarTitle(Text("Landmarks"), displayMode: .large) + } + } +} + +#if DEBUG +struct LandmarksList_Previews: PreviewProvider { + static var previews: some View { + ForEach(["iPhone SE", "iPhone XS Max"].identified(by: \.self)) { deviceName in + LandmarkList() + .previewDevice(PreviewDevice(rawValue: deviceName)) + .previewDisplayName(deviceName) + } + .environmentObject(UserData()) + } +} +#endif diff --git a/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Models/Data.swift b/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Models/Data.swift new file mode 100644 index 0000000..248d3b2 --- /dev/null +++ b/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Models/Data.swift @@ -0,0 +1,95 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +Helpers for loading images and data. +*/ + +import Foundation +import CoreLocation +import UIKit +import SwiftUI + +let landmarkData: [Landmark] = load("landmarkData.json") +let hikeData: [Hike] = load("hikeData.json") + +func load(_ filename: String, as type: T.Type = T.self) -> T { + let data: Data + + guard let file = Bundle.main.url(forResource: filename, withExtension: nil) + else { + fatalError("Couldn't find \(filename) in main bundle.") + } + + do { + data = try Data(contentsOf: file) + } catch { + fatalError("Couldn't load \(filename) from main bundle:\n\(error)") + } + + do { + let decoder = JSONDecoder() + return try decoder.decode(T.self, from: data) + } catch { + fatalError("Couldn't parse \(filename) as \(T.self):\n\(error)") + } +} + +final class ImageStore { + fileprivate typealias _ImageDictionary = [String: [Int: CGImage]] + fileprivate var images: _ImageDictionary = [:] + + fileprivate static var originalSize = 250 + fileprivate static var scale = 2 + + static var shared = ImageStore() + + func image(name: String, size: Int) -> Image { + let index = _guaranteeInitialImage(name: name) + + let sizedImage = images.values[index][size] + ?? _sizeImage(images.values[index][ImageStore.originalSize]!, to: size * ImageStore.scale) + images.values[index][size] = sizedImage + + return Image(sizedImage, scale: Length(ImageStore.scale), label: Text(verbatim: name)) + } + + fileprivate func _guaranteeInitialImage(name: String) -> _ImageDictionary.Index { + if let index = images.index(forKey: name) { return index } + + guard + let url = Bundle.main.url(forResource: name, withExtension: "jpg"), + let imageSource = CGImageSourceCreateWithURL(url as NSURL, nil), + let image = CGImageSourceCreateImageAtIndex(imageSource, 0, nil) + else { + fatalError("Couldn't load image \(name).jpg from main bundle.") + } + + images[name] = [ImageStore.originalSize: image] + return images.index(forKey: name)! + } + + fileprivate func _sizeImage(_ image: CGImage, to size: Int) -> CGImage { + guard + let colorSpace = image.colorSpace, + let context = CGContext( + data: nil, + width: size, height: size, + bitsPerComponent: image.bitsPerComponent, + bytesPerRow: image.bytesPerRow, + space: colorSpace, + bitmapInfo: image.bitmapInfo.rawValue) + else { + fatalError("Couldn't create graphics context.") + } + context.interpolationQuality = .high + context.draw(image, in: CGRect(x: 0, y: 0, width: size, height: size)) + + if let sizedImage = context.makeImage() { + return sizedImage + } else { + fatalError("Couldn't resize image.") + } + } +} + diff --git a/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Models/Hike.swift b/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Models/Hike.swift new file mode 100644 index 0000000..dfd2bb8 --- /dev/null +++ b/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Models/Hike.swift @@ -0,0 +1,31 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +The model for a hike. +*/ + +import SwiftUI + +struct Hike: Codable, Hashable, Identifiable { + var name: String + var id: Int + var distance: Double + var difficulty: Int + var observations: [Observation] + + static var formatter = LengthFormatter() + + var distanceText: String { + return Hike.formatter + .string(fromValue: distance, unit: .kilometer) + } + + struct Observation: Codable, Hashable { + var distanceFromStart: Double + + var elevation: Range + var pace: Range + var heartRate: Range + } +} diff --git a/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Models/Landmark.swift b/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Models/Landmark.swift new file mode 100644 index 0000000..79b9aa4 --- /dev/null +++ b/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Models/Landmark.swift @@ -0,0 +1,42 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +The model for an individual landmark. +*/ + +import SwiftUI +import CoreLocation + +struct Landmark: Hashable, Codable, Identifiable { + var id: Int + var name: String + fileprivate var imageName: String + fileprivate var coordinates: Coordinates + var state: String + var park: String + var category: Category + var isFavorite: Bool + + var locationCoordinate: CLLocationCoordinate2D { + CLLocationCoordinate2D( + latitude: coordinates.latitude, + longitude: coordinates.longitude) + } + + func image(forSize size: Int) -> Image { + ImageStore.shared.image(name: imageName, size: size) + } + + enum Category: String, CaseIterable, Codable, Hashable { + case featured = "Featured" + case lakes = "Lakes" + case rivers = "Rivers" + case mountains = "Mountains" + } +} + +struct Coordinates: Hashable, Codable { + var latitude: Double + var longitude: Double +} diff --git a/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Models/UserData.swift b/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Models/UserData.swift new file mode 100644 index 0000000..db31fb0 --- /dev/null +++ b/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Models/UserData.swift @@ -0,0 +1,25 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A model object that stores app data. +*/ + +import Combine +import SwiftUI + +final class UserData: BindableObject { + let didChange = PassthroughSubject() + + var showFavoritesOnly = false { + didSet { + didChange.send(self) + } + } + + var landmarks = landmarkData { + didSet { + didChange.send(self) + } + } +} diff --git a/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Preview Content/Preview Assets.xcassets/Contents.json b/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Preview Content/Preview Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Preview Content/Preview Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Resources/charleyrivers.jpg b/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Resources/charleyrivers.jpg new file mode 100644 index 0000000..17ff44b Binary files /dev/null and b/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Resources/charleyrivers.jpg differ diff --git a/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Resources/chilkoottrail.jpg b/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Resources/chilkoottrail.jpg new file mode 100644 index 0000000..e7f805e Binary files /dev/null and b/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Resources/chilkoottrail.jpg differ diff --git a/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Resources/chincoteague.jpg b/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Resources/chincoteague.jpg new file mode 100644 index 0000000..5f47986 Binary files /dev/null and b/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Resources/chincoteague.jpg differ diff --git a/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Resources/hiddenlake.jpg b/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Resources/hiddenlake.jpg new file mode 100644 index 0000000..d8e804c Binary files /dev/null and b/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Resources/hiddenlake.jpg differ diff --git a/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Resources/hikeData.json b/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Resources/hikeData.json new file mode 100644 index 0000000..3fb1e96 --- /dev/null +++ b/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Resources/hikeData.json @@ -0,0 +1,1882 @@ +[ + { + "name":"Lonesome Ridge Trail", + "id":1001, + "distance":4.5, + "difficulty":3, + "observations":[ + { + "elevation":[ + 291.65263635636268, + 309.26016677925196 + ], + "pace":[ + 396.08716481908732, + 403.68937873525232 + ], + "heartRate":[ + 117.16351898665887, + 121.95815455919609 + ], + "distanceFromStart":0 + }, + { + "elevation":[ + 299.24001936628116, + 317.44584350790012 + ], + "pace":[ + 380.19020240756623, + 395.3978319010256 + ], + "heartRate":[ + 117.6410892152911, + 124.82185220506081 + ], + "distanceFromStart":0.375 + }, + { + "elevation":[ + 303.62145464574394, + 336.05569457646544 + ], + "pace":[ + 380.55927782266116, + 397.60789726832775 + ], + "heartRate":[ + 121.52696452049059, + 127.31525441110122 + ], + "distanceFromStart":0.75 + }, + { + "elevation":[ + 319.90393365162629, + 346.26966025518789 + ], + "pace":[ + 357.94116421258531, + 398.0750288648062 + ], + "heartRate":[ + 123.75908585923588, + 132.77069404486801 + ], + "distanceFromStart":1.125 + }, + { + "elevation":[ + 354.17104439267905, + 403.57031216972939 + ], + "pace":[ + 335.07385149392701, + 397.82674381875808 + ], + "heartRate":[ + 130.8235194572915, + 140.55700591418218 + ], + "distanceFromStart":1.5 + }, + { + "elevation":[ + 357.42992871175124, + 385.92155620623635 + ], + "pace":[ + 395.16168913839374, + 404.60294066527558 + ], + "heartRate":[ + 131.5456052446734, + 134.65984504627627 + ], + "distanceFromStart":1.875 + }, + { + "elevation":[ + 345.47736721935661, + 363.18776661379422 + ], + "pace":[ + 340.82303041339082, + 404.71689228682374 + ], + "heartRate":[ + 125.1949698433959, + 131.31354363122026 + ], + "distanceFromStart":2.25 + }, + { + "elevation":[ + 346.23343025200535, + 497.23376445462401 + ], + "pace":[ + 261.27629148816021, + 331.68516208719467 + ], + "heartRate":[ + 131.67810544238606, + 154.26779645311458 + ], + "distanceFromStart":2.625 + }, + { + "elevation":[ + 491.57378483134391, + 547.49535224251053 + ], + "pace":[ + 296.05298644112088, + 401.14092967732398 + ], + "heartRate":[ + 151.36398089694217, + 166.20454793289232 + ], + "distanceFromStart":3 + }, + { + "elevation":[ + 472.06803233416338, + 531.92570520228401 + ], + "pace":[ + 395.50830663514012, + 401.67837917543591 + ], + "heartRate":[ + 134.41798110234078, + 151.90886697564241 + ], + "distanceFromStart":3.375 + }, + { + "elevation":[ + 339.81419476005283, + 461.03832527824829 + ], + "pace":[ + 395.31160487975183, + 404.49550455974907 + ], + "heartRate":[ + 129.97753472415462, + 138.13531094848992 + ], + "distanceFromStart":3.75 + }, + { + "elevation":[ + 303.1495508565697, + 342.3532820173541 + ], + "pace":[ + 395.02844559698116, + 402.65878340653796 + ], + "heartRate":[ + 127.72304232462609, + 133.26322270764186 + ], + "distanceFromStart":4.125 + } + ] + }, + { + "name":"Lonesome Ridge Trail", + "id":1002, + "distance":4.5, + "difficulty":3, + "observations":[ + { + "elevation":[ + 291.65263635636268, + 309.26016677925196 + ], + "pace":[ + 396.08716481908732, + 403.68937873525232 + ], + "heartRate":[ + 117.16351898665887, + 121.95815455919609 + ], + "distanceFromStart":0 + }, + { + "elevation":[ + 299.24001936628116, + 317.44584350790012 + ], + "pace":[ + 380.19020240756623, + 395.3978319010256 + ], + "heartRate":[ + 117.6410892152911, + 124.82185220506081 + ], + "distanceFromStart":0.375 + }, + { + "elevation":[ + 303.62145464574394, + 336.05569457646544 + ], + "pace":[ + 380.55927782266116, + 397.60789726832775 + ], + "heartRate":[ + 121.52696452049059, + 127.31525441110122 + ], + "distanceFromStart":0.75 + }, + { + "elevation":[ + 319.90393365162629, + 346.26966025518789 + ], + "pace":[ + 357.94116421258531, + 398.0750288648062 + ], + "heartRate":[ + 123.75908585923588, + 132.77069404486801 + ], + "distanceFromStart":1.125 + }, + { + "elevation":[ + 354.17104439267905, + 403.57031216972939 + ], + "pace":[ + 335.07385149392701, + 397.82674381875808 + ], + "heartRate":[ + 130.8235194572915, + 140.55700591418218 + ], + "distanceFromStart":1.5 + }, + { + "elevation":[ + 357.42992871175124, + 385.92155620623635 + ], + "pace":[ + 395.16168913839374, + 404.60294066527558 + ], + "heartRate":[ + 131.5456052446734, + 134.65984504627627 + ], + "distanceFromStart":1.875 + }, + { + "elevation":[ + 345.47736721935661, + 363.18776661379422 + ], + "pace":[ + 340.82303041339082, + 404.71689228682374 + ], + "heartRate":[ + 125.1949698433959, + 131.31354363122026 + ], + "distanceFromStart":2.25 + }, + { + "elevation":[ + 346.23343025200535, + 497.23376445462401 + ], + "pace":[ + 261.27629148816021, + 331.68516208719467 + ], + "heartRate":[ + 131.67810544238606, + 154.26779645311458 + ], + "distanceFromStart":2.625 + }, + { + "elevation":[ + 491.57378483134391, + 547.49535224251053 + ], + "pace":[ + 296.05298644112088, + 401.14092967732398 + ], + "heartRate":[ + 151.36398089694217, + 166.20454793289232 + ], + "distanceFromStart":3 + }, + { + "elevation":[ + 472.06803233416338, + 531.92570520228401 + ], + "pace":[ + 395.50830663514012, + 401.67837917543591 + ], + "heartRate":[ + 134.41798110234078, + 151.90886697564241 + ], + "distanceFromStart":3.375 + }, + { + "elevation":[ + 339.81419476005283, + 461.03832527824829 + ], + "pace":[ + 395.31160487975183, + 404.49550455974907 + ], + "heartRate":[ + 129.97753472415462, + 138.13531094848992 + ], + "distanceFromStart":3.75 + }, + { + "elevation":[ + 303.1495508565697, + 342.3532820173541 + ], + "pace":[ + 395.02844559698116, + 402.65878340653796 + ], + "heartRate":[ + 127.72304232462609, + 133.26322270764186 + ], + "distanceFromStart":4.125 + } + ] + }, + { + "name":"Lonesome Ridge Trail", + "id":1003, + "distance":4.5, + "difficulty":3, + "observations":[ + { + "elevation":[ + 291.65263635636268, + 309.26016677925196 + ], + "pace":[ + 396.08716481908732, + 403.68937873525232 + ], + "heartRate":[ + 117.16351898665887, + 121.95815455919609 + ], + "distanceFromStart":0 + }, + { + "elevation":[ + 299.24001936628116, + 317.44584350790012 + ], + "pace":[ + 380.19020240756623, + 395.3978319010256 + ], + "heartRate":[ + 117.6410892152911, + 124.82185220506081 + ], + "distanceFromStart":0.375 + }, + { + "elevation":[ + 303.62145464574394, + 336.05569457646544 + ], + "pace":[ + 380.55927782266116, + 397.60789726832775 + ], + "heartRate":[ + 121.52696452049059, + 127.31525441110122 + ], + "distanceFromStart":0.75 + }, + { + "elevation":[ + 319.90393365162629, + 346.26966025518789 + ], + "pace":[ + 357.94116421258531, + 398.0750288648062 + ], + "heartRate":[ + 123.75908585923588, + 132.77069404486801 + ], + "distanceFromStart":1.125 + }, + { + "elevation":[ + 354.17104439267905, + 403.57031216972939 + ], + "pace":[ + 335.07385149392701, + 397.82674381875808 + ], + "heartRate":[ + 130.8235194572915, + 140.55700591418218 + ], + "distanceFromStart":1.5 + }, + { + "elevation":[ + 357.42992871175124, + 385.92155620623635 + ], + "pace":[ + 395.16168913839374, + 404.60294066527558 + ], + "heartRate":[ + 131.5456052446734, + 134.65984504627627 + ], + "distanceFromStart":1.875 + }, + { + "elevation":[ + 345.47736721935661, + 363.18776661379422 + ], + "pace":[ + 340.82303041339082, + 404.71689228682374 + ], + "heartRate":[ + 125.1949698433959, + 131.31354363122026 + ], + "distanceFromStart":2.25 + }, + { + "elevation":[ + 346.23343025200535, + 497.23376445462401 + ], + "pace":[ + 261.27629148816021, + 331.68516208719467 + ], + "heartRate":[ + 131.67810544238606, + 154.26779645311458 + ], + "distanceFromStart":2.625 + }, + { + "elevation":[ + 491.57378483134391, + 547.49535224251053 + ], + "pace":[ + 296.05298644112088, + 401.14092967732398 + ], + "heartRate":[ + 151.36398089694217, + 166.20454793289232 + ], + "distanceFromStart":3 + }, + { + "elevation":[ + 472.06803233416338, + 531.92570520228401 + ], + "pace":[ + 395.50830663514012, + 401.67837917543591 + ], + "heartRate":[ + 134.41798110234078, + 151.90886697564241 + ], + "distanceFromStart":3.375 + }, + { + "elevation":[ + 339.81419476005283, + 461.03832527824829 + ], + "pace":[ + 395.31160487975183, + 404.49550455974907 + ], + "heartRate":[ + 129.97753472415462, + 138.13531094848992 + ], + "distanceFromStart":3.75 + }, + { + "elevation":[ + 303.1495508565697, + 342.3532820173541 + ], + "pace":[ + 395.02844559698116, + 402.65878340653796 + ], + "heartRate":[ + 127.72304232462609, + 133.26322270764186 + ], + "distanceFromStart":4.125 + } + ] + }, + { + "name":"Lonesome Ridge Trail", + "id":1004, + "distance":4.5, + "difficulty":3, + "observations":[ + { + "elevation":[ + 291.65263635636268, + 309.26016677925196 + ], + "pace":[ + 396.08716481908732, + 403.68937873525232 + ], + "heartRate":[ + 117.16351898665887, + 121.95815455919609 + ], + "distanceFromStart":0 + }, + { + "elevation":[ + 299.24001936628116, + 317.44584350790012 + ], + "pace":[ + 380.19020240756623, + 395.3978319010256 + ], + "heartRate":[ + 117.6410892152911, + 124.82185220506081 + ], + "distanceFromStart":0.375 + }, + { + "elevation":[ + 303.62145464574394, + 336.05569457646544 + ], + "pace":[ + 380.55927782266116, + 397.60789726832775 + ], + "heartRate":[ + 121.52696452049059, + 127.31525441110122 + ], + "distanceFromStart":0.75 + }, + { + "elevation":[ + 319.90393365162629, + 346.26966025518789 + ], + "pace":[ + 357.94116421258531, + 398.0750288648062 + ], + "heartRate":[ + 123.75908585923588, + 132.77069404486801 + ], + "distanceFromStart":1.125 + }, + { + "elevation":[ + 354.17104439267905, + 403.57031216972939 + ], + "pace":[ + 335.07385149392701, + 397.82674381875808 + ], + "heartRate":[ + 130.8235194572915, + 140.55700591418218 + ], + "distanceFromStart":1.5 + }, + { + "elevation":[ + 357.42992871175124, + 385.92155620623635 + ], + "pace":[ + 395.16168913839374, + 404.60294066527558 + ], + "heartRate":[ + 131.5456052446734, + 134.65984504627627 + ], + "distanceFromStart":1.875 + }, + { + "elevation":[ + 345.47736721935661, + 363.18776661379422 + ], + "pace":[ + 340.82303041339082, + 404.71689228682374 + ], + "heartRate":[ + 125.1949698433959, + 131.31354363122026 + ], + "distanceFromStart":2.25 + }, + { + "elevation":[ + 346.23343025200535, + 497.23376445462401 + ], + "pace":[ + 261.27629148816021, + 331.68516208719467 + ], + "heartRate":[ + 131.67810544238606, + 154.26779645311458 + ], + "distanceFromStart":2.625 + }, + { + "elevation":[ + 491.57378483134391, + 547.49535224251053 + ], + "pace":[ + 296.05298644112088, + 401.14092967732398 + ], + "heartRate":[ + 151.36398089694217, + 166.20454793289232 + ], + "distanceFromStart":3 + }, + { + "elevation":[ + 472.06803233416338, + 531.92570520228401 + ], + "pace":[ + 395.50830663514012, + 401.67837917543591 + ], + "heartRate":[ + 134.41798110234078, + 151.90886697564241 + ], + "distanceFromStart":3.375 + }, + { + "elevation":[ + 339.81419476005283, + 461.03832527824829 + ], + "pace":[ + 395.31160487975183, + 404.49550455974907 + ], + "heartRate":[ + 129.97753472415462, + 138.13531094848992 + ], + "distanceFromStart":3.75 + }, + { + "elevation":[ + 303.1495508565697, + 342.3532820173541 + ], + "pace":[ + 395.02844559698116, + 402.65878340653796 + ], + "heartRate":[ + 127.72304232462609, + 133.26322270764186 + ], + "distanceFromStart":4.125 + } + ] + }, + { + "name":"Lonesome Ridge Trail", + "id":1005, + "distance":4.5, + "difficulty":3, + "observations":[ + { + "elevation":[ + 291.65263635636268, + 309.26016677925196 + ], + "pace":[ + 396.08716481908732, + 403.68937873525232 + ], + "heartRate":[ + 117.16351898665887, + 121.95815455919609 + ], + "distanceFromStart":0 + }, + { + "elevation":[ + 299.24001936628116, + 317.44584350790012 + ], + "pace":[ + 380.19020240756623, + 395.3978319010256 + ], + "heartRate":[ + 117.6410892152911, + 124.82185220506081 + ], + "distanceFromStart":0.375 + }, + { + "elevation":[ + 303.62145464574394, + 336.05569457646544 + ], + "pace":[ + 380.55927782266116, + 397.60789726832775 + ], + "heartRate":[ + 121.52696452049059, + 127.31525441110122 + ], + "distanceFromStart":0.75 + }, + { + "elevation":[ + 319.90393365162629, + 346.26966025518789 + ], + "pace":[ + 357.94116421258531, + 398.0750288648062 + ], + "heartRate":[ + 123.75908585923588, + 132.77069404486801 + ], + "distanceFromStart":1.125 + }, + { + "elevation":[ + 354.17104439267905, + 403.57031216972939 + ], + "pace":[ + 335.07385149392701, + 397.82674381875808 + ], + "heartRate":[ + 130.8235194572915, + 140.55700591418218 + ], + "distanceFromStart":1.5 + }, + { + "elevation":[ + 357.42992871175124, + 385.92155620623635 + ], + "pace":[ + 395.16168913839374, + 404.60294066527558 + ], + "heartRate":[ + 131.5456052446734, + 134.65984504627627 + ], + "distanceFromStart":1.875 + }, + { + "elevation":[ + 345.47736721935661, + 363.18776661379422 + ], + "pace":[ + 340.82303041339082, + 404.71689228682374 + ], + "heartRate":[ + 125.1949698433959, + 131.31354363122026 + ], + "distanceFromStart":2.25 + }, + { + "elevation":[ + 346.23343025200535, + 497.23376445462401 + ], + "pace":[ + 261.27629148816021, + 331.68516208719467 + ], + "heartRate":[ + 131.67810544238606, + 154.26779645311458 + ], + "distanceFromStart":2.625 + }, + { + "elevation":[ + 491.57378483134391, + 547.49535224251053 + ], + "pace":[ + 296.05298644112088, + 401.14092967732398 + ], + "heartRate":[ + 151.36398089694217, + 166.20454793289232 + ], + "distanceFromStart":3 + }, + { + "elevation":[ + 472.06803233416338, + 531.92570520228401 + ], + "pace":[ + 395.50830663514012, + 401.67837917543591 + ], + "heartRate":[ + 134.41798110234078, + 151.90886697564241 + ], + "distanceFromStart":3.375 + }, + { + "elevation":[ + 339.81419476005283, + 461.03832527824829 + ], + "pace":[ + 395.31160487975183, + 404.49550455974907 + ], + "heartRate":[ + 129.97753472415462, + 138.13531094848992 + ], + "distanceFromStart":3.75 + }, + { + "elevation":[ + 303.1495508565697, + 342.3532820173541 + ], + "pace":[ + 395.02844559698116, + 402.65878340653796 + ], + "heartRate":[ + 127.72304232462609, + 133.26322270764186 + ], + "distanceFromStart":4.125 + } + ] + }, + { + "name":"Lonesome Ridge Trail", + "id":1006, + "distance":4.5, + "difficulty":3, + "observations":[ + { + "elevation":[ + 291.65263635636268, + 309.26016677925196 + ], + "pace":[ + 396.08716481908732, + 403.68937873525232 + ], + "heartRate":[ + 117.16351898665887, + 121.95815455919609 + ], + "distanceFromStart":0 + }, + { + "elevation":[ + 299.24001936628116, + 317.44584350790012 + ], + "pace":[ + 380.19020240756623, + 395.3978319010256 + ], + "heartRate":[ + 117.6410892152911, + 124.82185220506081 + ], + "distanceFromStart":0.375 + }, + { + "elevation":[ + 303.62145464574394, + 336.05569457646544 + ], + "pace":[ + 380.55927782266116, + 397.60789726832775 + ], + "heartRate":[ + 121.52696452049059, + 127.31525441110122 + ], + "distanceFromStart":0.75 + }, + { + "elevation":[ + 319.90393365162629, + 346.26966025518789 + ], + "pace":[ + 357.94116421258531, + 398.0750288648062 + ], + "heartRate":[ + 123.75908585923588, + 132.77069404486801 + ], + "distanceFromStart":1.125 + }, + { + "elevation":[ + 354.17104439267905, + 403.57031216972939 + ], + "pace":[ + 335.07385149392701, + 397.82674381875808 + ], + "heartRate":[ + 130.8235194572915, + 140.55700591418218 + ], + "distanceFromStart":1.5 + }, + { + "elevation":[ + 357.42992871175124, + 385.92155620623635 + ], + "pace":[ + 395.16168913839374, + 404.60294066527558 + ], + "heartRate":[ + 131.5456052446734, + 134.65984504627627 + ], + "distanceFromStart":1.875 + }, + { + "elevation":[ + 345.47736721935661, + 363.18776661379422 + ], + "pace":[ + 340.82303041339082, + 404.71689228682374 + ], + "heartRate":[ + 125.1949698433959, + 131.31354363122026 + ], + "distanceFromStart":2.25 + }, + { + "elevation":[ + 346.23343025200535, + 497.23376445462401 + ], + "pace":[ + 261.27629148816021, + 331.68516208719467 + ], + "heartRate":[ + 131.67810544238606, + 154.26779645311458 + ], + "distanceFromStart":2.625 + }, + { + "elevation":[ + 491.57378483134391, + 547.49535224251053 + ], + "pace":[ + 296.05298644112088, + 401.14092967732398 + ], + "heartRate":[ + 151.36398089694217, + 166.20454793289232 + ], + "distanceFromStart":3 + }, + { + "elevation":[ + 472.06803233416338, + 531.92570520228401 + ], + "pace":[ + 395.50830663514012, + 401.67837917543591 + ], + "heartRate":[ + 134.41798110234078, + 151.90886697564241 + ], + "distanceFromStart":3.375 + }, + { + "elevation":[ + 339.81419476005283, + 461.03832527824829 + ], + "pace":[ + 395.31160487975183, + 404.49550455974907 + ], + "heartRate":[ + 129.97753472415462, + 138.13531094848992 + ], + "distanceFromStart":3.75 + }, + { + "elevation":[ + 303.1495508565697, + 342.3532820173541 + ], + "pace":[ + 395.02844559698116, + 402.65878340653796 + ], + "heartRate":[ + 127.72304232462609, + 133.26322270764186 + ], + "distanceFromStart":4.125 + } + ] + }, + { + "name":"Lonesome Ridge Trail", + "id":1007, + "distance":4.5, + "difficulty":3, + "observations":[ + { + "elevation":[ + 291.65263635636268, + 309.26016677925196 + ], + "pace":[ + 396.08716481908732, + 403.68937873525232 + ], + "heartRate":[ + 117.16351898665887, + 121.95815455919609 + ], + "distanceFromStart":0 + }, + { + "elevation":[ + 299.24001936628116, + 317.44584350790012 + ], + "pace":[ + 380.19020240756623, + 395.3978319010256 + ], + "heartRate":[ + 117.6410892152911, + 124.82185220506081 + ], + "distanceFromStart":0.375 + }, + { + "elevation":[ + 303.62145464574394, + 336.05569457646544 + ], + "pace":[ + 380.55927782266116, + 397.60789726832775 + ], + "heartRate":[ + 121.52696452049059, + 127.31525441110122 + ], + "distanceFromStart":0.75 + }, + { + "elevation":[ + 319.90393365162629, + 346.26966025518789 + ], + "pace":[ + 357.94116421258531, + 398.0750288648062 + ], + "heartRate":[ + 123.75908585923588, + 132.77069404486801 + ], + "distanceFromStart":1.125 + }, + { + "elevation":[ + 354.17104439267905, + 403.57031216972939 + ], + "pace":[ + 335.07385149392701, + 397.82674381875808 + ], + "heartRate":[ + 130.8235194572915, + 140.55700591418218 + ], + "distanceFromStart":1.5 + }, + { + "elevation":[ + 357.42992871175124, + 385.92155620623635 + ], + "pace":[ + 395.16168913839374, + 404.60294066527558 + ], + "heartRate":[ + 131.5456052446734, + 134.65984504627627 + ], + "distanceFromStart":1.875 + }, + { + "elevation":[ + 345.47736721935661, + 363.18776661379422 + ], + "pace":[ + 340.82303041339082, + 404.71689228682374 + ], + "heartRate":[ + 125.1949698433959, + 131.31354363122026 + ], + "distanceFromStart":2.25 + }, + { + "elevation":[ + 346.23343025200535, + 497.23376445462401 + ], + "pace":[ + 261.27629148816021, + 331.68516208719467 + ], + "heartRate":[ + 131.67810544238606, + 154.26779645311458 + ], + "distanceFromStart":2.625 + }, + { + "elevation":[ + 491.57378483134391, + 547.49535224251053 + ], + "pace":[ + 296.05298644112088, + 401.14092967732398 + ], + "heartRate":[ + 151.36398089694217, + 166.20454793289232 + ], + "distanceFromStart":3 + }, + { + "elevation":[ + 472.06803233416338, + 531.92570520228401 + ], + "pace":[ + 395.50830663514012, + 401.67837917543591 + ], + "heartRate":[ + 134.41798110234078, + 151.90886697564241 + ], + "distanceFromStart":3.375 + }, + { + "elevation":[ + 339.81419476005283, + 461.03832527824829 + ], + "pace":[ + 395.31160487975183, + 404.49550455974907 + ], + "heartRate":[ + 129.97753472415462, + 138.13531094848992 + ], + "distanceFromStart":3.75 + }, + { + "elevation":[ + 303.1495508565697, + 342.3532820173541 + ], + "pace":[ + 395.02844559698116, + 402.65878340653796 + ], + "heartRate":[ + 127.72304232462609, + 133.26322270764186 + ], + "distanceFromStart":4.125 + } + ] + }, + { + "name":"Lonesome Ridge Trail", + "id":1008, + "distance":4.5, + "difficulty":3, + "observations":[ + { + "elevation":[ + 291.65263635636268, + 309.26016677925196 + ], + "pace":[ + 396.08716481908732, + 403.68937873525232 + ], + "heartRate":[ + 117.16351898665887, + 121.95815455919609 + ], + "distanceFromStart":0 + }, + { + "elevation":[ + 299.24001936628116, + 317.44584350790012 + ], + "pace":[ + 380.19020240756623, + 395.3978319010256 + ], + "heartRate":[ + 117.6410892152911, + 124.82185220506081 + ], + "distanceFromStart":0.375 + }, + { + "elevation":[ + 303.62145464574394, + 336.05569457646544 + ], + "pace":[ + 380.55927782266116, + 397.60789726832775 + ], + "heartRate":[ + 121.52696452049059, + 127.31525441110122 + ], + "distanceFromStart":0.75 + }, + { + "elevation":[ + 319.90393365162629, + 346.26966025518789 + ], + "pace":[ + 357.94116421258531, + 398.0750288648062 + ], + "heartRate":[ + 123.75908585923588, + 132.77069404486801 + ], + "distanceFromStart":1.125 + }, + { + "elevation":[ + 354.17104439267905, + 403.57031216972939 + ], + "pace":[ + 335.07385149392701, + 397.82674381875808 + ], + "heartRate":[ + 130.8235194572915, + 140.55700591418218 + ], + "distanceFromStart":1.5 + }, + { + "elevation":[ + 357.42992871175124, + 385.92155620623635 + ], + "pace":[ + 395.16168913839374, + 404.60294066527558 + ], + "heartRate":[ + 131.5456052446734, + 134.65984504627627 + ], + "distanceFromStart":1.875 + }, + { + "elevation":[ + 345.47736721935661, + 363.18776661379422 + ], + "pace":[ + 340.82303041339082, + 404.71689228682374 + ], + "heartRate":[ + 125.1949698433959, + 131.31354363122026 + ], + "distanceFromStart":2.25 + }, + { + "elevation":[ + 346.23343025200535, + 497.23376445462401 + ], + "pace":[ + 261.27629148816021, + 331.68516208719467 + ], + "heartRate":[ + 131.67810544238606, + 154.26779645311458 + ], + "distanceFromStart":2.625 + }, + { + "elevation":[ + 491.57378483134391, + 547.49535224251053 + ], + "pace":[ + 296.05298644112088, + 401.14092967732398 + ], + "heartRate":[ + 151.36398089694217, + 166.20454793289232 + ], + "distanceFromStart":3 + }, + { + "elevation":[ + 472.06803233416338, + 531.92570520228401 + ], + "pace":[ + 395.50830663514012, + 401.67837917543591 + ], + "heartRate":[ + 134.41798110234078, + 151.90886697564241 + ], + "distanceFromStart":3.375 + }, + { + "elevation":[ + 339.81419476005283, + 461.03832527824829 + ], + "pace":[ + 395.31160487975183, + 404.49550455974907 + ], + "heartRate":[ + 129.97753472415462, + 138.13531094848992 + ], + "distanceFromStart":3.75 + }, + { + "elevation":[ + 303.1495508565697, + 342.3532820173541 + ], + "pace":[ + 395.02844559698116, + 402.65878340653796 + ], + "heartRate":[ + 127.72304232462609, + 133.26322270764186 + ], + "distanceFromStart":4.125 + } + ] + }, + { + "name":"Lonesome Ridge Trail", + "id":1009, + "distance":4.5, + "difficulty":3, + "observations":[ + { + "elevation":[ + 291.65263635636268, + 309.26016677925196 + ], + "pace":[ + 396.08716481908732, + 403.68937873525232 + ], + "heartRate":[ + 117.16351898665887, + 121.95815455919609 + ], + "distanceFromStart":0 + }, + { + "elevation":[ + 299.24001936628116, + 317.44584350790012 + ], + "pace":[ + 380.19020240756623, + 395.3978319010256 + ], + "heartRate":[ + 117.6410892152911, + 124.82185220506081 + ], + "distanceFromStart":0.375 + }, + { + "elevation":[ + 303.62145464574394, + 336.05569457646544 + ], + "pace":[ + 380.55927782266116, + 397.60789726832775 + ], + "heartRate":[ + 121.52696452049059, + 127.31525441110122 + ], + "distanceFromStart":0.75 + }, + { + "elevation":[ + 319.90393365162629, + 346.26966025518789 + ], + "pace":[ + 357.94116421258531, + 398.0750288648062 + ], + "heartRate":[ + 123.75908585923588, + 132.77069404486801 + ], + "distanceFromStart":1.125 + }, + { + "elevation":[ + 354.17104439267905, + 403.57031216972939 + ], + "pace":[ + 335.07385149392701, + 397.82674381875808 + ], + "heartRate":[ + 130.8235194572915, + 140.55700591418218 + ], + "distanceFromStart":1.5 + }, + { + "elevation":[ + 357.42992871175124, + 385.92155620623635 + ], + "pace":[ + 395.16168913839374, + 404.60294066527558 + ], + "heartRate":[ + 131.5456052446734, + 134.65984504627627 + ], + "distanceFromStart":1.875 + }, + { + "elevation":[ + 345.47736721935661, + 363.18776661379422 + ], + "pace":[ + 340.82303041339082, + 404.71689228682374 + ], + "heartRate":[ + 125.1949698433959, + 131.31354363122026 + ], + "distanceFromStart":2.25 + }, + { + "elevation":[ + 346.23343025200535, + 497.23376445462401 + ], + "pace":[ + 261.27629148816021, + 331.68516208719467 + ], + "heartRate":[ + 131.67810544238606, + 154.26779645311458 + ], + "distanceFromStart":2.625 + }, + { + "elevation":[ + 491.57378483134391, + 547.49535224251053 + ], + "pace":[ + 296.05298644112088, + 401.14092967732398 + ], + "heartRate":[ + 151.36398089694217, + 166.20454793289232 + ], + "distanceFromStart":3 + }, + { + "elevation":[ + 472.06803233416338, + 531.92570520228401 + ], + "pace":[ + 395.50830663514012, + 401.67837917543591 + ], + "heartRate":[ + 134.41798110234078, + 151.90886697564241 + ], + "distanceFromStart":3.375 + }, + { + "elevation":[ + 339.81419476005283, + 461.03832527824829 + ], + "pace":[ + 395.31160487975183, + 404.49550455974907 + ], + "heartRate":[ + 129.97753472415462, + 138.13531094848992 + ], + "distanceFromStart":3.75 + }, + { + "elevation":[ + 303.1495508565697, + 342.3532820173541 + ], + "pace":[ + 395.02844559698116, + 402.65878340653796 + ], + "heartRate":[ + 127.72304232462609, + 133.26322270764186 + ], + "distanceFromStart":4.125 + } + ] + }, + { + "name":"Lonesome Ridge Trail", + "id":1010, + "distance":4.5, + "difficulty":3, + "observations":[ + { + "elevation":[ + 291.65263635636268, + 309.26016677925196 + ], + "pace":[ + 396.08716481908732, + 403.68937873525232 + ], + "heartRate":[ + 117.16351898665887, + 121.95815455919609 + ], + "distanceFromStart":0 + }, + { + "elevation":[ + 299.24001936628116, + 317.44584350790012 + ], + "pace":[ + 380.19020240756623, + 395.3978319010256 + ], + "heartRate":[ + 117.6410892152911, + 124.82185220506081 + ], + "distanceFromStart":0.375 + }, + { + "elevation":[ + 303.62145464574394, + 336.05569457646544 + ], + "pace":[ + 380.55927782266116, + 397.60789726832775 + ], + "heartRate":[ + 121.52696452049059, + 127.31525441110122 + ], + "distanceFromStart":0.75 + }, + { + "elevation":[ + 319.90393365162629, + 346.26966025518789 + ], + "pace":[ + 357.94116421258531, + 398.0750288648062 + ], + "heartRate":[ + 123.75908585923588, + 132.77069404486801 + ], + "distanceFromStart":1.125 + }, + { + "elevation":[ + 354.17104439267905, + 403.57031216972939 + ], + "pace":[ + 335.07385149392701, + 397.82674381875808 + ], + "heartRate":[ + 130.8235194572915, + 140.55700591418218 + ], + "distanceFromStart":1.5 + }, + { + "elevation":[ + 357.42992871175124, + 385.92155620623635 + ], + "pace":[ + 395.16168913839374, + 404.60294066527558 + ], + "heartRate":[ + 131.5456052446734, + 134.65984504627627 + ], + "distanceFromStart":1.875 + }, + { + "elevation":[ + 345.47736721935661, + 363.18776661379422 + ], + "pace":[ + 340.82303041339082, + 404.71689228682374 + ], + "heartRate":[ + 125.1949698433959, + 131.31354363122026 + ], + "distanceFromStart":2.25 + }, + { + "elevation":[ + 346.23343025200535, + 497.23376445462401 + ], + "pace":[ + 261.27629148816021, + 331.68516208719467 + ], + "heartRate":[ + 131.67810544238606, + 154.26779645311458 + ], + "distanceFromStart":2.625 + }, + { + "elevation":[ + 491.57378483134391, + 547.49535224251053 + ], + "pace":[ + 296.05298644112088, + 401.14092967732398 + ], + "heartRate":[ + 151.36398089694217, + 166.20454793289232 + ], + "distanceFromStart":3 + }, + { + "elevation":[ + 472.06803233416338, + 531.92570520228401 + ], + "pace":[ + 395.50830663514012, + 401.67837917543591 + ], + "heartRate":[ + 134.41798110234078, + 151.90886697564241 + ], + "distanceFromStart":3.375 + }, + { + "elevation":[ + 339.81419476005283, + 461.03832527824829 + ], + "pace":[ + 395.31160487975183, + 404.49550455974907 + ], + "heartRate":[ + 129.97753472415462, + 138.13531094848992 + ], + "distanceFromStart":3.75 + }, + { + "elevation":[ + 303.1495508565697, + 342.3532820173541 + ], + "pace":[ + 395.02844559698116, + 402.65878340653796 + ], + "heartRate":[ + 127.72304232462609, + 133.26322270764186 + ], + "distanceFromStart":4.125 + } + ] + } +] diff --git a/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Resources/icybay.jpg b/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Resources/icybay.jpg new file mode 100644 index 0000000..feb1764 Binary files /dev/null and b/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Resources/icybay.jpg differ diff --git a/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Resources/lakemcdonald.jpg b/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Resources/lakemcdonald.jpg new file mode 100644 index 0000000..bd9d6b9 Binary files /dev/null and b/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Resources/lakemcdonald.jpg differ diff --git a/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Resources/landmarkData.json b/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Resources/landmarkData.json new file mode 100644 index 0000000..e5b14fc --- /dev/null +++ b/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Resources/landmarkData.json @@ -0,0 +1,182 @@ +[ + { + "name": "Turtle Rock", + "category": "Rivers", + "city": "Twentynine Palms", + "state": "California", + "id": 1001, + "isFeatured": true, + "isFavorite": true, + "park": "Joshua Tree National Park", + "coordinates": { + "longitude": -116.166868, + "latitude": 34.011286 + }, + "imageName": "turtlerock" + }, + { + "name": "Silver Salmon Creek", + "category": "Lakes", + "city": "Port Alsworth", + "state": "Alaska", + "id": 1002, + "isFeatured": false, + "isFavorite": false, + "park": "Lake Clark National Park and Preserve", + "coordinates": { + "longitude": -152.665167, + "latitude": 59.980167 + }, + "imageName": "silversalmoncreek" + }, + { + "name": "Chilkoot Trail", + "category": "Mountains", + "city": "Skagway", + "state": "Alaska", + "id": 1003, + "isFeatured": false, + "isFavorite": true, + "park": "Klondike Gold Rush National Historical Park", + "coordinates": { + "longitude": -135.334571, + "latitude": 59.560551 + }, + "imageName": "chilkoottrail" + }, + { + "name": "St. Mary Lake", + "category": "Lakes", + "city": "Browning", + "state": "Montana", + "id": 1004, + "isFeatured": true, + "isFavorite": true, + "park": "Glacier National Park", + "coordinates": { + "longitude": -113.536248, + "latitude": 48.69423 + }, + "imageName": "stmarylake" + }, + { + "name": "Twin Lake", + "category": "Lakes", + "city": "Twin Lakes", + "state": "Alaska", + "id": 1005, + "isFeatured": false, + "isFavorite": false, + "park": "Lake Clark National Park and Preserve", + "coordinates": { + "longitude": -153.849883, + "latitude": 60.641684 + }, + "imageName": "twinlake" + }, + { + "name": "Lake McDonald", + "category": "Mountains", + "city": "West Glacier", + "state": "Montana", + "id": 1006, + "isFeatured": false, + "isFavorite": false, + "park": "Glacier National Park", + "coordinates": { + "longitude": -113.934831, + "latitude": 48.56002 + }, + "imageName": "lakemcdonald" + }, + { + "name": "Charley Rivers", + "category": "Rivers", + "city": "Eaking", + "state": "Alaska", + "id": 1007, + "isFeatured": true, + "isFavorite": false, + "park": "Charley Rivers National Preserve", + "coordinates": { + "longitude": -143.122586, + "latitude": 65.350021 + }, + "imageName": "charleyrivers", + }, + { + "name": "Icy Bay", + "category": "Mountains", + "city": "Icy Bay", + "state": "Alaska", + "id": 1008, + "isFeatured": false, + "isFavorite": false, + "park": "Wrangell-St. Elias National Park and Preserve", + "coordinates": { + "longitude": -141.518167, + "latitude": 60.089917 + }, + "imageName": "icybay" + }, + { + "name": "Rainbow Lake", + "category": "Lakes", + "city": "Willow", + "state": "Alaska", + "id": 1009, + "isFeatured": false, + "isFavorite": false, + "park": "State Recreation Area", + "coordinates": { + "longitude": -150.086103, + "latitude": 61.694334 + }, + "imageName": "rainbowlake" + }, + { + "name": "Hidden Lake", + "category": "Lakes", + "city": "Newhalem", + "state": "Washington", + "id": 1010, + "isFeatured": false, + "isFavorite": false, + "park": "North Cascades National Park", + "coordinates": { + "longitude": -121.17799, + "latitude": 48.495442 + }, + "imageName": "hiddenlake" + }, + { + "name": "Chincoteague", + "category": "Rivers", + "city": "Chincoteague", + "state": "Virginia", + "id": 1011, + "isFeatured": false, + "isFavorite": false, + "park": "Chincoteague National Wildlife Refuge", + "coordinates": { + "longitude": -75.383212, + "latitude": 37.91531 + }, + "imageName": "chincoteague" + }, + { + "name": "Lake Umbagog", + "category": "Lakes", + "city": "Errol", + "state": "New Hampshire", + "id": 1012, + "isFeatured": true, + "isFavorite": false, + "park": "Umbagog National Wildlife Refuge", + "coordinates": { + "longitude": -71.056816, + "latitude": 44.747408 + }, + "imageName": "umbagog" + } +] diff --git a/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Resources/rainbowlake.jpg b/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Resources/rainbowlake.jpg new file mode 100644 index 0000000..6da43dd Binary files /dev/null and b/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Resources/rainbowlake.jpg differ diff --git a/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Resources/silversalmoncreek.jpg b/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Resources/silversalmoncreek.jpg new file mode 100644 index 0000000..f657532 Binary files /dev/null and b/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Resources/silversalmoncreek.jpg differ diff --git a/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Resources/stmarylake.jpg b/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Resources/stmarylake.jpg new file mode 100644 index 0000000..1c71de4 Binary files /dev/null and b/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Resources/stmarylake.jpg differ diff --git a/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Resources/turtlerock.jpg b/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Resources/turtlerock.jpg new file mode 100644 index 0000000..f7a6e6d Binary files /dev/null and b/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Resources/turtlerock.jpg differ diff --git a/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Resources/twinlake.jpg b/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Resources/twinlake.jpg new file mode 100644 index 0000000..3e7a57c Binary files /dev/null and b/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Resources/twinlake.jpg differ diff --git a/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Resources/umbagog.jpg b/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Resources/umbagog.jpg new file mode 100644 index 0000000..56291c6 Binary files /dev/null and b/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Resources/umbagog.jpg differ diff --git a/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/SceneDelegate.swift b/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/SceneDelegate.swift new file mode 100644 index 0000000..96df0dc --- /dev/null +++ b/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/SceneDelegate.swift @@ -0,0 +1,56 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +The scene delegate. +*/ + +import UIKit +import SwiftUI + +class SceneDelegate: UIResponder, UIWindowSceneDelegate { + + var window: UIWindow? + + func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { + // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`. + // If using a storyboard, the `window` property will automatically be initialized and attached to the scene. + // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead). + + // Use a UIHostingController as window root view controller + let window = UIWindow(frame: UIScreen.main.bounds) + window.rootViewController = UIHostingController(rootView: LandmarkList().environmentObject(UserData())) + self.window = window + window.makeKeyAndVisible() + } + + func sceneDidDisconnect(_ scene: UIScene) { + // Called as the scene is being released by the system. + // This occurs shortly after the scene enters the background, or when its session is discarded. + // Release any resources associated with this scene that can be re-created the next time the scene connects. + // The scene may re-connect later, as its session was not neccessarily discarded (see `application:didDiscardSceneSessions` instead). + } + + func sceneDidBecomeActive(_ scene: UIScene) { + // Called when the scene has moved from an inactive state to an active state. + // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive. + } + + func sceneWillResignActive(_ scene: UIScene) { + // Called when the scene will move from an active state to an inactive state. + // This may occur due to temporary interruptions (ex. an incoming phone call). + } + + func sceneWillEnterForeground(_ scene: UIScene) { + // Called as the scene transitions from the background to the foreground. + // Use this method to undo the changes made on entering the background. + } + + func sceneDidEnterBackground(_ scene: UIScene) { + // Called as the scene transitions from the foreground to the background. + // Use this method to save data, release shared resources, and store enough scene-specific state information + // to restore the scene back to its current state. + } + +} + diff --git a/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Supporting Views/Badge.swift b/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Supporting Views/Badge.swift new file mode 100644 index 0000000..59f03b2 --- /dev/null +++ b/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Supporting Views/Badge.swift @@ -0,0 +1,41 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A view that displays a badge. +*/ + +import SwiftUI + +struct Badge: View { + static let rotationCount = 8 + + var badgeSymbols: some View { + ForEach(0.. + var overallRange: Range + + var heightRatio: Length { + max(Length(magnitude(of: range) / magnitude(of: overallRange)), 0.15) + } + + var offsetRatio: Length { + Length((range.lowerBound - overallRange.lowerBound) / magnitude(of: overallRange)) + } + + var body: some View { + Capsule() + .fill(Color.white) + .frame(height: height * heightRatio, alignment: .bottom) + .offset(x: 0, y: height * -offsetRatio) + } +} + +#if DEBUG +struct GraphCapsule_Previews: PreviewProvider { + static var previews: some View { + GraphCapsule(index: 0, height: 150, range: 10..<50, overallRange: 0..<100) + } +} +#endif diff --git a/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Supporting Views/HikeGraph.swift b/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Supporting Views/HikeGraph.swift new file mode 100644 index 0000000..7df5194 --- /dev/null +++ b/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Supporting Views/HikeGraph.swift @@ -0,0 +1,74 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +The elevation, heart rate, and pace of a hike plotted on a graph. +*/ + +import SwiftUI + +func rangeOfRanges(_ ranges: C) -> Range + where C.Element == Range { + guard !ranges.isEmpty else { return 0..<0 } + let low = ranges.lazy.map { $0.lowerBound }.min()! + let high = ranges.lazy.map { $0.upperBound }.max()! + return low..) -> Double { + return range.upperBound - range.lowerBound +} + +struct HikeGraph: View { + var hike: Hike + var path: KeyPath> + + var color: Color { + switch path { + case \.elevation: + return .gray + case \.heartRate: + return Color(hue: 0, saturation: 0.5, brightness: 0.7) + case \.pace: + return Color(hue: 0.7, saturation: 0.4, brightness: 0.7) + default: + return .black + } + } + + var body: some View { + let data = hike.observations + let overallRange = rangeOfRanges(data.lazy.map { $0[keyPath: self.path] }) + let maxMagnitude = data.map { magnitude(of: $0[keyPath: path]) }.max()! + let heightRatio = 1 - Length(maxMagnitude / magnitude(of: overallRange)) + + return GeometryReader { proxy in + HStack(alignment: .bottom, spacing: proxy.size.width / 120) { + ForEach(data.indices) { index in + GraphCapsule( + index: index, + height: proxy.size.height, + range: data[index][keyPath: self.path], + overallRange: overallRange) + .colorMultiply(self.color) + } + .offset(x: 0, y: proxy.size.height * heightRatio) + } + } + } +} + +#if DEBUG +struct HikeGraph_Previews: PreviewProvider { + static var previews: some View { + Group { + HikeGraph(hike: hikeData[0], path: \.elevation) + .frame(height: 200) + HikeGraph(hike: hikeData[0], path: \.heartRate) + .frame(height: 200) + HikeGraph(hike: hikeData[0], path: \.pace) + .frame(height: 200) + } + } +} +#endif diff --git a/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Supporting Views/LandmarkRow.swift b/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Supporting Views/LandmarkRow.swift new file mode 100644 index 0000000..2f8110c --- /dev/null +++ b/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Supporting Views/LandmarkRow.swift @@ -0,0 +1,38 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A single row to be displayed in a list of landmarks. +*/ + +import SwiftUI + +struct LandmarkRow: View { + var landmark: Landmark + + var body: some View { + HStack { + landmark.image(forSize: 50) + Text(verbatim: landmark.name) + Spacer() + + if landmark.isFavorite { + Image(systemName: "star.fill") + .imageScale(.medium) + .foregroundColor(.yellow) + } + } + } +} + +#if DEBUG +struct LandmarkRow_Previews: PreviewProvider { + static var previews: some View { + Group { + LandmarkRow(landmark: landmarkData[0]) + LandmarkRow(landmark: landmarkData[1]) + } + .previewLayout(.fixed(width: 300, height: 70)) + } +} +#endif diff --git a/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Supporting Views/MapView.swift b/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Supporting Views/MapView.swift new file mode 100644 index 0000000..5a8c64b --- /dev/null +++ b/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Supporting Views/MapView.swift @@ -0,0 +1,31 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A view that hosts an `MKMapView`. +*/ + +import SwiftUI +import MapKit + +struct MapView: UIViewRepresentable { + var coordinate: CLLocationCoordinate2D + + func makeUIView(context: Context) -> MKMapView { + MKMapView(frame: .zero) + } + + func updateUIView(_ view: MKMapView, context: Context) { + let span = MKCoordinateSpan(latitudeDelta: 0.02, longitudeDelta: 0.02) + let region = MKCoordinateRegion(center: coordinate, span: span) + view.setRegion(region, animated: true) + } +} + +#if DEBUG +struct MapView_Previews: PreviewProvider { + static var previews: some View { + MapView(coordinate: landmarkData[0].locationCoordinate) + } +} +#endif diff --git a/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Supporting Views/RotatedBadgeSymbol.swift b/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Supporting Views/RotatedBadgeSymbol.swift new file mode 100644 index 0000000..a7e4b53 --- /dev/null +++ b/Other Projects/Animating Views And Transitions/StartingPoint/Landmarks/Landmarks/Supporting Views/RotatedBadgeSymbol.swift @@ -0,0 +1,26 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A view that displays a rotated version of a badge symbol. +*/ + +import SwiftUI + +struct RotatedBadgeSymbol: View { + let angle: Angle + + var body: some View { + BadgeSymbol() + .padding(-60) + .rotationEffect(angle, anchor: .bottom) + } +} + +#if DEBUG +struct RotatedBadgeSymbol_Previews: PreviewProvider { + static var previews: some View { + RotatedBadgeSymbol(angle: .init(degrees: 5)) + } +} +#endif diff --git a/Other Projects/Animating Views And Transitions/StartingPoint/README.md b/Other Projects/Animating Views And Transitions/StartingPoint/README.md new file mode 100644 index 0000000..635754f --- /dev/null +++ b/Other Projects/Animating Views And Transitions/StartingPoint/README.md @@ -0,0 +1,3 @@ +# Drawing Animating Views and Transitions + +Use this project to code along with the [Animating Views and Transitions](https://developer.apple.com/tutorials/swiftui/animating-views-and-transitions) tutorial. \ No newline at end of file diff --git a/Other Projects/Async image loading/RemoteImage/ImageCache.swift b/Other Projects/Async image loading/RemoteImage/ImageCache.swift new file mode 100644 index 0000000..e97b182 --- /dev/null +++ b/Other Projects/Async image loading/RemoteImage/ImageCache.swift @@ -0,0 +1,27 @@ +// +// File 2.swift +// +// +// Created by Callum Trounce on 05/06/2019. +// + +import Foundation +import SwiftUI + +@available(iOS 13.0, *) +class ImageCache { + + private let cache = NSCache() + + private let queue = DispatchQueue.init(label: "cacheQueue", qos: .userInteractive) + + func store(image: CGImage, for url: URL) { + queue.async { [unowned cache] in + cache.setObject(image, forKey: url as NSURL) + } + } + + func image(for url: URL) -> CGImage? { + return cache.object(forKey: url as NSURL) + } +} diff --git a/Other Projects/Async image loading/RemoteImage/ImageLoader.swift b/Other Projects/Async image loading/RemoteImage/ImageLoader.swift new file mode 100644 index 0000000..bde9f7e --- /dev/null +++ b/Other Projects/Async image loading/RemoteImage/ImageLoader.swift @@ -0,0 +1,59 @@ +// +// File 2.swift +// +// +// Created by Callum Trounce on 05/06/2019. +// + +import Foundation +import SwiftUI +import Combine + +@available(iOS 13.0, *) +class ImageLoader { + + static let shared = ImageLoader() + + private let fileManager = FileManager() + + private let cache = ImageCache() + + private lazy var session = URLSession.init(configuration: .default) + + public func load(url: URL, result: @escaping ((CGImage) -> Void)) { + + if let cachedImage = cache.image(for: url) { + result(cachedImage) + return + } + + let request = session.downloadTask(with: url, completionHandler: { [weak self] (downloadLocation, response, error) in + self?.handleDownload(response: response!, location: downloadLocation!, result: result) + }) + + request.resume() + } + + func handleDownload(response: URLResponse, location: URL, result: @escaping ((CGImage) -> Void)) { + guard let url = response.url else { return } + do { + let directory = try fileManager.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true).appendingPathComponent(location.lastPathComponent) + try fileManager.copyItem(at: location, to: directory) + + guard + let imageSource = CGImageSourceCreateWithURL(directory as NSURL, nil) else { + fatalError("couldn't create image source") + } + + guard let image = CGImageSourceCreateImageAtIndex(imageSource, 0, nil) + else { + fatalError("Couldn't load image \(directory)") + } + + cache.store(image: image, for: url) + result(image) + } catch { + fatalError(error.localizedDescription) + } + } +} diff --git a/Other Projects/Async image loading/RemoteImage/RemoteImage.swift b/Other Projects/Async image loading/RemoteImage/RemoteImage.swift new file mode 100644 index 0000000..a21df42 --- /dev/null +++ b/Other Projects/Async image loading/RemoteImage/RemoteImage.swift @@ -0,0 +1,37 @@ +// +// RemoteImage.swift +// Landmarks +// +// Created by Callum Trounce on 06/06/2019. +// Copyright © 2019 Apple. All rights reserved. +// + +import Foundation +import SwiftUI +import Combine + +@available(iOS 13.0, *) +class RemoteImage: BindableObject { + + var didChange = PassthroughSubject() + + typealias PublisherType = PassthroughSubject + + var image: Image? = nil { + didSet { + guard oldValue != image else { return } + DispatchQueue.main.async { + self.didChange.send(self.image!) + } + } + } + + func load(url: URL) -> Self { + guard image == nil else { return self } + ImageLoader.shared.load(url: url) { [unowned self] (image) in + let final = Image.init(image, scale: 1, label: Text(url.lastPathComponent)) + self.image = final + } + return self + } +} diff --git a/Other Projects/Async image loading/RemoteImage/RemoteImageView.swift b/Other Projects/Async image loading/RemoteImage/RemoteImageView.swift new file mode 100644 index 0000000..d229b9e --- /dev/null +++ b/Other Projects/Async image loading/RemoteImage/RemoteImageView.swift @@ -0,0 +1,30 @@ +// +// RemoteImageView.swift +// Landmarks +// +// Created by Callum Trounce on 06/06/2019. +// Copyright © 2019 Apple. All rights reserved. +// + +import Foundation +import SwiftUI + +@available(iOS 13.0, *) +public struct RemoteImageView: View { + + var url: URL + + var placeholderImage: Image? + + @State + var remoteImage: RemoteImage = RemoteImage() + + public var body: some View { + return (remoteImage.load(url: url).image ?? placeholderImage)?.resizable() + } + + public init(url: URL, placeholderImage: Image? = nil) { + self.placeholderImage = placeholderImage + self.url = url + } +} diff --git a/Other Projects/Async image loading/SwURL.swift b/Other Projects/Async image loading/SwURL.swift new file mode 100644 index 0000000..ac4f2b9 --- /dev/null +++ b/Other Projects/Async image loading/SwURL.swift @@ -0,0 +1,5 @@ +struct SwURL { + + + +} diff --git a/Other Projects/Building Lists And Navigation/Complete/.gitignore b/Other Projects/Building Lists And Navigation/Complete/.gitignore new file mode 100644 index 0000000..9e50718 --- /dev/null +++ b/Other Projects/Building Lists And Navigation/Complete/.gitignore @@ -0,0 +1,21 @@ +# See LICENSE folder for this sample’s licensing information. +# +# Apple sample code gitignore configuration. + +# Finder +.DS_Store + +# Xcode - User files +xcuserdata/ + +**/*.xcodeproj/project.xcworkspace/* +!**/*.xcodeproj/project.xcworkspace/xcshareddata + +**/*.xcodeproj/project.xcworkspace/xcshareddata/* +!**/*.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings + +**/*.playground/playground.xcworkspace/* +!**/*.playground/playground.xcworkspace/xcshareddata + +**/*.playground/playground.xcworkspace/xcshareddata/* +!**/*.playground/playground.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings diff --git a/Other Projects/Building Lists And Navigation/Complete/Configuration/SampleCode.xcconfig b/Other Projects/Building Lists And Navigation/Complete/Configuration/SampleCode.xcconfig new file mode 100644 index 0000000..db86c06 --- /dev/null +++ b/Other Projects/Building Lists And Navigation/Complete/Configuration/SampleCode.xcconfig @@ -0,0 +1,13 @@ +// +// See LICENSE folder for this sample’s licensing information. +// +// SampleCode.xcconfig +// + +// The `SAMPLE_CODE_DISAMBIGUATOR` configuration is to make it easier to build +// and run a sample code project. Once you set your project's development team, +// you'll have a unique bundle identifier. This is because the bundle identifier +// is derived based on the 'SAMPLE_CODE_DISAMBIGUATOR' value. Do not use this +// approach in your own projects—it's only useful for sample code projects because +// they are frequently downloaded and don't have a development team set. +SAMPLE_CODE_DISAMBIGUATOR=${DEVELOPMENT_TEAM} diff --git a/Other Projects/Building Lists And Navigation/Complete/LICENSE/LICENSE.txt b/Other Projects/Building Lists And Navigation/Complete/LICENSE/LICENSE.txt new file mode 100644 index 0000000..94e3d54 --- /dev/null +++ b/Other Projects/Building Lists And Navigation/Complete/LICENSE/LICENSE.txt @@ -0,0 +1,8 @@ +Copyright © 2019 Apple Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + diff --git a/Other Projects/Building Lists And Navigation/Complete/Landmarks/BuildingListsAndNavigation.xcodeproj/.xcodesamplecode.plist b/Other Projects/Building Lists And Navigation/Complete/Landmarks/BuildingListsAndNavigation.xcodeproj/.xcodesamplecode.plist new file mode 100644 index 0000000..5dd5da8 --- /dev/null +++ b/Other Projects/Building Lists And Navigation/Complete/Landmarks/BuildingListsAndNavigation.xcodeproj/.xcodesamplecode.plist @@ -0,0 +1,5 @@ + + + + + diff --git a/Other Projects/Building Lists And Navigation/Complete/Landmarks/BuildingListsAndNavigation.xcodeproj/project.pbxproj b/Other Projects/Building Lists And Navigation/Complete/Landmarks/BuildingListsAndNavigation.xcodeproj/project.pbxproj new file mode 100644 index 0000000..0233bf4 --- /dev/null +++ b/Other Projects/Building Lists And Navigation/Complete/Landmarks/BuildingListsAndNavigation.xcodeproj/project.pbxproj @@ -0,0 +1,477 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 50; + objects = { + +/* Begin PBXBuildFile section */ + B7394866229F194000C47603 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7394865229F194000C47603 /* AppDelegate.swift */; }; + B7394868229F194000C47603 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7394867229F194000C47603 /* SceneDelegate.swift */; }; + B739486A229F194000C47603 /* LandmarkDetail.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7394869229F194000C47603 /* LandmarkDetail.swift */; }; + B739486C229F194200C47603 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B739486B229F194200C47603 /* Assets.xcassets */; }; + B739486F229F194200C47603 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B739486E229F194200C47603 /* Preview Assets.xcassets */; }; + B7394872229F194200C47603 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B7394870229F194200C47603 /* LaunchScreen.storyboard */; }; + B739487A229F1B3F00C47603 /* CircleImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7394879229F1B3F00C47603 /* CircleImage.swift */; }; + B739487C229F1B6800C47603 /* MapView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B739487B229F1B6800C47603 /* MapView.swift */; }; + B7394881229F28B900C47603 /* Landmark.swift in Sources */ = {isa = PBXBuildFile; fileRef = B739487F229F28B900C47603 /* Landmark.swift */; }; + B7394882229F28B900C47603 /* Data.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7394880229F28B900C47603 /* Data.swift */; }; + B7394891229F292F00C47603 /* rainbowlake.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B7394884229F292D00C47603 /* rainbowlake.jpg */; }; + B7394892229F292F00C47603 /* yukon_charleyrivers.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B7394885229F292D00C47603 /* yukon_charleyrivers.jpg */; }; + B7394893229F292F00C47603 /* icybay.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B7394886229F292E00C47603 /* icybay.jpg */; }; + B7394894229F292F00C47603 /* lakemcdonald.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B7394887229F292E00C47603 /* lakemcdonald.jpg */; }; + B7394895229F292F00C47603 /* turtlerock.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B7394888229F292E00C47603 /* turtlerock.jpg */; }; + B7394896229F292F00C47603 /* umbagog.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B7394889229F292E00C47603 /* umbagog.jpg */; }; + B7394897229F292F00C47603 /* hiddenlake.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B739488A229F292E00C47603 /* hiddenlake.jpg */; }; + B7394898229F292F00C47603 /* stmarylake.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B739488B229F292E00C47603 /* stmarylake.jpg */; }; + B7394899229F292F00C47603 /* twinlake.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B739488C229F292E00C47603 /* twinlake.jpg */; }; + B739489A229F292F00C47603 /* silversalmoncreek.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B739488D229F292E00C47603 /* silversalmoncreek.jpg */; }; + B739489B229F292F00C47603 /* landmarkData.json in Resources */ = {isa = PBXBuildFile; fileRef = B739488E229F292E00C47603 /* landmarkData.json */; }; + B739489C229F292F00C47603 /* chincoteague.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B739488F229F292F00C47603 /* chincoteague.jpg */; }; + B739489D229F292F00C47603 /* chilkoottrail.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B7394890229F292F00C47603 /* chilkoottrail.jpg */; }; + B739489F229F2D9700C47603 /* LandmarkRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = B739489E229F2D9700C47603 /* LandmarkRow.swift */; }; + B73948A1229F2E1F00C47603 /* LandmarkList.swift in Sources */ = {isa = PBXBuildFile; fileRef = B73948A0229F2E1F00C47603 /* LandmarkList.swift */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 875A65A0875A67A000000001 /* SampleCode.xcconfig */ = {isa = PBXFileReference; name = SampleCode.xcconfig; path = ../Configuration/SampleCode.xcconfig; sourceTree = ""; }; + 875CFFE0875D508000000001 /* LICENSE.txt */ = {isa = PBXFileReference; includeInIndex = 1; path = LICENSE.txt; sourceTree = ""; }; + B7394862229F194000C47603 /* Landmarks.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Landmarks.app; sourceTree = BUILT_PRODUCTS_DIR; }; + B7394865229F194000C47603 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + B7394867229F194000C47603 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; + B7394869229F194000C47603 /* LandmarkDetail.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LandmarkDetail.swift; sourceTree = ""; }; + B739486B229F194200C47603 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + B739486E229F194200C47603 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; + B7394871229F194200C47603 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + B7394873229F194200C47603 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + B7394879229F1B3F00C47603 /* CircleImage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CircleImage.swift; sourceTree = ""; }; + B739487B229F1B6800C47603 /* MapView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapView.swift; sourceTree = ""; }; + B739487F229F28B900C47603 /* Landmark.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Landmark.swift; sourceTree = ""; }; + B7394880229F28B900C47603 /* Data.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Data.swift; sourceTree = ""; }; + B7394884229F292D00C47603 /* rainbowlake.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = rainbowlake.jpg; sourceTree = ""; }; + B7394885229F292D00C47603 /* yukon_charleyrivers.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = yukon_charleyrivers.jpg; sourceTree = ""; }; + B7394886229F292E00C47603 /* icybay.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = icybay.jpg; sourceTree = ""; }; + B7394887229F292E00C47603 /* lakemcdonald.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = lakemcdonald.jpg; sourceTree = ""; }; + B7394888229F292E00C47603 /* turtlerock.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = turtlerock.jpg; sourceTree = ""; }; + B7394889229F292E00C47603 /* umbagog.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = umbagog.jpg; sourceTree = ""; }; + B739488A229F292E00C47603 /* hiddenlake.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = hiddenlake.jpg; sourceTree = ""; }; + B739488B229F292E00C47603 /* stmarylake.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = stmarylake.jpg; sourceTree = ""; }; + B739488C229F292E00C47603 /* twinlake.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = twinlake.jpg; sourceTree = ""; }; + B739488D229F292E00C47603 /* silversalmoncreek.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = silversalmoncreek.jpg; sourceTree = ""; }; + B739488E229F292E00C47603 /* landmarkData.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = landmarkData.json; sourceTree = ""; }; + B739488F229F292F00C47603 /* chincoteague.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = chincoteague.jpg; sourceTree = ""; }; + B7394890229F292F00C47603 /* chilkoottrail.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = chilkoottrail.jpg; sourceTree = ""; }; + B739489E229F2D9700C47603 /* LandmarkRow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = LandmarkRow.swift; path = "Supporting Views/LandmarkRow.swift"; sourceTree = ""; }; + B73948A0229F2E1F00C47603 /* LandmarkList.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LandmarkList.swift; sourceTree = ""; }; + C4E4AAA0C4E4035000000001 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; name = README.md; path = ../README.md; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + B739485F229F194000C47603 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 875A5F80875A5F4000000001 /* Configuration */ = { + isa = PBXGroup; + children = ( + 875A65A0875A67A000000001 /* SampleCode.xcconfig */, + ); + name = Configuration; + sourceTree = ""; + }; + 875D4790875D403000000001 /* LICENSE */ = { + isa = PBXGroup; + children = ( + 875CFFE0875D508000000001 /* LICENSE.txt */, + ); + name = LICENSE; + path = ../LICENSE; + sourceTree = ""; + }; + B7394859229F194000C47603 = { + isa = PBXGroup; + children = ( + C4E4AAA0C4E4035000000001 /* README.md */, + B7394864229F194000C47603 /* Landmarks */, + B7394863229F194000C47603 /* Products */, + 875A5F80875A5F4000000001 /* Configuration */, + 875D4790875D403000000001 /* LICENSE */, + ); + sourceTree = ""; + }; + B7394863229F194000C47603 /* Products */ = { + isa = PBXGroup; + children = ( + B7394862229F194000C47603 /* Landmarks.app */, + ); + name = Products; + sourceTree = ""; + }; + B7394864229F194000C47603 /* Landmarks */ = { + isa = PBXGroup; + children = ( + B739487E229F282200C47603 /* Models */, + B7394865229F194000C47603 /* AppDelegate.swift */, + B7394867229F194000C47603 /* SceneDelegate.swift */, + B73948A0229F2E1F00C47603 /* LandmarkList.swift */, + B739489E229F2D9700C47603 /* LandmarkRow.swift */, + B7394869229F194000C47603 /* LandmarkDetail.swift */, + B739487D229F1C0100C47603 /* Supporting Views */, + B7394883229F291A00C47603 /* Resources */, + B739486B229F194200C47603 /* Assets.xcassets */, + B7394870229F194200C47603 /* LaunchScreen.storyboard */, + B7394873229F194200C47603 /* Info.plist */, + B739486D229F194200C47603 /* Preview Content */, + ); + path = Landmarks; + sourceTree = ""; + }; + B739486D229F194200C47603 /* Preview Content */ = { + isa = PBXGroup; + children = ( + B739486E229F194200C47603 /* Preview Assets.xcassets */, + ); + path = "Preview Content"; + sourceTree = ""; + }; + B739487D229F1C0100C47603 /* Supporting Views */ = { + isa = PBXGroup; + children = ( + B7394879229F1B3F00C47603 /* CircleImage.swift */, + B739487B229F1B6800C47603 /* MapView.swift */, + ); + path = "Supporting Views"; + sourceTree = ""; + }; + B739487E229F282200C47603 /* Models */ = { + isa = PBXGroup; + children = ( + B7394880229F28B900C47603 /* Data.swift */, + B739487F229F28B900C47603 /* Landmark.swift */, + ); + path = Models; + sourceTree = ""; + }; + B7394883229F291A00C47603 /* Resources */ = { + isa = PBXGroup; + children = ( + B739488E229F292E00C47603 /* landmarkData.json */, + B7394890229F292F00C47603 /* chilkoottrail.jpg */, + B739488F229F292F00C47603 /* chincoteague.jpg */, + B739488A229F292E00C47603 /* hiddenlake.jpg */, + B7394886229F292E00C47603 /* icybay.jpg */, + B7394887229F292E00C47603 /* lakemcdonald.jpg */, + B7394884229F292D00C47603 /* rainbowlake.jpg */, + B739488D229F292E00C47603 /* silversalmoncreek.jpg */, + B739488B229F292E00C47603 /* stmarylake.jpg */, + B7394888229F292E00C47603 /* turtlerock.jpg */, + B739488C229F292E00C47603 /* twinlake.jpg */, + B7394889229F292E00C47603 /* umbagog.jpg */, + B7394885229F292D00C47603 /* yukon_charleyrivers.jpg */, + ); + path = Resources; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + B7394861229F194000C47603 /* Landmarks */ = { + isa = PBXNativeTarget; + buildConfigurationList = B7394876229F194200C47603 /* Build configuration list for PBXNativeTarget "Landmarks" */; + buildPhases = ( + B739485E229F194000C47603 /* Sources */, + B739485F229F194000C47603 /* Frameworks */, + B7394860229F194000C47603 /* Resources */, + C602AC70C605937000000001, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Landmarks; + productName = Landmarks; + productReference = B7394862229F194000C47603 /* Landmarks.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + B739485A229F194000C47603 /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 1100; + LastUpgradeCheck = 1100; + ORGANIZATIONNAME = Apple; + TargetAttributes = { + B7394861229F194000C47603 = { + CreatedOnToolsVersion = 11.0; + }; + }; + }; + buildConfigurationList = B739485D229F194000C47603 /* Build configuration list for PBXProject "BuildingListsAndNavigation" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = B7394859229F194000C47603; + productRefGroup = B7394863229F194000C47603 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + B7394861229F194000C47603 /* Landmarks */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + B7394860229F194000C47603 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + B739489A229F292F00C47603 /* silversalmoncreek.jpg in Resources */, + B7394894229F292F00C47603 /* lakemcdonald.jpg in Resources */, + B7394872229F194200C47603 /* LaunchScreen.storyboard in Resources */, + B7394891229F292F00C47603 /* rainbowlake.jpg in Resources */, + B739486F229F194200C47603 /* Preview Assets.xcassets in Resources */, + B7394895229F292F00C47603 /* turtlerock.jpg in Resources */, + B739486C229F194200C47603 /* Assets.xcassets in Resources */, + B7394899229F292F00C47603 /* twinlake.jpg in Resources */, + B7394896229F292F00C47603 /* umbagog.jpg in Resources */, + B739489D229F292F00C47603 /* chilkoottrail.jpg in Resources */, + B739489C229F292F00C47603 /* chincoteague.jpg in Resources */, + B739489B229F292F00C47603 /* landmarkData.json in Resources */, + B7394893229F292F00C47603 /* icybay.jpg in Resources */, + B7394897229F292F00C47603 /* hiddenlake.jpg in Resources */, + B7394898229F292F00C47603 /* stmarylake.jpg in Resources */, + B7394892229F292F00C47603 /* yukon_charleyrivers.jpg in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + B739485E229F194000C47603 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + B7394882229F28B900C47603 /* Data.swift in Sources */, + B7394866229F194000C47603 /* AppDelegate.swift in Sources */, + B739487A229F1B3F00C47603 /* CircleImage.swift in Sources */, + B739487C229F1B6800C47603 /* MapView.swift in Sources */, + B73948A1229F2E1F00C47603 /* LandmarkList.swift in Sources */, + B7394868229F194000C47603 /* SceneDelegate.swift in Sources */, + B739486A229F194000C47603 /* LandmarkDetail.swift in Sources */, + B739489F229F2D9700C47603 /* LandmarkRow.swift in Sources */, + B7394881229F28B900C47603 /* Landmark.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + B7394870229F194200C47603 /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + B7394871229F194200C47603 /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + B7394874229F194200C47603 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 875A65A0875A67A000000001 /* SampleCode.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + B7394875229F194200C47603 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 875A65A0875A67A000000001 /* SampleCode.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + B7394877229F194200C47603 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 875A65A0875A67A000000001 /* SampleCode.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_ASSET_PATHS = "Landmarks/Preview\\ Content"; + DEVELOPMENT_TEAM = ""; + ENABLE_PREVIEWS = YES; + INFOPLIST_FILE = Landmarks/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = "com.example.apple-samplecode.Landmarks${SAMPLE_CODE_DISAMBIGUATOR}"; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + B7394878229F194200C47603 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 875A65A0875A67A000000001 /* SampleCode.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_ASSET_PATHS = "Landmarks/Preview\\ Content"; + DEVELOPMENT_TEAM = ""; + ENABLE_PREVIEWS = YES; + INFOPLIST_FILE = Landmarks/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = "com.example.apple-samplecode.Landmarks${SAMPLE_CODE_DISAMBIGUATOR}"; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + B739485D229F194000C47603 /* Build configuration list for PBXProject "BuildingListsAndNavigation" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + B7394874229F194200C47603 /* Debug */, + B7394875229F194200C47603 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + B7394876229F194200C47603 /* Build configuration list for PBXNativeTarget "Landmarks" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + B7394877229F194200C47603 /* Debug */, + B7394878229F194200C47603 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = B739485A229F194000C47603 /* Project object */; +} diff --git a/Other Projects/Building Lists And Navigation/Complete/Landmarks/BuildingListsAndNavigation.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/Other Projects/Building Lists And Navigation/Complete/Landmarks/BuildingListsAndNavigation.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 0000000..3ddf867 --- /dev/null +++ b/Other Projects/Building Lists And Navigation/Complete/Landmarks/BuildingListsAndNavigation.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,8 @@ + + + + + BuildSystemType + Latest + + diff --git a/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/AppDelegate.swift b/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/AppDelegate.swift new file mode 100644 index 0000000..e22943b --- /dev/null +++ b/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/AppDelegate.swift @@ -0,0 +1,36 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +The application delegate. +*/ + +import UIKit + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { + // Override point for customization after application launch. + return true + } + + func applicationWillTerminate(_ application: UIApplication) { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. + } + + // MARK: UISceneSession Lifecycle + func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration { + // Called when a new scene session is being created. + // Use this method to select a configuration to create the new scene with. + return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role) + } + + func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) { + // Called when the user discards a scene session. + // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions. + // Use this method to release any resources that were specific to the discarded scenes, as they will not return. + } + +} + diff --git a/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/Contents.json b/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..6ab6c31 --- /dev/null +++ b/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,112 @@ +{ + "images" : [ + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "landmark_app_icon_40x40.png", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "3x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "landmark_app_icon_58x58.png", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "landmark_app_icon_87x87.png", + "scale" : "3x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "landmark_app_icon_80x80.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "landmark_app_icon_120x120.png", + "scale" : "3x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "landmark_app_icon_120x120-1.png", + "scale" : "2x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "landmark_app_icon_180x180.png", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "1x" + }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "landmark_app_icon_40x40-1.png", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "landmark_app_icon_58x58-1.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "landmark_app_icon_40x40-2.png", + "scale" : "1x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "landmark_app_icon_80x80-1.png", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "1x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "landmark_app_icon_152x152.png", + "scale" : "2x" + }, + { + "size" : "83.5x83.5", + "idiom" : "ipad", + "filename" : "landmark_app_icon_167x167.png", + "scale" : "2x" + }, + { + "size" : "1024x1024", + "idiom" : "ios-marketing", + "filename" : "landmark_app_icon_1024x1024.png", + "scale" : "1x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_1024x1024.png b/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_1024x1024.png new file mode 100644 index 0000000..00d81c1 Binary files /dev/null and b/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_1024x1024.png differ diff --git a/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_120x120-1.png b/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_120x120-1.png new file mode 100644 index 0000000..d382b8b Binary files /dev/null and b/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_120x120-1.png differ diff --git a/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_120x120.png b/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_120x120.png new file mode 100644 index 0000000..d382b8b Binary files /dev/null and b/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_120x120.png differ diff --git a/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_152x152.png b/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_152x152.png new file mode 100644 index 0000000..11057f8 Binary files /dev/null and b/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_152x152.png differ diff --git a/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_167x167.png b/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_167x167.png new file mode 100644 index 0000000..f73bc26 Binary files /dev/null and b/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_167x167.png differ diff --git a/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_180x180.png b/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_180x180.png new file mode 100644 index 0000000..b02738c Binary files /dev/null and b/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_180x180.png differ diff --git a/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40-1.png b/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40-1.png new file mode 100644 index 0000000..abaff0e Binary files /dev/null and b/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40-1.png differ diff --git a/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40-2.png b/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40-2.png new file mode 100644 index 0000000..abaff0e Binary files /dev/null and b/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40-2.png differ diff --git a/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40.png b/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40.png new file mode 100644 index 0000000..abaff0e Binary files /dev/null and b/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40.png differ diff --git a/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_58x58-1.png b/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_58x58-1.png new file mode 100644 index 0000000..cf7c73d Binary files /dev/null and b/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_58x58-1.png differ diff --git a/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_58x58.png b/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_58x58.png new file mode 100644 index 0000000..cf7c73d Binary files /dev/null and b/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_58x58.png differ diff --git a/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_80x80-1.png b/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_80x80-1.png new file mode 100644 index 0000000..6f33f66 Binary files /dev/null and b/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_80x80-1.png differ diff --git a/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_80x80.png b/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_80x80.png new file mode 100644 index 0000000..6f33f66 Binary files /dev/null and b/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_80x80.png differ diff --git a/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_87x87.png b/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_87x87.png new file mode 100644 index 0000000..9e1616c Binary files /dev/null and b/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_87x87.png differ diff --git a/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/Assets.xcassets/Contents.json b/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/Assets.xcassets/turtlerock.imageset/Contents.json b/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/Assets.xcassets/turtlerock.imageset/Contents.json new file mode 100644 index 0000000..5bfd7bf --- /dev/null +++ b/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/Assets.xcassets/turtlerock.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "turtlerock.jpg", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/Assets.xcassets/turtlerock.imageset/turtlerock.jpg b/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/Assets.xcassets/turtlerock.imageset/turtlerock.jpg new file mode 100644 index 0000000..68bcd3e Binary files /dev/null and b/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/Assets.xcassets/turtlerock.imageset/turtlerock.jpg differ diff --git a/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/Base.lproj/LaunchScreen.storyboard b/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000..865e932 --- /dev/null +++ b/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/Info.plist b/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/Info.plist new file mode 100644 index 0000000..e8bb4c6 --- /dev/null +++ b/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/Info.plist @@ -0,0 +1,62 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + $(PRODUCT_BUNDLE_PACKAGE_TYPE) + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UIApplicationSceneManifest + + UIApplicationSupportsMultipleScenes + + UISceneConfigurations + + UIWindowSceneSessionRoleApplication + + + UILaunchStoryboardName + LaunchScreen + UISceneConfigurationName + Default Configuration + UISceneDelegateClassName + $(PRODUCT_MODULE_NAME).SceneDelegate + + + + + UILaunchStoryboardName + LaunchScreen + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/LandmarkDetail.swift b/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/LandmarkDetail.swift new file mode 100644 index 0000000..e957172 --- /dev/null +++ b/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/LandmarkDetail.swift @@ -0,0 +1,48 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A view showing the details for a landmark. +*/ + +import SwiftUI + +struct LandmarkDetail: View { + var landmark: Landmark + + var body: some View { + VStack { + MapView(coordinate: landmark.locationCoordinate) + .frame(height: 300) + + CircleImage(image: landmark.image(forSize: 250)) + .offset(x: 0, y: -130) + .padding(.bottom, -130) + + VStack(alignment: .leading) { + Text(landmark.name) + .font(.title) + + HStack(alignment: .top) { + Text(landmark.park) + .font(.subheadline) + Spacer() + Text(landmark.state) + .font(.subheadline) + } + } + .padding() + + Spacer() + } + .navigationBarTitle(Text(verbatim: landmark.name), displayMode: .inline) + } +} + +#if DEBUG +struct LandmarkDetail_Previews: PreviewProvider { + static var previews: some View { + LandmarkDetail(landmark: landmarkData[0]) + } +} +#endif diff --git a/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/LandmarkList.swift b/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/LandmarkList.swift new file mode 100644 index 0000000..35592d5 --- /dev/null +++ b/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/LandmarkList.swift @@ -0,0 +1,33 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A view showing a list of landmarks. +*/ + +import SwiftUI + +struct LandmarkList: View { + var body: some View { + NavigationView { + List(landmarkData) { landmark in + NavigationLink(destination: LandmarkDetail(landmark: landmark)) { + LandmarkRow(landmark: landmark) + } + } + .navigationBarTitle(Text("Landmarks"), displayMode: .large) + } + } +} + +#if DEBUG +struct LandmarkList_Previews: PreviewProvider { + static var previews: some View { + ForEach(["iPhone SE", "iPhone XS Max"], id: \.self) { deviceName in + LandmarkList() + .previewDevice(PreviewDevice(rawValue: deviceName)) + .previewDisplayName(deviceName) + } + } +} +#endif diff --git a/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/Models/Data.swift b/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/Models/Data.swift new file mode 100644 index 0000000..7248384 --- /dev/null +++ b/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/Models/Data.swift @@ -0,0 +1,93 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +Helpers for loading images and data. +*/ + +import UIKit +import SwiftUI +import CoreLocation + +let landmarkData: [Landmark] = load("landmarkData.json") + +func load(_ filename: String, as type: T.Type = T.self) -> T { + let data: Data + + guard let file = Bundle.main.url(forResource: filename, withExtension: nil) + else { + fatalError("Couldn't find \(filename) in main bundle.") + } + + do { + data = try Data(contentsOf: file) + } catch { + fatalError("Couldn't load \(filename) from main bundle:\n\(error)") + } + + do { + let decoder = JSONDecoder() + return try decoder.decode(T.self, from: data) + } catch { + fatalError("Couldn't parse \(filename) as \(T.self):\n\(error)") + } +} + +final class ImageStore { + fileprivate typealias _ImageDictionary = [String: [Int: CGImage]] + fileprivate var images: _ImageDictionary = [:] + + fileprivate static var originalSize = 250 + fileprivate static var scale = 2 + + static var shared = ImageStore() + + func image(name: String, size: Int) -> Image { + let index = _guaranteeInitialImage(name: name) + + let sizedImage = images.values[index][size] + ?? _sizeImage(images.values[index][ImageStore.originalSize]!, to: size * ImageStore.scale) + images.values[index][size] = sizedImage + + return Image(sizedImage, scale: CGFloat(ImageStore.scale), label: Text(verbatim: name)) + } + + fileprivate func _guaranteeInitialImage(name: String) -> _ImageDictionary.Index { + if let index = images.index(forKey: name) { return index } + + guard + let url = Bundle.main.url(forResource: name, withExtension: "jpg"), + let imageSource = CGImageSourceCreateWithURL(url as NSURL, nil), + let image = CGImageSourceCreateImageAtIndex(imageSource, 0, nil) + else { + fatalError("Couldn't load image \(name).jpg from main bundle.") + } + + images[name] = [ImageStore.originalSize: image] + return images.index(forKey: name)! + } + + fileprivate func _sizeImage(_ image: CGImage, to size: Int) -> CGImage { + guard + let colorSpace = image.colorSpace, + let context = CGContext( + data: nil, + width: size, height: size, + bitsPerComponent: image.bitsPerComponent, + bytesPerRow: image.bytesPerRow, + space: colorSpace, + bitmapInfo: image.bitmapInfo.rawValue) + else { + fatalError("Couldn't create graphics context.") + } + context.interpolationQuality = .high + context.draw(image, in: CGRect(x: 0, y: 0, width: size, height: size)) + + if let sizedImage = context.makeImage() { + return sizedImage + } else { + fatalError("Couldn't resize image.") + } + } +} + diff --git a/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/Models/Landmark.swift b/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/Models/Landmark.swift new file mode 100644 index 0000000..f0be98d --- /dev/null +++ b/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/Models/Landmark.swift @@ -0,0 +1,40 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +The model for an individual landmark. +*/ + +import SwiftUI +import CoreLocation + +struct Landmark: Hashable, Codable, Identifiable { + var id: Int + var name: String + fileprivate var imageName: String + fileprivate var coordinates: Coordinates + var state: String + var park: String + var category: Category + + var locationCoordinate: CLLocationCoordinate2D { + CLLocationCoordinate2D( + latitude: coordinates.latitude, + longitude: coordinates.longitude) + } + + func image(forSize size: Int) -> Image { + ImageStore.shared.image(name: imageName, size: size) + } + + enum Category: String, CaseIterable, Codable, Hashable { + case featured = "Featured" + case lakes = "Lakes" + case rivers = "Rivers" + } +} + +struct Coordinates: Hashable, Codable { + var latitude: Double + var longitude: Double +} diff --git a/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/Preview Content/Preview Assets.xcassets/Contents.json b/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/Preview Content/Preview Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/Preview Content/Preview Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/Resources/chilkoottrail.jpg b/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/Resources/chilkoottrail.jpg new file mode 100644 index 0000000..e7f805e Binary files /dev/null and b/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/Resources/chilkoottrail.jpg differ diff --git a/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/Resources/chincoteague.jpg b/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/Resources/chincoteague.jpg new file mode 100644 index 0000000..5f47986 Binary files /dev/null and b/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/Resources/chincoteague.jpg differ diff --git a/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/Resources/hiddenlake.jpg b/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/Resources/hiddenlake.jpg new file mode 100644 index 0000000..d8e804c Binary files /dev/null and b/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/Resources/hiddenlake.jpg differ diff --git a/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/Resources/icybay.jpg b/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/Resources/icybay.jpg new file mode 100644 index 0000000..feb1764 Binary files /dev/null and b/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/Resources/icybay.jpg differ diff --git a/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/Resources/lakemcdonald.jpg b/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/Resources/lakemcdonald.jpg new file mode 100644 index 0000000..bd9d6b9 Binary files /dev/null and b/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/Resources/lakemcdonald.jpg differ diff --git a/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/Resources/landmarkData.json b/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/Resources/landmarkData.json new file mode 100644 index 0000000..01a9691 --- /dev/null +++ b/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/Resources/landmarkData.json @@ -0,0 +1,158 @@ +[ + { + "name": "Turtle Rock", + "category": "Featured", + "city": "Twentynine Palms", + "state": "California", + "id": 1001, + "park": "Joshua Tree National Park", + "coordinates": { + "longitude": -116.166868, + "latitude": 34.011286 + }, + "imageName": "turtlerock" + }, + { + "name": "Silver Salmon Creek", + "category": "Lakes", + "city": "Port Alsworth", + "state": "Alaska", + "id": 4, + "park": "Lake Clark National Park and Preserve", + "coordinates": { + "longitude": -152.665167, + "latitude": 59.980167 + }, + "imageName": "silversalmoncreek" + }, + { + "name": "Chilkoot Trail", + "category": "Rivers", + "city": "Skagway", + "state": "Alaska", + "id": 5, + "park": "Klondike Gold Rush National Historical Park", + "coordinates": { + "longitude": -135.334571, + "latitude": 59.560551 + }, + "imageName": "chilkoottrail" + }, + { + "name": "St. Mary Lake", + "category": "Lakes", + "city": "Browning", + "state": "Montana", + "id": 8, + "park": "Glacier National Park", + "coordinates": { + "longitude": -113.536248, + "latitude": 48.69423 + }, + "imageName": "stmarylake" + }, + { + "name": "Twin Lake", + "category": "Lakes", + "city": "Twin Lakes", + "state": "Alaska", + "id": 11, + "park": "Lake Clark National Park and Preserve", + "coordinates": { + "longitude": -153.849883, + "latitude": 60.641684 + }, + "imageName": "twinlake" + }, + { + "name": "Lake McDonald", + "category": "Lakes", + "city": "West Glacier", + "state": "Montana", + "id": 6, + "park": "Glacier National Park", + "coordinates": { + "longitude": -113.934831, + "latitude": 48.56002 + }, + "imageName": "lakemcdonald" + }, + { + "name": "Charley Rivers", + "category": "Rivers", + "city": "Eaking", + "state": "Alaska", + "id": 1, + "park": "Charley Rivers National Preserve", + "coordinates": { + "longitude": -143.122586, + "latitude": 65.350021 + }, + "imageName": "yukon_charleyrivers" + }, + { + "name": "Icy Bay", + "category": "Lakes", + "city": "Icy Bay", + "state": "Alaska", + "id": 2, + "park": "Wrangell-St. Elias National Park and Preserve", + "coordinates": { + "longitude": -141.518167, + "latitude": 60.089917 + }, + "imageName": "icybay" + }, + { + "name": "Rainbow Lake", + "category": "Lakes", + "city": "Willow", + "state": "Alaska", + "id": 3, + "park": "State Recreation Area", + "coordinates": { + "longitude": -150.086103, + "latitude": 61.694334 + }, + "imageName": "rainbowlake" + }, + { + "name": "Hidden Lake", + "category": "Lakes", + "city": "Newhalem", + "state": "Washington", + "id": 7, + "park": "North Cascades National Park", + "coordinates": { + "longitude": -121.17799, + "latitude": 48.495442 + }, + "imageName": "hiddenlake" + }, + { + "name": "Chincoteague", + "category": "Rivers", + "city": "Chincoteague", + "state": "Virginia", + "id": 9, + "park": "Chincoteague National Wildlife Refuge", + "coordinates": { + "longitude": -75.383212, + "latitude": 37.91531 + }, + "imageName": "chincoteague" + }, + { + "name": "Lake Umbagog", + "category": "Lakes", + "city": "Errol", + "state": "New Hampshire", + "id": 10, + "park": "Umbagog National Wildlife Refuge", + "coordinates": { + "longitude": -71.056816, + "latitude": 44.747408 + }, + "imageName": "umbagog" + } +] diff --git a/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/Resources/rainbowlake.jpg b/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/Resources/rainbowlake.jpg new file mode 100644 index 0000000..6da43dd Binary files /dev/null and b/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/Resources/rainbowlake.jpg differ diff --git a/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/Resources/silversalmoncreek.jpg b/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/Resources/silversalmoncreek.jpg new file mode 100644 index 0000000..f657532 Binary files /dev/null and b/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/Resources/silversalmoncreek.jpg differ diff --git a/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/Resources/stmarylake.jpg b/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/Resources/stmarylake.jpg new file mode 100644 index 0000000..1c71de4 Binary files /dev/null and b/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/Resources/stmarylake.jpg differ diff --git a/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/Resources/turtlerock.jpg b/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/Resources/turtlerock.jpg new file mode 100644 index 0000000..f7a6e6d Binary files /dev/null and b/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/Resources/turtlerock.jpg differ diff --git a/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/Resources/twinlake.jpg b/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/Resources/twinlake.jpg new file mode 100644 index 0000000..3e7a57c Binary files /dev/null and b/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/Resources/twinlake.jpg differ diff --git a/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/Resources/umbagog.jpg b/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/Resources/umbagog.jpg new file mode 100644 index 0000000..56291c6 Binary files /dev/null and b/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/Resources/umbagog.jpg differ diff --git a/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/Resources/yukon_charleyrivers.jpg b/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/Resources/yukon_charleyrivers.jpg new file mode 100644 index 0000000..17ff44b Binary files /dev/null and b/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/Resources/yukon_charleyrivers.jpg differ diff --git a/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/SceneDelegate.swift b/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/SceneDelegate.swift new file mode 100644 index 0000000..8695ad0 --- /dev/null +++ b/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/SceneDelegate.swift @@ -0,0 +1,58 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +The scene delegate. +*/ + +import UIKit +import SwiftUI + +class SceneDelegate: UIResponder, UIWindowSceneDelegate { + + var window: UIWindow? + + func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { + // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`. + // If using a storyboard, the `window` property will automatically be initialized and attached to the scene. + // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead). + + // Use a UIHostingController as window root view controller + if let windowScene = scene as? UIWindowScene { + let window = UIWindow(windowScene: windowScene) + window.rootViewController = UIHostingController(rootView: LandmarkList()) + self.window = window + window.makeKeyAndVisible() + } + } + + func sceneDidDisconnect(_ scene: UIScene) { + // Called as the scene is being released by the system. + // This occurs shortly after the scene enters the background, or when its session is discarded. + // Release any resources associated with this scene that can be re-created the next time the scene connects. + // The scene may re-connect later, as its session was not neccessarily discarded (see `application:didDiscardSceneSessions` instead). + } + + func sceneDidBecomeActive(_ scene: UIScene) { + // Called when the scene has moved from an inactive state to an active state. + // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive. + } + + func sceneWillResignActive(_ scene: UIScene) { + // Called when the scene will move from an active state to an inactive state. + // This may occur due to temporary interruptions (ex. an incoming phone call). + } + + func sceneWillEnterForeground(_ scene: UIScene) { + // Called as the scene transitions from the background to the foreground. + // Use this method to undo the changes made on entering the background. + } + + func sceneDidEnterBackground(_ scene: UIScene) { + // Called as the scene transitions from the foreground to the background. + // Use this method to save data, release shared resources, and store enough scene-specific state information + // to restore the scene back to its current state. + } + +} + diff --git a/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/Supporting Views/CircleImage.swift b/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/Supporting Views/CircleImage.swift new file mode 100644 index 0000000..ae44439 --- /dev/null +++ b/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/Supporting Views/CircleImage.swift @@ -0,0 +1,27 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A view that clips an image to a circle and adds a stroke and shadow. +*/ + +import SwiftUI + +struct CircleImage: View { + var image: Image + + var body: some View { + image + .clipShape(Circle()) + .overlay(Circle().stroke(Color.white, lineWidth: 4)) + .shadow(radius: 10) + } +} + +#if DEBUG +struct CircleImage_Previews: PreviewProvider { + static var previews: some View { + CircleImage(image: Image("turtlerock")) + } +} +#endif diff --git a/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/Supporting Views/LandmarkRow.swift b/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/Supporting Views/LandmarkRow.swift new file mode 100644 index 0000000..6a59563 --- /dev/null +++ b/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/Supporting Views/LandmarkRow.swift @@ -0,0 +1,32 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A single row to be displayed in a list of landmarks. +*/ + +import SwiftUI + +struct LandmarkRow: View { + var landmark: Landmark + + var body: some View { + HStack { + landmark.image(forSize: 50) + Text(verbatim: landmark.name) + Spacer() + } + } +} + +#if DEBUG +struct LandmarkRow_Previews: PreviewProvider { + static var previews: some View { + Group { + LandmarkRow(landmark: landmarkData[0]) + LandmarkRow(landmark: landmarkData[1]) + } + .previewLayout(.fixed(width: 300, height: 70)) + } +} +#endif diff --git a/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/Supporting Views/MapView.swift b/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/Supporting Views/MapView.swift new file mode 100644 index 0000000..5a8c64b --- /dev/null +++ b/Other Projects/Building Lists And Navigation/Complete/Landmarks/Landmarks/Supporting Views/MapView.swift @@ -0,0 +1,31 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A view that hosts an `MKMapView`. +*/ + +import SwiftUI +import MapKit + +struct MapView: UIViewRepresentable { + var coordinate: CLLocationCoordinate2D + + func makeUIView(context: Context) -> MKMapView { + MKMapView(frame: .zero) + } + + func updateUIView(_ view: MKMapView, context: Context) { + let span = MKCoordinateSpan(latitudeDelta: 0.02, longitudeDelta: 0.02) + let region = MKCoordinateRegion(center: coordinate, span: span) + view.setRegion(region, animated: true) + } +} + +#if DEBUG +struct MapView_Previews: PreviewProvider { + static var previews: some View { + MapView(coordinate: landmarkData[0].locationCoordinate) + } +} +#endif diff --git a/Other Projects/Building Lists And Navigation/Complete/README.md b/Other Projects/Building Lists And Navigation/Complete/README.md new file mode 100644 index 0000000..929abe6 --- /dev/null +++ b/Other Projects/Building Lists And Navigation/Complete/README.md @@ -0,0 +1,3 @@ +# Completed Project: Building Lists and Navigation + +Explore the completed project for the [Building Lists and Navigation](https://developer.apple.com/tutorials/swiftui/building-lists-and-navigation) tutorial. diff --git a/Other Projects/Building Lists And Navigation/StartingPoint/.gitignore b/Other Projects/Building Lists And Navigation/StartingPoint/.gitignore new file mode 100644 index 0000000..9e50718 --- /dev/null +++ b/Other Projects/Building Lists And Navigation/StartingPoint/.gitignore @@ -0,0 +1,21 @@ +# See LICENSE folder for this sample’s licensing information. +# +# Apple sample code gitignore configuration. + +# Finder +.DS_Store + +# Xcode - User files +xcuserdata/ + +**/*.xcodeproj/project.xcworkspace/* +!**/*.xcodeproj/project.xcworkspace/xcshareddata + +**/*.xcodeproj/project.xcworkspace/xcshareddata/* +!**/*.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings + +**/*.playground/playground.xcworkspace/* +!**/*.playground/playground.xcworkspace/xcshareddata + +**/*.playground/playground.xcworkspace/xcshareddata/* +!**/*.playground/playground.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings diff --git a/Other Projects/Building Lists And Navigation/StartingPoint/Configuration/SampleCode.xcconfig b/Other Projects/Building Lists And Navigation/StartingPoint/Configuration/SampleCode.xcconfig new file mode 100644 index 0000000..db86c06 --- /dev/null +++ b/Other Projects/Building Lists And Navigation/StartingPoint/Configuration/SampleCode.xcconfig @@ -0,0 +1,13 @@ +// +// See LICENSE folder for this sample’s licensing information. +// +// SampleCode.xcconfig +// + +// The `SAMPLE_CODE_DISAMBIGUATOR` configuration is to make it easier to build +// and run a sample code project. Once you set your project's development team, +// you'll have a unique bundle identifier. This is because the bundle identifier +// is derived based on the 'SAMPLE_CODE_DISAMBIGUATOR' value. Do not use this +// approach in your own projects—it's only useful for sample code projects because +// they are frequently downloaded and don't have a development team set. +SAMPLE_CODE_DISAMBIGUATOR=${DEVELOPMENT_TEAM} diff --git a/Other Projects/Building Lists And Navigation/StartingPoint/LICENSE/LICENSE.txt b/Other Projects/Building Lists And Navigation/StartingPoint/LICENSE/LICENSE.txt new file mode 100644 index 0000000..94e3d54 --- /dev/null +++ b/Other Projects/Building Lists And Navigation/StartingPoint/LICENSE/LICENSE.txt @@ -0,0 +1,8 @@ +Copyright © 2019 Apple Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + diff --git a/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/BuildingListsAndNavigation.xcodeproj/.xcodesamplecode.plist b/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/BuildingListsAndNavigation.xcodeproj/.xcodesamplecode.plist new file mode 100644 index 0000000..5dd5da8 --- /dev/null +++ b/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/BuildingListsAndNavigation.xcodeproj/.xcodesamplecode.plist @@ -0,0 +1,5 @@ + + + + + diff --git a/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/BuildingListsAndNavigation.xcodeproj/project.pbxproj b/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/BuildingListsAndNavigation.xcodeproj/project.pbxproj new file mode 100644 index 0000000..4d4bd47 --- /dev/null +++ b/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/BuildingListsAndNavigation.xcodeproj/project.pbxproj @@ -0,0 +1,469 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 50; + objects = { + +/* Begin PBXBuildFile section */ + B7394866229F194000C47603 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7394865229F194000C47603 /* AppDelegate.swift */; }; + B7394868229F194000C47603 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7394867229F194000C47603 /* SceneDelegate.swift */; }; + B739486A229F194000C47603 /* LandmarkDetail.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7394869229F194000C47603 /* LandmarkDetail.swift */; }; + B739486C229F194200C47603 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B739486B229F194200C47603 /* Assets.xcassets */; }; + B739486F229F194200C47603 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B739486E229F194200C47603 /* Preview Assets.xcassets */; }; + B7394872229F194200C47603 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B7394870229F194200C47603 /* LaunchScreen.storyboard */; }; + B739487A229F1B3F00C47603 /* CircleImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7394879229F1B3F00C47603 /* CircleImage.swift */; }; + B739487C229F1B6800C47603 /* MapView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B739487B229F1B6800C47603 /* MapView.swift */; }; + B7394881229F28B900C47603 /* Landmark.swift in Sources */ = {isa = PBXBuildFile; fileRef = B739487F229F28B900C47603 /* Landmark.swift */; }; + B7394882229F28B900C47603 /* Data.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7394880229F28B900C47603 /* Data.swift */; }; + B7394891229F292F00C47603 /* rainbowlake.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B7394884229F292D00C47603 /* rainbowlake.jpg */; }; + B7394892229F292F00C47603 /* yukon_charleyrivers.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B7394885229F292D00C47603 /* yukon_charleyrivers.jpg */; }; + B7394893229F292F00C47603 /* icybay.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B7394886229F292E00C47603 /* icybay.jpg */; }; + B7394894229F292F00C47603 /* lakemcdonald.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B7394887229F292E00C47603 /* lakemcdonald.jpg */; }; + B7394895229F292F00C47603 /* turtlerock.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B7394888229F292E00C47603 /* turtlerock.jpg */; }; + B7394896229F292F00C47603 /* umbagog.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B7394889229F292E00C47603 /* umbagog.jpg */; }; + B7394897229F292F00C47603 /* hiddenlake.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B739488A229F292E00C47603 /* hiddenlake.jpg */; }; + B7394898229F292F00C47603 /* stmarylake.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B739488B229F292E00C47603 /* stmarylake.jpg */; }; + B7394899229F292F00C47603 /* twinlake.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B739488C229F292E00C47603 /* twinlake.jpg */; }; + B739489A229F292F00C47603 /* silversalmoncreek.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B739488D229F292E00C47603 /* silversalmoncreek.jpg */; }; + B739489B229F292F00C47603 /* landmarkData.json in Resources */ = {isa = PBXBuildFile; fileRef = B739488E229F292E00C47603 /* landmarkData.json */; }; + B739489C229F292F00C47603 /* chincoteague.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B739488F229F292F00C47603 /* chincoteague.jpg */; }; + B739489D229F292F00C47603 /* chilkoottrail.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B7394890229F292F00C47603 /* chilkoottrail.jpg */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + B7394862229F194000C47603 /* Landmarks.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Landmarks.app; sourceTree = BUILT_PRODUCTS_DIR; }; + B7394865229F194000C47603 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + B7394867229F194000C47603 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; + B7394869229F194000C47603 /* LandmarkDetail.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LandmarkDetail.swift; sourceTree = ""; }; + B739486B229F194200C47603 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + B739486E229F194200C47603 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; + B7394871229F194200C47603 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + B7394873229F194200C47603 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + B7394879229F1B3F00C47603 /* CircleImage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CircleImage.swift; sourceTree = ""; }; + B739487B229F1B6800C47603 /* MapView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapView.swift; sourceTree = ""; }; + B739487F229F28B900C47603 /* Landmark.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Landmark.swift; sourceTree = ""; }; + B7394880229F28B900C47603 /* Data.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Data.swift; sourceTree = ""; }; + B7394884229F292D00C47603 /* rainbowlake.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = rainbowlake.jpg; sourceTree = ""; }; + B7394885229F292D00C47603 /* yukon_charleyrivers.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = yukon_charleyrivers.jpg; sourceTree = ""; }; + B7394886229F292E00C47603 /* icybay.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = icybay.jpg; sourceTree = ""; }; + B7394887229F292E00C47603 /* lakemcdonald.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = lakemcdonald.jpg; sourceTree = ""; }; + B7394888229F292E00C47603 /* turtlerock.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = turtlerock.jpg; sourceTree = ""; }; + B7394889229F292E00C47603 /* umbagog.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = umbagog.jpg; sourceTree = ""; }; + B739488A229F292E00C47603 /* hiddenlake.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = hiddenlake.jpg; sourceTree = ""; }; + B739488B229F292E00C47603 /* stmarylake.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = stmarylake.jpg; sourceTree = ""; }; + B739488C229F292E00C47603 /* twinlake.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = twinlake.jpg; sourceTree = ""; }; + B739488D229F292E00C47603 /* silversalmoncreek.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = silversalmoncreek.jpg; sourceTree = ""; }; + B739488E229F292E00C47603 /* landmarkData.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = landmarkData.json; sourceTree = ""; }; + B739488F229F292F00C47603 /* chincoteague.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = chincoteague.jpg; sourceTree = ""; }; + B7394890229F292F00C47603 /* chilkoottrail.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = chilkoottrail.jpg; sourceTree = ""; }; + C4E4AAA0C4E4035000000001 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; name = README.md; path = ../README.md; sourceTree = ""; }; + F4750E80F475342000000001 /* SampleCode.xcconfig */ = {isa = PBXFileReference; name = SampleCode.xcconfig; path = ../Configuration/SampleCode.xcconfig; sourceTree = ""; }; + F479D5A0F479BCB000000001 /* LICENSE.txt */ = {isa = PBXFileReference; includeInIndex = 1; path = LICENSE.txt; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + B739485F229F194000C47603 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + B7394859229F194000C47603 = { + isa = PBXGroup; + children = ( + C4E4AAA0C4E4035000000001 /* README.md */, + B7394864229F194000C47603 /* Landmarks */, + B7394863229F194000C47603 /* Products */, + F475C870F475A24000000001 /* Configuration */, + F479F160F479F93000000001 /* LICENSE */, + ); + sourceTree = ""; + }; + B7394863229F194000C47603 /* Products */ = { + isa = PBXGroup; + children = ( + B7394862229F194000C47603 /* Landmarks.app */, + ); + name = Products; + sourceTree = ""; + }; + B7394864229F194000C47603 /* Landmarks */ = { + isa = PBXGroup; + children = ( + B739487E229F282200C47603 /* Models */, + B7394865229F194000C47603 /* AppDelegate.swift */, + B7394867229F194000C47603 /* SceneDelegate.swift */, + B7394869229F194000C47603 /* LandmarkDetail.swift */, + B739487D229F1C0100C47603 /* Supporting Views */, + B7394883229F291A00C47603 /* Resources */, + B739486B229F194200C47603 /* Assets.xcassets */, + B7394870229F194200C47603 /* LaunchScreen.storyboard */, + B7394873229F194200C47603 /* Info.plist */, + B739486D229F194200C47603 /* Preview Content */, + ); + path = Landmarks; + sourceTree = ""; + }; + B739486D229F194200C47603 /* Preview Content */ = { + isa = PBXGroup; + children = ( + B739486E229F194200C47603 /* Preview Assets.xcassets */, + ); + path = "Preview Content"; + sourceTree = ""; + }; + B739487D229F1C0100C47603 /* Supporting Views */ = { + isa = PBXGroup; + children = ( + B7394879229F1B3F00C47603 /* CircleImage.swift */, + B739487B229F1B6800C47603 /* MapView.swift */, + ); + path = "Supporting Views"; + sourceTree = ""; + }; + B739487E229F282200C47603 /* Models */ = { + isa = PBXGroup; + children = ( + B7394880229F28B900C47603 /* Data.swift */, + B739487F229F28B900C47603 /* Landmark.swift */, + ); + path = Models; + sourceTree = ""; + }; + B7394883229F291A00C47603 /* Resources */ = { + isa = PBXGroup; + children = ( + B739488E229F292E00C47603 /* landmarkData.json */, + B7394890229F292F00C47603 /* chilkoottrail.jpg */, + B739488F229F292F00C47603 /* chincoteague.jpg */, + B739488A229F292E00C47603 /* hiddenlake.jpg */, + B7394886229F292E00C47603 /* icybay.jpg */, + B7394887229F292E00C47603 /* lakemcdonald.jpg */, + B7394884229F292D00C47603 /* rainbowlake.jpg */, + B739488D229F292E00C47603 /* silversalmoncreek.jpg */, + B739488B229F292E00C47603 /* stmarylake.jpg */, + B7394888229F292E00C47603 /* turtlerock.jpg */, + B739488C229F292E00C47603 /* twinlake.jpg */, + B7394889229F292E00C47603 /* umbagog.jpg */, + B7394885229F292D00C47603 /* yukon_charleyrivers.jpg */, + ); + path = Resources; + sourceTree = ""; + }; + F475C870F475A24000000001 /* Configuration */ = { + isa = PBXGroup; + children = ( + F4750E80F475342000000001 /* SampleCode.xcconfig */, + ); + name = Configuration; + sourceTree = ""; + }; + F479F160F479F93000000001 /* LICENSE */ = { + isa = PBXGroup; + children = ( + F479D5A0F479BCB000000001 /* LICENSE.txt */, + ); + name = LICENSE; + path = ../LICENSE; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + B7394861229F194000C47603 /* Landmarks */ = { + isa = PBXNativeTarget; + buildConfigurationList = B7394876229F194200C47603 /* Build configuration list for PBXNativeTarget "Landmarks" */; + buildPhases = ( + B739485E229F194000C47603 /* Sources */, + B739485F229F194000C47603 /* Frameworks */, + B7394860229F194000C47603 /* Resources */, + C602AC70C605937000000001, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Landmarks; + productName = Landmarks; + productReference = B7394862229F194000C47603 /* Landmarks.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + B739485A229F194000C47603 /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 1100; + LastUpgradeCheck = 1100; + ORGANIZATIONNAME = Apple; + TargetAttributes = { + B7394861229F194000C47603 = { + CreatedOnToolsVersion = 11.0; + }; + }; + }; + buildConfigurationList = B739485D229F194000C47603 /* Build configuration list for PBXProject "BuildingListsAndNavigation" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = B7394859229F194000C47603; + productRefGroup = B7394863229F194000C47603 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + B7394861229F194000C47603 /* Landmarks */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + B7394860229F194000C47603 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + B739489A229F292F00C47603 /* silversalmoncreek.jpg in Resources */, + B7394894229F292F00C47603 /* lakemcdonald.jpg in Resources */, + B7394872229F194200C47603 /* LaunchScreen.storyboard in Resources */, + B7394891229F292F00C47603 /* rainbowlake.jpg in Resources */, + B739486F229F194200C47603 /* Preview Assets.xcassets in Resources */, + B7394895229F292F00C47603 /* turtlerock.jpg in Resources */, + B739486C229F194200C47603 /* Assets.xcassets in Resources */, + B7394899229F292F00C47603 /* twinlake.jpg in Resources */, + B7394896229F292F00C47603 /* umbagog.jpg in Resources */, + B739489D229F292F00C47603 /* chilkoottrail.jpg in Resources */, + B739489C229F292F00C47603 /* chincoteague.jpg in Resources */, + B739489B229F292F00C47603 /* landmarkData.json in Resources */, + B7394893229F292F00C47603 /* icybay.jpg in Resources */, + B7394897229F292F00C47603 /* hiddenlake.jpg in Resources */, + B7394898229F292F00C47603 /* stmarylake.jpg in Resources */, + B7394892229F292F00C47603 /* yukon_charleyrivers.jpg in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + B739485E229F194000C47603 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + B7394882229F28B900C47603 /* Data.swift in Sources */, + B7394866229F194000C47603 /* AppDelegate.swift in Sources */, + B739487A229F1B3F00C47603 /* CircleImage.swift in Sources */, + B739487C229F1B6800C47603 /* MapView.swift in Sources */, + B7394868229F194000C47603 /* SceneDelegate.swift in Sources */, + B739486A229F194000C47603 /* LandmarkDetail.swift in Sources */, + B7394881229F28B900C47603 /* Landmark.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + B7394870229F194200C47603 /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + B7394871229F194200C47603 /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + B7394874229F194200C47603 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = F4750E80F475342000000001 /* SampleCode.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + B7394875229F194200C47603 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = F4750E80F475342000000001 /* SampleCode.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + B7394877229F194200C47603 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = F4750E80F475342000000001 /* SampleCode.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_ASSET_PATHS = "Landmarks/Preview\\ Content"; + DEVELOPMENT_TEAM = ""; + ENABLE_PREVIEWS = YES; + INFOPLIST_FILE = Landmarks/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = "com.example.apple-samplecode.Landmarks${SAMPLE_CODE_DISAMBIGUATOR}"; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + B7394878229F194200C47603 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = F4750E80F475342000000001 /* SampleCode.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_ASSET_PATHS = "Landmarks/Preview\\ Content"; + DEVELOPMENT_TEAM = ""; + ENABLE_PREVIEWS = YES; + INFOPLIST_FILE = Landmarks/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = "com.example.apple-samplecode.Landmarks${SAMPLE_CODE_DISAMBIGUATOR}"; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + B739485D229F194000C47603 /* Build configuration list for PBXProject "BuildingListsAndNavigation" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + B7394874229F194200C47603 /* Debug */, + B7394875229F194200C47603 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + B7394876229F194200C47603 /* Build configuration list for PBXNativeTarget "Landmarks" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + B7394877229F194200C47603 /* Debug */, + B7394878229F194200C47603 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = B739485A229F194000C47603 /* Project object */; +} diff --git a/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/BuildingListsAndNavigation.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/BuildingListsAndNavigation.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 0000000..3ddf867 --- /dev/null +++ b/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/BuildingListsAndNavigation.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,8 @@ + + + + + BuildSystemType + Latest + + diff --git a/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/AppDelegate.swift b/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/AppDelegate.swift new file mode 100644 index 0000000..e22943b --- /dev/null +++ b/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/AppDelegate.swift @@ -0,0 +1,36 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +The application delegate. +*/ + +import UIKit + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { + // Override point for customization after application launch. + return true + } + + func applicationWillTerminate(_ application: UIApplication) { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. + } + + // MARK: UISceneSession Lifecycle + func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration { + // Called when a new scene session is being created. + // Use this method to select a configuration to create the new scene with. + return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role) + } + + func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) { + // Called when the user discards a scene session. + // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions. + // Use this method to release any resources that were specific to the discarded scenes, as they will not return. + } + +} + diff --git a/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/Contents.json b/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..fa0d2db --- /dev/null +++ b/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,113 @@ +{ + "images" : [ + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "landmark_app_icon_40x40.png", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "3x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "landmark_app_icon_58x58.png", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "landmark_app_icon_87x87.png", + "scale" : "3x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "landmark_app_icon_80x80.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "landmark_app_icon_120x120.png", + "scale" : "3x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "landmark_app_icon_120x120-1.png", + "scale" : "2x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "landmark_app_icon_180x180.png", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "1x" + }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "landmark_app_icon_40x40-1.png", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "landmark_app_icon_58x58-1.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "landmark_app_icon_40x40-2.png", + "scale" : "1x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "landmark_app_icon_80x80-1.png", + "scale" : "2x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "landmark_app_icon_76x76.png", + "scale" : "1x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "landmark_app_icon_152x152.png", + "scale" : "2x" + }, + { + "size" : "83.5x83.5", + "idiom" : "ipad", + "filename" : "landmark_app_icon_167x167.png", + "scale" : "2x" + }, + { + "size" : "1024x1024", + "idiom" : "ios-marketing", + "filename" : "landmark_app_icon_1024x1024.png", + "scale" : "1x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_1024x1024.png b/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_1024x1024.png new file mode 100644 index 0000000..00d81c1 Binary files /dev/null and b/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_1024x1024.png differ diff --git a/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_120x120-1.png b/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_120x120-1.png new file mode 100644 index 0000000..d382b8b Binary files /dev/null and b/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_120x120-1.png differ diff --git a/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_120x120.png b/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_120x120.png new file mode 100644 index 0000000..d382b8b Binary files /dev/null and b/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_120x120.png differ diff --git a/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_152x152.png b/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_152x152.png new file mode 100644 index 0000000..11057f8 Binary files /dev/null and b/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_152x152.png differ diff --git a/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_167x167.png b/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_167x167.png new file mode 100644 index 0000000..f73bc26 Binary files /dev/null and b/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_167x167.png differ diff --git a/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_180x180.png b/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_180x180.png new file mode 100644 index 0000000..b02738c Binary files /dev/null and b/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_180x180.png differ diff --git a/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40-1.png b/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40-1.png new file mode 100644 index 0000000..abaff0e Binary files /dev/null and b/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40-1.png differ diff --git a/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40-2.png b/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40-2.png new file mode 100644 index 0000000..abaff0e Binary files /dev/null and b/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40-2.png differ diff --git a/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40.png b/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40.png new file mode 100644 index 0000000..abaff0e Binary files /dev/null and b/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40.png differ diff --git a/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_58x58-1.png b/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_58x58-1.png new file mode 100644 index 0000000..cf7c73d Binary files /dev/null and b/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_58x58-1.png differ diff --git a/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_58x58.png b/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_58x58.png new file mode 100644 index 0000000..cf7c73d Binary files /dev/null and b/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_58x58.png differ diff --git a/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_76x76.png b/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_76x76.png new file mode 100644 index 0000000..3eff85b Binary files /dev/null and b/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_76x76.png differ diff --git a/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_80x80-1.png b/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_80x80-1.png new file mode 100644 index 0000000..6f33f66 Binary files /dev/null and b/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_80x80-1.png differ diff --git a/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_80x80.png b/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_80x80.png new file mode 100644 index 0000000..6f33f66 Binary files /dev/null and b/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_80x80.png differ diff --git a/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_87x87.png b/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_87x87.png new file mode 100644 index 0000000..9e1616c Binary files /dev/null and b/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_87x87.png differ diff --git a/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/Assets.xcassets/Contents.json b/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/Assets.xcassets/turtlerock.imageset/Contents.json b/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/Assets.xcassets/turtlerock.imageset/Contents.json new file mode 100644 index 0000000..5bfd7bf --- /dev/null +++ b/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/Assets.xcassets/turtlerock.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "turtlerock.jpg", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/Assets.xcassets/turtlerock.imageset/turtlerock.jpg b/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/Assets.xcassets/turtlerock.imageset/turtlerock.jpg new file mode 100644 index 0000000..68bcd3e Binary files /dev/null and b/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/Assets.xcassets/turtlerock.imageset/turtlerock.jpg differ diff --git a/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/Base.lproj/LaunchScreen.storyboard b/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000..865e932 --- /dev/null +++ b/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/Info.plist b/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/Info.plist new file mode 100644 index 0000000..e8bb4c6 --- /dev/null +++ b/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/Info.plist @@ -0,0 +1,62 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + $(PRODUCT_BUNDLE_PACKAGE_TYPE) + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UIApplicationSceneManifest + + UIApplicationSupportsMultipleScenes + + UISceneConfigurations + + UIWindowSceneSessionRoleApplication + + + UILaunchStoryboardName + LaunchScreen + UISceneConfigurationName + Default Configuration + UISceneDelegateClassName + $(PRODUCT_MODULE_NAME).SceneDelegate + + + + + UILaunchStoryboardName + LaunchScreen + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/LandmarkDetail.swift b/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/LandmarkDetail.swift new file mode 100644 index 0000000..ee34bba --- /dev/null +++ b/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/LandmarkDetail.swift @@ -0,0 +1,45 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A view showing the details for a landmark. +*/ + +import SwiftUI + +struct LandmarkDetail: View { + var body: some View { + VStack { + MapView() + .edgesIgnoringSafeArea(.top) + .frame(height: 300) + + CircleImage() + .offset(x: 0, y: -130) + .padding(.bottom, -130) + + VStack(alignment: .leading) { + Text("Turtle Rock") + .font(.title) + HStack(alignment: .top) { + Text("Joshua Tree National Park") + .font(.subheadline) + Spacer() + Text("California") + .font(.subheadline) + } + } + .padding() + + Spacer() + } + } +} + +#if DEBUG +struct LandmarkDetail_Previews: PreviewProvider { + static var previews: some View { + LandmarkDetail() + } +} +#endif diff --git a/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/Models/Data.swift b/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/Models/Data.swift new file mode 100644 index 0000000..78837f6 --- /dev/null +++ b/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/Models/Data.swift @@ -0,0 +1,93 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +Helpers for loading images and data. +*/ + +import UIKit +import SwiftUI +import CoreLocation + +let landmarkData: [Landmark] = load("landmarkData.json") + +func load(_ filename: String, as type: T.Type = T.self) -> T { + let data: Data + + guard let file = Bundle.main.url(forResource: filename, withExtension: nil) + else { + fatalError("Couldn't find \(filename) in main bundle.") + } + + do { + data = try Data(contentsOf: file) + } catch { + fatalError("Couldn't load \(filename) from main bundle:\n\(error)") + } + + do { + let decoder = JSONDecoder() + return try decoder.decode(T.self, from: data) + } catch { + fatalError("Couldn't parse \(filename) as \(T.self):\n\(error)") + } +} + +final class ImageStore { + fileprivate typealias _ImageDictionary = [String: [Int: CGImage]] + fileprivate var images: _ImageDictionary = [:] + + fileprivate static var originalSize = 250 + fileprivate static var scale = 2 + + static var shared = ImageStore() + + func image(name: String, size: Int) -> Image { + let index = _guaranteeInitialImage(name: name) + + let sizedImage = images.values[index][size] + ?? _sizeImage(images.values[index][ImageStore.originalSize]!, to: size * ImageStore.scale) + images.values[index][size] = sizedImage + + return Image(sizedImage, scale: Length(ImageStore.scale), label: Text(verbatim: name)) + } + + fileprivate func _guaranteeInitialImage(name: String) -> _ImageDictionary.Index { + if let index = images.index(forKey: name) { return index } + + guard + let url = Bundle.main.url(forResource: name, withExtension: "jpg"), + let imageSource = CGImageSourceCreateWithURL(url as NSURL, nil), + let image = CGImageSourceCreateImageAtIndex(imageSource, 0, nil) + else { + fatalError("Couldn't load image \(name).jpg from main bundle.") + } + + images[name] = [ImageStore.originalSize: image] + return images.index(forKey: name)! + } + + fileprivate func _sizeImage(_ image: CGImage, to size: Int) -> CGImage { + guard + let colorSpace = image.colorSpace, + let context = CGContext( + data: nil, + width: size, height: size, + bitsPerComponent: image.bitsPerComponent, + bytesPerRow: image.bytesPerRow, + space: colorSpace, + bitmapInfo: image.bitmapInfo.rawValue) + else { + fatalError("Couldn't create graphics context.") + } + context.interpolationQuality = .high + context.draw(image, in: CGRect(x: 0, y: 0, width: size, height: size)) + + if let sizedImage = context.makeImage() { + return sizedImage + } else { + fatalError("Couldn't resize image.") + } + } +} + diff --git a/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/Models/Landmark.swift b/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/Models/Landmark.swift new file mode 100644 index 0000000..31c85e1 --- /dev/null +++ b/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/Models/Landmark.swift @@ -0,0 +1,40 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +The model for an individual landmark. +*/ + +import SwiftUI +import CoreLocation + +struct Landmark: Hashable, Codable { + var id: Int + var name: String + fileprivate var imageName: String + fileprivate var coordinates: Coordinates + var state: String + var park: String + var category: Category + + var locationCoordinate: CLLocationCoordinate2D { + CLLocationCoordinate2D( + latitude: coordinates.latitude, + longitude: coordinates.longitude) + } + + func image(forSize size: Int) -> Image { + ImageStore.shared.image(name: imageName, size: size) + } + + enum Category: String, CaseIterable, Codable, Hashable { + case featured = "Featured" + case lakes = "Lakes" + case rivers = "Rivers" + } +} + +struct Coordinates: Hashable, Codable { + var latitude: Double + var longitude: Double +} diff --git a/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/Preview Content/Preview Assets.xcassets/Contents.json b/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/Preview Content/Preview Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/Preview Content/Preview Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/Resources/chilkoottrail.jpg b/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/Resources/chilkoottrail.jpg new file mode 100644 index 0000000..e7f805e Binary files /dev/null and b/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/Resources/chilkoottrail.jpg differ diff --git a/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/Resources/chincoteague.jpg b/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/Resources/chincoteague.jpg new file mode 100644 index 0000000..5f47986 Binary files /dev/null and b/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/Resources/chincoteague.jpg differ diff --git a/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/Resources/hiddenlake.jpg b/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/Resources/hiddenlake.jpg new file mode 100644 index 0000000..d8e804c Binary files /dev/null and b/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/Resources/hiddenlake.jpg differ diff --git a/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/Resources/icybay.jpg b/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/Resources/icybay.jpg new file mode 100644 index 0000000..feb1764 Binary files /dev/null and b/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/Resources/icybay.jpg differ diff --git a/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/Resources/lakemcdonald.jpg b/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/Resources/lakemcdonald.jpg new file mode 100644 index 0000000..bd9d6b9 Binary files /dev/null and b/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/Resources/lakemcdonald.jpg differ diff --git a/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/Resources/landmarkData.json b/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/Resources/landmarkData.json new file mode 100644 index 0000000..01a9691 --- /dev/null +++ b/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/Resources/landmarkData.json @@ -0,0 +1,158 @@ +[ + { + "name": "Turtle Rock", + "category": "Featured", + "city": "Twentynine Palms", + "state": "California", + "id": 1001, + "park": "Joshua Tree National Park", + "coordinates": { + "longitude": -116.166868, + "latitude": 34.011286 + }, + "imageName": "turtlerock" + }, + { + "name": "Silver Salmon Creek", + "category": "Lakes", + "city": "Port Alsworth", + "state": "Alaska", + "id": 4, + "park": "Lake Clark National Park and Preserve", + "coordinates": { + "longitude": -152.665167, + "latitude": 59.980167 + }, + "imageName": "silversalmoncreek" + }, + { + "name": "Chilkoot Trail", + "category": "Rivers", + "city": "Skagway", + "state": "Alaska", + "id": 5, + "park": "Klondike Gold Rush National Historical Park", + "coordinates": { + "longitude": -135.334571, + "latitude": 59.560551 + }, + "imageName": "chilkoottrail" + }, + { + "name": "St. Mary Lake", + "category": "Lakes", + "city": "Browning", + "state": "Montana", + "id": 8, + "park": "Glacier National Park", + "coordinates": { + "longitude": -113.536248, + "latitude": 48.69423 + }, + "imageName": "stmarylake" + }, + { + "name": "Twin Lake", + "category": "Lakes", + "city": "Twin Lakes", + "state": "Alaska", + "id": 11, + "park": "Lake Clark National Park and Preserve", + "coordinates": { + "longitude": -153.849883, + "latitude": 60.641684 + }, + "imageName": "twinlake" + }, + { + "name": "Lake McDonald", + "category": "Lakes", + "city": "West Glacier", + "state": "Montana", + "id": 6, + "park": "Glacier National Park", + "coordinates": { + "longitude": -113.934831, + "latitude": 48.56002 + }, + "imageName": "lakemcdonald" + }, + { + "name": "Charley Rivers", + "category": "Rivers", + "city": "Eaking", + "state": "Alaska", + "id": 1, + "park": "Charley Rivers National Preserve", + "coordinates": { + "longitude": -143.122586, + "latitude": 65.350021 + }, + "imageName": "yukon_charleyrivers" + }, + { + "name": "Icy Bay", + "category": "Lakes", + "city": "Icy Bay", + "state": "Alaska", + "id": 2, + "park": "Wrangell-St. Elias National Park and Preserve", + "coordinates": { + "longitude": -141.518167, + "latitude": 60.089917 + }, + "imageName": "icybay" + }, + { + "name": "Rainbow Lake", + "category": "Lakes", + "city": "Willow", + "state": "Alaska", + "id": 3, + "park": "State Recreation Area", + "coordinates": { + "longitude": -150.086103, + "latitude": 61.694334 + }, + "imageName": "rainbowlake" + }, + { + "name": "Hidden Lake", + "category": "Lakes", + "city": "Newhalem", + "state": "Washington", + "id": 7, + "park": "North Cascades National Park", + "coordinates": { + "longitude": -121.17799, + "latitude": 48.495442 + }, + "imageName": "hiddenlake" + }, + { + "name": "Chincoteague", + "category": "Rivers", + "city": "Chincoteague", + "state": "Virginia", + "id": 9, + "park": "Chincoteague National Wildlife Refuge", + "coordinates": { + "longitude": -75.383212, + "latitude": 37.91531 + }, + "imageName": "chincoteague" + }, + { + "name": "Lake Umbagog", + "category": "Lakes", + "city": "Errol", + "state": "New Hampshire", + "id": 10, + "park": "Umbagog National Wildlife Refuge", + "coordinates": { + "longitude": -71.056816, + "latitude": 44.747408 + }, + "imageName": "umbagog" + } +] diff --git a/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/Resources/rainbowlake.jpg b/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/Resources/rainbowlake.jpg new file mode 100644 index 0000000..6da43dd Binary files /dev/null and b/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/Resources/rainbowlake.jpg differ diff --git a/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/Resources/silversalmoncreek.jpg b/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/Resources/silversalmoncreek.jpg new file mode 100644 index 0000000..f657532 Binary files /dev/null and b/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/Resources/silversalmoncreek.jpg differ diff --git a/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/Resources/stmarylake.jpg b/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/Resources/stmarylake.jpg new file mode 100644 index 0000000..1c71de4 Binary files /dev/null and b/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/Resources/stmarylake.jpg differ diff --git a/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/Resources/turtlerock.jpg b/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/Resources/turtlerock.jpg new file mode 100644 index 0000000..f7a6e6d Binary files /dev/null and b/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/Resources/turtlerock.jpg differ diff --git a/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/Resources/twinlake.jpg b/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/Resources/twinlake.jpg new file mode 100644 index 0000000..3e7a57c Binary files /dev/null and b/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/Resources/twinlake.jpg differ diff --git a/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/Resources/umbagog.jpg b/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/Resources/umbagog.jpg new file mode 100644 index 0000000..56291c6 Binary files /dev/null and b/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/Resources/umbagog.jpg differ diff --git a/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/Resources/yukon_charleyrivers.jpg b/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/Resources/yukon_charleyrivers.jpg new file mode 100644 index 0000000..17ff44b Binary files /dev/null and b/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/Resources/yukon_charleyrivers.jpg differ diff --git a/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/SceneDelegate.swift b/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/SceneDelegate.swift new file mode 100644 index 0000000..f7316e2 --- /dev/null +++ b/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/SceneDelegate.swift @@ -0,0 +1,56 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +The scene delegate. +*/ + +import UIKit +import SwiftUI + +class SceneDelegate: UIResponder, UIWindowSceneDelegate { + + var window: UIWindow? + + func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { + // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`. + // If using a storyboard, the `window` property will automatically be initialized and attached to the scene. + // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead). + + // Use a UIHostingController as window root view controller + let window = UIWindow(frame: UIScreen.main.bounds) + window.rootViewController = UIHostingController(rootView: LandmarkDetail()) + self.window = window + window.makeKeyAndVisible() + } + + func sceneDidDisconnect(_ scene: UIScene) { + // Called as the scene is being released by the system. + // This occurs shortly after the scene enters the background, or when its session is discarded. + // Release any resources associated with this scene that can be re-created the next time the scene connects. + // The scene may re-connect later, as its session was not neccessarily discarded (see `application:didDiscardSceneSessions` instead). + } + + func sceneDidBecomeActive(_ scene: UIScene) { + // Called when the scene has moved from an inactive state to an active state. + // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive. + } + + func sceneWillResignActive(_ scene: UIScene) { + // Called when the scene will move from an active state to an inactive state. + // This may occur due to temporary interruptions (ex. an incoming phone call). + } + + func sceneWillEnterForeground(_ scene: UIScene) { + // Called as the scene transitions from the background to the foreground. + // Use this method to undo the changes made on entering the background. + } + + func sceneDidEnterBackground(_ scene: UIScene) { + // Called as the scene transitions from the foreground to the background. + // Use this method to save data, release shared resources, and store enough scene-specific state information + // to restore the scene back to its current state. + } + +} + diff --git a/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/Supporting Views/CircleImage.swift b/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/Supporting Views/CircleImage.swift new file mode 100644 index 0000000..f32a333 --- /dev/null +++ b/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/Supporting Views/CircleImage.swift @@ -0,0 +1,26 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A view that clips an image to a circle and adds a stroke and shadow. +*/ + +import SwiftUI + +struct CircleImage: View { + var body: some View { + Image("turtlerock") + .clipShape(Circle()) + .overlay( + Circle().stroke(Color.white, lineWidth: 4)) + .shadow(radius: 10) + } +} + +#if DEBUG +struct CircleImage_Previews: PreviewProvider { + static var previews: some View { + CircleImage() + } +} +#endif diff --git a/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/Supporting Views/MapView.swift b/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/Supporting Views/MapView.swift new file mode 100644 index 0000000..ea5716e --- /dev/null +++ b/Other Projects/Building Lists And Navigation/StartingPoint/Landmarks/Landmarks/Supporting Views/MapView.swift @@ -0,0 +1,31 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A view that hosts an `MKMapView`. +*/ + +import SwiftUI +import MapKit + +struct MapView: UIViewRepresentable { + func makeUIView(context: Context) -> MKMapView { + MKMapView(frame: .zero) + } + + func updateUIView(_ view: MKMapView, context: Context) { + let coordinate = CLLocationCoordinate2D( + latitude: 34.011_286, longitude: -116.166_868) + let span = MKCoordinateSpan(latitudeDelta: 2.0, longitudeDelta: 2.0) + let region = MKCoordinateRegion(center: coordinate, span: span) + view.setRegion(region, animated: true) + } +} + +#if DEBUG +struct MapView_Previews: PreviewProvider { + static var previews: some View { + MapView() + } +} +#endif diff --git a/Other Projects/Building Lists And Navigation/StartingPoint/README.md b/Other Projects/Building Lists And Navigation/StartingPoint/README.md new file mode 100644 index 0000000..f8596c8 --- /dev/null +++ b/Other Projects/Building Lists And Navigation/StartingPoint/README.md @@ -0,0 +1,3 @@ +# Building Lists and Navigation + +Use this project to code along with the [Building Lists and Navigation](https://developer.apple.com/tutorials/swiftui/building-lists-and-navigation) tutorial. diff --git a/Other Projects/Calculator/.gitignore b/Other Projects/Calculator/.gitignore new file mode 100644 index 0000000..312d1f6 --- /dev/null +++ b/Other Projects/Calculator/.gitignore @@ -0,0 +1,68 @@ +# Xcode +# +# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore + +## Build generated +build/ +DerivedData/ + +## Various settings +*.pbxuser +!default.pbxuser +*.mode1v3 +!default.mode1v3 +*.mode2v3 +!default.mode2v3 +*.perspectivev3 +!default.perspectivev3 +xcuserdata/ + +## Other +*.moved-aside +*.xccheckout +*.xcscmblueprint + +## Obj-C/Swift specific +*.hmap +*.ipa +*.dSYM.zip +*.dSYM + +## Playgrounds +timeline.xctimeline +playground.xcworkspace + +# Swift Package Manager +# +# Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. +# Packages/ +# Package.pins +# Package.resolved +.build/ + +# CocoaPods +# +# We recommend against adding the Pods directory to your .gitignore. However +# you should judge for yourself, the pros and cons are mentioned at: +# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control +# +# Pods/ + +# Carthage +# +# Add this line if you want to avoid checking in source code from Carthage dependencies. +# Carthage/Checkouts + +Carthage/Build + +# fastlane +# +# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the +# screenshots whenever they are needed. +# For more information about the recommended setup visit: +# https://docs.fastlane.tools/best-practices/source-control/#source-control + +fastlane/report.xml +fastlane/Preview.html +fastlane/screenshots/**/*.png +fastlane/test_output diff --git a/Other Projects/Calculator/Calculator/Calculator.xcodeproj/project.pbxproj b/Other Projects/Calculator/Calculator/Calculator.xcodeproj/project.pbxproj new file mode 100644 index 0000000..ef682c7 --- /dev/null +++ b/Other Projects/Calculator/Calculator/Calculator.xcodeproj/project.pbxproj @@ -0,0 +1,349 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 50; + objects = { + +/* Begin PBXBuildFile section */ + FB5DD72922A8D8D000642035 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = FB5DD72822A8D8D000642035 /* AppDelegate.swift */; }; + FB5DD72B22A8D8D000642035 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = FB5DD72A22A8D8D000642035 /* SceneDelegate.swift */; }; + FB5DD72D22A8D8D000642035 /* Calculator.swift in Sources */ = {isa = PBXBuildFile; fileRef = FB5DD72C22A8D8D000642035 /* Calculator.swift */; }; + FB5DD72F22A8D8D100642035 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = FB5DD72E22A8D8D100642035 /* Assets.xcassets */; }; + FB5DD73222A8D8D100642035 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = FB5DD73122A8D8D100642035 /* Preview Assets.xcassets */; }; + FB5DD73522A8D8D100642035 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = FB5DD73322A8D8D100642035 /* LaunchScreen.storyboard */; }; + FB5DD73D22A8D9C800642035 /* CalculatorBrain.swift in Sources */ = {isa = PBXBuildFile; fileRef = FB5DD73C22A8D9C800642035 /* CalculatorBrain.swift */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + FB5DD72522A8D8D000642035 /* Calculator.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Calculator.app; sourceTree = BUILT_PRODUCTS_DIR; }; + FB5DD72822A8D8D000642035 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + FB5DD72A22A8D8D000642035 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; + FB5DD72C22A8D8D000642035 /* Calculator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Calculator.swift; sourceTree = ""; }; + FB5DD72E22A8D8D100642035 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + FB5DD73122A8D8D100642035 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; + FB5DD73422A8D8D100642035 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + FB5DD73622A8D8D100642035 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + FB5DD73C22A8D9C800642035 /* CalculatorBrain.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CalculatorBrain.swift; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + FB5DD72222A8D8D000642035 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + FB5DD71C22A8D8D000642035 = { + isa = PBXGroup; + children = ( + FB5DD72722A8D8D000642035 /* Calculator */, + FB5DD72622A8D8D000642035 /* Products */, + ); + sourceTree = ""; + }; + FB5DD72622A8D8D000642035 /* Products */ = { + isa = PBXGroup; + children = ( + FB5DD72522A8D8D000642035 /* Calculator.app */, + ); + name = Products; + sourceTree = ""; + }; + FB5DD72722A8D8D000642035 /* Calculator */ = { + isa = PBXGroup; + children = ( + FB5DD72822A8D8D000642035 /* AppDelegate.swift */, + FB5DD72A22A8D8D000642035 /* SceneDelegate.swift */, + FB5DD72C22A8D8D000642035 /* Calculator.swift */, + FB5DD73C22A8D9C800642035 /* CalculatorBrain.swift */, + FB5DD72E22A8D8D100642035 /* Assets.xcassets */, + FB5DD73322A8D8D100642035 /* LaunchScreen.storyboard */, + FB5DD73622A8D8D100642035 /* Info.plist */, + FB5DD73022A8D8D100642035 /* Preview Content */, + ); + path = Calculator; + sourceTree = ""; + }; + FB5DD73022A8D8D100642035 /* Preview Content */ = { + isa = PBXGroup; + children = ( + FB5DD73122A8D8D100642035 /* Preview Assets.xcassets */, + ); + path = "Preview Content"; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + FB5DD72422A8D8D000642035 /* Calculator */ = { + isa = PBXNativeTarget; + buildConfigurationList = FB5DD73922A8D8D100642035 /* Build configuration list for PBXNativeTarget "Calculator" */; + buildPhases = ( + FB5DD72122A8D8D000642035 /* Sources */, + FB5DD72222A8D8D000642035 /* Frameworks */, + FB5DD72322A8D8D000642035 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Calculator; + productName = Calculator; + productReference = FB5DD72522A8D8D000642035 /* Calculator.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + FB5DD71D22A8D8D000642035 /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 1100; + LastUpgradeCheck = 1100; + ORGANIZATIONNAME = NSHotchner; + TargetAttributes = { + FB5DD72422A8D8D000642035 = { + CreatedOnToolsVersion = 11.0; + }; + }; + }; + buildConfigurationList = FB5DD72022A8D8D000642035 /* Build configuration list for PBXProject "Calculator" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = FB5DD71C22A8D8D000642035; + productRefGroup = FB5DD72622A8D8D000642035 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + FB5DD72422A8D8D000642035 /* Calculator */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + FB5DD72322A8D8D000642035 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + FB5DD73522A8D8D100642035 /* LaunchScreen.storyboard in Resources */, + FB5DD73222A8D8D100642035 /* Preview Assets.xcassets in Resources */, + FB5DD72F22A8D8D100642035 /* Assets.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + FB5DD72122A8D8D000642035 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + FB5DD72922A8D8D000642035 /* AppDelegate.swift in Sources */, + FB5DD72B22A8D8D000642035 /* SceneDelegate.swift in Sources */, + FB5DD73D22A8D9C800642035 /* CalculatorBrain.swift in Sources */, + FB5DD72D22A8D8D000642035 /* Calculator.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + FB5DD73322A8D8D100642035 /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + FB5DD73422A8D8D100642035 /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + FB5DD73722A8D8D100642035 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + FB5DD73822A8D8D100642035 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + FB5DD73A22A8D8D100642035 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_ASSET_PATHS = "Calculator/Preview\\ Content"; + ENABLE_PREVIEWS = YES; + INFOPLIST_FILE = Calculator/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = hotchner.tk.Calculator; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + FB5DD73B22A8D8D100642035 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_ASSET_PATHS = "Calculator/Preview\\ Content"; + ENABLE_PREVIEWS = YES; + INFOPLIST_FILE = Calculator/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = hotchner.tk.Calculator; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + FB5DD72022A8D8D000642035 /* Build configuration list for PBXProject "Calculator" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + FB5DD73722A8D8D100642035 /* Debug */, + FB5DD73822A8D8D100642035 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + FB5DD73922A8D8D100642035 /* Build configuration list for PBXNativeTarget "Calculator" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + FB5DD73A22A8D8D100642035 /* Debug */, + FB5DD73B22A8D8D100642035 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = FB5DD71D22A8D8D000642035 /* Project object */; +} diff --git a/Other Projects/Calculator/Calculator/Calculator.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/Other Projects/Calculator/Calculator/Calculator.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..294c83a --- /dev/null +++ b/Other Projects/Calculator/Calculator/Calculator.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/Other Projects/Calculator/Calculator/Calculator.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/Other Projects/Calculator/Calculator/Calculator.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/Other Projects/Calculator/Calculator/Calculator.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/Other Projects/Calculator/Calculator/Calculator/AppDelegate.swift b/Other Projects/Calculator/Calculator/Calculator/AppDelegate.swift new file mode 100644 index 0000000..f6c8ca8 --- /dev/null +++ b/Other Projects/Calculator/Calculator/Calculator/AppDelegate.swift @@ -0,0 +1,41 @@ +// +// AppDelegate.swift +// Calculator +// +// Created by 马红奇 on 2019/6/6. +// Copyright © 2019 NSHotchner. All rights reserved. +// + +import UIKit + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + + + + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { + // Override point for customization after application launch. + return true + } + + func applicationWillTerminate(_ application: UIApplication) { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. + } + + // MARK: UISceneSession Lifecycle + + func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration { + // Called when a new scene session is being created. + // Use this method to select a configuration to create the new scene with. + return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role) + } + + func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) { + // Called when the user discards a scene session. + // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions. + // Use this method to release any resources that were specific to the discarded scenes, as they will not return. + } + + +} + diff --git a/Other Projects/Calculator/Calculator/Calculator/Assets.xcassets/AppIcon.appiconset/Contents.json b/Other Projects/Calculator/Calculator/Calculator/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..d8db8d6 --- /dev/null +++ b/Other Projects/Calculator/Calculator/Calculator/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,98 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "83.5x83.5", + "scale" : "2x" + }, + { + "idiom" : "ios-marketing", + "size" : "1024x1024", + "scale" : "1x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/Calculator/Calculator/Calculator/Assets.xcassets/Contents.json b/Other Projects/Calculator/Calculator/Calculator/Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/Other Projects/Calculator/Calculator/Calculator/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/Calculator/Calculator/Calculator/Base.lproj/LaunchScreen.storyboard b/Other Projects/Calculator/Calculator/Calculator/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000..865e932 --- /dev/null +++ b/Other Projects/Calculator/Calculator/Calculator/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Other Projects/Calculator/Calculator/Calculator/Calculator.swift b/Other Projects/Calculator/Calculator/Calculator/Calculator.swift new file mode 100644 index 0000000..32b95d6 --- /dev/null +++ b/Other Projects/Calculator/Calculator/Calculator/Calculator.swift @@ -0,0 +1,103 @@ +// +// Calculator.swift +// Calculator +// +// Created by 马红奇 on 2019/6/6. +// Copyright © 2019 NSHotchner. All rights reserved. +// + +import SwiftUI + +struct Calculator: View { + @State private var userIsInTheMiddleOfTyping = false + @State private var display = "0" + @State private var brain = CalculatorBrain() + + let data = [["AC","±", "%", "÷"], + ["7", "8", "9","×"], + ["4", "5", "6","-"], + ["1", "2", "3", "+"], + ["0", ".", "="]] + + var body: some View { + let margin: CGFloat = 10 + return VStack(alignment: .center) { + HStack { + Spacer() + + Button(action: {}){ + Text(display) + .foregroundColor(Color(red: 231 / 255.0, green: 76 / 255.0, blue: 60 / 255.0)) + .font(.largeTitle) + .frame(height: 120) + }.padding(.all) + } + .padding(margin) + + VStack(alignment: .center, spacing: margin) { + ForEach(data, id: \.description) { items in + HStack(alignment: .center, spacing: margin) { + ForEach(items, id: \.description) { item in + Button(action: {}){ + Text(item) + .font(.title) + .bold() + .foregroundColor(Color.blue) + .frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity) + .background(Color(red: 234 / 255.0, green: 240 / 255.0, blue: 241 / 255.0)) + .onTapGesture { + self.touchAction(item) + } + + } + } + } + } + } + .padding(EdgeInsets(top: 0, leading: margin, bottom: 0, trailing: margin)) + } + .frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity) + } + + private func touchAction(_ symbol: String) { + if Int(symbol) != nil || symbol == "." { + touchDigit(symbol) + } else { + performOperation(symbol) + } + + } + + + private func touchDigit(_ digit: String) { + print(#function) + if userIsInTheMiddleOfTyping { + display += digit + } else { + display = digit + userIsInTheMiddleOfTyping = true + } + } + + private func performOperation(_ symbol: String) { + print(#function) + if userIsInTheMiddleOfTyping { + brain.setOperand(Double(display)!) + userIsInTheMiddleOfTyping = false + } + + brain.performOperation(symbol) + + if let result = brain.result { + display = String(result) + } + } +} + +#if DEBUG +struct Calculator_Previews : PreviewProvider { + static var previews: some View { + Calculator() + } +} +#endif diff --git a/Other Projects/Calculator/Calculator/Calculator/CalculatorBrain.swift b/Other Projects/Calculator/Calculator/Calculator/CalculatorBrain.swift new file mode 100644 index 0000000..234776a --- /dev/null +++ b/Other Projects/Calculator/Calculator/Calculator/CalculatorBrain.swift @@ -0,0 +1,98 @@ +// +// CalculatorBrain.swift +// Calculator +// +// Created by 马红奇 on 2019/6/6. +// Copyright © 2019 NSHotchner. All rights reserved. +// from class + +import Foundation + +struct CalculatorBrain { + + // optional on initialization = not set + private var accumulator: Double? + + // private enum specifying operation types + // with an associated value + private enum Operation { + case constant(Double) + case unary((Double) -> Double) + case binary((Double,Double) -> Double) + case equals + } + + // private extensible dictionary of operations with closures + private var operations: Dictionary = [ + "π" : Operation.constant(Double.pi), + "e" : Operation.constant(M_E), + "√" : Operation.unary(sqrt), + "cos" : Operation.unary(cos), + "±" : Operation.unary({ -$0 }), + "×" : Operation.binary({ $0 * $1 }), + "÷" : Operation.binary({ $0 / $1 }), + "+" : Operation.binary({ $0 + $1 }), + "−" : Operation.binary({ $0 - $1 }), + "=" : Operation.equals, + "%" : Operation.binary({$0.truncatingRemainder(dividingBy: $1)}), + "AC" : Operation.constant(0) + ] + + mutating func performOperation(_ symbol: String) { + if let operation = operations[symbol] { + switch operation { + case .constant(let value): + accumulator = value + case .unary(let f): + if accumulator != nil { + accumulator = f(accumulator!) + } + case .binary(let f): + if accumulator != nil { + pendingBinaryOperation = PendingBinaryOperation(function: f, firstOperand: accumulator!) + accumulator = nil + } + case .equals: + performPendingBinaryOperation() + } + } else { + print("wrong operation symbol") + } + } + + // Private mutating func for performing pending binary operations + mutating func performPendingBinaryOperation() { + if pendingBinaryOperation != nil && accumulator != nil { + accumulator = pendingBinaryOperation!.perform(with: accumulator!) + pendingBinaryOperation = nil + } + } + + // Private optional Pending Binary Operation + private var pendingBinaryOperation: PendingBinaryOperation? + + // embedded private struct to support binary operations + // with a constant function and pending first operand + // doesn't need mutating since its just returning a value + private struct PendingBinaryOperation { + let function: (Double, Double) -> Double + let firstOperand: Double + + func perform(with secondOperand: Double) -> Double { + return function(firstOperand, secondOperand) + } + } + + // mark method as mutating in order to assign to property + mutating func setOperand(_ operand: Double) { + accumulator = operand + } + + // return an optional since the accumulator can be not set + var result: Double? { + get { + return accumulator + } + } + +} diff --git a/Other Projects/Calculator/Calculator/Calculator/Info.plist b/Other Projects/Calculator/Calculator/Calculator/Info.plist new file mode 100644 index 0000000..e8bb4c6 --- /dev/null +++ b/Other Projects/Calculator/Calculator/Calculator/Info.plist @@ -0,0 +1,62 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + $(PRODUCT_BUNDLE_PACKAGE_TYPE) + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UIApplicationSceneManifest + + UIApplicationSupportsMultipleScenes + + UISceneConfigurations + + UIWindowSceneSessionRoleApplication + + + UILaunchStoryboardName + LaunchScreen + UISceneConfigurationName + Default Configuration + UISceneDelegateClassName + $(PRODUCT_MODULE_NAME).SceneDelegate + + + + + UILaunchStoryboardName + LaunchScreen + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/Other Projects/Calculator/Calculator/Calculator/Preview Content/Preview Assets.xcassets/Contents.json b/Other Projects/Calculator/Calculator/Calculator/Preview Content/Preview Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/Other Projects/Calculator/Calculator/Calculator/Preview Content/Preview Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/Calculator/Calculator/Calculator/SceneDelegate.swift b/Other Projects/Calculator/Calculator/Calculator/SceneDelegate.swift new file mode 100644 index 0000000..162e0e4 --- /dev/null +++ b/Other Projects/Calculator/Calculator/Calculator/SceneDelegate.swift @@ -0,0 +1,61 @@ +// +// SceneDelegate.swift +// Calculator +// +// Created by 马红奇 on 2019/6/6. +// Copyright © 2019 NSHotchner. All rights reserved. +// + +import UIKit +import SwiftUI + +class SceneDelegate: UIResponder, UIWindowSceneDelegate { + + var window: UIWindow? + + + func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { + // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`. + // If using a storyboard, the `window` property will automatically be initialized and attached to the scene. + // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead). + + // Use a UIHostingController as window root view controller + if let windowScene = scene as? UIWindowScene { + let window = UIWindow(windowScene: windowScene) + window.rootViewController = UIHostingController(rootView: Calculator()) + self.window = window + window.makeKeyAndVisible() + } + } + + func sceneDidDisconnect(_ scene: UIScene) { + // Called as the scene is being released by the system. + // This occurs shortly after the scene enters the background, or when its session is discarded. + // Release any resources associated with this scene that can be re-created the next time the scene connects. + // The scene may re-connect later, as its session was not neccessarily discarded (see `application:didDiscardSceneSessions` instead). + } + + func sceneDidBecomeActive(_ scene: UIScene) { + // Called when the scene has moved from an inactive state to an active state. + // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive. + } + + func sceneWillResignActive(_ scene: UIScene) { + // Called when the scene will move from an active state to an inactive state. + // This may occur due to temporary interruptions (ex. an incoming phone call). + } + + func sceneWillEnterForeground(_ scene: UIScene) { + // Called as the scene transitions from the background to the foreground. + // Use this method to undo the changes made on entering the background. + } + + func sceneDidEnterBackground(_ scene: UIScene) { + // Called as the scene transitions from the foreground to the background. + // Use this method to save data, release shared resources, and store enough scene-specific state information + // to restore the scene back to its current state. + } + + +} + diff --git a/Other Projects/Calculator/LICENSE b/Other Projects/Calculator/LICENSE new file mode 100644 index 0000000..2eba90c --- /dev/null +++ b/Other Projects/Calculator/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2019 hotchner + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/Other Projects/Calculator/README.md b/Other Projects/Calculator/README.md new file mode 100644 index 0000000..c44e9d1 --- /dev/null +++ b/Other Projects/Calculator/README.md @@ -0,0 +1,11 @@ +# SwiftUICalculator + +SwiftUI 实现的计算器 + + + +## Requirements + +* Xcode 11 Beta +* Swift 5.1 +* iOS 13.0 diff --git a/Other Projects/Calculator/screenShots/1.png b/Other Projects/Calculator/screenShots/1.png new file mode 100644 index 0000000..de7a4f7 Binary files /dev/null and b/Other Projects/Calculator/screenShots/1.png differ diff --git a/Other Projects/Calculator/screenShots/2.png b/Other Projects/Calculator/screenShots/2.png new file mode 100644 index 0000000..5f1f1a8 Binary files /dev/null and b/Other Projects/Calculator/screenShots/2.png differ diff --git a/Other Projects/Combine using GitHub API/SwiftUI-Combine-Example.xcodeproj/project.pbxproj b/Other Projects/Combine using GitHub API/SwiftUI-Combine-Example.xcodeproj/project.pbxproj new file mode 100644 index 0000000..9663e95 --- /dev/null +++ b/Other Projects/Combine using GitHub API/SwiftUI-Combine-Example.xcodeproj/project.pbxproj @@ -0,0 +1,373 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 50; + objects = { + +/* Begin PBXBuildFile section */ + 6B194EFF22A6BA07001B3151 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6B194EFE22A6BA07001B3151 /* AppDelegate.swift */; }; + 6B194F0122A6BA07001B3151 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6B194F0022A6BA07001B3151 /* SceneDelegate.swift */; }; + 6B194F0322A6BA07001B3151 /* SearchUserView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6B194F0222A6BA07001B3151 /* SearchUserView.swift */; }; + 6B194F0522A6BA08001B3151 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6B194F0422A6BA08001B3151 /* Assets.xcassets */; }; + 6B194F0822A6BA08001B3151 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6B194F0722A6BA08001B3151 /* Preview Assets.xcassets */; }; + 6B194F0B22A6BA08001B3151 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 6B194F0922A6BA08001B3151 /* LaunchScreen.storyboard */; }; + 6B194F1322A7108C001B3151 /* SearchUserRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6B194F1222A7108C001B3151 /* SearchUserRow.swift */; }; + 6B194F1522A710AB001B3151 /* User.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6B194F1422A710AB001B3151 /* User.swift */; }; + 6B194F1722A710E6001B3151 /* SearchUserResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6B194F1622A710E6001B3151 /* SearchUserResponse.swift */; }; + 6B194F1922A710FF001B3151 /* SearchUserViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6B194F1822A710FF001B3151 /* SearchUserViewModel.swift */; }; + 6B194F1B22A7112D001B3151 /* SearchUserBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6B194F1A22A7112D001B3151 /* SearchUserBar.swift */; }; + 6B194F1D22A71154001B3151 /* FoundationExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6B194F1C22A71154001B3151 /* FoundationExtensions.swift */; }; + 6B194F1F22A71B0F001B3151 /* AnySubscription.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6B194F1E22A71B0F001B3151 /* AnySubscription.swift */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 6B194EFB22A6BA07001B3151 /* SwiftUI-Combine-Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "SwiftUI-Combine-Example.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + 6B194EFE22A6BA07001B3151 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 6B194F0022A6BA07001B3151 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; + 6B194F0222A6BA07001B3151 /* SearchUserView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchUserView.swift; sourceTree = ""; }; + 6B194F0422A6BA08001B3151 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 6B194F0722A6BA08001B3151 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; + 6B194F0A22A6BA08001B3151 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 6B194F0C22A6BA08001B3151 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 6B194F1222A7108C001B3151 /* SearchUserRow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchUserRow.swift; sourceTree = ""; }; + 6B194F1422A710AB001B3151 /* User.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = User.swift; sourceTree = ""; }; + 6B194F1622A710E6001B3151 /* SearchUserResponse.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchUserResponse.swift; sourceTree = ""; }; + 6B194F1822A710FF001B3151 /* SearchUserViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchUserViewModel.swift; sourceTree = ""; }; + 6B194F1A22A7112D001B3151 /* SearchUserBar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchUserBar.swift; sourceTree = ""; }; + 6B194F1C22A71154001B3151 /* FoundationExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FoundationExtensions.swift; sourceTree = ""; }; + 6B194F1E22A71B0F001B3151 /* AnySubscription.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnySubscription.swift; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 6B194EF822A6BA07001B3151 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 6B194EF222A6BA07001B3151 = { + isa = PBXGroup; + children = ( + 6B194EFD22A6BA07001B3151 /* SwiftUI-Combine-Example */, + 6B194EFC22A6BA07001B3151 /* Products */, + ); + sourceTree = ""; + }; + 6B194EFC22A6BA07001B3151 /* Products */ = { + isa = PBXGroup; + children = ( + 6B194EFB22A6BA07001B3151 /* SwiftUI-Combine-Example.app */, + ); + name = Products; + sourceTree = ""; + }; + 6B194EFD22A6BA07001B3151 /* SwiftUI-Combine-Example */ = { + isa = PBXGroup; + children = ( + 6B194F0222A6BA07001B3151 /* SearchUserView.swift */, + 6B194F1822A710FF001B3151 /* SearchUserViewModel.swift */, + 6B194F1A22A7112D001B3151 /* SearchUserBar.swift */, + 6B194F1222A7108C001B3151 /* SearchUserRow.swift */, + 6B194F1622A710E6001B3151 /* SearchUserResponse.swift */, + 6B194F1422A710AB001B3151 /* User.swift */, + 6B194F1E22A71B0F001B3151 /* AnySubscription.swift */, + 6B194F1C22A71154001B3151 /* FoundationExtensions.swift */, + 6B194F0022A6BA07001B3151 /* SceneDelegate.swift */, + 6B194EFE22A6BA07001B3151 /* AppDelegate.swift */, + 6B194F0422A6BA08001B3151 /* Assets.xcassets */, + 6B194F0922A6BA08001B3151 /* LaunchScreen.storyboard */, + 6B194F0C22A6BA08001B3151 /* Info.plist */, + 6B194F0622A6BA08001B3151 /* Preview Content */, + ); + path = "SwiftUI-Combine-Example"; + sourceTree = ""; + }; + 6B194F0622A6BA08001B3151 /* Preview Content */ = { + isa = PBXGroup; + children = ( + 6B194F0722A6BA08001B3151 /* Preview Assets.xcassets */, + ); + path = "Preview Content"; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 6B194EFA22A6BA07001B3151 /* SwiftUI-Combine-Example */ = { + isa = PBXNativeTarget; + buildConfigurationList = 6B194F0F22A6BA08001B3151 /* Build configuration list for PBXNativeTarget "SwiftUI-Combine-Example" */; + buildPhases = ( + 6B194EF722A6BA07001B3151 /* Sources */, + 6B194EF822A6BA07001B3151 /* Frameworks */, + 6B194EF922A6BA07001B3151 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "SwiftUI-Combine-Example"; + productName = "SwiftUI-Combine-Example"; + productReference = 6B194EFB22A6BA07001B3151 /* SwiftUI-Combine-Example.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 6B194EF322A6BA07001B3151 /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 1100; + LastUpgradeCheck = 1100; + ORGANIZATIONNAME = "Ryo Aoyama"; + TargetAttributes = { + 6B194EFA22A6BA07001B3151 = { + CreatedOnToolsVersion = 11.0; + }; + }; + }; + buildConfigurationList = 6B194EF622A6BA07001B3151 /* Build configuration list for PBXProject "SwiftUI-Combine-Example" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 6B194EF222A6BA07001B3151; + productRefGroup = 6B194EFC22A6BA07001B3151 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 6B194EFA22A6BA07001B3151 /* SwiftUI-Combine-Example */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 6B194EF922A6BA07001B3151 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 6B194F0B22A6BA08001B3151 /* LaunchScreen.storyboard in Resources */, + 6B194F0822A6BA08001B3151 /* Preview Assets.xcassets in Resources */, + 6B194F0522A6BA08001B3151 /* Assets.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 6B194EF722A6BA07001B3151 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 6B194F1B22A7112D001B3151 /* SearchUserBar.swift in Sources */, + 6B194EFF22A6BA07001B3151 /* AppDelegate.swift in Sources */, + 6B194F0122A6BA07001B3151 /* SceneDelegate.swift in Sources */, + 6B194F1F22A71B0F001B3151 /* AnySubscription.swift in Sources */, + 6B194F0322A6BA07001B3151 /* SearchUserView.swift in Sources */, + 6B194F1922A710FF001B3151 /* SearchUserViewModel.swift in Sources */, + 6B194F1722A710E6001B3151 /* SearchUserResponse.swift in Sources */, + 6B194F1D22A71154001B3151 /* FoundationExtensions.swift in Sources */, + 6B194F1522A710AB001B3151 /* User.swift in Sources */, + 6B194F1322A7108C001B3151 /* SearchUserRow.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 6B194F0922A6BA08001B3151 /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 6B194F0A22A6BA08001B3151 /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 6B194F0D22A6BA08001B3151 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + 6B194F0E22A6BA08001B3151 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 6B194F1022A6BA08001B3151 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_ASSET_PATHS = "SwiftUI-Combine-Example/Preview\\ Content"; + ENABLE_PREVIEWS = YES; + INFOPLIST_FILE = "SwiftUI-Combine-Example/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = "com.ryo.SwiftUI-Combine-Example"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = 1; + }; + name = Debug; + }; + 6B194F1122A6BA08001B3151 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_ASSET_PATHS = "SwiftUI-Combine-Example/Preview\\ Content"; + ENABLE_PREVIEWS = YES; + INFOPLIST_FILE = "SwiftUI-Combine-Example/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = "com.ryo.SwiftUI-Combine-Example"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = 1; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 6B194EF622A6BA07001B3151 /* Build configuration list for PBXProject "SwiftUI-Combine-Example" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 6B194F0D22A6BA08001B3151 /* Debug */, + 6B194F0E22A6BA08001B3151 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 6B194F0F22A6BA08001B3151 /* Build configuration list for PBXNativeTarget "SwiftUI-Combine-Example" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 6B194F1022A6BA08001B3151 /* Debug */, + 6B194F1122A6BA08001B3151 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 6B194EF322A6BA07001B3151 /* Project object */; +} diff --git a/Other Projects/Combine using GitHub API/SwiftUI-Combine-Example.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/Other Projects/Combine using GitHub API/SwiftUI-Combine-Example.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..d046e2b --- /dev/null +++ b/Other Projects/Combine using GitHub API/SwiftUI-Combine-Example.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/Other Projects/Combine using GitHub API/SwiftUI-Combine-Example.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/Other Projects/Combine using GitHub API/SwiftUI-Combine-Example.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/Other Projects/Combine using GitHub API/SwiftUI-Combine-Example.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/Other Projects/Combine using GitHub API/SwiftUI-Combine-Example/AnySubscription.swift b/Other Projects/Combine using GitHub API/SwiftUI-Combine-Example/AnySubscription.swift new file mode 100644 index 0000000..b6b7768 --- /dev/null +++ b/Other Projects/Combine using GitHub API/SwiftUI-Combine-Example/AnySubscription.swift @@ -0,0 +1,15 @@ +import Combine + +final class AnySubscription: Subscription { + private let cancellable: Cancellable + + init(_ cancel: @escaping () -> Void) { + cancellable = AnyCancellable(cancel) + } + + func request(_ demand: Subscribers.Demand) {} + + func cancel() { + cancellable.cancel() + } +} diff --git a/Other Projects/Combine using GitHub API/SwiftUI-Combine-Example/AppDelegate.swift b/Other Projects/Combine using GitHub API/SwiftUI-Combine-Example/AppDelegate.swift new file mode 100644 index 0000000..b259097 --- /dev/null +++ b/Other Projects/Combine using GitHub API/SwiftUI-Combine-Example/AppDelegate.swift @@ -0,0 +1,4 @@ +import UIKit + +@UIApplicationMain +final class AppDelegate: UIResponder, UIApplicationDelegate {} diff --git a/Other Projects/Combine using GitHub API/SwiftUI-Combine-Example/Assets.xcassets/AppIcon.appiconset/Contents.json b/Other Projects/Combine using GitHub API/SwiftUI-Combine-Example/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..d8db8d6 --- /dev/null +++ b/Other Projects/Combine using GitHub API/SwiftUI-Combine-Example/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,98 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "83.5x83.5", + "scale" : "2x" + }, + { + "idiom" : "ios-marketing", + "size" : "1024x1024", + "scale" : "1x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/Combine using GitHub API/SwiftUI-Combine-Example/Assets.xcassets/Contents.json b/Other Projects/Combine using GitHub API/SwiftUI-Combine-Example/Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/Other Projects/Combine using GitHub API/SwiftUI-Combine-Example/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/Combine using GitHub API/SwiftUI-Combine-Example/Base.lproj/LaunchScreen.storyboard b/Other Projects/Combine using GitHub API/SwiftUI-Combine-Example/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000..865e932 --- /dev/null +++ b/Other Projects/Combine using GitHub API/SwiftUI-Combine-Example/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Other Projects/Combine using GitHub API/SwiftUI-Combine-Example/FoundationExtensions.swift b/Other Projects/Combine using GitHub API/SwiftUI-Combine-Example/FoundationExtensions.swift new file mode 100644 index 0000000..d744cac --- /dev/null +++ b/Other Projects/Combine using GitHub API/SwiftUI-Combine-Example/FoundationExtensions.swift @@ -0,0 +1,57 @@ +import SwiftUI +import Combine + +enum URLSessionError: Error { + case invalidResponse + case serverErrorMessage(statusCode: Int, data: Data) + case urlError(URLError) +} + +extension URLSession { + func send(request: URLRequest) -> AnyPublisher { + + dataTaskPublisher(for: request) + .mapError { URLSessionError.urlError($0) } + .flatMap { data, response -> AnyPublisher in + guard let response = response as? HTTPURLResponse else { + return .fail(.invalidResponse) + } + + guard 200..<300 ~= response.statusCode else { + return .fail(.serverErrorMessage(statusCode: response.statusCode, + data: data)) + } + + return .just(data) + }.eraseToAnyPublisher() + } +} + +extension JSONDecoder: TopLevelDecoder {} + +extension Publisher { + + /// - seealso: https://twitter.com/peres/status/1136132104020881408 + func flatMapLatest(_ transform: @escaping (Self.Output) -> T) -> Publishers.SwitchToLatest> where T.Failure == Self.Failure { + map(transform).switchToLatest() + } +} + +extension Publisher { + + static func empty() -> AnyPublisher { + return Empty() + .eraseToAnyPublisher() + } + + static func just(_ output: Output) -> AnyPublisher { + return Just(output) + .catch { _ in AnyPublisher.empty() } + .eraseToAnyPublisher() + } + + static func fail(_ error: Failure) -> AnyPublisher { + return Fail(error: error) + .eraseToAnyPublisher() + } +} diff --git a/Other Projects/Combine using GitHub API/SwiftUI-Combine-Example/Info.plist b/Other Projects/Combine using GitHub API/SwiftUI-Combine-Example/Info.plist new file mode 100644 index 0000000..f602e95 --- /dev/null +++ b/Other Projects/Combine using GitHub API/SwiftUI-Combine-Example/Info.plist @@ -0,0 +1,60 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + $(PRODUCT_BUNDLE_PACKAGE_TYPE) + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UIApplicationSceneManifest + + UIApplicationSupportsMultipleScenes + + UISceneConfigurations + + UIWindowSceneSessionRoleApplication + + + UILaunchStoryboardName + LaunchScreen + UISceneConfigurationName + Default Configuration + UISceneDelegateClassName + $(PRODUCT_MODULE_NAME).SceneDelegate + + + + + UILaunchStoryboardName + LaunchScreen + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/Other Projects/Combine using GitHub API/SwiftUI-Combine-Example/Preview Content/Preview Assets.xcassets/Contents.json b/Other Projects/Combine using GitHub API/SwiftUI-Combine-Example/Preview Content/Preview Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/Other Projects/Combine using GitHub API/SwiftUI-Combine-Example/Preview Content/Preview Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/Combine using GitHub API/SwiftUI-Combine-Example/SceneDelegate.swift b/Other Projects/Combine using GitHub API/SwiftUI-Combine-Example/SceneDelegate.swift new file mode 100644 index 0000000..e4db875 --- /dev/null +++ b/Other Projects/Combine using GitHub API/SwiftUI-Combine-Example/SceneDelegate.swift @@ -0,0 +1,21 @@ +import UIKit +import SwiftUI + +final class SceneDelegate: UIResponder, UIWindowSceneDelegate { + var window: UIWindow? + + func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { + let window = UIWindow(frame: UIScreen.main.bounds) + window.rootViewController = UIHostingController( + rootView: SearchUserView().environmentObject(SearchUserViewModel()) + ) + self.window = window + window.makeKeyAndVisible() + if let windowScene = scene as? UIWindowScene { + let window = UIWindow(windowScene: windowScene) + window.rootViewController = UIHostingController(rootView: SearchUserView().environmentObject(SearchUserViewModel())) + self.window = window + window.makeKeyAndVisible() + } + } +} diff --git a/Other Projects/Combine using GitHub API/SwiftUI-Combine-Example/SearchUserBar.swift b/Other Projects/Combine using GitHub API/SwiftUI-Combine-Example/SearchUserBar.swift new file mode 100644 index 0000000..87e9ea0 --- /dev/null +++ b/Other Projects/Combine using GitHub API/SwiftUI-Combine-Example/SearchUserBar.swift @@ -0,0 +1,29 @@ +import SwiftUI + +struct SearchUserBar: View { + @Binding var text: String + @State var action: () -> Void + + var body: some View { + ZStack { + HStack { + TextField( + "Search User", text: $text + ) + .padding([.leading, .trailing], 8) + .frame(height: 32) + .background(Color.white.opacity(0.4)) + .cornerRadius(8) + + Button( + action: action, + label: { Text("Search") } + ) + .foregroundColor(Color.white) + } + .padding([.leading, .trailing], 16) + } + .frame(height: 64) + .background(Color.yellow) + } +} diff --git a/Other Projects/Combine using GitHub API/SwiftUI-Combine-Example/SearchUserResponse.swift b/Other Projects/Combine using GitHub API/SwiftUI-Combine-Example/SearchUserResponse.swift new file mode 100644 index 0000000..e950ce8 --- /dev/null +++ b/Other Projects/Combine using GitHub API/SwiftUI-Combine-Example/SearchUserResponse.swift @@ -0,0 +1,3 @@ +struct SearchUserResponse: Decodable { + var items: [User] +} diff --git a/Other Projects/Combine using GitHub API/SwiftUI-Combine-Example/SearchUserRow.swift b/Other Projects/Combine using GitHub API/SwiftUI-Combine-Example/SearchUserRow.swift new file mode 100644 index 0000000..76624d9 --- /dev/null +++ b/Other Projects/Combine using GitHub API/SwiftUI-Combine-Example/SearchUserRow.swift @@ -0,0 +1,27 @@ +import SwiftUI + +struct SearchUserRow: View { + @EnvironmentObject var viewModel: SearchUserViewModel + @State var user: User + + var body: some View { + HStack { + self.viewModel.userImages[user].map { image in + Image(uiImage: image) + .resizable() + .frame(width: 44, height: 44) + .aspectRatio(contentMode: .fit) + .clipShape(Circle()) + .overlay(Circle().stroke(Color.gray, lineWidth: 1)) + } + + Text(user.login) + .font(Font.system(size: 18).bold()) + + Spacer() + } + .padding(EdgeInsets(top: 8, leading: 16, bottom: 8, trailing: 16)) + .frame(height: 60) + .onAppear { self.viewModel.getImage(for: self.user) } + } +} diff --git a/Other Projects/Combine using GitHub API/SwiftUI-Combine-Example/SearchUserView.swift b/Other Projects/Combine using GitHub API/SwiftUI-Combine-Example/SearchUserView.swift new file mode 100644 index 0000000..b86319f --- /dev/null +++ b/Other Projects/Combine using GitHub API/SwiftUI-Combine-Example/SearchUserView.swift @@ -0,0 +1,22 @@ +import SwiftUI + +struct SearchUserView: View { + @EnvironmentObject var viewModel: SearchUserViewModel + @State var text = "ra1028" + + var body: some View { + NavigationView { + VStack { + SearchUserBar(text: $text) { + self.viewModel.search(name: self.text) + } + + List(viewModel.users) { user in + SearchUserRow(user: user) + .onTapGesture { print(user) } + } + } + .navigationBarTitle(Text("Users")) + } + } +} diff --git a/Other Projects/Combine using GitHub API/SwiftUI-Combine-Example/SearchUserViewModel.swift b/Other Projects/Combine using GitHub API/SwiftUI-Combine-Example/SearchUserViewModel.swift new file mode 100644 index 0000000..aedb621 --- /dev/null +++ b/Other Projects/Combine using GitHub API/SwiftUI-Combine-Example/SearchUserViewModel.swift @@ -0,0 +1,49 @@ +import SwiftUI +import Combine + +final class SearchUserViewModel: ObservableObject { + @Published private(set) var users = [User]() + + @Published private(set) var userImages = [User: UIImage]() + + @Published private var cancellable: Cancellable? + + func search(name: String) { + guard !name.isEmpty else { + return users = [] + } + + var urlComponents = URLComponents(string: "https://api.github.com/search/users")! + urlComponents.queryItems = [ + URLQueryItem(name: "q", value: name) + ] + var request = URLRequest(url: urlComponents.url!) + request.addValue("application/json", forHTTPHeaderField: "Content-Type") + + let assign = Subscribers.Assign(object: self, keyPath: \.users) + cancellable = assign + + URLSession.shared.send(request: request) + .decode(type: SearchUserResponse.self, decoder: JSONDecoder()) + .map { $0.items } + .replaceError(with: []) + .receive(on: DispatchQueue.main) + .receive(subscriber: assign) + } + + func getImage(for user: User) { + guard case .none = userImages[user] else { + return + } + + let request = URLRequest(url: user.avatar_url) + URLSession.shared.send(request: request) + .map { UIImage(data: $0) } + .replaceError(with: nil) + .eraseToAnyPublisher() + .receive(on: DispatchQueue.main) + .receive(subscriber: Subscribers.Sink(receiveCompletion: {_ in}) { [weak self] image in + self?.userImages[user] = image + }) + } +} diff --git a/Other Projects/Combine using GitHub API/SwiftUI-Combine-Example/User.swift b/Other Projects/Combine using GitHub API/SwiftUI-Combine-Example/User.swift new file mode 100644 index 0000000..f66f698 --- /dev/null +++ b/Other Projects/Combine using GitHub API/SwiftUI-Combine-Example/User.swift @@ -0,0 +1,8 @@ +import Foundation +import SwiftUI + +struct User: Hashable, Identifiable, Decodable { + var id: Int64 + var login: String + var avatar_url: URL +} diff --git a/Other Projects/Composing Complex Interfaces/Complete/.gitignore b/Other Projects/Composing Complex Interfaces/Complete/.gitignore new file mode 100644 index 0000000..9e50718 --- /dev/null +++ b/Other Projects/Composing Complex Interfaces/Complete/.gitignore @@ -0,0 +1,21 @@ +# See LICENSE folder for this sample’s licensing information. +# +# Apple sample code gitignore configuration. + +# Finder +.DS_Store + +# Xcode - User files +xcuserdata/ + +**/*.xcodeproj/project.xcworkspace/* +!**/*.xcodeproj/project.xcworkspace/xcshareddata + +**/*.xcodeproj/project.xcworkspace/xcshareddata/* +!**/*.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings + +**/*.playground/playground.xcworkspace/* +!**/*.playground/playground.xcworkspace/xcshareddata + +**/*.playground/playground.xcworkspace/xcshareddata/* +!**/*.playground/playground.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings diff --git a/Other Projects/Composing Complex Interfaces/Complete/Configuration/SampleCode.xcconfig b/Other Projects/Composing Complex Interfaces/Complete/Configuration/SampleCode.xcconfig new file mode 100644 index 0000000..db86c06 --- /dev/null +++ b/Other Projects/Composing Complex Interfaces/Complete/Configuration/SampleCode.xcconfig @@ -0,0 +1,13 @@ +// +// See LICENSE folder for this sample’s licensing information. +// +// SampleCode.xcconfig +// + +// The `SAMPLE_CODE_DISAMBIGUATOR` configuration is to make it easier to build +// and run a sample code project. Once you set your project's development team, +// you'll have a unique bundle identifier. This is because the bundle identifier +// is derived based on the 'SAMPLE_CODE_DISAMBIGUATOR' value. Do not use this +// approach in your own projects—it's only useful for sample code projects because +// they are frequently downloaded and don't have a development team set. +SAMPLE_CODE_DISAMBIGUATOR=${DEVELOPMENT_TEAM} diff --git a/Other Projects/Composing Complex Interfaces/Complete/LICENSE/LICENSE.txt b/Other Projects/Composing Complex Interfaces/Complete/LICENSE/LICENSE.txt new file mode 100644 index 0000000..94e3d54 --- /dev/null +++ b/Other Projects/Composing Complex Interfaces/Complete/LICENSE/LICENSE.txt @@ -0,0 +1,8 @@ +Copyright © 2019 Apple Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + diff --git a/Other Projects/Composing Complex Interfaces/Complete/Landmarks/ComposingComplexInterfaces.xcodeproj/.xcodesamplecode.plist b/Other Projects/Composing Complex Interfaces/Complete/Landmarks/ComposingComplexInterfaces.xcodeproj/.xcodesamplecode.plist new file mode 100644 index 0000000..5dd5da8 --- /dev/null +++ b/Other Projects/Composing Complex Interfaces/Complete/Landmarks/ComposingComplexInterfaces.xcodeproj/.xcodesamplecode.plist @@ -0,0 +1,5 @@ + + + + + diff --git a/Other Projects/Composing Complex Interfaces/Complete/Landmarks/ComposingComplexInterfaces.xcodeproj/project.pbxproj b/Other Projects/Composing Complex Interfaces/Complete/Landmarks/ComposingComplexInterfaces.xcodeproj/project.pbxproj new file mode 100644 index 0000000..099efaa --- /dev/null +++ b/Other Projects/Composing Complex Interfaces/Complete/Landmarks/ComposingComplexInterfaces.xcodeproj/project.pbxproj @@ -0,0 +1,533 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 50; + objects = { + +/* Begin PBXBuildFile section */ + B7310DD1229F6839001079B9 /* HexagonParameters.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7310DD0229F6839001079B9 /* HexagonParameters.swift */; }; + B7310DD3229F6CA9001079B9 /* Badge.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7310DD2229F6CA9001079B9 /* Badge.swift */; }; + B7394866229F194000C47603 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7394865229F194000C47603 /* AppDelegate.swift */; }; + B7394868229F194000C47603 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7394867229F194000C47603 /* SceneDelegate.swift */; }; + B739486A229F194000C47603 /* LandmarkDetail.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7394869229F194000C47603 /* LandmarkDetail.swift */; }; + B739486C229F194200C47603 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B739486B229F194200C47603 /* Assets.xcassets */; }; + B739486F229F194200C47603 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B739486E229F194200C47603 /* Preview Assets.xcassets */; }; + B7394872229F194200C47603 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B7394870229F194200C47603 /* LaunchScreen.storyboard */; }; + B739487A229F1B3F00C47603 /* CircleImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7394879229F1B3F00C47603 /* CircleImage.swift */; }; + B739487C229F1B6800C47603 /* MapView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B739487B229F1B6800C47603 /* MapView.swift */; }; + B7394881229F28B900C47603 /* Landmark.swift in Sources */ = {isa = PBXBuildFile; fileRef = B739487F229F28B900C47603 /* Landmark.swift */; }; + B7394882229F28B900C47603 /* Data.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7394880229F28B900C47603 /* Data.swift */; }; + B7394891229F292F00C47603 /* rainbowlake.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B7394884229F292D00C47603 /* rainbowlake.jpg */; }; + B7394893229F292F00C47603 /* icybay.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B7394886229F292E00C47603 /* icybay.jpg */; }; + B7394894229F292F00C47603 /* lakemcdonald.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B7394887229F292E00C47603 /* lakemcdonald.jpg */; }; + B7394895229F292F00C47603 /* turtlerock.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B7394888229F292E00C47603 /* turtlerock.jpg */; }; + B7394896229F292F00C47603 /* umbagog.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B7394889229F292E00C47603 /* umbagog.jpg */; }; + B7394897229F292F00C47603 /* hiddenlake.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B739488A229F292E00C47603 /* hiddenlake.jpg */; }; + B7394898229F292F00C47603 /* stmarylake.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B739488B229F292E00C47603 /* stmarylake.jpg */; }; + B7394899229F292F00C47603 /* twinlake.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B739488C229F292E00C47603 /* twinlake.jpg */; }; + B739489A229F292F00C47603 /* silversalmoncreek.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B739488D229F292E00C47603 /* silversalmoncreek.jpg */; }; + B739489B229F292F00C47603 /* landmarkData.json in Resources */ = {isa = PBXBuildFile; fileRef = B739488E229F292E00C47603 /* landmarkData.json */; }; + B739489C229F292F00C47603 /* chincoteague.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B739488F229F292F00C47603 /* chincoteague.jpg */; }; + B739489D229F292F00C47603 /* chilkoottrail.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B7394890229F292F00C47603 /* chilkoottrail.jpg */; }; + B739489F229F2D9700C47603 /* LandmarkRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = B739489E229F2D9700C47603 /* LandmarkRow.swift */; }; + B73948A1229F2E1F00C47603 /* LandmarkList.swift in Sources */ = {isa = PBXBuildFile; fileRef = B73948A0229F2E1F00C47603 /* LandmarkList.swift */; }; + B73948A3229F3E2200C47603 /* charleyrivers.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B73948A2229F3E2200C47603 /* charleyrivers.jpg */; }; + B7D2AAC5229F4D7C0061E5F5 /* UserData.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7D2AAC4229F4D7C0061E5F5 /* UserData.swift */; }; + B7D587AE229F7382006E8DCF /* BadgeBackground.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7D587AD229F7382006E8DCF /* BadgeBackground.swift */; }; + B7D587B0229F73C1006E8DCF /* BadgeSymbol.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7D587AF229F73C1006E8DCF /* BadgeSymbol.swift */; }; + B7D587B2229F7406006E8DCF /* RotatedBadgeSymbol.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7D587B1229F7406006E8DCF /* RotatedBadgeSymbol.swift */; }; + B7D587B6229F825D006E8DCF /* HikeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7D587B5229F825D006E8DCF /* HikeView.swift */; }; + B7D587B8229F826D006E8DCF /* GraphCapsule.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7D587B7229F826D006E8DCF /* GraphCapsule.swift */; }; + B7D587BA229F8288006E8DCF /* Hike.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7D587B9229F8288006E8DCF /* Hike.swift */; }; + B7D587BC229F82EB006E8DCF /* HikeDetail.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7D587BB229F82EB006E8DCF /* HikeDetail.swift */; }; + B7D587BE229F82FF006E8DCF /* HikeGraph.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7D587BD229F82FF006E8DCF /* HikeGraph.swift */; }; + B7D587C0229F830B006E8DCF /* hikeData.json in Resources */ = {isa = PBXBuildFile; fileRef = B7D587BF229F830B006E8DCF /* hikeData.json */; }; + B7D587D222A0892C006E8DCF /* Home.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7D587D122A0892C006E8DCF /* Home.swift */; }; + B7D587D422A08965006E8DCF /* CategoryRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7D587D322A08965006E8DCF /* CategoryRow.swift */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + A27B87A0A27B580000000001 /* SampleCode.xcconfig */ = {isa = PBXFileReference; name = SampleCode.xcconfig; path = ../Configuration/SampleCode.xcconfig; sourceTree = ""; }; + A4D4D040A4D4CB5000000001 /* LICENSE.txt */ = {isa = PBXFileReference; includeInIndex = 1; path = LICENSE.txt; sourceTree = ""; }; + B7310DD0229F6839001079B9 /* HexagonParameters.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HexagonParameters.swift; sourceTree = ""; }; + B7310DD2229F6CA9001079B9 /* Badge.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Badge.swift; sourceTree = ""; }; + B7394862229F194000C47603 /* Landmarks.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Landmarks.app; sourceTree = BUILT_PRODUCTS_DIR; }; + B7394865229F194000C47603 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + B7394867229F194000C47603 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; + B7394869229F194000C47603 /* LandmarkDetail.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LandmarkDetail.swift; sourceTree = ""; }; + B739486B229F194200C47603 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + B739486E229F194200C47603 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; + B7394871229F194200C47603 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + B7394873229F194200C47603 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + B7394879229F1B3F00C47603 /* CircleImage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CircleImage.swift; sourceTree = ""; }; + B739487B229F1B6800C47603 /* MapView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapView.swift; sourceTree = ""; }; + B739487F229F28B900C47603 /* Landmark.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Landmark.swift; sourceTree = ""; }; + B7394880229F28B900C47603 /* Data.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Data.swift; sourceTree = ""; }; + B7394884229F292D00C47603 /* rainbowlake.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = rainbowlake.jpg; sourceTree = ""; }; + B7394886229F292E00C47603 /* icybay.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = icybay.jpg; sourceTree = ""; }; + B7394887229F292E00C47603 /* lakemcdonald.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = lakemcdonald.jpg; sourceTree = ""; }; + B7394888229F292E00C47603 /* turtlerock.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = turtlerock.jpg; sourceTree = ""; }; + B7394889229F292E00C47603 /* umbagog.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = umbagog.jpg; sourceTree = ""; }; + B739488A229F292E00C47603 /* hiddenlake.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = hiddenlake.jpg; sourceTree = ""; }; + B739488B229F292E00C47603 /* stmarylake.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = stmarylake.jpg; sourceTree = ""; }; + B739488C229F292E00C47603 /* twinlake.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = twinlake.jpg; sourceTree = ""; }; + B739488D229F292E00C47603 /* silversalmoncreek.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = silversalmoncreek.jpg; sourceTree = ""; }; + B739488E229F292E00C47603 /* landmarkData.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = landmarkData.json; sourceTree = ""; }; + B739488F229F292F00C47603 /* chincoteague.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = chincoteague.jpg; sourceTree = ""; }; + B7394890229F292F00C47603 /* chilkoottrail.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = chilkoottrail.jpg; sourceTree = ""; }; + B739489E229F2D9700C47603 /* LandmarkRow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = LandmarkRow.swift; path = "Supporting Views/LandmarkRow.swift"; sourceTree = ""; }; + B73948A0229F2E1F00C47603 /* LandmarkList.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LandmarkList.swift; sourceTree = ""; }; + B73948A2229F3E2200C47603 /* charleyrivers.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = charleyrivers.jpg; sourceTree = ""; }; + B7D2AAC4229F4D7C0061E5F5 /* UserData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserData.swift; sourceTree = ""; }; + B7D587AD229F7382006E8DCF /* BadgeBackground.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BadgeBackground.swift; sourceTree = ""; }; + B7D587AF229F73C1006E8DCF /* BadgeSymbol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BadgeSymbol.swift; sourceTree = ""; }; + B7D587B1229F7406006E8DCF /* RotatedBadgeSymbol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RotatedBadgeSymbol.swift; sourceTree = ""; }; + B7D587B5229F825D006E8DCF /* HikeView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HikeView.swift; sourceTree = ""; }; + B7D587B7229F826D006E8DCF /* GraphCapsule.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GraphCapsule.swift; sourceTree = ""; }; + B7D587B9229F8288006E8DCF /* Hike.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Hike.swift; sourceTree = ""; }; + B7D587BB229F82EB006E8DCF /* HikeDetail.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HikeDetail.swift; sourceTree = ""; }; + B7D587BD229F82FF006E8DCF /* HikeGraph.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HikeGraph.swift; sourceTree = ""; }; + B7D587BF229F830B006E8DCF /* hikeData.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = hikeData.json; sourceTree = ""; }; + B7D587D122A0892C006E8DCF /* Home.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Home.swift; sourceTree = ""; }; + B7D587D322A08965006E8DCF /* CategoryRow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CategoryRow.swift; sourceTree = ""; }; + C4E4AAA0C4E4035000000001 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; name = README.md; path = ../README.md; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + B739485F229F194000C47603 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + A279A190A27B3EC000000001 /* Configuration */ = { + isa = PBXGroup; + children = ( + A27B87A0A27B580000000001 /* SampleCode.xcconfig */, + ); + name = Configuration; + sourceTree = ""; + }; + A4D4C180A4D4BC9000000001 /* LICENSE */ = { + isa = PBXGroup; + children = ( + A4D4D040A4D4CB5000000001 /* LICENSE.txt */, + ); + name = LICENSE; + path = ../LICENSE; + sourceTree = ""; + }; + B7394859229F194000C47603 = { + isa = PBXGroup; + children = ( + C4E4AAA0C4E4035000000001 /* README.md */, + B7394864229F194000C47603 /* Landmarks */, + B7394863229F194000C47603 /* Products */, + A279A190A27B3EC000000001 /* Configuration */, + A4D4C180A4D4BC9000000001 /* LICENSE */, + ); + sourceTree = ""; + }; + B7394863229F194000C47603 /* Products */ = { + isa = PBXGroup; + children = ( + B7394862229F194000C47603 /* Landmarks.app */, + ); + name = Products; + sourceTree = ""; + }; + B7394864229F194000C47603 /* Landmarks */ = { + isa = PBXGroup; + children = ( + B739487E229F282200C47603 /* Models */, + B7394865229F194000C47603 /* AppDelegate.swift */, + B7394867229F194000C47603 /* SceneDelegate.swift */, + B7D587D122A0892C006E8DCF /* Home.swift */, + B7D587D322A08965006E8DCF /* CategoryRow.swift */, + B73948A0229F2E1F00C47603 /* LandmarkList.swift */, + B739489E229F2D9700C47603 /* LandmarkRow.swift */, + B7394869229F194000C47603 /* LandmarkDetail.swift */, + B7D587B5229F825D006E8DCF /* HikeView.swift */, + B7D587BB229F82EB006E8DCF /* HikeDetail.swift */, + B7310DD0229F6839001079B9 /* HexagonParameters.swift */, + B739487D229F1C0100C47603 /* Supporting Views */, + B7394883229F291A00C47603 /* Resources */, + B739486B229F194200C47603 /* Assets.xcassets */, + B7394870229F194200C47603 /* LaunchScreen.storyboard */, + B7394873229F194200C47603 /* Info.plist */, + B739486D229F194200C47603 /* Preview Content */, + ); + path = Landmarks; + sourceTree = ""; + }; + B739486D229F194200C47603 /* Preview Content */ = { + isa = PBXGroup; + children = ( + B739486E229F194200C47603 /* Preview Assets.xcassets */, + ); + path = "Preview Content"; + sourceTree = ""; + }; + B739487D229F1C0100C47603 /* Supporting Views */ = { + isa = PBXGroup; + children = ( + B7394879229F1B3F00C47603 /* CircleImage.swift */, + B739487B229F1B6800C47603 /* MapView.swift */, + B7310DD2229F6CA9001079B9 /* Badge.swift */, + B7D587AF229F73C1006E8DCF /* BadgeSymbol.swift */, + B7D587B1229F7406006E8DCF /* RotatedBadgeSymbol.swift */, + B7D587AD229F7382006E8DCF /* BadgeBackground.swift */, + B7D587BD229F82FF006E8DCF /* HikeGraph.swift */, + B7D587B7229F826D006E8DCF /* GraphCapsule.swift */, + ); + path = "Supporting Views"; + sourceTree = ""; + }; + B739487E229F282200C47603 /* Models */ = { + isa = PBXGroup; + children = ( + B7394880229F28B900C47603 /* Data.swift */, + B739487F229F28B900C47603 /* Landmark.swift */, + B7D587B9229F8288006E8DCF /* Hike.swift */, + B7D2AAC4229F4D7C0061E5F5 /* UserData.swift */, + ); + path = Models; + sourceTree = ""; + }; + B7394883229F291A00C47603 /* Resources */ = { + isa = PBXGroup; + children = ( + B739488E229F292E00C47603 /* landmarkData.json */, + B7D587BF229F830B006E8DCF /* hikeData.json */, + B7394890229F292F00C47603 /* chilkoottrail.jpg */, + B739488F229F292F00C47603 /* chincoteague.jpg */, + B739488A229F292E00C47603 /* hiddenlake.jpg */, + B7394886229F292E00C47603 /* icybay.jpg */, + B7394887229F292E00C47603 /* lakemcdonald.jpg */, + B7394884229F292D00C47603 /* rainbowlake.jpg */, + B739488D229F292E00C47603 /* silversalmoncreek.jpg */, + B739488B229F292E00C47603 /* stmarylake.jpg */, + B7394888229F292E00C47603 /* turtlerock.jpg */, + B739488C229F292E00C47603 /* twinlake.jpg */, + B7394889229F292E00C47603 /* umbagog.jpg */, + B73948A2229F3E2200C47603 /* charleyrivers.jpg */, + ); + path = Resources; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + B7394861229F194000C47603 /* Landmarks */ = { + isa = PBXNativeTarget; + buildConfigurationList = B7394876229F194200C47603 /* Build configuration list for PBXNativeTarget "Landmarks" */; + buildPhases = ( + B739485E229F194000C47603 /* Sources */, + B739485F229F194000C47603 /* Frameworks */, + B7394860229F194000C47603 /* Resources */, + C602AC70C605937000000001, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Landmarks; + productName = Landmarks; + productReference = B7394862229F194000C47603 /* Landmarks.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + B739485A229F194000C47603 /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 1100; + LastUpgradeCheck = 1100; + ORGANIZATIONNAME = Apple; + TargetAttributes = { + B7394861229F194000C47603 = { + CreatedOnToolsVersion = 11.0; + }; + }; + }; + buildConfigurationList = B739485D229F194000C47603 /* Build configuration list for PBXProject "ComposingComplexInterfaces" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = B7394859229F194000C47603; + productRefGroup = B7394863229F194000C47603 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + B7394861229F194000C47603 /* Landmarks */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + B7394860229F194000C47603 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + B739489A229F292F00C47603 /* silversalmoncreek.jpg in Resources */, + B7394894229F292F00C47603 /* lakemcdonald.jpg in Resources */, + B7D587C0229F830B006E8DCF /* hikeData.json in Resources */, + B7394872229F194200C47603 /* LaunchScreen.storyboard in Resources */, + B73948A3229F3E2200C47603 /* charleyrivers.jpg in Resources */, + B7394891229F292F00C47603 /* rainbowlake.jpg in Resources */, + B739486F229F194200C47603 /* Preview Assets.xcassets in Resources */, + B7394895229F292F00C47603 /* turtlerock.jpg in Resources */, + B739486C229F194200C47603 /* Assets.xcassets in Resources */, + B7394899229F292F00C47603 /* twinlake.jpg in Resources */, + B7394896229F292F00C47603 /* umbagog.jpg in Resources */, + B739489D229F292F00C47603 /* chilkoottrail.jpg in Resources */, + B739489C229F292F00C47603 /* chincoteague.jpg in Resources */, + B739489B229F292F00C47603 /* landmarkData.json in Resources */, + B7394893229F292F00C47603 /* icybay.jpg in Resources */, + B7394897229F292F00C47603 /* hiddenlake.jpg in Resources */, + B7394898229F292F00C47603 /* stmarylake.jpg in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + B739485E229F194000C47603 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + B7394882229F28B900C47603 /* Data.swift in Sources */, + B7310DD3229F6CA9001079B9 /* Badge.swift in Sources */, + B7394866229F194000C47603 /* AppDelegate.swift in Sources */, + B7D587B8229F826D006E8DCF /* GraphCapsule.swift in Sources */, + B7D587D422A08965006E8DCF /* CategoryRow.swift in Sources */, + B739487A229F1B3F00C47603 /* CircleImage.swift in Sources */, + B739487C229F1B6800C47603 /* MapView.swift in Sources */, + B7D587BA229F8288006E8DCF /* Hike.swift in Sources */, + B7D587BC229F82EB006E8DCF /* HikeDetail.swift in Sources */, + B7D587B6229F825D006E8DCF /* HikeView.swift in Sources */, + B7310DD1229F6839001079B9 /* HexagonParameters.swift in Sources */, + B73948A1229F2E1F00C47603 /* LandmarkList.swift in Sources */, + B7D587B0229F73C1006E8DCF /* BadgeSymbol.swift in Sources */, + B7D587B2229F7406006E8DCF /* RotatedBadgeSymbol.swift in Sources */, + B7D587D222A0892C006E8DCF /* Home.swift in Sources */, + B7D587BE229F82FF006E8DCF /* HikeGraph.swift in Sources */, + B7394868229F194000C47603 /* SceneDelegate.swift in Sources */, + B7D587AE229F7382006E8DCF /* BadgeBackground.swift in Sources */, + B739486A229F194000C47603 /* LandmarkDetail.swift in Sources */, + B739489F229F2D9700C47603 /* LandmarkRow.swift in Sources */, + B7D2AAC5229F4D7C0061E5F5 /* UserData.swift in Sources */, + B7394881229F28B900C47603 /* Landmark.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + B7394870229F194200C47603 /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + B7394871229F194200C47603 /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + B7394874229F194200C47603 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = A27B87A0A27B580000000001 /* SampleCode.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + B7394875229F194200C47603 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = A27B87A0A27B580000000001 /* SampleCode.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + B7394877229F194200C47603 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = A27B87A0A27B580000000001 /* SampleCode.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_ASSET_PATHS = "Landmarks/Preview\\ Content"; + DEVELOPMENT_TEAM = ""; + ENABLE_PREVIEWS = YES; + INFOPLIST_FILE = Landmarks/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = "com.example.apple-samplecode.Landmarks${SAMPLE_CODE_DISAMBIGUATOR}"; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + B7394878229F194200C47603 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = A27B87A0A27B580000000001 /* SampleCode.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_ASSET_PATHS = "Landmarks/Preview\\ Content"; + DEVELOPMENT_TEAM = ""; + ENABLE_PREVIEWS = YES; + INFOPLIST_FILE = Landmarks/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = "com.example.apple-samplecode.Landmarks${SAMPLE_CODE_DISAMBIGUATOR}"; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + B739485D229F194000C47603 /* Build configuration list for PBXProject "ComposingComplexInterfaces" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + B7394874229F194200C47603 /* Debug */, + B7394875229F194200C47603 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + B7394876229F194200C47603 /* Build configuration list for PBXNativeTarget "Landmarks" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + B7394877229F194200C47603 /* Debug */, + B7394878229F194200C47603 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = B739485A229F194000C47603 /* Project object */; +} diff --git a/Other Projects/Composing Complex Interfaces/Complete/Landmarks/ComposingComplexInterfaces.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/Other Projects/Composing Complex Interfaces/Complete/Landmarks/ComposingComplexInterfaces.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 0000000..3ddf867 --- /dev/null +++ b/Other Projects/Composing Complex Interfaces/Complete/Landmarks/ComposingComplexInterfaces.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,8 @@ + + + + + BuildSystemType + Latest + + diff --git a/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/AppDelegate.swift b/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/AppDelegate.swift new file mode 100644 index 0000000..e22943b --- /dev/null +++ b/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/AppDelegate.swift @@ -0,0 +1,36 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +The application delegate. +*/ + +import UIKit + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { + // Override point for customization after application launch. + return true + } + + func applicationWillTerminate(_ application: UIApplication) { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. + } + + // MARK: UISceneSession Lifecycle + func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration { + // Called when a new scene session is being created. + // Use this method to select a configuration to create the new scene with. + return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role) + } + + func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) { + // Called when the user discards a scene session. + // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions. + // Use this method to release any resources that were specific to the discarded scenes, as they will not return. + } + +} + diff --git a/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/Contents.json b/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..fa0d2db --- /dev/null +++ b/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,113 @@ +{ + "images" : [ + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "landmark_app_icon_40x40.png", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "3x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "landmark_app_icon_58x58.png", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "landmark_app_icon_87x87.png", + "scale" : "3x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "landmark_app_icon_80x80.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "landmark_app_icon_120x120.png", + "scale" : "3x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "landmark_app_icon_120x120-1.png", + "scale" : "2x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "landmark_app_icon_180x180.png", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "1x" + }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "landmark_app_icon_40x40-1.png", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "landmark_app_icon_58x58-1.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "landmark_app_icon_40x40-2.png", + "scale" : "1x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "landmark_app_icon_80x80-1.png", + "scale" : "2x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "landmark_app_icon_76x76.png", + "scale" : "1x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "landmark_app_icon_152x152.png", + "scale" : "2x" + }, + { + "size" : "83.5x83.5", + "idiom" : "ipad", + "filename" : "landmark_app_icon_167x167.png", + "scale" : "2x" + }, + { + "size" : "1024x1024", + "idiom" : "ios-marketing", + "filename" : "landmark_app_icon_1024x1024.png", + "scale" : "1x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_1024x1024.png b/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_1024x1024.png new file mode 100644 index 0000000..00d81c1 Binary files /dev/null and b/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_1024x1024.png differ diff --git a/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_120x120-1.png b/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_120x120-1.png new file mode 100644 index 0000000..d382b8b Binary files /dev/null and b/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_120x120-1.png differ diff --git a/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_120x120.png b/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_120x120.png new file mode 100644 index 0000000..d382b8b Binary files /dev/null and b/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_120x120.png differ diff --git a/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_152x152.png b/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_152x152.png new file mode 100644 index 0000000..11057f8 Binary files /dev/null and b/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_152x152.png differ diff --git a/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_167x167.png b/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_167x167.png new file mode 100644 index 0000000..f73bc26 Binary files /dev/null and b/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_167x167.png differ diff --git a/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_180x180.png b/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_180x180.png new file mode 100644 index 0000000..b02738c Binary files /dev/null and b/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_180x180.png differ diff --git a/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40-1.png b/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40-1.png new file mode 100644 index 0000000..abaff0e Binary files /dev/null and b/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40-1.png differ diff --git a/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40-2.png b/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40-2.png new file mode 100644 index 0000000..abaff0e Binary files /dev/null and b/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40-2.png differ diff --git a/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40.png b/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40.png new file mode 100644 index 0000000..abaff0e Binary files /dev/null and b/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40.png differ diff --git a/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_58x58-1.png b/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_58x58-1.png new file mode 100644 index 0000000..cf7c73d Binary files /dev/null and b/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_58x58-1.png differ diff --git a/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_58x58.png b/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_58x58.png new file mode 100644 index 0000000..cf7c73d Binary files /dev/null and b/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_58x58.png differ diff --git a/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_76x76.png b/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_76x76.png new file mode 100644 index 0000000..3eff85b Binary files /dev/null and b/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_76x76.png differ diff --git a/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_80x80-1.png b/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_80x80-1.png new file mode 100644 index 0000000..6f33f66 Binary files /dev/null and b/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_80x80-1.png differ diff --git a/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_80x80.png b/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_80x80.png new file mode 100644 index 0000000..6f33f66 Binary files /dev/null and b/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_80x80.png differ diff --git a/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_87x87.png b/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_87x87.png new file mode 100644 index 0000000..9e1616c Binary files /dev/null and b/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_87x87.png differ diff --git a/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Assets.xcassets/Contents.json b/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Assets.xcassets/turtlerock.imageset/Contents.json b/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Assets.xcassets/turtlerock.imageset/Contents.json new file mode 100644 index 0000000..5bfd7bf --- /dev/null +++ b/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Assets.xcassets/turtlerock.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "turtlerock.jpg", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Assets.xcassets/turtlerock.imageset/turtlerock.jpg b/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Assets.xcassets/turtlerock.imageset/turtlerock.jpg new file mode 100644 index 0000000..68bcd3e Binary files /dev/null and b/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Assets.xcassets/turtlerock.imageset/turtlerock.jpg differ diff --git a/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Base.lproj/LaunchScreen.storyboard b/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000..865e932 --- /dev/null +++ b/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/CategoryRow.swift b/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/CategoryRow.swift new file mode 100644 index 0000000..e3d5760 --- /dev/null +++ b/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/CategoryRow.swift @@ -0,0 +1,64 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A view showing a scrollable list of landmarks. +*/ + +import SwiftUI + +struct CategoryRow: View { + var categoryName: String + var items: [Landmark] + + var body: some View { + VStack(alignment: .leading) { + Text(self.categoryName) + .font(.headline) + .padding(.leading, 15) + .padding(.top, 5) + + ScrollView(.horizontal) { + HStack(alignment: .top, spacing: 0) { + ForEach(self.items, id: \.name) { landmark in + NavigationLink( + destination: LandmarkDetail( + landmark: landmark + ) + ) { + CategoryItem(landmark: landmark) + } + } + } + } + .frame(height: 185) + } + } +} + +struct CategoryItem: View { + var landmark: Landmark + var body: some View { + VStack(alignment: .leading) { + landmark + .image(forSize: 155) + .renderingMode(.original) + .cornerRadius(5) + Text(landmark.name) + .foregroundColor(.primary) + .font(.caption) + } + .padding(.leading, 15) + } +} + +#if DEBUG +struct CategoryRow_Previews: PreviewProvider { + static var previews: some View { + CategoryRow( + categoryName: landmarkData[0].category.rawValue, + items: Array(landmarkData.prefix(4)) + ) + } +} +#endif diff --git a/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/HexagonParameters.swift b/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/HexagonParameters.swift new file mode 100644 index 0000000..8decba4 --- /dev/null +++ b/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/HexagonParameters.swift @@ -0,0 +1,57 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +Size, position, and other information used to draw a badge. +*/ + +import SwiftUI + +struct HexagonParameters { + struct Segment { + let useWidth: (CGFloat, CGFloat, CGFloat) + let xFactors: (CGFloat, CGFloat, CGFloat) + let useHeight: (CGFloat, CGFloat, CGFloat) + let yFactors: (CGFloat, CGFloat, CGFloat) + } + + static let adjustment: CGFloat = 0.085 + static let points = [ + Segment( + useWidth: (1.00, 1.00, 1.00), + xFactors: (0.60, 0.40, 0.50), + useHeight: (1.00, 1.00, 0.00), + yFactors: (0.05, 0.05, 0.00) + ), + Segment( + useWidth: (1.00, 1.00, 0.00), + xFactors: (0.05, 0.00, 0.00), + useHeight: (1.00, 1.00, 1.00), + yFactors: (0.20 + adjustment, 0.30 + adjustment, 0.25 + adjustment) + ), + Segment( + useWidth: (1.00, 1.00, 0.00), + xFactors: (0.00, 0.05, 0.00), + useHeight: (1.00, 1.00, 1.00), + yFactors: (0.70 - adjustment, 0.80 - adjustment, 0.75 - adjustment) + ), + Segment( + useWidth: (1.00, 1.00, 1.00), + xFactors: (0.40, 0.60, 0.50), + useHeight: (1.00, 1.00, 1.00), + yFactors: (0.95, 0.95, 1.00) + ), + Segment( + useWidth: (1.00, 1.00, 1.00), + xFactors: (0.95, 1.00, 1.00), + useHeight: (1.00, 1.00, 1.00), + yFactors: (0.80 - adjustment, 0.70 - adjustment, 0.75 - adjustment) + ), + Segment( + useWidth: (1.00, 1.00, 1.00), + xFactors: (1.00, 0.95, 1.00), + useHeight: (1.00, 1.00, 1.00), + yFactors: (0.30 + adjustment, 0.20 + adjustment, 0.25 + adjustment) + ) + ] +} diff --git a/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/HikeDetail.swift b/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/HikeDetail.swift new file mode 100644 index 0000000..1d63904 --- /dev/null +++ b/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/HikeDetail.swift @@ -0,0 +1,49 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A view showing the details for a hike. +*/ + +import SwiftUI + +struct HikeDetail: View { + let hike: Hike + @State var dataToShow = \Hike.Observation.elevation + + var buttons = [ + ("Elevation", \Hike.Observation.elevation), + ("Heart Rate", \Hike.Observation.heartRate), + ("Pace", \Hike.Observation.pace), + ] + + var body: some View { + return VStack { + HikeGraph(hike: hike, path: dataToShow) + .frame(height: 200, alignment: .center) + + HStack(spacing: 25) { + ForEach(buttons, id: \.0) { value in + Button(action: { + self.dataToShow = value.1 + }) { + Text(verbatim: value.0) + .font(.system(size: 15)) + .foregroundColor(value.1 == self.dataToShow + ? Color.gray + : Color.accentColor) + .animation(nil) + } + } + } + } + } +} + +#if DEBUG +struct HikeDetail_Previews: PreviewProvider { + static var previews: some View { + HikeDetail(hike: hikeData[0]) + } +} +#endif diff --git a/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/HikeView.swift b/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/HikeView.swift new file mode 100644 index 0000000..b9964c7 --- /dev/null +++ b/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/HikeView.swift @@ -0,0 +1,68 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A view displaying inforamtion about a hike, including an elevation graph. +*/ + +import SwiftUI + +struct HikeView: View { + var hike: Hike + @State private var showDetail = false + + var transition: AnyTransition { + let insertion = AnyTransition.move(edge: .trailing) + .combined(with: .opacity) + let removal = AnyTransition.scale(scale: 0.0) + .combined(with: .opacity) + return .asymmetric(insertion: insertion, removal: removal) + } + + var body: some View { + VStack { + HStack { + HikeGraph(hike: hike, path: \.elevation) + .frame(width: 50, height: 30) + .animation(nil) + + VStack(alignment: .leading) { + Text(verbatim: hike.name) + .font(.headline) + Text(verbatim: hike.distanceText) + } + + Spacer() + + Button(action: { + withAnimation { + self.showDetail.toggle() + } + }) { + Image(systemName: "chevron.right.circle") + .imageScale(.large) + .rotationEffect(.degrees(showDetail ? 90 : 0)) + .scaleEffect(showDetail ? 1.5 : 1) + .padding() + } + } + + if showDetail { + HikeDetail(hike: hike) + .transition(transition) + } + } + } +} + +#if DEBUG +struct HikeView_Previews: PreviewProvider { + static var previews: some View { + VStack { + HikeView(hike: hikeData[0]) + .padding() + Spacer() + } + } +} +#endif diff --git a/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Home.swift b/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Home.swift new file mode 100644 index 0000000..a40b74d --- /dev/null +++ b/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Home.swift @@ -0,0 +1,71 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A view showing featured landmarks above a list of all of the landmarks. +*/ + +import SwiftUI + +struct CategoryHome: View { + @State private var isProfilePresented = false + + var categories: [String: [Landmark]] { + .init( + grouping: landmarkData, + by: { $0.category.rawValue } + ) + } + + var featured: [Landmark] { + landmarkData.filter { $0.isFeatured } + } + + var body: some View { + NavigationView { + List { + FeaturedLandmarks(landmarks: featured) + .scaledToFill() + .frame(height: 200) + .clipped() + .listRowInsets(EdgeInsets()) + + ForEach(categories.keys.sorted(), id: \.self) { key in + CategoryRow(categoryName: key, items: self.categories[key]!) + } + .listRowInsets(EdgeInsets()) + + NavigationLink(destination: LandmarkList()) { + Text("See All") + } + } + .navigationBarTitle(Text("Featured")) + .navigationBarItems(trailing: + Button(action: { + self.isProfilePresented = true + }) { + Image(systemName: "person.crop.circle") + .imageScale(.large) + .accessibility(label: Text("User Profile")) + .padding() + } + ).sheet(isPresented: $isProfilePresented, + content: { Text("User Profile") }) + } + } +} + +struct FeaturedLandmarks: View { + var landmarks: [Landmark] + var body: some View { + landmarks[0].image(forSize: 250).resizable() + } +} + +#if DEBUG +struct CategoryHome_Previews: PreviewProvider { + static var previews: some View { + CategoryHome() + } +} +#endif diff --git a/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Info.plist b/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Info.plist new file mode 100644 index 0000000..e8bb4c6 --- /dev/null +++ b/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Info.plist @@ -0,0 +1,62 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + $(PRODUCT_BUNDLE_PACKAGE_TYPE) + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UIApplicationSceneManifest + + UIApplicationSupportsMultipleScenes + + UISceneConfigurations + + UIWindowSceneSessionRoleApplication + + + UILaunchStoryboardName + LaunchScreen + UISceneConfigurationName + Default Configuration + UISceneDelegateClassName + $(PRODUCT_MODULE_NAME).SceneDelegate + + + + + UILaunchStoryboardName + LaunchScreen + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/LandmarkDetail.swift b/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/LandmarkDetail.swift new file mode 100644 index 0000000..6c290a3 --- /dev/null +++ b/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/LandmarkDetail.swift @@ -0,0 +1,71 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A view showing the details for a landmark. +*/ + +import SwiftUI + +struct LandmarkDetail: View { + @EnvironmentObject var userData: UserData + var landmark: Landmark + + var landmarkIndex: Int { + userData.landmarks.firstIndex(where: { $0.id == landmark.id })! + } + + var body: some View { + VStack { + MapView(coordinate: landmark.locationCoordinate) + .edgesIgnoringSafeArea(.top) + .frame(height: 300) + + CircleImage(image: landmark.image(forSize: 250)) + .offset(x: 0, y: -130) + .padding(.bottom, -130) + + VStack(alignment: .leading) { + HStack { + Text(verbatim: landmark.name) + .font(.title) + + Button(action: { + self.userData.landmarks[self.landmarkIndex] + .isFavorite.toggle() + }) { + if self.userData.landmarks[self.landmarkIndex] + .isFavorite { + Image(systemName: "star.fill") + .foregroundColor(Color.yellow) + } else { + Image(systemName: "star") + .foregroundColor(Color.gray) + } + } + } + + HStack(alignment: .top) { + Text(verbatim: landmark.park) + .font(.subheadline) + Spacer() + Text(verbatim: landmark.state) + .font(.subheadline) + } + } + .padding() + + Spacer() + } + } +} + +#if DEBUG +struct LandmarkDetail_Preview: PreviewProvider { + static var previews: some View { + let userData = UserData() + return LandmarkDetail(landmark: userData.landmarks[0]) + .environmentObject(userData) + } +} +#endif diff --git a/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/LandmarkList.swift b/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/LandmarkList.swift new file mode 100644 index 0000000..be4b764 --- /dev/null +++ b/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/LandmarkList.swift @@ -0,0 +1,46 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A view showing a list of landmarks. +*/ + +import SwiftUI + +struct LandmarkList: View { + @EnvironmentObject private var userData: UserData + + var body: some View { + NavigationView { + List { + Toggle(isOn: $userData.showFavoritesOnly) { + Text("Show Favorites Only") + } + + ForEach(userData.landmarks) { landmark in + if !self.userData.showFavoritesOnly || landmark.isFavorite { + NavigationLink( + destination: LandmarkDetail(landmark: landmark) + .environmentObject(self.userData)) { + LandmarkRow(landmark: landmark) + } + } + } + } + .navigationBarTitle(Text("Landmarks"), displayMode: .large) + } + } +} + +#if DEBUG +struct LandmarksList_Previews: PreviewProvider { + static var previews: some View { + ForEach(["iPhone SE", "iPhone XS Max"], id: \.self) { deviceName in + LandmarkList() + .previewDevice(PreviewDevice(rawValue: deviceName)) + .previewDisplayName(deviceName) + } + .environmentObject(UserData()) + } +} +#endif diff --git a/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Models/Data.swift b/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Models/Data.swift new file mode 100644 index 0000000..cfe5a4a --- /dev/null +++ b/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Models/Data.swift @@ -0,0 +1,95 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +Helpers for loading images and data. +*/ + +import Foundation +import CoreLocation +import UIKit +import SwiftUI + +let landmarkData: [Landmark] = load("landmarkData.json") +let hikeData: [Hike] = load("hikeData.json") + +func load(_ filename: String, as type: T.Type = T.self) -> T { + let data: Data + + guard let file = Bundle.main.url(forResource: filename, withExtension: nil) + else { + fatalError("Couldn't find \(filename) in main bundle.") + } + + do { + data = try Data(contentsOf: file) + } catch { + fatalError("Couldn't load \(filename) from main bundle:\n\(error)") + } + + do { + let decoder = JSONDecoder() + return try decoder.decode(T.self, from: data) + } catch { + fatalError("Couldn't parse \(filename) as \(T.self):\n\(error)") + } +} + +final class ImageStore { + fileprivate typealias _ImageDictionary = [String: [Int: CGImage]] + fileprivate var images: _ImageDictionary = [:] + + fileprivate static var originalSize = 250 + fileprivate static var scale = 2 + + static var shared = ImageStore() + + func image(name: String, size: Int) -> Image { + let index = _guaranteeInitialImage(name: name) + + let sizedImage = images.values[index][size] + ?? _sizeImage(images.values[index][ImageStore.originalSize]!, to: size * ImageStore.scale) + images.values[index][size] = sizedImage + + return Image(sizedImage, scale: CGFloat(ImageStore.scale), label: Text(verbatim: name)) + } + + fileprivate func _guaranteeInitialImage(name: String) -> _ImageDictionary.Index { + if let index = images.index(forKey: name) { return index } + + guard + let url = Bundle.main.url(forResource: name, withExtension: "jpg"), + let imageSource = CGImageSourceCreateWithURL(url as NSURL, nil), + let image = CGImageSourceCreateImageAtIndex(imageSource, 0, nil) + else { + fatalError("Couldn't load image \(name).jpg from main bundle.") + } + + images[name] = [ImageStore.originalSize: image] + return images.index(forKey: name)! + } + + fileprivate func _sizeImage(_ image: CGImage, to size: Int) -> CGImage { + guard + let colorSpace = image.colorSpace, + let context = CGContext( + data: nil, + width: size, height: size, + bitsPerComponent: image.bitsPerComponent, + bytesPerRow: image.bytesPerRow, + space: colorSpace, + bitmapInfo: image.bitmapInfo.rawValue) + else { + fatalError("Couldn't create graphics context.") + } + context.interpolationQuality = .high + context.draw(image, in: CGRect(x: 0, y: 0, width: size, height: size)) + + if let sizedImage = context.makeImage() { + return sizedImage + } else { + fatalError("Couldn't resize image.") + } + } +} + diff --git a/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Models/Hike.swift b/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Models/Hike.swift new file mode 100644 index 0000000..dfd2bb8 --- /dev/null +++ b/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Models/Hike.swift @@ -0,0 +1,31 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +The model for a hike. +*/ + +import SwiftUI + +struct Hike: Codable, Hashable, Identifiable { + var name: String + var id: Int + var distance: Double + var difficulty: Int + var observations: [Observation] + + static var formatter = LengthFormatter() + + var distanceText: String { + return Hike.formatter + .string(fromValue: distance, unit: .kilometer) + } + + struct Observation: Codable, Hashable { + var distanceFromStart: Double + + var elevation: Range + var pace: Range + var heartRate: Range + } +} diff --git a/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Models/Landmark.swift b/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Models/Landmark.swift new file mode 100644 index 0000000..4a7586d --- /dev/null +++ b/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Models/Landmark.swift @@ -0,0 +1,43 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +The model for an individual landmark. +*/ + +import SwiftUI +import CoreLocation + +struct Landmark: Hashable, Codable, Identifiable { + var id: Int + var name: String + fileprivate var imageName: String + fileprivate var coordinates: Coordinates + var state: String + var park: String + var category: Category + var isFavorite: Bool + var isFeatured: Bool + + var locationCoordinate: CLLocationCoordinate2D { + CLLocationCoordinate2D( + latitude: coordinates.latitude, + longitude: coordinates.longitude) + } + + func image(forSize size: Int) -> Image { + ImageStore.shared.image(name: imageName, size: size) + } + + enum Category: String, CaseIterable, Codable, Hashable { + case featured = "Featured" + case lakes = "Lakes" + case rivers = "Rivers" + case mountains = "Mountains" + } +} + +struct Coordinates: Hashable, Codable { + var latitude: Double + var longitude: Double +} diff --git a/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Models/UserData.swift b/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Models/UserData.swift new file mode 100644 index 0000000..afc2cca --- /dev/null +++ b/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Models/UserData.swift @@ -0,0 +1,15 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A model object that stores app data. +*/ + +import Combine +import SwiftUI + +final class UserData: ObservableObject { + @Published var showFavoritesOnly = false + + @Published var landmarks = landmarkData +} diff --git a/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Preview Content/Preview Assets.xcassets/Contents.json b/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Preview Content/Preview Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Preview Content/Preview Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Resources/charleyrivers.jpg b/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Resources/charleyrivers.jpg new file mode 100644 index 0000000..17ff44b Binary files /dev/null and b/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Resources/charleyrivers.jpg differ diff --git a/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Resources/chilkoottrail.jpg b/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Resources/chilkoottrail.jpg new file mode 100644 index 0000000..e7f805e Binary files /dev/null and b/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Resources/chilkoottrail.jpg differ diff --git a/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Resources/chincoteague.jpg b/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Resources/chincoteague.jpg new file mode 100644 index 0000000..5f47986 Binary files /dev/null and b/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Resources/chincoteague.jpg differ diff --git a/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Resources/hiddenlake.jpg b/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Resources/hiddenlake.jpg new file mode 100644 index 0000000..d8e804c Binary files /dev/null and b/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Resources/hiddenlake.jpg differ diff --git a/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Resources/hikeData.json b/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Resources/hikeData.json new file mode 100644 index 0000000..3fb1e96 --- /dev/null +++ b/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Resources/hikeData.json @@ -0,0 +1,1882 @@ +[ + { + "name":"Lonesome Ridge Trail", + "id":1001, + "distance":4.5, + "difficulty":3, + "observations":[ + { + "elevation":[ + 291.65263635636268, + 309.26016677925196 + ], + "pace":[ + 396.08716481908732, + 403.68937873525232 + ], + "heartRate":[ + 117.16351898665887, + 121.95815455919609 + ], + "distanceFromStart":0 + }, + { + "elevation":[ + 299.24001936628116, + 317.44584350790012 + ], + "pace":[ + 380.19020240756623, + 395.3978319010256 + ], + "heartRate":[ + 117.6410892152911, + 124.82185220506081 + ], + "distanceFromStart":0.375 + }, + { + "elevation":[ + 303.62145464574394, + 336.05569457646544 + ], + "pace":[ + 380.55927782266116, + 397.60789726832775 + ], + "heartRate":[ + 121.52696452049059, + 127.31525441110122 + ], + "distanceFromStart":0.75 + }, + { + "elevation":[ + 319.90393365162629, + 346.26966025518789 + ], + "pace":[ + 357.94116421258531, + 398.0750288648062 + ], + "heartRate":[ + 123.75908585923588, + 132.77069404486801 + ], + "distanceFromStart":1.125 + }, + { + "elevation":[ + 354.17104439267905, + 403.57031216972939 + ], + "pace":[ + 335.07385149392701, + 397.82674381875808 + ], + "heartRate":[ + 130.8235194572915, + 140.55700591418218 + ], + "distanceFromStart":1.5 + }, + { + "elevation":[ + 357.42992871175124, + 385.92155620623635 + ], + "pace":[ + 395.16168913839374, + 404.60294066527558 + ], + "heartRate":[ + 131.5456052446734, + 134.65984504627627 + ], + "distanceFromStart":1.875 + }, + { + "elevation":[ + 345.47736721935661, + 363.18776661379422 + ], + "pace":[ + 340.82303041339082, + 404.71689228682374 + ], + "heartRate":[ + 125.1949698433959, + 131.31354363122026 + ], + "distanceFromStart":2.25 + }, + { + "elevation":[ + 346.23343025200535, + 497.23376445462401 + ], + "pace":[ + 261.27629148816021, + 331.68516208719467 + ], + "heartRate":[ + 131.67810544238606, + 154.26779645311458 + ], + "distanceFromStart":2.625 + }, + { + "elevation":[ + 491.57378483134391, + 547.49535224251053 + ], + "pace":[ + 296.05298644112088, + 401.14092967732398 + ], + "heartRate":[ + 151.36398089694217, + 166.20454793289232 + ], + "distanceFromStart":3 + }, + { + "elevation":[ + 472.06803233416338, + 531.92570520228401 + ], + "pace":[ + 395.50830663514012, + 401.67837917543591 + ], + "heartRate":[ + 134.41798110234078, + 151.90886697564241 + ], + "distanceFromStart":3.375 + }, + { + "elevation":[ + 339.81419476005283, + 461.03832527824829 + ], + "pace":[ + 395.31160487975183, + 404.49550455974907 + ], + "heartRate":[ + 129.97753472415462, + 138.13531094848992 + ], + "distanceFromStart":3.75 + }, + { + "elevation":[ + 303.1495508565697, + 342.3532820173541 + ], + "pace":[ + 395.02844559698116, + 402.65878340653796 + ], + "heartRate":[ + 127.72304232462609, + 133.26322270764186 + ], + "distanceFromStart":4.125 + } + ] + }, + { + "name":"Lonesome Ridge Trail", + "id":1002, + "distance":4.5, + "difficulty":3, + "observations":[ + { + "elevation":[ + 291.65263635636268, + 309.26016677925196 + ], + "pace":[ + 396.08716481908732, + 403.68937873525232 + ], + "heartRate":[ + 117.16351898665887, + 121.95815455919609 + ], + "distanceFromStart":0 + }, + { + "elevation":[ + 299.24001936628116, + 317.44584350790012 + ], + "pace":[ + 380.19020240756623, + 395.3978319010256 + ], + "heartRate":[ + 117.6410892152911, + 124.82185220506081 + ], + "distanceFromStart":0.375 + }, + { + "elevation":[ + 303.62145464574394, + 336.05569457646544 + ], + "pace":[ + 380.55927782266116, + 397.60789726832775 + ], + "heartRate":[ + 121.52696452049059, + 127.31525441110122 + ], + "distanceFromStart":0.75 + }, + { + "elevation":[ + 319.90393365162629, + 346.26966025518789 + ], + "pace":[ + 357.94116421258531, + 398.0750288648062 + ], + "heartRate":[ + 123.75908585923588, + 132.77069404486801 + ], + "distanceFromStart":1.125 + }, + { + "elevation":[ + 354.17104439267905, + 403.57031216972939 + ], + "pace":[ + 335.07385149392701, + 397.82674381875808 + ], + "heartRate":[ + 130.8235194572915, + 140.55700591418218 + ], + "distanceFromStart":1.5 + }, + { + "elevation":[ + 357.42992871175124, + 385.92155620623635 + ], + "pace":[ + 395.16168913839374, + 404.60294066527558 + ], + "heartRate":[ + 131.5456052446734, + 134.65984504627627 + ], + "distanceFromStart":1.875 + }, + { + "elevation":[ + 345.47736721935661, + 363.18776661379422 + ], + "pace":[ + 340.82303041339082, + 404.71689228682374 + ], + "heartRate":[ + 125.1949698433959, + 131.31354363122026 + ], + "distanceFromStart":2.25 + }, + { + "elevation":[ + 346.23343025200535, + 497.23376445462401 + ], + "pace":[ + 261.27629148816021, + 331.68516208719467 + ], + "heartRate":[ + 131.67810544238606, + 154.26779645311458 + ], + "distanceFromStart":2.625 + }, + { + "elevation":[ + 491.57378483134391, + 547.49535224251053 + ], + "pace":[ + 296.05298644112088, + 401.14092967732398 + ], + "heartRate":[ + 151.36398089694217, + 166.20454793289232 + ], + "distanceFromStart":3 + }, + { + "elevation":[ + 472.06803233416338, + 531.92570520228401 + ], + "pace":[ + 395.50830663514012, + 401.67837917543591 + ], + "heartRate":[ + 134.41798110234078, + 151.90886697564241 + ], + "distanceFromStart":3.375 + }, + { + "elevation":[ + 339.81419476005283, + 461.03832527824829 + ], + "pace":[ + 395.31160487975183, + 404.49550455974907 + ], + "heartRate":[ + 129.97753472415462, + 138.13531094848992 + ], + "distanceFromStart":3.75 + }, + { + "elevation":[ + 303.1495508565697, + 342.3532820173541 + ], + "pace":[ + 395.02844559698116, + 402.65878340653796 + ], + "heartRate":[ + 127.72304232462609, + 133.26322270764186 + ], + "distanceFromStart":4.125 + } + ] + }, + { + "name":"Lonesome Ridge Trail", + "id":1003, + "distance":4.5, + "difficulty":3, + "observations":[ + { + "elevation":[ + 291.65263635636268, + 309.26016677925196 + ], + "pace":[ + 396.08716481908732, + 403.68937873525232 + ], + "heartRate":[ + 117.16351898665887, + 121.95815455919609 + ], + "distanceFromStart":0 + }, + { + "elevation":[ + 299.24001936628116, + 317.44584350790012 + ], + "pace":[ + 380.19020240756623, + 395.3978319010256 + ], + "heartRate":[ + 117.6410892152911, + 124.82185220506081 + ], + "distanceFromStart":0.375 + }, + { + "elevation":[ + 303.62145464574394, + 336.05569457646544 + ], + "pace":[ + 380.55927782266116, + 397.60789726832775 + ], + "heartRate":[ + 121.52696452049059, + 127.31525441110122 + ], + "distanceFromStart":0.75 + }, + { + "elevation":[ + 319.90393365162629, + 346.26966025518789 + ], + "pace":[ + 357.94116421258531, + 398.0750288648062 + ], + "heartRate":[ + 123.75908585923588, + 132.77069404486801 + ], + "distanceFromStart":1.125 + }, + { + "elevation":[ + 354.17104439267905, + 403.57031216972939 + ], + "pace":[ + 335.07385149392701, + 397.82674381875808 + ], + "heartRate":[ + 130.8235194572915, + 140.55700591418218 + ], + "distanceFromStart":1.5 + }, + { + "elevation":[ + 357.42992871175124, + 385.92155620623635 + ], + "pace":[ + 395.16168913839374, + 404.60294066527558 + ], + "heartRate":[ + 131.5456052446734, + 134.65984504627627 + ], + "distanceFromStart":1.875 + }, + { + "elevation":[ + 345.47736721935661, + 363.18776661379422 + ], + "pace":[ + 340.82303041339082, + 404.71689228682374 + ], + "heartRate":[ + 125.1949698433959, + 131.31354363122026 + ], + "distanceFromStart":2.25 + }, + { + "elevation":[ + 346.23343025200535, + 497.23376445462401 + ], + "pace":[ + 261.27629148816021, + 331.68516208719467 + ], + "heartRate":[ + 131.67810544238606, + 154.26779645311458 + ], + "distanceFromStart":2.625 + }, + { + "elevation":[ + 491.57378483134391, + 547.49535224251053 + ], + "pace":[ + 296.05298644112088, + 401.14092967732398 + ], + "heartRate":[ + 151.36398089694217, + 166.20454793289232 + ], + "distanceFromStart":3 + }, + { + "elevation":[ + 472.06803233416338, + 531.92570520228401 + ], + "pace":[ + 395.50830663514012, + 401.67837917543591 + ], + "heartRate":[ + 134.41798110234078, + 151.90886697564241 + ], + "distanceFromStart":3.375 + }, + { + "elevation":[ + 339.81419476005283, + 461.03832527824829 + ], + "pace":[ + 395.31160487975183, + 404.49550455974907 + ], + "heartRate":[ + 129.97753472415462, + 138.13531094848992 + ], + "distanceFromStart":3.75 + }, + { + "elevation":[ + 303.1495508565697, + 342.3532820173541 + ], + "pace":[ + 395.02844559698116, + 402.65878340653796 + ], + "heartRate":[ + 127.72304232462609, + 133.26322270764186 + ], + "distanceFromStart":4.125 + } + ] + }, + { + "name":"Lonesome Ridge Trail", + "id":1004, + "distance":4.5, + "difficulty":3, + "observations":[ + { + "elevation":[ + 291.65263635636268, + 309.26016677925196 + ], + "pace":[ + 396.08716481908732, + 403.68937873525232 + ], + "heartRate":[ + 117.16351898665887, + 121.95815455919609 + ], + "distanceFromStart":0 + }, + { + "elevation":[ + 299.24001936628116, + 317.44584350790012 + ], + "pace":[ + 380.19020240756623, + 395.3978319010256 + ], + "heartRate":[ + 117.6410892152911, + 124.82185220506081 + ], + "distanceFromStart":0.375 + }, + { + "elevation":[ + 303.62145464574394, + 336.05569457646544 + ], + "pace":[ + 380.55927782266116, + 397.60789726832775 + ], + "heartRate":[ + 121.52696452049059, + 127.31525441110122 + ], + "distanceFromStart":0.75 + }, + { + "elevation":[ + 319.90393365162629, + 346.26966025518789 + ], + "pace":[ + 357.94116421258531, + 398.0750288648062 + ], + "heartRate":[ + 123.75908585923588, + 132.77069404486801 + ], + "distanceFromStart":1.125 + }, + { + "elevation":[ + 354.17104439267905, + 403.57031216972939 + ], + "pace":[ + 335.07385149392701, + 397.82674381875808 + ], + "heartRate":[ + 130.8235194572915, + 140.55700591418218 + ], + "distanceFromStart":1.5 + }, + { + "elevation":[ + 357.42992871175124, + 385.92155620623635 + ], + "pace":[ + 395.16168913839374, + 404.60294066527558 + ], + "heartRate":[ + 131.5456052446734, + 134.65984504627627 + ], + "distanceFromStart":1.875 + }, + { + "elevation":[ + 345.47736721935661, + 363.18776661379422 + ], + "pace":[ + 340.82303041339082, + 404.71689228682374 + ], + "heartRate":[ + 125.1949698433959, + 131.31354363122026 + ], + "distanceFromStart":2.25 + }, + { + "elevation":[ + 346.23343025200535, + 497.23376445462401 + ], + "pace":[ + 261.27629148816021, + 331.68516208719467 + ], + "heartRate":[ + 131.67810544238606, + 154.26779645311458 + ], + "distanceFromStart":2.625 + }, + { + "elevation":[ + 491.57378483134391, + 547.49535224251053 + ], + "pace":[ + 296.05298644112088, + 401.14092967732398 + ], + "heartRate":[ + 151.36398089694217, + 166.20454793289232 + ], + "distanceFromStart":3 + }, + { + "elevation":[ + 472.06803233416338, + 531.92570520228401 + ], + "pace":[ + 395.50830663514012, + 401.67837917543591 + ], + "heartRate":[ + 134.41798110234078, + 151.90886697564241 + ], + "distanceFromStart":3.375 + }, + { + "elevation":[ + 339.81419476005283, + 461.03832527824829 + ], + "pace":[ + 395.31160487975183, + 404.49550455974907 + ], + "heartRate":[ + 129.97753472415462, + 138.13531094848992 + ], + "distanceFromStart":3.75 + }, + { + "elevation":[ + 303.1495508565697, + 342.3532820173541 + ], + "pace":[ + 395.02844559698116, + 402.65878340653796 + ], + "heartRate":[ + 127.72304232462609, + 133.26322270764186 + ], + "distanceFromStart":4.125 + } + ] + }, + { + "name":"Lonesome Ridge Trail", + "id":1005, + "distance":4.5, + "difficulty":3, + "observations":[ + { + "elevation":[ + 291.65263635636268, + 309.26016677925196 + ], + "pace":[ + 396.08716481908732, + 403.68937873525232 + ], + "heartRate":[ + 117.16351898665887, + 121.95815455919609 + ], + "distanceFromStart":0 + }, + { + "elevation":[ + 299.24001936628116, + 317.44584350790012 + ], + "pace":[ + 380.19020240756623, + 395.3978319010256 + ], + "heartRate":[ + 117.6410892152911, + 124.82185220506081 + ], + "distanceFromStart":0.375 + }, + { + "elevation":[ + 303.62145464574394, + 336.05569457646544 + ], + "pace":[ + 380.55927782266116, + 397.60789726832775 + ], + "heartRate":[ + 121.52696452049059, + 127.31525441110122 + ], + "distanceFromStart":0.75 + }, + { + "elevation":[ + 319.90393365162629, + 346.26966025518789 + ], + "pace":[ + 357.94116421258531, + 398.0750288648062 + ], + "heartRate":[ + 123.75908585923588, + 132.77069404486801 + ], + "distanceFromStart":1.125 + }, + { + "elevation":[ + 354.17104439267905, + 403.57031216972939 + ], + "pace":[ + 335.07385149392701, + 397.82674381875808 + ], + "heartRate":[ + 130.8235194572915, + 140.55700591418218 + ], + "distanceFromStart":1.5 + }, + { + "elevation":[ + 357.42992871175124, + 385.92155620623635 + ], + "pace":[ + 395.16168913839374, + 404.60294066527558 + ], + "heartRate":[ + 131.5456052446734, + 134.65984504627627 + ], + "distanceFromStart":1.875 + }, + { + "elevation":[ + 345.47736721935661, + 363.18776661379422 + ], + "pace":[ + 340.82303041339082, + 404.71689228682374 + ], + "heartRate":[ + 125.1949698433959, + 131.31354363122026 + ], + "distanceFromStart":2.25 + }, + { + "elevation":[ + 346.23343025200535, + 497.23376445462401 + ], + "pace":[ + 261.27629148816021, + 331.68516208719467 + ], + "heartRate":[ + 131.67810544238606, + 154.26779645311458 + ], + "distanceFromStart":2.625 + }, + { + "elevation":[ + 491.57378483134391, + 547.49535224251053 + ], + "pace":[ + 296.05298644112088, + 401.14092967732398 + ], + "heartRate":[ + 151.36398089694217, + 166.20454793289232 + ], + "distanceFromStart":3 + }, + { + "elevation":[ + 472.06803233416338, + 531.92570520228401 + ], + "pace":[ + 395.50830663514012, + 401.67837917543591 + ], + "heartRate":[ + 134.41798110234078, + 151.90886697564241 + ], + "distanceFromStart":3.375 + }, + { + "elevation":[ + 339.81419476005283, + 461.03832527824829 + ], + "pace":[ + 395.31160487975183, + 404.49550455974907 + ], + "heartRate":[ + 129.97753472415462, + 138.13531094848992 + ], + "distanceFromStart":3.75 + }, + { + "elevation":[ + 303.1495508565697, + 342.3532820173541 + ], + "pace":[ + 395.02844559698116, + 402.65878340653796 + ], + "heartRate":[ + 127.72304232462609, + 133.26322270764186 + ], + "distanceFromStart":4.125 + } + ] + }, + { + "name":"Lonesome Ridge Trail", + "id":1006, + "distance":4.5, + "difficulty":3, + "observations":[ + { + "elevation":[ + 291.65263635636268, + 309.26016677925196 + ], + "pace":[ + 396.08716481908732, + 403.68937873525232 + ], + "heartRate":[ + 117.16351898665887, + 121.95815455919609 + ], + "distanceFromStart":0 + }, + { + "elevation":[ + 299.24001936628116, + 317.44584350790012 + ], + "pace":[ + 380.19020240756623, + 395.3978319010256 + ], + "heartRate":[ + 117.6410892152911, + 124.82185220506081 + ], + "distanceFromStart":0.375 + }, + { + "elevation":[ + 303.62145464574394, + 336.05569457646544 + ], + "pace":[ + 380.55927782266116, + 397.60789726832775 + ], + "heartRate":[ + 121.52696452049059, + 127.31525441110122 + ], + "distanceFromStart":0.75 + }, + { + "elevation":[ + 319.90393365162629, + 346.26966025518789 + ], + "pace":[ + 357.94116421258531, + 398.0750288648062 + ], + "heartRate":[ + 123.75908585923588, + 132.77069404486801 + ], + "distanceFromStart":1.125 + }, + { + "elevation":[ + 354.17104439267905, + 403.57031216972939 + ], + "pace":[ + 335.07385149392701, + 397.82674381875808 + ], + "heartRate":[ + 130.8235194572915, + 140.55700591418218 + ], + "distanceFromStart":1.5 + }, + { + "elevation":[ + 357.42992871175124, + 385.92155620623635 + ], + "pace":[ + 395.16168913839374, + 404.60294066527558 + ], + "heartRate":[ + 131.5456052446734, + 134.65984504627627 + ], + "distanceFromStart":1.875 + }, + { + "elevation":[ + 345.47736721935661, + 363.18776661379422 + ], + "pace":[ + 340.82303041339082, + 404.71689228682374 + ], + "heartRate":[ + 125.1949698433959, + 131.31354363122026 + ], + "distanceFromStart":2.25 + }, + { + "elevation":[ + 346.23343025200535, + 497.23376445462401 + ], + "pace":[ + 261.27629148816021, + 331.68516208719467 + ], + "heartRate":[ + 131.67810544238606, + 154.26779645311458 + ], + "distanceFromStart":2.625 + }, + { + "elevation":[ + 491.57378483134391, + 547.49535224251053 + ], + "pace":[ + 296.05298644112088, + 401.14092967732398 + ], + "heartRate":[ + 151.36398089694217, + 166.20454793289232 + ], + "distanceFromStart":3 + }, + { + "elevation":[ + 472.06803233416338, + 531.92570520228401 + ], + "pace":[ + 395.50830663514012, + 401.67837917543591 + ], + "heartRate":[ + 134.41798110234078, + 151.90886697564241 + ], + "distanceFromStart":3.375 + }, + { + "elevation":[ + 339.81419476005283, + 461.03832527824829 + ], + "pace":[ + 395.31160487975183, + 404.49550455974907 + ], + "heartRate":[ + 129.97753472415462, + 138.13531094848992 + ], + "distanceFromStart":3.75 + }, + { + "elevation":[ + 303.1495508565697, + 342.3532820173541 + ], + "pace":[ + 395.02844559698116, + 402.65878340653796 + ], + "heartRate":[ + 127.72304232462609, + 133.26322270764186 + ], + "distanceFromStart":4.125 + } + ] + }, + { + "name":"Lonesome Ridge Trail", + "id":1007, + "distance":4.5, + "difficulty":3, + "observations":[ + { + "elevation":[ + 291.65263635636268, + 309.26016677925196 + ], + "pace":[ + 396.08716481908732, + 403.68937873525232 + ], + "heartRate":[ + 117.16351898665887, + 121.95815455919609 + ], + "distanceFromStart":0 + }, + { + "elevation":[ + 299.24001936628116, + 317.44584350790012 + ], + "pace":[ + 380.19020240756623, + 395.3978319010256 + ], + "heartRate":[ + 117.6410892152911, + 124.82185220506081 + ], + "distanceFromStart":0.375 + }, + { + "elevation":[ + 303.62145464574394, + 336.05569457646544 + ], + "pace":[ + 380.55927782266116, + 397.60789726832775 + ], + "heartRate":[ + 121.52696452049059, + 127.31525441110122 + ], + "distanceFromStart":0.75 + }, + { + "elevation":[ + 319.90393365162629, + 346.26966025518789 + ], + "pace":[ + 357.94116421258531, + 398.0750288648062 + ], + "heartRate":[ + 123.75908585923588, + 132.77069404486801 + ], + "distanceFromStart":1.125 + }, + { + "elevation":[ + 354.17104439267905, + 403.57031216972939 + ], + "pace":[ + 335.07385149392701, + 397.82674381875808 + ], + "heartRate":[ + 130.8235194572915, + 140.55700591418218 + ], + "distanceFromStart":1.5 + }, + { + "elevation":[ + 357.42992871175124, + 385.92155620623635 + ], + "pace":[ + 395.16168913839374, + 404.60294066527558 + ], + "heartRate":[ + 131.5456052446734, + 134.65984504627627 + ], + "distanceFromStart":1.875 + }, + { + "elevation":[ + 345.47736721935661, + 363.18776661379422 + ], + "pace":[ + 340.82303041339082, + 404.71689228682374 + ], + "heartRate":[ + 125.1949698433959, + 131.31354363122026 + ], + "distanceFromStart":2.25 + }, + { + "elevation":[ + 346.23343025200535, + 497.23376445462401 + ], + "pace":[ + 261.27629148816021, + 331.68516208719467 + ], + "heartRate":[ + 131.67810544238606, + 154.26779645311458 + ], + "distanceFromStart":2.625 + }, + { + "elevation":[ + 491.57378483134391, + 547.49535224251053 + ], + "pace":[ + 296.05298644112088, + 401.14092967732398 + ], + "heartRate":[ + 151.36398089694217, + 166.20454793289232 + ], + "distanceFromStart":3 + }, + { + "elevation":[ + 472.06803233416338, + 531.92570520228401 + ], + "pace":[ + 395.50830663514012, + 401.67837917543591 + ], + "heartRate":[ + 134.41798110234078, + 151.90886697564241 + ], + "distanceFromStart":3.375 + }, + { + "elevation":[ + 339.81419476005283, + 461.03832527824829 + ], + "pace":[ + 395.31160487975183, + 404.49550455974907 + ], + "heartRate":[ + 129.97753472415462, + 138.13531094848992 + ], + "distanceFromStart":3.75 + }, + { + "elevation":[ + 303.1495508565697, + 342.3532820173541 + ], + "pace":[ + 395.02844559698116, + 402.65878340653796 + ], + "heartRate":[ + 127.72304232462609, + 133.26322270764186 + ], + "distanceFromStart":4.125 + } + ] + }, + { + "name":"Lonesome Ridge Trail", + "id":1008, + "distance":4.5, + "difficulty":3, + "observations":[ + { + "elevation":[ + 291.65263635636268, + 309.26016677925196 + ], + "pace":[ + 396.08716481908732, + 403.68937873525232 + ], + "heartRate":[ + 117.16351898665887, + 121.95815455919609 + ], + "distanceFromStart":0 + }, + { + "elevation":[ + 299.24001936628116, + 317.44584350790012 + ], + "pace":[ + 380.19020240756623, + 395.3978319010256 + ], + "heartRate":[ + 117.6410892152911, + 124.82185220506081 + ], + "distanceFromStart":0.375 + }, + { + "elevation":[ + 303.62145464574394, + 336.05569457646544 + ], + "pace":[ + 380.55927782266116, + 397.60789726832775 + ], + "heartRate":[ + 121.52696452049059, + 127.31525441110122 + ], + "distanceFromStart":0.75 + }, + { + "elevation":[ + 319.90393365162629, + 346.26966025518789 + ], + "pace":[ + 357.94116421258531, + 398.0750288648062 + ], + "heartRate":[ + 123.75908585923588, + 132.77069404486801 + ], + "distanceFromStart":1.125 + }, + { + "elevation":[ + 354.17104439267905, + 403.57031216972939 + ], + "pace":[ + 335.07385149392701, + 397.82674381875808 + ], + "heartRate":[ + 130.8235194572915, + 140.55700591418218 + ], + "distanceFromStart":1.5 + }, + { + "elevation":[ + 357.42992871175124, + 385.92155620623635 + ], + "pace":[ + 395.16168913839374, + 404.60294066527558 + ], + "heartRate":[ + 131.5456052446734, + 134.65984504627627 + ], + "distanceFromStart":1.875 + }, + { + "elevation":[ + 345.47736721935661, + 363.18776661379422 + ], + "pace":[ + 340.82303041339082, + 404.71689228682374 + ], + "heartRate":[ + 125.1949698433959, + 131.31354363122026 + ], + "distanceFromStart":2.25 + }, + { + "elevation":[ + 346.23343025200535, + 497.23376445462401 + ], + "pace":[ + 261.27629148816021, + 331.68516208719467 + ], + "heartRate":[ + 131.67810544238606, + 154.26779645311458 + ], + "distanceFromStart":2.625 + }, + { + "elevation":[ + 491.57378483134391, + 547.49535224251053 + ], + "pace":[ + 296.05298644112088, + 401.14092967732398 + ], + "heartRate":[ + 151.36398089694217, + 166.20454793289232 + ], + "distanceFromStart":3 + }, + { + "elevation":[ + 472.06803233416338, + 531.92570520228401 + ], + "pace":[ + 395.50830663514012, + 401.67837917543591 + ], + "heartRate":[ + 134.41798110234078, + 151.90886697564241 + ], + "distanceFromStart":3.375 + }, + { + "elevation":[ + 339.81419476005283, + 461.03832527824829 + ], + "pace":[ + 395.31160487975183, + 404.49550455974907 + ], + "heartRate":[ + 129.97753472415462, + 138.13531094848992 + ], + "distanceFromStart":3.75 + }, + { + "elevation":[ + 303.1495508565697, + 342.3532820173541 + ], + "pace":[ + 395.02844559698116, + 402.65878340653796 + ], + "heartRate":[ + 127.72304232462609, + 133.26322270764186 + ], + "distanceFromStart":4.125 + } + ] + }, + { + "name":"Lonesome Ridge Trail", + "id":1009, + "distance":4.5, + "difficulty":3, + "observations":[ + { + "elevation":[ + 291.65263635636268, + 309.26016677925196 + ], + "pace":[ + 396.08716481908732, + 403.68937873525232 + ], + "heartRate":[ + 117.16351898665887, + 121.95815455919609 + ], + "distanceFromStart":0 + }, + { + "elevation":[ + 299.24001936628116, + 317.44584350790012 + ], + "pace":[ + 380.19020240756623, + 395.3978319010256 + ], + "heartRate":[ + 117.6410892152911, + 124.82185220506081 + ], + "distanceFromStart":0.375 + }, + { + "elevation":[ + 303.62145464574394, + 336.05569457646544 + ], + "pace":[ + 380.55927782266116, + 397.60789726832775 + ], + "heartRate":[ + 121.52696452049059, + 127.31525441110122 + ], + "distanceFromStart":0.75 + }, + { + "elevation":[ + 319.90393365162629, + 346.26966025518789 + ], + "pace":[ + 357.94116421258531, + 398.0750288648062 + ], + "heartRate":[ + 123.75908585923588, + 132.77069404486801 + ], + "distanceFromStart":1.125 + }, + { + "elevation":[ + 354.17104439267905, + 403.57031216972939 + ], + "pace":[ + 335.07385149392701, + 397.82674381875808 + ], + "heartRate":[ + 130.8235194572915, + 140.55700591418218 + ], + "distanceFromStart":1.5 + }, + { + "elevation":[ + 357.42992871175124, + 385.92155620623635 + ], + "pace":[ + 395.16168913839374, + 404.60294066527558 + ], + "heartRate":[ + 131.5456052446734, + 134.65984504627627 + ], + "distanceFromStart":1.875 + }, + { + "elevation":[ + 345.47736721935661, + 363.18776661379422 + ], + "pace":[ + 340.82303041339082, + 404.71689228682374 + ], + "heartRate":[ + 125.1949698433959, + 131.31354363122026 + ], + "distanceFromStart":2.25 + }, + { + "elevation":[ + 346.23343025200535, + 497.23376445462401 + ], + "pace":[ + 261.27629148816021, + 331.68516208719467 + ], + "heartRate":[ + 131.67810544238606, + 154.26779645311458 + ], + "distanceFromStart":2.625 + }, + { + "elevation":[ + 491.57378483134391, + 547.49535224251053 + ], + "pace":[ + 296.05298644112088, + 401.14092967732398 + ], + "heartRate":[ + 151.36398089694217, + 166.20454793289232 + ], + "distanceFromStart":3 + }, + { + "elevation":[ + 472.06803233416338, + 531.92570520228401 + ], + "pace":[ + 395.50830663514012, + 401.67837917543591 + ], + "heartRate":[ + 134.41798110234078, + 151.90886697564241 + ], + "distanceFromStart":3.375 + }, + { + "elevation":[ + 339.81419476005283, + 461.03832527824829 + ], + "pace":[ + 395.31160487975183, + 404.49550455974907 + ], + "heartRate":[ + 129.97753472415462, + 138.13531094848992 + ], + "distanceFromStart":3.75 + }, + { + "elevation":[ + 303.1495508565697, + 342.3532820173541 + ], + "pace":[ + 395.02844559698116, + 402.65878340653796 + ], + "heartRate":[ + 127.72304232462609, + 133.26322270764186 + ], + "distanceFromStart":4.125 + } + ] + }, + { + "name":"Lonesome Ridge Trail", + "id":1010, + "distance":4.5, + "difficulty":3, + "observations":[ + { + "elevation":[ + 291.65263635636268, + 309.26016677925196 + ], + "pace":[ + 396.08716481908732, + 403.68937873525232 + ], + "heartRate":[ + 117.16351898665887, + 121.95815455919609 + ], + "distanceFromStart":0 + }, + { + "elevation":[ + 299.24001936628116, + 317.44584350790012 + ], + "pace":[ + 380.19020240756623, + 395.3978319010256 + ], + "heartRate":[ + 117.6410892152911, + 124.82185220506081 + ], + "distanceFromStart":0.375 + }, + { + "elevation":[ + 303.62145464574394, + 336.05569457646544 + ], + "pace":[ + 380.55927782266116, + 397.60789726832775 + ], + "heartRate":[ + 121.52696452049059, + 127.31525441110122 + ], + "distanceFromStart":0.75 + }, + { + "elevation":[ + 319.90393365162629, + 346.26966025518789 + ], + "pace":[ + 357.94116421258531, + 398.0750288648062 + ], + "heartRate":[ + 123.75908585923588, + 132.77069404486801 + ], + "distanceFromStart":1.125 + }, + { + "elevation":[ + 354.17104439267905, + 403.57031216972939 + ], + "pace":[ + 335.07385149392701, + 397.82674381875808 + ], + "heartRate":[ + 130.8235194572915, + 140.55700591418218 + ], + "distanceFromStart":1.5 + }, + { + "elevation":[ + 357.42992871175124, + 385.92155620623635 + ], + "pace":[ + 395.16168913839374, + 404.60294066527558 + ], + "heartRate":[ + 131.5456052446734, + 134.65984504627627 + ], + "distanceFromStart":1.875 + }, + { + "elevation":[ + 345.47736721935661, + 363.18776661379422 + ], + "pace":[ + 340.82303041339082, + 404.71689228682374 + ], + "heartRate":[ + 125.1949698433959, + 131.31354363122026 + ], + "distanceFromStart":2.25 + }, + { + "elevation":[ + 346.23343025200535, + 497.23376445462401 + ], + "pace":[ + 261.27629148816021, + 331.68516208719467 + ], + "heartRate":[ + 131.67810544238606, + 154.26779645311458 + ], + "distanceFromStart":2.625 + }, + { + "elevation":[ + 491.57378483134391, + 547.49535224251053 + ], + "pace":[ + 296.05298644112088, + 401.14092967732398 + ], + "heartRate":[ + 151.36398089694217, + 166.20454793289232 + ], + "distanceFromStart":3 + }, + { + "elevation":[ + 472.06803233416338, + 531.92570520228401 + ], + "pace":[ + 395.50830663514012, + 401.67837917543591 + ], + "heartRate":[ + 134.41798110234078, + 151.90886697564241 + ], + "distanceFromStart":3.375 + }, + { + "elevation":[ + 339.81419476005283, + 461.03832527824829 + ], + "pace":[ + 395.31160487975183, + 404.49550455974907 + ], + "heartRate":[ + 129.97753472415462, + 138.13531094848992 + ], + "distanceFromStart":3.75 + }, + { + "elevation":[ + 303.1495508565697, + 342.3532820173541 + ], + "pace":[ + 395.02844559698116, + 402.65878340653796 + ], + "heartRate":[ + 127.72304232462609, + 133.26322270764186 + ], + "distanceFromStart":4.125 + } + ] + } +] diff --git a/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Resources/icybay.jpg b/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Resources/icybay.jpg new file mode 100644 index 0000000..feb1764 Binary files /dev/null and b/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Resources/icybay.jpg differ diff --git a/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Resources/lakemcdonald.jpg b/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Resources/lakemcdonald.jpg new file mode 100644 index 0000000..bd9d6b9 Binary files /dev/null and b/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Resources/lakemcdonald.jpg differ diff --git a/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Resources/landmarkData.json b/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Resources/landmarkData.json new file mode 100644 index 0000000..e5b14fc --- /dev/null +++ b/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Resources/landmarkData.json @@ -0,0 +1,182 @@ +[ + { + "name": "Turtle Rock", + "category": "Rivers", + "city": "Twentynine Palms", + "state": "California", + "id": 1001, + "isFeatured": true, + "isFavorite": true, + "park": "Joshua Tree National Park", + "coordinates": { + "longitude": -116.166868, + "latitude": 34.011286 + }, + "imageName": "turtlerock" + }, + { + "name": "Silver Salmon Creek", + "category": "Lakes", + "city": "Port Alsworth", + "state": "Alaska", + "id": 1002, + "isFeatured": false, + "isFavorite": false, + "park": "Lake Clark National Park and Preserve", + "coordinates": { + "longitude": -152.665167, + "latitude": 59.980167 + }, + "imageName": "silversalmoncreek" + }, + { + "name": "Chilkoot Trail", + "category": "Mountains", + "city": "Skagway", + "state": "Alaska", + "id": 1003, + "isFeatured": false, + "isFavorite": true, + "park": "Klondike Gold Rush National Historical Park", + "coordinates": { + "longitude": -135.334571, + "latitude": 59.560551 + }, + "imageName": "chilkoottrail" + }, + { + "name": "St. Mary Lake", + "category": "Lakes", + "city": "Browning", + "state": "Montana", + "id": 1004, + "isFeatured": true, + "isFavorite": true, + "park": "Glacier National Park", + "coordinates": { + "longitude": -113.536248, + "latitude": 48.69423 + }, + "imageName": "stmarylake" + }, + { + "name": "Twin Lake", + "category": "Lakes", + "city": "Twin Lakes", + "state": "Alaska", + "id": 1005, + "isFeatured": false, + "isFavorite": false, + "park": "Lake Clark National Park and Preserve", + "coordinates": { + "longitude": -153.849883, + "latitude": 60.641684 + }, + "imageName": "twinlake" + }, + { + "name": "Lake McDonald", + "category": "Mountains", + "city": "West Glacier", + "state": "Montana", + "id": 1006, + "isFeatured": false, + "isFavorite": false, + "park": "Glacier National Park", + "coordinates": { + "longitude": -113.934831, + "latitude": 48.56002 + }, + "imageName": "lakemcdonald" + }, + { + "name": "Charley Rivers", + "category": "Rivers", + "city": "Eaking", + "state": "Alaska", + "id": 1007, + "isFeatured": true, + "isFavorite": false, + "park": "Charley Rivers National Preserve", + "coordinates": { + "longitude": -143.122586, + "latitude": 65.350021 + }, + "imageName": "charleyrivers", + }, + { + "name": "Icy Bay", + "category": "Mountains", + "city": "Icy Bay", + "state": "Alaska", + "id": 1008, + "isFeatured": false, + "isFavorite": false, + "park": "Wrangell-St. Elias National Park and Preserve", + "coordinates": { + "longitude": -141.518167, + "latitude": 60.089917 + }, + "imageName": "icybay" + }, + { + "name": "Rainbow Lake", + "category": "Lakes", + "city": "Willow", + "state": "Alaska", + "id": 1009, + "isFeatured": false, + "isFavorite": false, + "park": "State Recreation Area", + "coordinates": { + "longitude": -150.086103, + "latitude": 61.694334 + }, + "imageName": "rainbowlake" + }, + { + "name": "Hidden Lake", + "category": "Lakes", + "city": "Newhalem", + "state": "Washington", + "id": 1010, + "isFeatured": false, + "isFavorite": false, + "park": "North Cascades National Park", + "coordinates": { + "longitude": -121.17799, + "latitude": 48.495442 + }, + "imageName": "hiddenlake" + }, + { + "name": "Chincoteague", + "category": "Rivers", + "city": "Chincoteague", + "state": "Virginia", + "id": 1011, + "isFeatured": false, + "isFavorite": false, + "park": "Chincoteague National Wildlife Refuge", + "coordinates": { + "longitude": -75.383212, + "latitude": 37.91531 + }, + "imageName": "chincoteague" + }, + { + "name": "Lake Umbagog", + "category": "Lakes", + "city": "Errol", + "state": "New Hampshire", + "id": 1012, + "isFeatured": true, + "isFavorite": false, + "park": "Umbagog National Wildlife Refuge", + "coordinates": { + "longitude": -71.056816, + "latitude": 44.747408 + }, + "imageName": "umbagog" + } +] diff --git a/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Resources/rainbowlake.jpg b/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Resources/rainbowlake.jpg new file mode 100644 index 0000000..6da43dd Binary files /dev/null and b/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Resources/rainbowlake.jpg differ diff --git a/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Resources/silversalmoncreek.jpg b/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Resources/silversalmoncreek.jpg new file mode 100644 index 0000000..f657532 Binary files /dev/null and b/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Resources/silversalmoncreek.jpg differ diff --git a/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Resources/stmarylake.jpg b/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Resources/stmarylake.jpg new file mode 100644 index 0000000..1c71de4 Binary files /dev/null and b/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Resources/stmarylake.jpg differ diff --git a/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Resources/turtlerock.jpg b/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Resources/turtlerock.jpg new file mode 100644 index 0000000..f7a6e6d Binary files /dev/null and b/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Resources/turtlerock.jpg differ diff --git a/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Resources/twinlake.jpg b/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Resources/twinlake.jpg new file mode 100644 index 0000000..3e7a57c Binary files /dev/null and b/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Resources/twinlake.jpg differ diff --git a/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Resources/umbagog.jpg b/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Resources/umbagog.jpg new file mode 100644 index 0000000..56291c6 Binary files /dev/null and b/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Resources/umbagog.jpg differ diff --git a/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/SceneDelegate.swift b/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/SceneDelegate.swift new file mode 100644 index 0000000..51057d3 --- /dev/null +++ b/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/SceneDelegate.swift @@ -0,0 +1,58 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +The scene delegate. +*/ + +import UIKit +import SwiftUI + +class SceneDelegate: UIResponder, UIWindowSceneDelegate { + + var window: UIWindow? + + func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { + // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`. + // If using a storyboard, the `window` property will automatically be initialized and attached to the scene. + // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead). + + // Use a UIHostingController as window root view controller + if let windowScene = scene as? UIWindowScene { + let window = UIWindow(windowScene: windowScene) + window.rootViewController = UIHostingController(rootView: CategoryHome().environmentObject(UserData())) + self.window = window + window.makeKeyAndVisible() + } + } + + func sceneDidDisconnect(_ scene: UIScene) { + // Called as the scene is being released by the system. + // This occurs shortly after the scene enters the background, or when its session is discarded. + // Release any resources associated with this scene that can be re-created the next time the scene connects. + // The scene may re-connect later, as its session was not neccessarily discarded (see `application:didDiscardSceneSessions` instead). + } + + func sceneDidBecomeActive(_ scene: UIScene) { + // Called when the scene has moved from an inactive state to an active state. + // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive. + } + + func sceneWillResignActive(_ scene: UIScene) { + // Called when the scene will move from an active state to an inactive state. + // This may occur due to temporary interruptions (ex. an incoming phone call). + } + + func sceneWillEnterForeground(_ scene: UIScene) { + // Called as the scene transitions from the background to the foreground. + // Use this method to undo the changes made on entering the background. + } + + func sceneDidEnterBackground(_ scene: UIScene) { + // Called as the scene transitions from the foreground to the background. + // Use this method to save data, release shared resources, and store enough scene-specific state information + // to restore the scene back to its current state. + } + +} + diff --git a/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Supporting Views/Badge.swift b/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Supporting Views/Badge.swift new file mode 100644 index 0000000..59f03b2 --- /dev/null +++ b/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Supporting Views/Badge.swift @@ -0,0 +1,41 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A view that displays a badge. +*/ + +import SwiftUI + +struct Badge: View { + static let rotationCount = 8 + + var badgeSymbols: some View { + ForEach(0.. + var overallRange: Range + + var heightRatio: CGFloat { + max(CGFloat(magnitude(of: range) / magnitude(of: overallRange)), 0.15) + } + + var offsetRatio: CGFloat { + CGFloat((range.lowerBound - overallRange.lowerBound) / magnitude(of: overallRange)) + } + + var animation: Animation { + Animation.spring() + .speed(2) + .delay(0.03 * Double(index)) + } + + var body: some View { + Capsule() + .fill(Color.white) + .frame(height: height * heightRatio, alignment: .bottom) + .offset(x: 0, y: height * -offsetRatio) + .animation(animation) + } +} + +#if DEBUG +struct GraphCapsule_Previews: PreviewProvider { + static var previews: some View { + GraphCapsule(index: 0, height: 150, range: 10..<50, overallRange: 0..<100) + } +} +#endif diff --git a/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Supporting Views/HikeGraph.swift b/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Supporting Views/HikeGraph.swift new file mode 100644 index 0000000..2a4ff27 --- /dev/null +++ b/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Supporting Views/HikeGraph.swift @@ -0,0 +1,74 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +The elevation, heart rate, and pace of a hike plotted on a graph. +*/ + +import SwiftUI + +func rangeOfRanges(_ ranges: C) -> Range + where C.Element == Range { + guard !ranges.isEmpty else { return 0..<0 } + let low = ranges.lazy.map { $0.lowerBound }.min()! + let high = ranges.lazy.map { $0.upperBound }.max()! + return low..) -> Double { + return range.upperBound - range.lowerBound +} + +struct HikeGraph: View { + var hike: Hike + var path: KeyPath> + + var color: Color { + switch path { + case \.elevation: + return .gray + case \.heartRate: + return Color(hue: 0, saturation: 0.5, brightness: 0.7) + case \.pace: + return Color(hue: 0.7, saturation: 0.4, brightness: 0.7) + default: + return .black + } + } + + var body: some View { + let data = hike.observations + let overallRange = rangeOfRanges(data.lazy.map { $0[keyPath: self.path] }) + let maxMagnitude = data.map { magnitude(of: $0[keyPath: path]) }.max()! + let heightRatio = 1 - CGFloat(maxMagnitude / magnitude(of: overallRange)) + + return GeometryReader { proxy in + HStack(alignment: .bottom, spacing: proxy.size.width / 120) { + ForEach(data.indices) { index in + GraphCapsule( + index: index, + height: proxy.size.height, + range: data[index][keyPath: self.path], + overallRange: overallRange) + .colorMultiply(self.color) + } + .offset(x: 0, y: proxy.size.height * heightRatio) + } + } + } +} + +#if DEBUG +struct HikeGraph_Previews: PreviewProvider { + static var previews: some View { + Group { + HikeGraph(hike: hikeData[0], path: \.elevation) + .frame(height: 200) + HikeGraph(hike: hikeData[0], path: \.heartRate) + .frame(height: 200) + HikeGraph(hike: hikeData[0], path: \.pace) + .frame(height: 200) + } + } +} +#endif diff --git a/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Supporting Views/LandmarkRow.swift b/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Supporting Views/LandmarkRow.swift new file mode 100644 index 0000000..2f8110c --- /dev/null +++ b/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Supporting Views/LandmarkRow.swift @@ -0,0 +1,38 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A single row to be displayed in a list of landmarks. +*/ + +import SwiftUI + +struct LandmarkRow: View { + var landmark: Landmark + + var body: some View { + HStack { + landmark.image(forSize: 50) + Text(verbatim: landmark.name) + Spacer() + + if landmark.isFavorite { + Image(systemName: "star.fill") + .imageScale(.medium) + .foregroundColor(.yellow) + } + } + } +} + +#if DEBUG +struct LandmarkRow_Previews: PreviewProvider { + static var previews: some View { + Group { + LandmarkRow(landmark: landmarkData[0]) + LandmarkRow(landmark: landmarkData[1]) + } + .previewLayout(.fixed(width: 300, height: 70)) + } +} +#endif diff --git a/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Supporting Views/MapView.swift b/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Supporting Views/MapView.swift new file mode 100644 index 0000000..5a8c64b --- /dev/null +++ b/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Supporting Views/MapView.swift @@ -0,0 +1,31 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A view that hosts an `MKMapView`. +*/ + +import SwiftUI +import MapKit + +struct MapView: UIViewRepresentable { + var coordinate: CLLocationCoordinate2D + + func makeUIView(context: Context) -> MKMapView { + MKMapView(frame: .zero) + } + + func updateUIView(_ view: MKMapView, context: Context) { + let span = MKCoordinateSpan(latitudeDelta: 0.02, longitudeDelta: 0.02) + let region = MKCoordinateRegion(center: coordinate, span: span) + view.setRegion(region, animated: true) + } +} + +#if DEBUG +struct MapView_Previews: PreviewProvider { + static var previews: some View { + MapView(coordinate: landmarkData[0].locationCoordinate) + } +} +#endif diff --git a/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Supporting Views/RotatedBadgeSymbol.swift b/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Supporting Views/RotatedBadgeSymbol.swift new file mode 100644 index 0000000..a7e4b53 --- /dev/null +++ b/Other Projects/Composing Complex Interfaces/Complete/Landmarks/Landmarks/Supporting Views/RotatedBadgeSymbol.swift @@ -0,0 +1,26 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A view that displays a rotated version of a badge symbol. +*/ + +import SwiftUI + +struct RotatedBadgeSymbol: View { + let angle: Angle + + var body: some View { + BadgeSymbol() + .padding(-60) + .rotationEffect(angle, anchor: .bottom) + } +} + +#if DEBUG +struct RotatedBadgeSymbol_Previews: PreviewProvider { + static var previews: some View { + RotatedBadgeSymbol(angle: .init(degrees: 5)) + } +} +#endif diff --git a/Other Projects/Composing Complex Interfaces/Complete/README.md b/Other Projects/Composing Complex Interfaces/Complete/README.md new file mode 100644 index 0000000..43ccf8c --- /dev/null +++ b/Other Projects/Composing Complex Interfaces/Complete/README.md @@ -0,0 +1,3 @@ +# Completed Project: Composing Complex Interfaces + +Explore the completed project for the [Composing Complex Interfaces](https://developer.apple.com/tutorials/swiftui/composing-complex-interfaces) tutorial. \ No newline at end of file diff --git a/Other Projects/Composing Complex Interfaces/StartingPoint/.gitignore b/Other Projects/Composing Complex Interfaces/StartingPoint/.gitignore new file mode 100644 index 0000000..9e50718 --- /dev/null +++ b/Other Projects/Composing Complex Interfaces/StartingPoint/.gitignore @@ -0,0 +1,21 @@ +# See LICENSE folder for this sample’s licensing information. +# +# Apple sample code gitignore configuration. + +# Finder +.DS_Store + +# Xcode - User files +xcuserdata/ + +**/*.xcodeproj/project.xcworkspace/* +!**/*.xcodeproj/project.xcworkspace/xcshareddata + +**/*.xcodeproj/project.xcworkspace/xcshareddata/* +!**/*.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings + +**/*.playground/playground.xcworkspace/* +!**/*.playground/playground.xcworkspace/xcshareddata + +**/*.playground/playground.xcworkspace/xcshareddata/* +!**/*.playground/playground.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings diff --git a/Other Projects/Composing Complex Interfaces/StartingPoint/Configuration/SampleCode.xcconfig b/Other Projects/Composing Complex Interfaces/StartingPoint/Configuration/SampleCode.xcconfig new file mode 100644 index 0000000..db86c06 --- /dev/null +++ b/Other Projects/Composing Complex Interfaces/StartingPoint/Configuration/SampleCode.xcconfig @@ -0,0 +1,13 @@ +// +// See LICENSE folder for this sample’s licensing information. +// +// SampleCode.xcconfig +// + +// The `SAMPLE_CODE_DISAMBIGUATOR` configuration is to make it easier to build +// and run a sample code project. Once you set your project's development team, +// you'll have a unique bundle identifier. This is because the bundle identifier +// is derived based on the 'SAMPLE_CODE_DISAMBIGUATOR' value. Do not use this +// approach in your own projects—it's only useful for sample code projects because +// they are frequently downloaded and don't have a development team set. +SAMPLE_CODE_DISAMBIGUATOR=${DEVELOPMENT_TEAM} diff --git a/Other Projects/Composing Complex Interfaces/StartingPoint/LICENSE/LICENSE.txt b/Other Projects/Composing Complex Interfaces/StartingPoint/LICENSE/LICENSE.txt new file mode 100644 index 0000000..94e3d54 --- /dev/null +++ b/Other Projects/Composing Complex Interfaces/StartingPoint/LICENSE/LICENSE.txt @@ -0,0 +1,8 @@ +Copyright © 2019 Apple Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + diff --git a/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/ComposingComplexInterfaces.xcodeproj/.xcodesamplecode.plist b/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/ComposingComplexInterfaces.xcodeproj/.xcodesamplecode.plist new file mode 100644 index 0000000..5dd5da8 --- /dev/null +++ b/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/ComposingComplexInterfaces.xcodeproj/.xcodesamplecode.plist @@ -0,0 +1,5 @@ + + + + + diff --git a/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/ComposingComplexInterfaces.xcodeproj/project.pbxproj b/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/ComposingComplexInterfaces.xcodeproj/project.pbxproj new file mode 100644 index 0000000..9348a60 --- /dev/null +++ b/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/ComposingComplexInterfaces.xcodeproj/project.pbxproj @@ -0,0 +1,525 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 50; + objects = { + +/* Begin PBXBuildFile section */ + B7310DD1229F6839001079B9 /* HexagonParameters.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7310DD0229F6839001079B9 /* HexagonParameters.swift */; }; + B7310DD3229F6CA9001079B9 /* Badge.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7310DD2229F6CA9001079B9 /* Badge.swift */; }; + B7394866229F194000C47603 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7394865229F194000C47603 /* AppDelegate.swift */; }; + B7394868229F194000C47603 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7394867229F194000C47603 /* SceneDelegate.swift */; }; + B739486A229F194000C47603 /* LandmarkDetail.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7394869229F194000C47603 /* LandmarkDetail.swift */; }; + B739486C229F194200C47603 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B739486B229F194200C47603 /* Assets.xcassets */; }; + B739486F229F194200C47603 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B739486E229F194200C47603 /* Preview Assets.xcassets */; }; + B7394872229F194200C47603 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B7394870229F194200C47603 /* LaunchScreen.storyboard */; }; + B739487A229F1B3F00C47603 /* CircleImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7394879229F1B3F00C47603 /* CircleImage.swift */; }; + B739487C229F1B6800C47603 /* MapView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B739487B229F1B6800C47603 /* MapView.swift */; }; + B7394881229F28B900C47603 /* Landmark.swift in Sources */ = {isa = PBXBuildFile; fileRef = B739487F229F28B900C47603 /* Landmark.swift */; }; + B7394882229F28B900C47603 /* Data.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7394880229F28B900C47603 /* Data.swift */; }; + B7394891229F292F00C47603 /* rainbowlake.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B7394884229F292D00C47603 /* rainbowlake.jpg */; }; + B7394893229F292F00C47603 /* icybay.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B7394886229F292E00C47603 /* icybay.jpg */; }; + B7394894229F292F00C47603 /* lakemcdonald.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B7394887229F292E00C47603 /* lakemcdonald.jpg */; }; + B7394895229F292F00C47603 /* turtlerock.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B7394888229F292E00C47603 /* turtlerock.jpg */; }; + B7394896229F292F00C47603 /* umbagog.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B7394889229F292E00C47603 /* umbagog.jpg */; }; + B7394897229F292F00C47603 /* hiddenlake.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B739488A229F292E00C47603 /* hiddenlake.jpg */; }; + B7394898229F292F00C47603 /* stmarylake.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B739488B229F292E00C47603 /* stmarylake.jpg */; }; + B7394899229F292F00C47603 /* twinlake.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B739488C229F292E00C47603 /* twinlake.jpg */; }; + B739489A229F292F00C47603 /* silversalmoncreek.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B739488D229F292E00C47603 /* silversalmoncreek.jpg */; }; + B739489B229F292F00C47603 /* landmarkData.json in Resources */ = {isa = PBXBuildFile; fileRef = B739488E229F292E00C47603 /* landmarkData.json */; }; + B739489C229F292F00C47603 /* chincoteague.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B739488F229F292F00C47603 /* chincoteague.jpg */; }; + B739489D229F292F00C47603 /* chilkoottrail.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B7394890229F292F00C47603 /* chilkoottrail.jpg */; }; + B739489F229F2D9700C47603 /* LandmarkRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = B739489E229F2D9700C47603 /* LandmarkRow.swift */; }; + B73948A1229F2E1F00C47603 /* LandmarkList.swift in Sources */ = {isa = PBXBuildFile; fileRef = B73948A0229F2E1F00C47603 /* LandmarkList.swift */; }; + B73948A3229F3E2200C47603 /* charleyrivers.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B73948A2229F3E2200C47603 /* charleyrivers.jpg */; }; + B7D2AAC5229F4D7C0061E5F5 /* UserData.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7D2AAC4229F4D7C0061E5F5 /* UserData.swift */; }; + B7D587AE229F7382006E8DCF /* BadgeBackground.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7D587AD229F7382006E8DCF /* BadgeBackground.swift */; }; + B7D587B0229F73C1006E8DCF /* BadgeSymbol.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7D587AF229F73C1006E8DCF /* BadgeSymbol.swift */; }; + B7D587B2229F7406006E8DCF /* RotatedBadgeSymbol.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7D587B1229F7406006E8DCF /* RotatedBadgeSymbol.swift */; }; + B7D587B6229F825D006E8DCF /* HikeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7D587B5229F825D006E8DCF /* HikeView.swift */; }; + B7D587B8229F826D006E8DCF /* GraphCapsule.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7D587B7229F826D006E8DCF /* GraphCapsule.swift */; }; + B7D587BA229F8288006E8DCF /* Hike.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7D587B9229F8288006E8DCF /* Hike.swift */; }; + B7D587BC229F82EB006E8DCF /* HikeDetail.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7D587BB229F82EB006E8DCF /* HikeDetail.swift */; }; + B7D587BE229F82FF006E8DCF /* HikeGraph.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7D587BD229F82FF006E8DCF /* HikeGraph.swift */; }; + B7D587C0229F830B006E8DCF /* hikeData.json in Resources */ = {isa = PBXBuildFile; fileRef = B7D587BF229F830B006E8DCF /* hikeData.json */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 2858D4702858CD0000000001 /* SampleCode.xcconfig */ = {isa = PBXFileReference; name = SampleCode.xcconfig; path = ../Configuration/SampleCode.xcconfig; sourceTree = ""; }; + 285AE3C0285ADF0000000001 /* LICENSE.txt */ = {isa = PBXFileReference; includeInIndex = 1; path = LICENSE.txt; sourceTree = ""; }; + B7310DD0229F6839001079B9 /* HexagonParameters.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HexagonParameters.swift; sourceTree = ""; }; + B7310DD2229F6CA9001079B9 /* Badge.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Badge.swift; sourceTree = ""; }; + B7394862229F194000C47603 /* Landmarks.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Landmarks.app; sourceTree = BUILT_PRODUCTS_DIR; }; + B7394865229F194000C47603 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + B7394867229F194000C47603 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; + B7394869229F194000C47603 /* LandmarkDetail.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LandmarkDetail.swift; sourceTree = ""; }; + B739486B229F194200C47603 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + B739486E229F194200C47603 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; + B7394871229F194200C47603 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + B7394873229F194200C47603 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + B7394879229F1B3F00C47603 /* CircleImage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CircleImage.swift; sourceTree = ""; }; + B739487B229F1B6800C47603 /* MapView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapView.swift; sourceTree = ""; }; + B739487F229F28B900C47603 /* Landmark.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Landmark.swift; sourceTree = ""; }; + B7394880229F28B900C47603 /* Data.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Data.swift; sourceTree = ""; }; + B7394884229F292D00C47603 /* rainbowlake.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = rainbowlake.jpg; sourceTree = ""; }; + B7394886229F292E00C47603 /* icybay.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = icybay.jpg; sourceTree = ""; }; + B7394887229F292E00C47603 /* lakemcdonald.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = lakemcdonald.jpg; sourceTree = ""; }; + B7394888229F292E00C47603 /* turtlerock.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = turtlerock.jpg; sourceTree = ""; }; + B7394889229F292E00C47603 /* umbagog.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = umbagog.jpg; sourceTree = ""; }; + B739488A229F292E00C47603 /* hiddenlake.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = hiddenlake.jpg; sourceTree = ""; }; + B739488B229F292E00C47603 /* stmarylake.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = stmarylake.jpg; sourceTree = ""; }; + B739488C229F292E00C47603 /* twinlake.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = twinlake.jpg; sourceTree = ""; }; + B739488D229F292E00C47603 /* silversalmoncreek.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = silversalmoncreek.jpg; sourceTree = ""; }; + B739488E229F292E00C47603 /* landmarkData.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = landmarkData.json; sourceTree = ""; }; + B739488F229F292F00C47603 /* chincoteague.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = chincoteague.jpg; sourceTree = ""; }; + B7394890229F292F00C47603 /* chilkoottrail.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = chilkoottrail.jpg; sourceTree = ""; }; + B739489E229F2D9700C47603 /* LandmarkRow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = LandmarkRow.swift; path = "Supporting Views/LandmarkRow.swift"; sourceTree = ""; }; + B73948A0229F2E1F00C47603 /* LandmarkList.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LandmarkList.swift; sourceTree = ""; }; + B73948A2229F3E2200C47603 /* charleyrivers.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = charleyrivers.jpg; sourceTree = ""; }; + B7D2AAC4229F4D7C0061E5F5 /* UserData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserData.swift; sourceTree = ""; }; + B7D587AD229F7382006E8DCF /* BadgeBackground.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BadgeBackground.swift; sourceTree = ""; }; + B7D587AF229F73C1006E8DCF /* BadgeSymbol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BadgeSymbol.swift; sourceTree = ""; }; + B7D587B1229F7406006E8DCF /* RotatedBadgeSymbol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RotatedBadgeSymbol.swift; sourceTree = ""; }; + B7D587B5229F825D006E8DCF /* HikeView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HikeView.swift; sourceTree = ""; }; + B7D587B7229F826D006E8DCF /* GraphCapsule.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GraphCapsule.swift; sourceTree = ""; }; + B7D587B9229F8288006E8DCF /* Hike.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Hike.swift; sourceTree = ""; }; + B7D587BB229F82EB006E8DCF /* HikeDetail.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HikeDetail.swift; sourceTree = ""; }; + B7D587BD229F82FF006E8DCF /* HikeGraph.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HikeGraph.swift; sourceTree = ""; }; + B7D587BF229F830B006E8DCF /* hikeData.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = hikeData.json; sourceTree = ""; }; + C4E4AAA0C4E4035000000001 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; name = README.md; path = ../README.md; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + B739485F229F194000C47603 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 2858CF802858CF4000000001 /* Configuration */ = { + isa = PBXGroup; + children = ( + 2858D4702858CD0000000001 /* SampleCode.xcconfig */, + ); + name = Configuration; + sourceTree = ""; + }; + 285ACD50285AD6E000000001 /* LICENSE */ = { + isa = PBXGroup; + children = ( + 285AE3C0285ADF0000000001 /* LICENSE.txt */, + ); + name = LICENSE; + path = ../LICENSE; + sourceTree = ""; + }; + B7394859229F194000C47603 = { + isa = PBXGroup; + children = ( + C4E4AAA0C4E4035000000001 /* README.md */, + B7394864229F194000C47603 /* Landmarks */, + B7394863229F194000C47603 /* Products */, + 2858CF802858CF4000000001 /* Configuration */, + 285ACD50285AD6E000000001 /* LICENSE */, + ); + sourceTree = ""; + }; + B7394863229F194000C47603 /* Products */ = { + isa = PBXGroup; + children = ( + B7394862229F194000C47603 /* Landmarks.app */, + ); + name = Products; + sourceTree = ""; + }; + B7394864229F194000C47603 /* Landmarks */ = { + isa = PBXGroup; + children = ( + B739487E229F282200C47603 /* Models */, + B7394865229F194000C47603 /* AppDelegate.swift */, + B7394867229F194000C47603 /* SceneDelegate.swift */, + B73948A0229F2E1F00C47603 /* LandmarkList.swift */, + B739489E229F2D9700C47603 /* LandmarkRow.swift */, + B7394869229F194000C47603 /* LandmarkDetail.swift */, + B7D587B5229F825D006E8DCF /* HikeView.swift */, + B7D587BB229F82EB006E8DCF /* HikeDetail.swift */, + B7310DD0229F6839001079B9 /* HexagonParameters.swift */, + B739487D229F1C0100C47603 /* Supporting Views */, + B7394883229F291A00C47603 /* Resources */, + B739486B229F194200C47603 /* Assets.xcassets */, + B7394870229F194200C47603 /* LaunchScreen.storyboard */, + B7394873229F194200C47603 /* Info.plist */, + B739486D229F194200C47603 /* Preview Content */, + ); + path = Landmarks; + sourceTree = ""; + }; + B739486D229F194200C47603 /* Preview Content */ = { + isa = PBXGroup; + children = ( + B739486E229F194200C47603 /* Preview Assets.xcassets */, + ); + path = "Preview Content"; + sourceTree = ""; + }; + B739487D229F1C0100C47603 /* Supporting Views */ = { + isa = PBXGroup; + children = ( + B7394879229F1B3F00C47603 /* CircleImage.swift */, + B739487B229F1B6800C47603 /* MapView.swift */, + B7310DD2229F6CA9001079B9 /* Badge.swift */, + B7D587AF229F73C1006E8DCF /* BadgeSymbol.swift */, + B7D587B1229F7406006E8DCF /* RotatedBadgeSymbol.swift */, + B7D587AD229F7382006E8DCF /* BadgeBackground.swift */, + B7D587BD229F82FF006E8DCF /* HikeGraph.swift */, + B7D587B7229F826D006E8DCF /* GraphCapsule.swift */, + ); + path = "Supporting Views"; + sourceTree = ""; + }; + B739487E229F282200C47603 /* Models */ = { + isa = PBXGroup; + children = ( + B7394880229F28B900C47603 /* Data.swift */, + B739487F229F28B900C47603 /* Landmark.swift */, + B7D587B9229F8288006E8DCF /* Hike.swift */, + B7D2AAC4229F4D7C0061E5F5 /* UserData.swift */, + ); + path = Models; + sourceTree = ""; + }; + B7394883229F291A00C47603 /* Resources */ = { + isa = PBXGroup; + children = ( + B739488E229F292E00C47603 /* landmarkData.json */, + B7D587BF229F830B006E8DCF /* hikeData.json */, + B7394890229F292F00C47603 /* chilkoottrail.jpg */, + B739488F229F292F00C47603 /* chincoteague.jpg */, + B739488A229F292E00C47603 /* hiddenlake.jpg */, + B7394886229F292E00C47603 /* icybay.jpg */, + B7394887229F292E00C47603 /* lakemcdonald.jpg */, + B7394884229F292D00C47603 /* rainbowlake.jpg */, + B739488D229F292E00C47603 /* silversalmoncreek.jpg */, + B739488B229F292E00C47603 /* stmarylake.jpg */, + B7394888229F292E00C47603 /* turtlerock.jpg */, + B739488C229F292E00C47603 /* twinlake.jpg */, + B7394889229F292E00C47603 /* umbagog.jpg */, + B73948A2229F3E2200C47603 /* charleyrivers.jpg */, + ); + path = Resources; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + B7394861229F194000C47603 /* Landmarks */ = { + isa = PBXNativeTarget; + buildConfigurationList = B7394876229F194200C47603 /* Build configuration list for PBXNativeTarget "Landmarks" */; + buildPhases = ( + B739485E229F194000C47603 /* Sources */, + B739485F229F194000C47603 /* Frameworks */, + B7394860229F194000C47603 /* Resources */, + C602AC70C605937000000001, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Landmarks; + productName = Landmarks; + productReference = B7394862229F194000C47603 /* Landmarks.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + B739485A229F194000C47603 /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 1100; + LastUpgradeCheck = 1100; + ORGANIZATIONNAME = Apple; + TargetAttributes = { + B7394861229F194000C47603 = { + CreatedOnToolsVersion = 11.0; + }; + }; + }; + buildConfigurationList = B739485D229F194000C47603 /* Build configuration list for PBXProject "ComposingComplexInterfaces" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = B7394859229F194000C47603; + productRefGroup = B7394863229F194000C47603 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + B7394861229F194000C47603 /* Landmarks */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + B7394860229F194000C47603 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + B739489A229F292F00C47603 /* silversalmoncreek.jpg in Resources */, + B7394894229F292F00C47603 /* lakemcdonald.jpg in Resources */, + B7D587C0229F830B006E8DCF /* hikeData.json in Resources */, + B7394872229F194200C47603 /* LaunchScreen.storyboard in Resources */, + B73948A3229F3E2200C47603 /* charleyrivers.jpg in Resources */, + B7394891229F292F00C47603 /* rainbowlake.jpg in Resources */, + B739486F229F194200C47603 /* Preview Assets.xcassets in Resources */, + B7394895229F292F00C47603 /* turtlerock.jpg in Resources */, + B739486C229F194200C47603 /* Assets.xcassets in Resources */, + B7394899229F292F00C47603 /* twinlake.jpg in Resources */, + B7394896229F292F00C47603 /* umbagog.jpg in Resources */, + B739489D229F292F00C47603 /* chilkoottrail.jpg in Resources */, + B739489C229F292F00C47603 /* chincoteague.jpg in Resources */, + B739489B229F292F00C47603 /* landmarkData.json in Resources */, + B7394893229F292F00C47603 /* icybay.jpg in Resources */, + B7394897229F292F00C47603 /* hiddenlake.jpg in Resources */, + B7394898229F292F00C47603 /* stmarylake.jpg in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + B739485E229F194000C47603 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + B7394882229F28B900C47603 /* Data.swift in Sources */, + B7310DD3229F6CA9001079B9 /* Badge.swift in Sources */, + B7394866229F194000C47603 /* AppDelegate.swift in Sources */, + B7D587B8229F826D006E8DCF /* GraphCapsule.swift in Sources */, + B739487A229F1B3F00C47603 /* CircleImage.swift in Sources */, + B739487C229F1B6800C47603 /* MapView.swift in Sources */, + B7D587BA229F8288006E8DCF /* Hike.swift in Sources */, + B7D587BC229F82EB006E8DCF /* HikeDetail.swift in Sources */, + B7D587B6229F825D006E8DCF /* HikeView.swift in Sources */, + B7310DD1229F6839001079B9 /* HexagonParameters.swift in Sources */, + B73948A1229F2E1F00C47603 /* LandmarkList.swift in Sources */, + B7D587B0229F73C1006E8DCF /* BadgeSymbol.swift in Sources */, + B7D587B2229F7406006E8DCF /* RotatedBadgeSymbol.swift in Sources */, + B7D587BE229F82FF006E8DCF /* HikeGraph.swift in Sources */, + B7394868229F194000C47603 /* SceneDelegate.swift in Sources */, + B7D587AE229F7382006E8DCF /* BadgeBackground.swift in Sources */, + B739486A229F194000C47603 /* LandmarkDetail.swift in Sources */, + B739489F229F2D9700C47603 /* LandmarkRow.swift in Sources */, + B7D2AAC5229F4D7C0061E5F5 /* UserData.swift in Sources */, + B7394881229F28B900C47603 /* Landmark.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + B7394870229F194200C47603 /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + B7394871229F194200C47603 /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + B7394874229F194200C47603 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 2858D4702858CD0000000001 /* SampleCode.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + B7394875229F194200C47603 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 2858D4702858CD0000000001 /* SampleCode.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + B7394877229F194200C47603 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 2858D4702858CD0000000001 /* SampleCode.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_ASSET_PATHS = "Landmarks/Preview\\ Content"; + DEVELOPMENT_TEAM = ""; + ENABLE_PREVIEWS = YES; + INFOPLIST_FILE = Landmarks/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = "com.example.apple-samplecode.Landmarks${SAMPLE_CODE_DISAMBIGUATOR}"; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + B7394878229F194200C47603 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 2858D4702858CD0000000001 /* SampleCode.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_ASSET_PATHS = "Landmarks/Preview\\ Content"; + DEVELOPMENT_TEAM = ""; + ENABLE_PREVIEWS = YES; + INFOPLIST_FILE = Landmarks/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = "com.example.apple-samplecode.Landmarks${SAMPLE_CODE_DISAMBIGUATOR}"; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + B739485D229F194000C47603 /* Build configuration list for PBXProject "ComposingComplexInterfaces" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + B7394874229F194200C47603 /* Debug */, + B7394875229F194200C47603 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + B7394876229F194200C47603 /* Build configuration list for PBXNativeTarget "Landmarks" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + B7394877229F194200C47603 /* Debug */, + B7394878229F194200C47603 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = B739485A229F194000C47603 /* Project object */; +} diff --git a/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/ComposingComplexInterfaces.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/ComposingComplexInterfaces.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 0000000..3ddf867 --- /dev/null +++ b/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/ComposingComplexInterfaces.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,8 @@ + + + + + BuildSystemType + Latest + + diff --git a/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/AppDelegate.swift b/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/AppDelegate.swift new file mode 100644 index 0000000..e22943b --- /dev/null +++ b/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/AppDelegate.swift @@ -0,0 +1,36 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +The application delegate. +*/ + +import UIKit + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { + // Override point for customization after application launch. + return true + } + + func applicationWillTerminate(_ application: UIApplication) { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. + } + + // MARK: UISceneSession Lifecycle + func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration { + // Called when a new scene session is being created. + // Use this method to select a configuration to create the new scene with. + return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role) + } + + func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) { + // Called when the user discards a scene session. + // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions. + // Use this method to release any resources that were specific to the discarded scenes, as they will not return. + } + +} + diff --git a/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/Contents.json b/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..55bad5e --- /dev/null +++ b/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,111 @@ +{ + "images" : [ + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "landmark_app_icon_40x40.png", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "3x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "landmark_app_icon_58x58.png", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "landmark_app_icon_87x87.png", + "scale" : "3x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "landmark_app_icon_80x80.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "landmark_app_icon_120x120.png", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "1x" + }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "landmark_app_icon_40x40-1.png", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "landmark_app_icon_58x58-1.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "landmark_app_icon_40x40-2.png", + "scale" : "1x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "landmark_app_icon_80x80-1.png", + "scale" : "2x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "landmark_app_icon_76x76.png", + "scale" : "1x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "landmark_app_icon_152x152.png", + "scale" : "2x" + }, + { + "size" : "83.5x83.5", + "idiom" : "ipad", + "filename" : "landmark_app_icon_167x167.png", + "scale" : "2x" + }, + { + "size" : "1024x1024", + "idiom" : "ios-marketing", + "filename" : "landmark_app_icon_1024x1024.png", + "scale" : "1x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_1024x1024.png b/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_1024x1024.png new file mode 100644 index 0000000..00d81c1 Binary files /dev/null and b/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_1024x1024.png differ diff --git a/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_120x120.png b/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_120x120.png new file mode 100644 index 0000000..d382b8b Binary files /dev/null and b/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_120x120.png differ diff --git a/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_152x152.png b/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_152x152.png new file mode 100644 index 0000000..11057f8 Binary files /dev/null and b/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_152x152.png differ diff --git a/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_167x167.png b/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_167x167.png new file mode 100644 index 0000000..f73bc26 Binary files /dev/null and b/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_167x167.png differ diff --git a/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40-1.png b/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40-1.png new file mode 100644 index 0000000..abaff0e Binary files /dev/null and b/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40-1.png differ diff --git a/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40-2.png b/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40-2.png new file mode 100644 index 0000000..abaff0e Binary files /dev/null and b/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40-2.png differ diff --git a/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40.png b/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40.png new file mode 100644 index 0000000..abaff0e Binary files /dev/null and b/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40.png differ diff --git a/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_58x58-1.png b/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_58x58-1.png new file mode 100644 index 0000000..cf7c73d Binary files /dev/null and b/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_58x58-1.png differ diff --git a/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_58x58.png b/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_58x58.png new file mode 100644 index 0000000..cf7c73d Binary files /dev/null and b/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_58x58.png differ diff --git a/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_76x76.png b/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_76x76.png new file mode 100644 index 0000000..3eff85b Binary files /dev/null and b/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_76x76.png differ diff --git a/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_80x80-1.png b/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_80x80-1.png new file mode 100644 index 0000000..6f33f66 Binary files /dev/null and b/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_80x80-1.png differ diff --git a/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_80x80.png b/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_80x80.png new file mode 100644 index 0000000..6f33f66 Binary files /dev/null and b/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_80x80.png differ diff --git a/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_87x87.png b/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_87x87.png new file mode 100644 index 0000000..9e1616c Binary files /dev/null and b/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_87x87.png differ diff --git a/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Assets.xcassets/Contents.json b/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Assets.xcassets/turtlerock.imageset/Contents.json b/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Assets.xcassets/turtlerock.imageset/Contents.json new file mode 100644 index 0000000..5bfd7bf --- /dev/null +++ b/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Assets.xcassets/turtlerock.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "turtlerock.jpg", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Assets.xcassets/turtlerock.imageset/turtlerock.jpg b/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Assets.xcassets/turtlerock.imageset/turtlerock.jpg new file mode 100644 index 0000000..68bcd3e Binary files /dev/null and b/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Assets.xcassets/turtlerock.imageset/turtlerock.jpg differ diff --git a/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Base.lproj/LaunchScreen.storyboard b/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000..865e932 --- /dev/null +++ b/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/HexagonParameters.swift b/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/HexagonParameters.swift new file mode 100644 index 0000000..8decba4 --- /dev/null +++ b/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/HexagonParameters.swift @@ -0,0 +1,57 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +Size, position, and other information used to draw a badge. +*/ + +import SwiftUI + +struct HexagonParameters { + struct Segment { + let useWidth: (CGFloat, CGFloat, CGFloat) + let xFactors: (CGFloat, CGFloat, CGFloat) + let useHeight: (CGFloat, CGFloat, CGFloat) + let yFactors: (CGFloat, CGFloat, CGFloat) + } + + static let adjustment: CGFloat = 0.085 + static let points = [ + Segment( + useWidth: (1.00, 1.00, 1.00), + xFactors: (0.60, 0.40, 0.50), + useHeight: (1.00, 1.00, 0.00), + yFactors: (0.05, 0.05, 0.00) + ), + Segment( + useWidth: (1.00, 1.00, 0.00), + xFactors: (0.05, 0.00, 0.00), + useHeight: (1.00, 1.00, 1.00), + yFactors: (0.20 + adjustment, 0.30 + adjustment, 0.25 + adjustment) + ), + Segment( + useWidth: (1.00, 1.00, 0.00), + xFactors: (0.00, 0.05, 0.00), + useHeight: (1.00, 1.00, 1.00), + yFactors: (0.70 - adjustment, 0.80 - adjustment, 0.75 - adjustment) + ), + Segment( + useWidth: (1.00, 1.00, 1.00), + xFactors: (0.40, 0.60, 0.50), + useHeight: (1.00, 1.00, 1.00), + yFactors: (0.95, 0.95, 1.00) + ), + Segment( + useWidth: (1.00, 1.00, 1.00), + xFactors: (0.95, 1.00, 1.00), + useHeight: (1.00, 1.00, 1.00), + yFactors: (0.80 - adjustment, 0.70 - adjustment, 0.75 - adjustment) + ), + Segment( + useWidth: (1.00, 1.00, 1.00), + xFactors: (1.00, 0.95, 1.00), + useHeight: (1.00, 1.00, 1.00), + yFactors: (0.30 + adjustment, 0.20 + adjustment, 0.25 + adjustment) + ) + ] +} diff --git a/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/HikeDetail.swift b/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/HikeDetail.swift new file mode 100644 index 0000000..3406a6d --- /dev/null +++ b/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/HikeDetail.swift @@ -0,0 +1,49 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A view showing the details for a hike. +*/ + +import SwiftUI + +struct HikeDetail: View { + let hike: Hike + @State var dataToShow = \Hike.Observation.elevation + + var buttons = [ + ("Elevation", \Hike.Observation.elevation), + ("Heart Rate", \Hike.Observation.heartRate), + ("Pace", \Hike.Observation.pace), + ] + + var body: some View { + return VStack { + HikeGraph(hike: hike, path: dataToShow) + .frame(height: 200, alignment: .center) + + HStack(spacing: 25) { + ForEach(buttons.identified(by: \.0)) { value in + Button(action: { + self.dataToShow = value.1 + }) { + Text(verbatim: value.0) + .font(.system(size: 15)) + .color(value.1 == self.dataToShow + ? Color.gray + : Color.accentColor) + .animation(nil) + } + } + } + } + } +} + +#if DEBUG +struct HikeDetail_Previews: PreviewProvider { + static var previews: some View { + HikeDetail(hike: hikeData[0]) + } +} +#endif diff --git a/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/HikeView.swift b/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/HikeView.swift new file mode 100644 index 0000000..f4c02cc --- /dev/null +++ b/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/HikeView.swift @@ -0,0 +1,68 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A view displaying inforamtion about a hike, including an elevation graph. +*/ + +import SwiftUI + +struct HikeView: View { + var hike: Hike + @State private var showDetail = false + + var transition: AnyTransition { + let insertion = AnyTransition.move(edge: .trailing) + .combined(with: .opacity) + let removal = AnyTransition.scale() + .combined(with: .opacity) + return .asymmetric(insertion: insertion, removal: removal) + } + + var body: some View { + VStack { + HStack { + HikeGraph(hike: hike, path: \.elevation) + .frame(width: 50, height: 30) + .animation(nil) + + VStack(alignment: .leading) { + Text(verbatim: hike.name) + .font(.headline) + Text(verbatim: hike.distanceText) + } + + Spacer() + + Button(action: { + withAnimation { + self.showDetail.toggle() + } + }) { + Image(systemName: "chevron.right.circle") + .imageScale(.large) + .rotationEffect(.degrees(showDetail ? 90 : 0)) + .scaleEffect(showDetail ? 1.5 : 1) + .padding() + } + } + + if showDetail { + HikeDetail(hike: hike) + .transition(transition) + } + } + } +} + +#if DEBUG +struct HikeView_Previews: PreviewProvider { + static var previews: some View { + VStack { + HikeView(hike: hikeData[0]) + .padding() + Spacer() + } + } +} +#endif diff --git a/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Info.plist b/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Info.plist new file mode 100644 index 0000000..e8bb4c6 --- /dev/null +++ b/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Info.plist @@ -0,0 +1,62 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + $(PRODUCT_BUNDLE_PACKAGE_TYPE) + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UIApplicationSceneManifest + + UIApplicationSupportsMultipleScenes + + UISceneConfigurations + + UIWindowSceneSessionRoleApplication + + + UILaunchStoryboardName + LaunchScreen + UISceneConfigurationName + Default Configuration + UISceneDelegateClassName + $(PRODUCT_MODULE_NAME).SceneDelegate + + + + + UILaunchStoryboardName + LaunchScreen + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/LandmarkDetail.swift b/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/LandmarkDetail.swift new file mode 100644 index 0000000..6c290a3 --- /dev/null +++ b/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/LandmarkDetail.swift @@ -0,0 +1,71 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A view showing the details for a landmark. +*/ + +import SwiftUI + +struct LandmarkDetail: View { + @EnvironmentObject var userData: UserData + var landmark: Landmark + + var landmarkIndex: Int { + userData.landmarks.firstIndex(where: { $0.id == landmark.id })! + } + + var body: some View { + VStack { + MapView(coordinate: landmark.locationCoordinate) + .edgesIgnoringSafeArea(.top) + .frame(height: 300) + + CircleImage(image: landmark.image(forSize: 250)) + .offset(x: 0, y: -130) + .padding(.bottom, -130) + + VStack(alignment: .leading) { + HStack { + Text(verbatim: landmark.name) + .font(.title) + + Button(action: { + self.userData.landmarks[self.landmarkIndex] + .isFavorite.toggle() + }) { + if self.userData.landmarks[self.landmarkIndex] + .isFavorite { + Image(systemName: "star.fill") + .foregroundColor(Color.yellow) + } else { + Image(systemName: "star") + .foregroundColor(Color.gray) + } + } + } + + HStack(alignment: .top) { + Text(verbatim: landmark.park) + .font(.subheadline) + Spacer() + Text(verbatim: landmark.state) + .font(.subheadline) + } + } + .padding() + + Spacer() + } + } +} + +#if DEBUG +struct LandmarkDetail_Preview: PreviewProvider { + static var previews: some View { + let userData = UserData() + return LandmarkDetail(landmark: userData.landmarks[0]) + .environmentObject(userData) + } +} +#endif diff --git a/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/LandmarkList.swift b/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/LandmarkList.swift new file mode 100644 index 0000000..c17b5f3 --- /dev/null +++ b/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/LandmarkList.swift @@ -0,0 +1,45 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A view showing a list of landmarks. +*/ + +import SwiftUI + +struct LandmarkList: View { + @EnvironmentObject private var userData: UserData + + var body: some View { + NavigationView { + List { + Toggle(isOn: $userData.showFavoritesOnly) { + Text("Show Favorites Only") + } + + ForEach(userData.landmarks) { landmark in + if !self.userData.showFavoritesOnly || landmark.isFavorite { + NavigationButton( + destination: LandmarkDetail(landmark: landmark)) { + LandmarkRow(landmark: landmark) + } + } + } + } + .navigationBarTitle(Text("Landmarks"), displayMode: .large) + } + } +} + +#if DEBUG +struct LandmarksList_Previews: PreviewProvider { + static var previews: some View { + ForEach(["iPhone SE", "iPhone XS Max"].identified(by: \.self)) { deviceName in + LandmarkList() + .previewDevice(PreviewDevice(rawValue: deviceName)) + .previewDisplayName(deviceName) + } + .environmentObject(UserData()) + } +} +#endif diff --git a/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Models/Data.swift b/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Models/Data.swift new file mode 100644 index 0000000..248d3b2 --- /dev/null +++ b/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Models/Data.swift @@ -0,0 +1,95 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +Helpers for loading images and data. +*/ + +import Foundation +import CoreLocation +import UIKit +import SwiftUI + +let landmarkData: [Landmark] = load("landmarkData.json") +let hikeData: [Hike] = load("hikeData.json") + +func load(_ filename: String, as type: T.Type = T.self) -> T { + let data: Data + + guard let file = Bundle.main.url(forResource: filename, withExtension: nil) + else { + fatalError("Couldn't find \(filename) in main bundle.") + } + + do { + data = try Data(contentsOf: file) + } catch { + fatalError("Couldn't load \(filename) from main bundle:\n\(error)") + } + + do { + let decoder = JSONDecoder() + return try decoder.decode(T.self, from: data) + } catch { + fatalError("Couldn't parse \(filename) as \(T.self):\n\(error)") + } +} + +final class ImageStore { + fileprivate typealias _ImageDictionary = [String: [Int: CGImage]] + fileprivate var images: _ImageDictionary = [:] + + fileprivate static var originalSize = 250 + fileprivate static var scale = 2 + + static var shared = ImageStore() + + func image(name: String, size: Int) -> Image { + let index = _guaranteeInitialImage(name: name) + + let sizedImage = images.values[index][size] + ?? _sizeImage(images.values[index][ImageStore.originalSize]!, to: size * ImageStore.scale) + images.values[index][size] = sizedImage + + return Image(sizedImage, scale: Length(ImageStore.scale), label: Text(verbatim: name)) + } + + fileprivate func _guaranteeInitialImage(name: String) -> _ImageDictionary.Index { + if let index = images.index(forKey: name) { return index } + + guard + let url = Bundle.main.url(forResource: name, withExtension: "jpg"), + let imageSource = CGImageSourceCreateWithURL(url as NSURL, nil), + let image = CGImageSourceCreateImageAtIndex(imageSource, 0, nil) + else { + fatalError("Couldn't load image \(name).jpg from main bundle.") + } + + images[name] = [ImageStore.originalSize: image] + return images.index(forKey: name)! + } + + fileprivate func _sizeImage(_ image: CGImage, to size: Int) -> CGImage { + guard + let colorSpace = image.colorSpace, + let context = CGContext( + data: nil, + width: size, height: size, + bitsPerComponent: image.bitsPerComponent, + bytesPerRow: image.bytesPerRow, + space: colorSpace, + bitmapInfo: image.bitmapInfo.rawValue) + else { + fatalError("Couldn't create graphics context.") + } + context.interpolationQuality = .high + context.draw(image, in: CGRect(x: 0, y: 0, width: size, height: size)) + + if let sizedImage = context.makeImage() { + return sizedImage + } else { + fatalError("Couldn't resize image.") + } + } +} + diff --git a/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Models/Hike.swift b/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Models/Hike.swift new file mode 100644 index 0000000..dfd2bb8 --- /dev/null +++ b/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Models/Hike.swift @@ -0,0 +1,31 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +The model for a hike. +*/ + +import SwiftUI + +struct Hike: Codable, Hashable, Identifiable { + var name: String + var id: Int + var distance: Double + var difficulty: Int + var observations: [Observation] + + static var formatter = LengthFormatter() + + var distanceText: String { + return Hike.formatter + .string(fromValue: distance, unit: .kilometer) + } + + struct Observation: Codable, Hashable { + var distanceFromStart: Double + + var elevation: Range + var pace: Range + var heartRate: Range + } +} diff --git a/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Models/Landmark.swift b/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Models/Landmark.swift new file mode 100644 index 0000000..4a7586d --- /dev/null +++ b/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Models/Landmark.swift @@ -0,0 +1,43 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +The model for an individual landmark. +*/ + +import SwiftUI +import CoreLocation + +struct Landmark: Hashable, Codable, Identifiable { + var id: Int + var name: String + fileprivate var imageName: String + fileprivate var coordinates: Coordinates + var state: String + var park: String + var category: Category + var isFavorite: Bool + var isFeatured: Bool + + var locationCoordinate: CLLocationCoordinate2D { + CLLocationCoordinate2D( + latitude: coordinates.latitude, + longitude: coordinates.longitude) + } + + func image(forSize size: Int) -> Image { + ImageStore.shared.image(name: imageName, size: size) + } + + enum Category: String, CaseIterable, Codable, Hashable { + case featured = "Featured" + case lakes = "Lakes" + case rivers = "Rivers" + case mountains = "Mountains" + } +} + +struct Coordinates: Hashable, Codable { + var latitude: Double + var longitude: Double +} diff --git a/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Models/UserData.swift b/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Models/UserData.swift new file mode 100644 index 0000000..db31fb0 --- /dev/null +++ b/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Models/UserData.swift @@ -0,0 +1,25 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A model object that stores app data. +*/ + +import Combine +import SwiftUI + +final class UserData: BindableObject { + let didChange = PassthroughSubject() + + var showFavoritesOnly = false { + didSet { + didChange.send(self) + } + } + + var landmarks = landmarkData { + didSet { + didChange.send(self) + } + } +} diff --git a/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Preview Content/Preview Assets.xcassets/Contents.json b/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Preview Content/Preview Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Preview Content/Preview Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Resources/charleyrivers.jpg b/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Resources/charleyrivers.jpg new file mode 100644 index 0000000..17ff44b Binary files /dev/null and b/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Resources/charleyrivers.jpg differ diff --git a/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Resources/chilkoottrail.jpg b/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Resources/chilkoottrail.jpg new file mode 100644 index 0000000..e7f805e Binary files /dev/null and b/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Resources/chilkoottrail.jpg differ diff --git a/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Resources/chincoteague.jpg b/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Resources/chincoteague.jpg new file mode 100644 index 0000000..5f47986 Binary files /dev/null and b/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Resources/chincoteague.jpg differ diff --git a/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Resources/hiddenlake.jpg b/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Resources/hiddenlake.jpg new file mode 100644 index 0000000..d8e804c Binary files /dev/null and b/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Resources/hiddenlake.jpg differ diff --git a/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Resources/hikeData.json b/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Resources/hikeData.json new file mode 100644 index 0000000..3fb1e96 --- /dev/null +++ b/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Resources/hikeData.json @@ -0,0 +1,1882 @@ +[ + { + "name":"Lonesome Ridge Trail", + "id":1001, + "distance":4.5, + "difficulty":3, + "observations":[ + { + "elevation":[ + 291.65263635636268, + 309.26016677925196 + ], + "pace":[ + 396.08716481908732, + 403.68937873525232 + ], + "heartRate":[ + 117.16351898665887, + 121.95815455919609 + ], + "distanceFromStart":0 + }, + { + "elevation":[ + 299.24001936628116, + 317.44584350790012 + ], + "pace":[ + 380.19020240756623, + 395.3978319010256 + ], + "heartRate":[ + 117.6410892152911, + 124.82185220506081 + ], + "distanceFromStart":0.375 + }, + { + "elevation":[ + 303.62145464574394, + 336.05569457646544 + ], + "pace":[ + 380.55927782266116, + 397.60789726832775 + ], + "heartRate":[ + 121.52696452049059, + 127.31525441110122 + ], + "distanceFromStart":0.75 + }, + { + "elevation":[ + 319.90393365162629, + 346.26966025518789 + ], + "pace":[ + 357.94116421258531, + 398.0750288648062 + ], + "heartRate":[ + 123.75908585923588, + 132.77069404486801 + ], + "distanceFromStart":1.125 + }, + { + "elevation":[ + 354.17104439267905, + 403.57031216972939 + ], + "pace":[ + 335.07385149392701, + 397.82674381875808 + ], + "heartRate":[ + 130.8235194572915, + 140.55700591418218 + ], + "distanceFromStart":1.5 + }, + { + "elevation":[ + 357.42992871175124, + 385.92155620623635 + ], + "pace":[ + 395.16168913839374, + 404.60294066527558 + ], + "heartRate":[ + 131.5456052446734, + 134.65984504627627 + ], + "distanceFromStart":1.875 + }, + { + "elevation":[ + 345.47736721935661, + 363.18776661379422 + ], + "pace":[ + 340.82303041339082, + 404.71689228682374 + ], + "heartRate":[ + 125.1949698433959, + 131.31354363122026 + ], + "distanceFromStart":2.25 + }, + { + "elevation":[ + 346.23343025200535, + 497.23376445462401 + ], + "pace":[ + 261.27629148816021, + 331.68516208719467 + ], + "heartRate":[ + 131.67810544238606, + 154.26779645311458 + ], + "distanceFromStart":2.625 + }, + { + "elevation":[ + 491.57378483134391, + 547.49535224251053 + ], + "pace":[ + 296.05298644112088, + 401.14092967732398 + ], + "heartRate":[ + 151.36398089694217, + 166.20454793289232 + ], + "distanceFromStart":3 + }, + { + "elevation":[ + 472.06803233416338, + 531.92570520228401 + ], + "pace":[ + 395.50830663514012, + 401.67837917543591 + ], + "heartRate":[ + 134.41798110234078, + 151.90886697564241 + ], + "distanceFromStart":3.375 + }, + { + "elevation":[ + 339.81419476005283, + 461.03832527824829 + ], + "pace":[ + 395.31160487975183, + 404.49550455974907 + ], + "heartRate":[ + 129.97753472415462, + 138.13531094848992 + ], + "distanceFromStart":3.75 + }, + { + "elevation":[ + 303.1495508565697, + 342.3532820173541 + ], + "pace":[ + 395.02844559698116, + 402.65878340653796 + ], + "heartRate":[ + 127.72304232462609, + 133.26322270764186 + ], + "distanceFromStart":4.125 + } + ] + }, + { + "name":"Lonesome Ridge Trail", + "id":1002, + "distance":4.5, + "difficulty":3, + "observations":[ + { + "elevation":[ + 291.65263635636268, + 309.26016677925196 + ], + "pace":[ + 396.08716481908732, + 403.68937873525232 + ], + "heartRate":[ + 117.16351898665887, + 121.95815455919609 + ], + "distanceFromStart":0 + }, + { + "elevation":[ + 299.24001936628116, + 317.44584350790012 + ], + "pace":[ + 380.19020240756623, + 395.3978319010256 + ], + "heartRate":[ + 117.6410892152911, + 124.82185220506081 + ], + "distanceFromStart":0.375 + }, + { + "elevation":[ + 303.62145464574394, + 336.05569457646544 + ], + "pace":[ + 380.55927782266116, + 397.60789726832775 + ], + "heartRate":[ + 121.52696452049059, + 127.31525441110122 + ], + "distanceFromStart":0.75 + }, + { + "elevation":[ + 319.90393365162629, + 346.26966025518789 + ], + "pace":[ + 357.94116421258531, + 398.0750288648062 + ], + "heartRate":[ + 123.75908585923588, + 132.77069404486801 + ], + "distanceFromStart":1.125 + }, + { + "elevation":[ + 354.17104439267905, + 403.57031216972939 + ], + "pace":[ + 335.07385149392701, + 397.82674381875808 + ], + "heartRate":[ + 130.8235194572915, + 140.55700591418218 + ], + "distanceFromStart":1.5 + }, + { + "elevation":[ + 357.42992871175124, + 385.92155620623635 + ], + "pace":[ + 395.16168913839374, + 404.60294066527558 + ], + "heartRate":[ + 131.5456052446734, + 134.65984504627627 + ], + "distanceFromStart":1.875 + }, + { + "elevation":[ + 345.47736721935661, + 363.18776661379422 + ], + "pace":[ + 340.82303041339082, + 404.71689228682374 + ], + "heartRate":[ + 125.1949698433959, + 131.31354363122026 + ], + "distanceFromStart":2.25 + }, + { + "elevation":[ + 346.23343025200535, + 497.23376445462401 + ], + "pace":[ + 261.27629148816021, + 331.68516208719467 + ], + "heartRate":[ + 131.67810544238606, + 154.26779645311458 + ], + "distanceFromStart":2.625 + }, + { + "elevation":[ + 491.57378483134391, + 547.49535224251053 + ], + "pace":[ + 296.05298644112088, + 401.14092967732398 + ], + "heartRate":[ + 151.36398089694217, + 166.20454793289232 + ], + "distanceFromStart":3 + }, + { + "elevation":[ + 472.06803233416338, + 531.92570520228401 + ], + "pace":[ + 395.50830663514012, + 401.67837917543591 + ], + "heartRate":[ + 134.41798110234078, + 151.90886697564241 + ], + "distanceFromStart":3.375 + }, + { + "elevation":[ + 339.81419476005283, + 461.03832527824829 + ], + "pace":[ + 395.31160487975183, + 404.49550455974907 + ], + "heartRate":[ + 129.97753472415462, + 138.13531094848992 + ], + "distanceFromStart":3.75 + }, + { + "elevation":[ + 303.1495508565697, + 342.3532820173541 + ], + "pace":[ + 395.02844559698116, + 402.65878340653796 + ], + "heartRate":[ + 127.72304232462609, + 133.26322270764186 + ], + "distanceFromStart":4.125 + } + ] + }, + { + "name":"Lonesome Ridge Trail", + "id":1003, + "distance":4.5, + "difficulty":3, + "observations":[ + { + "elevation":[ + 291.65263635636268, + 309.26016677925196 + ], + "pace":[ + 396.08716481908732, + 403.68937873525232 + ], + "heartRate":[ + 117.16351898665887, + 121.95815455919609 + ], + "distanceFromStart":0 + }, + { + "elevation":[ + 299.24001936628116, + 317.44584350790012 + ], + "pace":[ + 380.19020240756623, + 395.3978319010256 + ], + "heartRate":[ + 117.6410892152911, + 124.82185220506081 + ], + "distanceFromStart":0.375 + }, + { + "elevation":[ + 303.62145464574394, + 336.05569457646544 + ], + "pace":[ + 380.55927782266116, + 397.60789726832775 + ], + "heartRate":[ + 121.52696452049059, + 127.31525441110122 + ], + "distanceFromStart":0.75 + }, + { + "elevation":[ + 319.90393365162629, + 346.26966025518789 + ], + "pace":[ + 357.94116421258531, + 398.0750288648062 + ], + "heartRate":[ + 123.75908585923588, + 132.77069404486801 + ], + "distanceFromStart":1.125 + }, + { + "elevation":[ + 354.17104439267905, + 403.57031216972939 + ], + "pace":[ + 335.07385149392701, + 397.82674381875808 + ], + "heartRate":[ + 130.8235194572915, + 140.55700591418218 + ], + "distanceFromStart":1.5 + }, + { + "elevation":[ + 357.42992871175124, + 385.92155620623635 + ], + "pace":[ + 395.16168913839374, + 404.60294066527558 + ], + "heartRate":[ + 131.5456052446734, + 134.65984504627627 + ], + "distanceFromStart":1.875 + }, + { + "elevation":[ + 345.47736721935661, + 363.18776661379422 + ], + "pace":[ + 340.82303041339082, + 404.71689228682374 + ], + "heartRate":[ + 125.1949698433959, + 131.31354363122026 + ], + "distanceFromStart":2.25 + }, + { + "elevation":[ + 346.23343025200535, + 497.23376445462401 + ], + "pace":[ + 261.27629148816021, + 331.68516208719467 + ], + "heartRate":[ + 131.67810544238606, + 154.26779645311458 + ], + "distanceFromStart":2.625 + }, + { + "elevation":[ + 491.57378483134391, + 547.49535224251053 + ], + "pace":[ + 296.05298644112088, + 401.14092967732398 + ], + "heartRate":[ + 151.36398089694217, + 166.20454793289232 + ], + "distanceFromStart":3 + }, + { + "elevation":[ + 472.06803233416338, + 531.92570520228401 + ], + "pace":[ + 395.50830663514012, + 401.67837917543591 + ], + "heartRate":[ + 134.41798110234078, + 151.90886697564241 + ], + "distanceFromStart":3.375 + }, + { + "elevation":[ + 339.81419476005283, + 461.03832527824829 + ], + "pace":[ + 395.31160487975183, + 404.49550455974907 + ], + "heartRate":[ + 129.97753472415462, + 138.13531094848992 + ], + "distanceFromStart":3.75 + }, + { + "elevation":[ + 303.1495508565697, + 342.3532820173541 + ], + "pace":[ + 395.02844559698116, + 402.65878340653796 + ], + "heartRate":[ + 127.72304232462609, + 133.26322270764186 + ], + "distanceFromStart":4.125 + } + ] + }, + { + "name":"Lonesome Ridge Trail", + "id":1004, + "distance":4.5, + "difficulty":3, + "observations":[ + { + "elevation":[ + 291.65263635636268, + 309.26016677925196 + ], + "pace":[ + 396.08716481908732, + 403.68937873525232 + ], + "heartRate":[ + 117.16351898665887, + 121.95815455919609 + ], + "distanceFromStart":0 + }, + { + "elevation":[ + 299.24001936628116, + 317.44584350790012 + ], + "pace":[ + 380.19020240756623, + 395.3978319010256 + ], + "heartRate":[ + 117.6410892152911, + 124.82185220506081 + ], + "distanceFromStart":0.375 + }, + { + "elevation":[ + 303.62145464574394, + 336.05569457646544 + ], + "pace":[ + 380.55927782266116, + 397.60789726832775 + ], + "heartRate":[ + 121.52696452049059, + 127.31525441110122 + ], + "distanceFromStart":0.75 + }, + { + "elevation":[ + 319.90393365162629, + 346.26966025518789 + ], + "pace":[ + 357.94116421258531, + 398.0750288648062 + ], + "heartRate":[ + 123.75908585923588, + 132.77069404486801 + ], + "distanceFromStart":1.125 + }, + { + "elevation":[ + 354.17104439267905, + 403.57031216972939 + ], + "pace":[ + 335.07385149392701, + 397.82674381875808 + ], + "heartRate":[ + 130.8235194572915, + 140.55700591418218 + ], + "distanceFromStart":1.5 + }, + { + "elevation":[ + 357.42992871175124, + 385.92155620623635 + ], + "pace":[ + 395.16168913839374, + 404.60294066527558 + ], + "heartRate":[ + 131.5456052446734, + 134.65984504627627 + ], + "distanceFromStart":1.875 + }, + { + "elevation":[ + 345.47736721935661, + 363.18776661379422 + ], + "pace":[ + 340.82303041339082, + 404.71689228682374 + ], + "heartRate":[ + 125.1949698433959, + 131.31354363122026 + ], + "distanceFromStart":2.25 + }, + { + "elevation":[ + 346.23343025200535, + 497.23376445462401 + ], + "pace":[ + 261.27629148816021, + 331.68516208719467 + ], + "heartRate":[ + 131.67810544238606, + 154.26779645311458 + ], + "distanceFromStart":2.625 + }, + { + "elevation":[ + 491.57378483134391, + 547.49535224251053 + ], + "pace":[ + 296.05298644112088, + 401.14092967732398 + ], + "heartRate":[ + 151.36398089694217, + 166.20454793289232 + ], + "distanceFromStart":3 + }, + { + "elevation":[ + 472.06803233416338, + 531.92570520228401 + ], + "pace":[ + 395.50830663514012, + 401.67837917543591 + ], + "heartRate":[ + 134.41798110234078, + 151.90886697564241 + ], + "distanceFromStart":3.375 + }, + { + "elevation":[ + 339.81419476005283, + 461.03832527824829 + ], + "pace":[ + 395.31160487975183, + 404.49550455974907 + ], + "heartRate":[ + 129.97753472415462, + 138.13531094848992 + ], + "distanceFromStart":3.75 + }, + { + "elevation":[ + 303.1495508565697, + 342.3532820173541 + ], + "pace":[ + 395.02844559698116, + 402.65878340653796 + ], + "heartRate":[ + 127.72304232462609, + 133.26322270764186 + ], + "distanceFromStart":4.125 + } + ] + }, + { + "name":"Lonesome Ridge Trail", + "id":1005, + "distance":4.5, + "difficulty":3, + "observations":[ + { + "elevation":[ + 291.65263635636268, + 309.26016677925196 + ], + "pace":[ + 396.08716481908732, + 403.68937873525232 + ], + "heartRate":[ + 117.16351898665887, + 121.95815455919609 + ], + "distanceFromStart":0 + }, + { + "elevation":[ + 299.24001936628116, + 317.44584350790012 + ], + "pace":[ + 380.19020240756623, + 395.3978319010256 + ], + "heartRate":[ + 117.6410892152911, + 124.82185220506081 + ], + "distanceFromStart":0.375 + }, + { + "elevation":[ + 303.62145464574394, + 336.05569457646544 + ], + "pace":[ + 380.55927782266116, + 397.60789726832775 + ], + "heartRate":[ + 121.52696452049059, + 127.31525441110122 + ], + "distanceFromStart":0.75 + }, + { + "elevation":[ + 319.90393365162629, + 346.26966025518789 + ], + "pace":[ + 357.94116421258531, + 398.0750288648062 + ], + "heartRate":[ + 123.75908585923588, + 132.77069404486801 + ], + "distanceFromStart":1.125 + }, + { + "elevation":[ + 354.17104439267905, + 403.57031216972939 + ], + "pace":[ + 335.07385149392701, + 397.82674381875808 + ], + "heartRate":[ + 130.8235194572915, + 140.55700591418218 + ], + "distanceFromStart":1.5 + }, + { + "elevation":[ + 357.42992871175124, + 385.92155620623635 + ], + "pace":[ + 395.16168913839374, + 404.60294066527558 + ], + "heartRate":[ + 131.5456052446734, + 134.65984504627627 + ], + "distanceFromStart":1.875 + }, + { + "elevation":[ + 345.47736721935661, + 363.18776661379422 + ], + "pace":[ + 340.82303041339082, + 404.71689228682374 + ], + "heartRate":[ + 125.1949698433959, + 131.31354363122026 + ], + "distanceFromStart":2.25 + }, + { + "elevation":[ + 346.23343025200535, + 497.23376445462401 + ], + "pace":[ + 261.27629148816021, + 331.68516208719467 + ], + "heartRate":[ + 131.67810544238606, + 154.26779645311458 + ], + "distanceFromStart":2.625 + }, + { + "elevation":[ + 491.57378483134391, + 547.49535224251053 + ], + "pace":[ + 296.05298644112088, + 401.14092967732398 + ], + "heartRate":[ + 151.36398089694217, + 166.20454793289232 + ], + "distanceFromStart":3 + }, + { + "elevation":[ + 472.06803233416338, + 531.92570520228401 + ], + "pace":[ + 395.50830663514012, + 401.67837917543591 + ], + "heartRate":[ + 134.41798110234078, + 151.90886697564241 + ], + "distanceFromStart":3.375 + }, + { + "elevation":[ + 339.81419476005283, + 461.03832527824829 + ], + "pace":[ + 395.31160487975183, + 404.49550455974907 + ], + "heartRate":[ + 129.97753472415462, + 138.13531094848992 + ], + "distanceFromStart":3.75 + }, + { + "elevation":[ + 303.1495508565697, + 342.3532820173541 + ], + "pace":[ + 395.02844559698116, + 402.65878340653796 + ], + "heartRate":[ + 127.72304232462609, + 133.26322270764186 + ], + "distanceFromStart":4.125 + } + ] + }, + { + "name":"Lonesome Ridge Trail", + "id":1006, + "distance":4.5, + "difficulty":3, + "observations":[ + { + "elevation":[ + 291.65263635636268, + 309.26016677925196 + ], + "pace":[ + 396.08716481908732, + 403.68937873525232 + ], + "heartRate":[ + 117.16351898665887, + 121.95815455919609 + ], + "distanceFromStart":0 + }, + { + "elevation":[ + 299.24001936628116, + 317.44584350790012 + ], + "pace":[ + 380.19020240756623, + 395.3978319010256 + ], + "heartRate":[ + 117.6410892152911, + 124.82185220506081 + ], + "distanceFromStart":0.375 + }, + { + "elevation":[ + 303.62145464574394, + 336.05569457646544 + ], + "pace":[ + 380.55927782266116, + 397.60789726832775 + ], + "heartRate":[ + 121.52696452049059, + 127.31525441110122 + ], + "distanceFromStart":0.75 + }, + { + "elevation":[ + 319.90393365162629, + 346.26966025518789 + ], + "pace":[ + 357.94116421258531, + 398.0750288648062 + ], + "heartRate":[ + 123.75908585923588, + 132.77069404486801 + ], + "distanceFromStart":1.125 + }, + { + "elevation":[ + 354.17104439267905, + 403.57031216972939 + ], + "pace":[ + 335.07385149392701, + 397.82674381875808 + ], + "heartRate":[ + 130.8235194572915, + 140.55700591418218 + ], + "distanceFromStart":1.5 + }, + { + "elevation":[ + 357.42992871175124, + 385.92155620623635 + ], + "pace":[ + 395.16168913839374, + 404.60294066527558 + ], + "heartRate":[ + 131.5456052446734, + 134.65984504627627 + ], + "distanceFromStart":1.875 + }, + { + "elevation":[ + 345.47736721935661, + 363.18776661379422 + ], + "pace":[ + 340.82303041339082, + 404.71689228682374 + ], + "heartRate":[ + 125.1949698433959, + 131.31354363122026 + ], + "distanceFromStart":2.25 + }, + { + "elevation":[ + 346.23343025200535, + 497.23376445462401 + ], + "pace":[ + 261.27629148816021, + 331.68516208719467 + ], + "heartRate":[ + 131.67810544238606, + 154.26779645311458 + ], + "distanceFromStart":2.625 + }, + { + "elevation":[ + 491.57378483134391, + 547.49535224251053 + ], + "pace":[ + 296.05298644112088, + 401.14092967732398 + ], + "heartRate":[ + 151.36398089694217, + 166.20454793289232 + ], + "distanceFromStart":3 + }, + { + "elevation":[ + 472.06803233416338, + 531.92570520228401 + ], + "pace":[ + 395.50830663514012, + 401.67837917543591 + ], + "heartRate":[ + 134.41798110234078, + 151.90886697564241 + ], + "distanceFromStart":3.375 + }, + { + "elevation":[ + 339.81419476005283, + 461.03832527824829 + ], + "pace":[ + 395.31160487975183, + 404.49550455974907 + ], + "heartRate":[ + 129.97753472415462, + 138.13531094848992 + ], + "distanceFromStart":3.75 + }, + { + "elevation":[ + 303.1495508565697, + 342.3532820173541 + ], + "pace":[ + 395.02844559698116, + 402.65878340653796 + ], + "heartRate":[ + 127.72304232462609, + 133.26322270764186 + ], + "distanceFromStart":4.125 + } + ] + }, + { + "name":"Lonesome Ridge Trail", + "id":1007, + "distance":4.5, + "difficulty":3, + "observations":[ + { + "elevation":[ + 291.65263635636268, + 309.26016677925196 + ], + "pace":[ + 396.08716481908732, + 403.68937873525232 + ], + "heartRate":[ + 117.16351898665887, + 121.95815455919609 + ], + "distanceFromStart":0 + }, + { + "elevation":[ + 299.24001936628116, + 317.44584350790012 + ], + "pace":[ + 380.19020240756623, + 395.3978319010256 + ], + "heartRate":[ + 117.6410892152911, + 124.82185220506081 + ], + "distanceFromStart":0.375 + }, + { + "elevation":[ + 303.62145464574394, + 336.05569457646544 + ], + "pace":[ + 380.55927782266116, + 397.60789726832775 + ], + "heartRate":[ + 121.52696452049059, + 127.31525441110122 + ], + "distanceFromStart":0.75 + }, + { + "elevation":[ + 319.90393365162629, + 346.26966025518789 + ], + "pace":[ + 357.94116421258531, + 398.0750288648062 + ], + "heartRate":[ + 123.75908585923588, + 132.77069404486801 + ], + "distanceFromStart":1.125 + }, + { + "elevation":[ + 354.17104439267905, + 403.57031216972939 + ], + "pace":[ + 335.07385149392701, + 397.82674381875808 + ], + "heartRate":[ + 130.8235194572915, + 140.55700591418218 + ], + "distanceFromStart":1.5 + }, + { + "elevation":[ + 357.42992871175124, + 385.92155620623635 + ], + "pace":[ + 395.16168913839374, + 404.60294066527558 + ], + "heartRate":[ + 131.5456052446734, + 134.65984504627627 + ], + "distanceFromStart":1.875 + }, + { + "elevation":[ + 345.47736721935661, + 363.18776661379422 + ], + "pace":[ + 340.82303041339082, + 404.71689228682374 + ], + "heartRate":[ + 125.1949698433959, + 131.31354363122026 + ], + "distanceFromStart":2.25 + }, + { + "elevation":[ + 346.23343025200535, + 497.23376445462401 + ], + "pace":[ + 261.27629148816021, + 331.68516208719467 + ], + "heartRate":[ + 131.67810544238606, + 154.26779645311458 + ], + "distanceFromStart":2.625 + }, + { + "elevation":[ + 491.57378483134391, + 547.49535224251053 + ], + "pace":[ + 296.05298644112088, + 401.14092967732398 + ], + "heartRate":[ + 151.36398089694217, + 166.20454793289232 + ], + "distanceFromStart":3 + }, + { + "elevation":[ + 472.06803233416338, + 531.92570520228401 + ], + "pace":[ + 395.50830663514012, + 401.67837917543591 + ], + "heartRate":[ + 134.41798110234078, + 151.90886697564241 + ], + "distanceFromStart":3.375 + }, + { + "elevation":[ + 339.81419476005283, + 461.03832527824829 + ], + "pace":[ + 395.31160487975183, + 404.49550455974907 + ], + "heartRate":[ + 129.97753472415462, + 138.13531094848992 + ], + "distanceFromStart":3.75 + }, + { + "elevation":[ + 303.1495508565697, + 342.3532820173541 + ], + "pace":[ + 395.02844559698116, + 402.65878340653796 + ], + "heartRate":[ + 127.72304232462609, + 133.26322270764186 + ], + "distanceFromStart":4.125 + } + ] + }, + { + "name":"Lonesome Ridge Trail", + "id":1008, + "distance":4.5, + "difficulty":3, + "observations":[ + { + "elevation":[ + 291.65263635636268, + 309.26016677925196 + ], + "pace":[ + 396.08716481908732, + 403.68937873525232 + ], + "heartRate":[ + 117.16351898665887, + 121.95815455919609 + ], + "distanceFromStart":0 + }, + { + "elevation":[ + 299.24001936628116, + 317.44584350790012 + ], + "pace":[ + 380.19020240756623, + 395.3978319010256 + ], + "heartRate":[ + 117.6410892152911, + 124.82185220506081 + ], + "distanceFromStart":0.375 + }, + { + "elevation":[ + 303.62145464574394, + 336.05569457646544 + ], + "pace":[ + 380.55927782266116, + 397.60789726832775 + ], + "heartRate":[ + 121.52696452049059, + 127.31525441110122 + ], + "distanceFromStart":0.75 + }, + { + "elevation":[ + 319.90393365162629, + 346.26966025518789 + ], + "pace":[ + 357.94116421258531, + 398.0750288648062 + ], + "heartRate":[ + 123.75908585923588, + 132.77069404486801 + ], + "distanceFromStart":1.125 + }, + { + "elevation":[ + 354.17104439267905, + 403.57031216972939 + ], + "pace":[ + 335.07385149392701, + 397.82674381875808 + ], + "heartRate":[ + 130.8235194572915, + 140.55700591418218 + ], + "distanceFromStart":1.5 + }, + { + "elevation":[ + 357.42992871175124, + 385.92155620623635 + ], + "pace":[ + 395.16168913839374, + 404.60294066527558 + ], + "heartRate":[ + 131.5456052446734, + 134.65984504627627 + ], + "distanceFromStart":1.875 + }, + { + "elevation":[ + 345.47736721935661, + 363.18776661379422 + ], + "pace":[ + 340.82303041339082, + 404.71689228682374 + ], + "heartRate":[ + 125.1949698433959, + 131.31354363122026 + ], + "distanceFromStart":2.25 + }, + { + "elevation":[ + 346.23343025200535, + 497.23376445462401 + ], + "pace":[ + 261.27629148816021, + 331.68516208719467 + ], + "heartRate":[ + 131.67810544238606, + 154.26779645311458 + ], + "distanceFromStart":2.625 + }, + { + "elevation":[ + 491.57378483134391, + 547.49535224251053 + ], + "pace":[ + 296.05298644112088, + 401.14092967732398 + ], + "heartRate":[ + 151.36398089694217, + 166.20454793289232 + ], + "distanceFromStart":3 + }, + { + "elevation":[ + 472.06803233416338, + 531.92570520228401 + ], + "pace":[ + 395.50830663514012, + 401.67837917543591 + ], + "heartRate":[ + 134.41798110234078, + 151.90886697564241 + ], + "distanceFromStart":3.375 + }, + { + "elevation":[ + 339.81419476005283, + 461.03832527824829 + ], + "pace":[ + 395.31160487975183, + 404.49550455974907 + ], + "heartRate":[ + 129.97753472415462, + 138.13531094848992 + ], + "distanceFromStart":3.75 + }, + { + "elevation":[ + 303.1495508565697, + 342.3532820173541 + ], + "pace":[ + 395.02844559698116, + 402.65878340653796 + ], + "heartRate":[ + 127.72304232462609, + 133.26322270764186 + ], + "distanceFromStart":4.125 + } + ] + }, + { + "name":"Lonesome Ridge Trail", + "id":1009, + "distance":4.5, + "difficulty":3, + "observations":[ + { + "elevation":[ + 291.65263635636268, + 309.26016677925196 + ], + "pace":[ + 396.08716481908732, + 403.68937873525232 + ], + "heartRate":[ + 117.16351898665887, + 121.95815455919609 + ], + "distanceFromStart":0 + }, + { + "elevation":[ + 299.24001936628116, + 317.44584350790012 + ], + "pace":[ + 380.19020240756623, + 395.3978319010256 + ], + "heartRate":[ + 117.6410892152911, + 124.82185220506081 + ], + "distanceFromStart":0.375 + }, + { + "elevation":[ + 303.62145464574394, + 336.05569457646544 + ], + "pace":[ + 380.55927782266116, + 397.60789726832775 + ], + "heartRate":[ + 121.52696452049059, + 127.31525441110122 + ], + "distanceFromStart":0.75 + }, + { + "elevation":[ + 319.90393365162629, + 346.26966025518789 + ], + "pace":[ + 357.94116421258531, + 398.0750288648062 + ], + "heartRate":[ + 123.75908585923588, + 132.77069404486801 + ], + "distanceFromStart":1.125 + }, + { + "elevation":[ + 354.17104439267905, + 403.57031216972939 + ], + "pace":[ + 335.07385149392701, + 397.82674381875808 + ], + "heartRate":[ + 130.8235194572915, + 140.55700591418218 + ], + "distanceFromStart":1.5 + }, + { + "elevation":[ + 357.42992871175124, + 385.92155620623635 + ], + "pace":[ + 395.16168913839374, + 404.60294066527558 + ], + "heartRate":[ + 131.5456052446734, + 134.65984504627627 + ], + "distanceFromStart":1.875 + }, + { + "elevation":[ + 345.47736721935661, + 363.18776661379422 + ], + "pace":[ + 340.82303041339082, + 404.71689228682374 + ], + "heartRate":[ + 125.1949698433959, + 131.31354363122026 + ], + "distanceFromStart":2.25 + }, + { + "elevation":[ + 346.23343025200535, + 497.23376445462401 + ], + "pace":[ + 261.27629148816021, + 331.68516208719467 + ], + "heartRate":[ + 131.67810544238606, + 154.26779645311458 + ], + "distanceFromStart":2.625 + }, + { + "elevation":[ + 491.57378483134391, + 547.49535224251053 + ], + "pace":[ + 296.05298644112088, + 401.14092967732398 + ], + "heartRate":[ + 151.36398089694217, + 166.20454793289232 + ], + "distanceFromStart":3 + }, + { + "elevation":[ + 472.06803233416338, + 531.92570520228401 + ], + "pace":[ + 395.50830663514012, + 401.67837917543591 + ], + "heartRate":[ + 134.41798110234078, + 151.90886697564241 + ], + "distanceFromStart":3.375 + }, + { + "elevation":[ + 339.81419476005283, + 461.03832527824829 + ], + "pace":[ + 395.31160487975183, + 404.49550455974907 + ], + "heartRate":[ + 129.97753472415462, + 138.13531094848992 + ], + "distanceFromStart":3.75 + }, + { + "elevation":[ + 303.1495508565697, + 342.3532820173541 + ], + "pace":[ + 395.02844559698116, + 402.65878340653796 + ], + "heartRate":[ + 127.72304232462609, + 133.26322270764186 + ], + "distanceFromStart":4.125 + } + ] + }, + { + "name":"Lonesome Ridge Trail", + "id":1010, + "distance":4.5, + "difficulty":3, + "observations":[ + { + "elevation":[ + 291.65263635636268, + 309.26016677925196 + ], + "pace":[ + 396.08716481908732, + 403.68937873525232 + ], + "heartRate":[ + 117.16351898665887, + 121.95815455919609 + ], + "distanceFromStart":0 + }, + { + "elevation":[ + 299.24001936628116, + 317.44584350790012 + ], + "pace":[ + 380.19020240756623, + 395.3978319010256 + ], + "heartRate":[ + 117.6410892152911, + 124.82185220506081 + ], + "distanceFromStart":0.375 + }, + { + "elevation":[ + 303.62145464574394, + 336.05569457646544 + ], + "pace":[ + 380.55927782266116, + 397.60789726832775 + ], + "heartRate":[ + 121.52696452049059, + 127.31525441110122 + ], + "distanceFromStart":0.75 + }, + { + "elevation":[ + 319.90393365162629, + 346.26966025518789 + ], + "pace":[ + 357.94116421258531, + 398.0750288648062 + ], + "heartRate":[ + 123.75908585923588, + 132.77069404486801 + ], + "distanceFromStart":1.125 + }, + { + "elevation":[ + 354.17104439267905, + 403.57031216972939 + ], + "pace":[ + 335.07385149392701, + 397.82674381875808 + ], + "heartRate":[ + 130.8235194572915, + 140.55700591418218 + ], + "distanceFromStart":1.5 + }, + { + "elevation":[ + 357.42992871175124, + 385.92155620623635 + ], + "pace":[ + 395.16168913839374, + 404.60294066527558 + ], + "heartRate":[ + 131.5456052446734, + 134.65984504627627 + ], + "distanceFromStart":1.875 + }, + { + "elevation":[ + 345.47736721935661, + 363.18776661379422 + ], + "pace":[ + 340.82303041339082, + 404.71689228682374 + ], + "heartRate":[ + 125.1949698433959, + 131.31354363122026 + ], + "distanceFromStart":2.25 + }, + { + "elevation":[ + 346.23343025200535, + 497.23376445462401 + ], + "pace":[ + 261.27629148816021, + 331.68516208719467 + ], + "heartRate":[ + 131.67810544238606, + 154.26779645311458 + ], + "distanceFromStart":2.625 + }, + { + "elevation":[ + 491.57378483134391, + 547.49535224251053 + ], + "pace":[ + 296.05298644112088, + 401.14092967732398 + ], + "heartRate":[ + 151.36398089694217, + 166.20454793289232 + ], + "distanceFromStart":3 + }, + { + "elevation":[ + 472.06803233416338, + 531.92570520228401 + ], + "pace":[ + 395.50830663514012, + 401.67837917543591 + ], + "heartRate":[ + 134.41798110234078, + 151.90886697564241 + ], + "distanceFromStart":3.375 + }, + { + "elevation":[ + 339.81419476005283, + 461.03832527824829 + ], + "pace":[ + 395.31160487975183, + 404.49550455974907 + ], + "heartRate":[ + 129.97753472415462, + 138.13531094848992 + ], + "distanceFromStart":3.75 + }, + { + "elevation":[ + 303.1495508565697, + 342.3532820173541 + ], + "pace":[ + 395.02844559698116, + 402.65878340653796 + ], + "heartRate":[ + 127.72304232462609, + 133.26322270764186 + ], + "distanceFromStart":4.125 + } + ] + } +] diff --git a/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Resources/icybay.jpg b/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Resources/icybay.jpg new file mode 100644 index 0000000..feb1764 Binary files /dev/null and b/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Resources/icybay.jpg differ diff --git a/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Resources/lakemcdonald.jpg b/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Resources/lakemcdonald.jpg new file mode 100644 index 0000000..bd9d6b9 Binary files /dev/null and b/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Resources/lakemcdonald.jpg differ diff --git a/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Resources/landmarkData.json b/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Resources/landmarkData.json new file mode 100644 index 0000000..e5b14fc --- /dev/null +++ b/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Resources/landmarkData.json @@ -0,0 +1,182 @@ +[ + { + "name": "Turtle Rock", + "category": "Rivers", + "city": "Twentynine Palms", + "state": "California", + "id": 1001, + "isFeatured": true, + "isFavorite": true, + "park": "Joshua Tree National Park", + "coordinates": { + "longitude": -116.166868, + "latitude": 34.011286 + }, + "imageName": "turtlerock" + }, + { + "name": "Silver Salmon Creek", + "category": "Lakes", + "city": "Port Alsworth", + "state": "Alaska", + "id": 1002, + "isFeatured": false, + "isFavorite": false, + "park": "Lake Clark National Park and Preserve", + "coordinates": { + "longitude": -152.665167, + "latitude": 59.980167 + }, + "imageName": "silversalmoncreek" + }, + { + "name": "Chilkoot Trail", + "category": "Mountains", + "city": "Skagway", + "state": "Alaska", + "id": 1003, + "isFeatured": false, + "isFavorite": true, + "park": "Klondike Gold Rush National Historical Park", + "coordinates": { + "longitude": -135.334571, + "latitude": 59.560551 + }, + "imageName": "chilkoottrail" + }, + { + "name": "St. Mary Lake", + "category": "Lakes", + "city": "Browning", + "state": "Montana", + "id": 1004, + "isFeatured": true, + "isFavorite": true, + "park": "Glacier National Park", + "coordinates": { + "longitude": -113.536248, + "latitude": 48.69423 + }, + "imageName": "stmarylake" + }, + { + "name": "Twin Lake", + "category": "Lakes", + "city": "Twin Lakes", + "state": "Alaska", + "id": 1005, + "isFeatured": false, + "isFavorite": false, + "park": "Lake Clark National Park and Preserve", + "coordinates": { + "longitude": -153.849883, + "latitude": 60.641684 + }, + "imageName": "twinlake" + }, + { + "name": "Lake McDonald", + "category": "Mountains", + "city": "West Glacier", + "state": "Montana", + "id": 1006, + "isFeatured": false, + "isFavorite": false, + "park": "Glacier National Park", + "coordinates": { + "longitude": -113.934831, + "latitude": 48.56002 + }, + "imageName": "lakemcdonald" + }, + { + "name": "Charley Rivers", + "category": "Rivers", + "city": "Eaking", + "state": "Alaska", + "id": 1007, + "isFeatured": true, + "isFavorite": false, + "park": "Charley Rivers National Preserve", + "coordinates": { + "longitude": -143.122586, + "latitude": 65.350021 + }, + "imageName": "charleyrivers", + }, + { + "name": "Icy Bay", + "category": "Mountains", + "city": "Icy Bay", + "state": "Alaska", + "id": 1008, + "isFeatured": false, + "isFavorite": false, + "park": "Wrangell-St. Elias National Park and Preserve", + "coordinates": { + "longitude": -141.518167, + "latitude": 60.089917 + }, + "imageName": "icybay" + }, + { + "name": "Rainbow Lake", + "category": "Lakes", + "city": "Willow", + "state": "Alaska", + "id": 1009, + "isFeatured": false, + "isFavorite": false, + "park": "State Recreation Area", + "coordinates": { + "longitude": -150.086103, + "latitude": 61.694334 + }, + "imageName": "rainbowlake" + }, + { + "name": "Hidden Lake", + "category": "Lakes", + "city": "Newhalem", + "state": "Washington", + "id": 1010, + "isFeatured": false, + "isFavorite": false, + "park": "North Cascades National Park", + "coordinates": { + "longitude": -121.17799, + "latitude": 48.495442 + }, + "imageName": "hiddenlake" + }, + { + "name": "Chincoteague", + "category": "Rivers", + "city": "Chincoteague", + "state": "Virginia", + "id": 1011, + "isFeatured": false, + "isFavorite": false, + "park": "Chincoteague National Wildlife Refuge", + "coordinates": { + "longitude": -75.383212, + "latitude": 37.91531 + }, + "imageName": "chincoteague" + }, + { + "name": "Lake Umbagog", + "category": "Lakes", + "city": "Errol", + "state": "New Hampshire", + "id": 1012, + "isFeatured": true, + "isFavorite": false, + "park": "Umbagog National Wildlife Refuge", + "coordinates": { + "longitude": -71.056816, + "latitude": 44.747408 + }, + "imageName": "umbagog" + } +] diff --git a/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Resources/rainbowlake.jpg b/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Resources/rainbowlake.jpg new file mode 100644 index 0000000..6da43dd Binary files /dev/null and b/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Resources/rainbowlake.jpg differ diff --git a/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Resources/silversalmoncreek.jpg b/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Resources/silversalmoncreek.jpg new file mode 100644 index 0000000..f657532 Binary files /dev/null and b/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Resources/silversalmoncreek.jpg differ diff --git a/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Resources/stmarylake.jpg b/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Resources/stmarylake.jpg new file mode 100644 index 0000000..1c71de4 Binary files /dev/null and b/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Resources/stmarylake.jpg differ diff --git a/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Resources/turtlerock.jpg b/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Resources/turtlerock.jpg new file mode 100644 index 0000000..f7a6e6d Binary files /dev/null and b/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Resources/turtlerock.jpg differ diff --git a/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Resources/twinlake.jpg b/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Resources/twinlake.jpg new file mode 100644 index 0000000..3e7a57c Binary files /dev/null and b/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Resources/twinlake.jpg differ diff --git a/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Resources/umbagog.jpg b/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Resources/umbagog.jpg new file mode 100644 index 0000000..56291c6 Binary files /dev/null and b/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Resources/umbagog.jpg differ diff --git a/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/SceneDelegate.swift b/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/SceneDelegate.swift new file mode 100644 index 0000000..96df0dc --- /dev/null +++ b/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/SceneDelegate.swift @@ -0,0 +1,56 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +The scene delegate. +*/ + +import UIKit +import SwiftUI + +class SceneDelegate: UIResponder, UIWindowSceneDelegate { + + var window: UIWindow? + + func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { + // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`. + // If using a storyboard, the `window` property will automatically be initialized and attached to the scene. + // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead). + + // Use a UIHostingController as window root view controller + let window = UIWindow(frame: UIScreen.main.bounds) + window.rootViewController = UIHostingController(rootView: LandmarkList().environmentObject(UserData())) + self.window = window + window.makeKeyAndVisible() + } + + func sceneDidDisconnect(_ scene: UIScene) { + // Called as the scene is being released by the system. + // This occurs shortly after the scene enters the background, or when its session is discarded. + // Release any resources associated with this scene that can be re-created the next time the scene connects. + // The scene may re-connect later, as its session was not neccessarily discarded (see `application:didDiscardSceneSessions` instead). + } + + func sceneDidBecomeActive(_ scene: UIScene) { + // Called when the scene has moved from an inactive state to an active state. + // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive. + } + + func sceneWillResignActive(_ scene: UIScene) { + // Called when the scene will move from an active state to an inactive state. + // This may occur due to temporary interruptions (ex. an incoming phone call). + } + + func sceneWillEnterForeground(_ scene: UIScene) { + // Called as the scene transitions from the background to the foreground. + // Use this method to undo the changes made on entering the background. + } + + func sceneDidEnterBackground(_ scene: UIScene) { + // Called as the scene transitions from the foreground to the background. + // Use this method to save data, release shared resources, and store enough scene-specific state information + // to restore the scene back to its current state. + } + +} + diff --git a/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Supporting Views/Badge.swift b/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Supporting Views/Badge.swift new file mode 100644 index 0000000..59f03b2 --- /dev/null +++ b/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Supporting Views/Badge.swift @@ -0,0 +1,41 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A view that displays a badge. +*/ + +import SwiftUI + +struct Badge: View { + static let rotationCount = 8 + + var badgeSymbols: some View { + ForEach(0.. + var overallRange: Range + + var heightRatio: Length { + max(Length(magnitude(of: range) / magnitude(of: overallRange)), 0.15) + } + + var offsetRatio: Length { + Length((range.lowerBound - overallRange.lowerBound) / magnitude(of: overallRange)) + } + + var animation: Animation { + Animation.spring(initialVelocity: 5) + .speed(2) + .delay(0.03 * Double(index)) + } + + var body: some View { + Capsule() + .fill(Color.white) + .frame(height: height * heightRatio, alignment: .bottom) + .offset(x: 0, y: height * -offsetRatio) + .animation(animation) + } +} + +#if DEBUG +struct GraphCapsule_Previews: PreviewProvider { + static var previews: some View { + GraphCapsule(index: 0, height: 150, range: 10..<50, overallRange: 0..<100) + } +} +#endif diff --git a/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Supporting Views/HikeGraph.swift b/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Supporting Views/HikeGraph.swift new file mode 100644 index 0000000..7df5194 --- /dev/null +++ b/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Supporting Views/HikeGraph.swift @@ -0,0 +1,74 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +The elevation, heart rate, and pace of a hike plotted on a graph. +*/ + +import SwiftUI + +func rangeOfRanges(_ ranges: C) -> Range + where C.Element == Range { + guard !ranges.isEmpty else { return 0..<0 } + let low = ranges.lazy.map { $0.lowerBound }.min()! + let high = ranges.lazy.map { $0.upperBound }.max()! + return low..) -> Double { + return range.upperBound - range.lowerBound +} + +struct HikeGraph: View { + var hike: Hike + var path: KeyPath> + + var color: Color { + switch path { + case \.elevation: + return .gray + case \.heartRate: + return Color(hue: 0, saturation: 0.5, brightness: 0.7) + case \.pace: + return Color(hue: 0.7, saturation: 0.4, brightness: 0.7) + default: + return .black + } + } + + var body: some View { + let data = hike.observations + let overallRange = rangeOfRanges(data.lazy.map { $0[keyPath: self.path] }) + let maxMagnitude = data.map { magnitude(of: $0[keyPath: path]) }.max()! + let heightRatio = 1 - Length(maxMagnitude / magnitude(of: overallRange)) + + return GeometryReader { proxy in + HStack(alignment: .bottom, spacing: proxy.size.width / 120) { + ForEach(data.indices) { index in + GraphCapsule( + index: index, + height: proxy.size.height, + range: data[index][keyPath: self.path], + overallRange: overallRange) + .colorMultiply(self.color) + } + .offset(x: 0, y: proxy.size.height * heightRatio) + } + } + } +} + +#if DEBUG +struct HikeGraph_Previews: PreviewProvider { + static var previews: some View { + Group { + HikeGraph(hike: hikeData[0], path: \.elevation) + .frame(height: 200) + HikeGraph(hike: hikeData[0], path: \.heartRate) + .frame(height: 200) + HikeGraph(hike: hikeData[0], path: \.pace) + .frame(height: 200) + } + } +} +#endif diff --git a/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Supporting Views/LandmarkRow.swift b/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Supporting Views/LandmarkRow.swift new file mode 100644 index 0000000..2f8110c --- /dev/null +++ b/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Supporting Views/LandmarkRow.swift @@ -0,0 +1,38 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A single row to be displayed in a list of landmarks. +*/ + +import SwiftUI + +struct LandmarkRow: View { + var landmark: Landmark + + var body: some View { + HStack { + landmark.image(forSize: 50) + Text(verbatim: landmark.name) + Spacer() + + if landmark.isFavorite { + Image(systemName: "star.fill") + .imageScale(.medium) + .foregroundColor(.yellow) + } + } + } +} + +#if DEBUG +struct LandmarkRow_Previews: PreviewProvider { + static var previews: some View { + Group { + LandmarkRow(landmark: landmarkData[0]) + LandmarkRow(landmark: landmarkData[1]) + } + .previewLayout(.fixed(width: 300, height: 70)) + } +} +#endif diff --git a/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Supporting Views/MapView.swift b/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Supporting Views/MapView.swift new file mode 100644 index 0000000..5a8c64b --- /dev/null +++ b/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Supporting Views/MapView.swift @@ -0,0 +1,31 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A view that hosts an `MKMapView`. +*/ + +import SwiftUI +import MapKit + +struct MapView: UIViewRepresentable { + var coordinate: CLLocationCoordinate2D + + func makeUIView(context: Context) -> MKMapView { + MKMapView(frame: .zero) + } + + func updateUIView(_ view: MKMapView, context: Context) { + let span = MKCoordinateSpan(latitudeDelta: 0.02, longitudeDelta: 0.02) + let region = MKCoordinateRegion(center: coordinate, span: span) + view.setRegion(region, animated: true) + } +} + +#if DEBUG +struct MapView_Previews: PreviewProvider { + static var previews: some View { + MapView(coordinate: landmarkData[0].locationCoordinate) + } +} +#endif diff --git a/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Supporting Views/RotatedBadgeSymbol.swift b/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Supporting Views/RotatedBadgeSymbol.swift new file mode 100644 index 0000000..a7e4b53 --- /dev/null +++ b/Other Projects/Composing Complex Interfaces/StartingPoint/Landmarks/Landmarks/Supporting Views/RotatedBadgeSymbol.swift @@ -0,0 +1,26 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A view that displays a rotated version of a badge symbol. +*/ + +import SwiftUI + +struct RotatedBadgeSymbol: View { + let angle: Angle + + var body: some View { + BadgeSymbol() + .padding(-60) + .rotationEffect(angle, anchor: .bottom) + } +} + +#if DEBUG +struct RotatedBadgeSymbol_Previews: PreviewProvider { + static var previews: some View { + RotatedBadgeSymbol(angle: .init(degrees: 5)) + } +} +#endif diff --git a/Other Projects/Composing Complex Interfaces/StartingPoint/README.md b/Other Projects/Composing Complex Interfaces/StartingPoint/README.md new file mode 100644 index 0000000..04c6b3a --- /dev/null +++ b/Other Projects/Composing Complex Interfaces/StartingPoint/README.md @@ -0,0 +1,3 @@ +# Composing Complex Interfaces + +Use this project to code along with the [Composing Complex Interfaces](https://developer.apple.com/tutorials/swiftui/composing-complex-interfaces) tutorial. \ No newline at end of file diff --git a/Other Projects/Creating And Combining Views/Complete/.gitignore b/Other Projects/Creating And Combining Views/Complete/.gitignore new file mode 100644 index 0000000..9e50718 --- /dev/null +++ b/Other Projects/Creating And Combining Views/Complete/.gitignore @@ -0,0 +1,21 @@ +# See LICENSE folder for this sample’s licensing information. +# +# Apple sample code gitignore configuration. + +# Finder +.DS_Store + +# Xcode - User files +xcuserdata/ + +**/*.xcodeproj/project.xcworkspace/* +!**/*.xcodeproj/project.xcworkspace/xcshareddata + +**/*.xcodeproj/project.xcworkspace/xcshareddata/* +!**/*.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings + +**/*.playground/playground.xcworkspace/* +!**/*.playground/playground.xcworkspace/xcshareddata + +**/*.playground/playground.xcworkspace/xcshareddata/* +!**/*.playground/playground.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings diff --git a/Other Projects/Creating And Combining Views/Complete/Configuration/SampleCode.xcconfig b/Other Projects/Creating And Combining Views/Complete/Configuration/SampleCode.xcconfig new file mode 100644 index 0000000..db86c06 --- /dev/null +++ b/Other Projects/Creating And Combining Views/Complete/Configuration/SampleCode.xcconfig @@ -0,0 +1,13 @@ +// +// See LICENSE folder for this sample’s licensing information. +// +// SampleCode.xcconfig +// + +// The `SAMPLE_CODE_DISAMBIGUATOR` configuration is to make it easier to build +// and run a sample code project. Once you set your project's development team, +// you'll have a unique bundle identifier. This is because the bundle identifier +// is derived based on the 'SAMPLE_CODE_DISAMBIGUATOR' value. Do not use this +// approach in your own projects—it's only useful for sample code projects because +// they are frequently downloaded and don't have a development team set. +SAMPLE_CODE_DISAMBIGUATOR=${DEVELOPMENT_TEAM} diff --git a/Other Projects/Creating And Combining Views/Complete/LICENSE/LICENSE.txt b/Other Projects/Creating And Combining Views/Complete/LICENSE/LICENSE.txt new file mode 100644 index 0000000..94e3d54 --- /dev/null +++ b/Other Projects/Creating And Combining Views/Complete/LICENSE/LICENSE.txt @@ -0,0 +1,8 @@ +Copyright © 2019 Apple Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + diff --git a/Other Projects/Creating And Combining Views/Complete/Landmarks/CreatingAndCombiningViews.xcodeproj/.xcodesamplecode.plist b/Other Projects/Creating And Combining Views/Complete/Landmarks/CreatingAndCombiningViews.xcodeproj/.xcodesamplecode.plist new file mode 100644 index 0000000..5dd5da8 --- /dev/null +++ b/Other Projects/Creating And Combining Views/Complete/Landmarks/CreatingAndCombiningViews.xcodeproj/.xcodesamplecode.plist @@ -0,0 +1,5 @@ + + + + + diff --git a/Other Projects/Creating And Combining Views/Complete/Landmarks/CreatingAndCombiningViews.xcodeproj/project.pbxproj b/Other Projects/Creating And Combining Views/Complete/Landmarks/CreatingAndCombiningViews.xcodeproj/project.pbxproj new file mode 100644 index 0000000..b440a3a --- /dev/null +++ b/Other Projects/Creating And Combining Views/Complete/Landmarks/CreatingAndCombiningViews.xcodeproj/project.pbxproj @@ -0,0 +1,393 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 50; + objects = { + +/* Begin PBXBuildFile section */ + B7394866229F194000C47603 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7394865229F194000C47603 /* AppDelegate.swift */; }; + B7394868229F194000C47603 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7394867229F194000C47603 /* SceneDelegate.swift */; }; + B739486A229F194000C47603 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7394869229F194000C47603 /* ContentView.swift */; }; + B739486C229F194200C47603 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B739486B229F194200C47603 /* Assets.xcassets */; }; + B739486F229F194200C47603 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B739486E229F194200C47603 /* Preview Assets.xcassets */; }; + B7394872229F194200C47603 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B7394870229F194200C47603 /* LaunchScreen.storyboard */; }; + B739487A229F1B3F00C47603 /* CircleImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7394879229F1B3F00C47603 /* CircleImage.swift */; }; + B739487C229F1B6800C47603 /* MapView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B739487B229F1B6800C47603 /* MapView.swift */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 795AC830795A92E000000001 /* SampleCode.xcconfig */ = {isa = PBXFileReference; name = SampleCode.xcconfig; path = ../Configuration/SampleCode.xcconfig; sourceTree = ""; }; + 7B51AA007B507C1000000001 /* LICENSE.txt */ = {isa = PBXFileReference; includeInIndex = 1; path = LICENSE.txt; sourceTree = ""; }; + B7394862229F194000C47603 /* Landmarks.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Landmarks.app; sourceTree = BUILT_PRODUCTS_DIR; }; + B7394865229F194000C47603 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + B7394867229F194000C47603 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; + B7394869229F194000C47603 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; }; + B739486B229F194200C47603 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + B739486E229F194200C47603 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; + B7394871229F194200C47603 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + B7394873229F194200C47603 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + B7394879229F1B3F00C47603 /* CircleImage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CircleImage.swift; sourceTree = ""; }; + B739487B229F1B6800C47603 /* MapView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapView.swift; sourceTree = ""; }; + C4E4AAA0C4E4035000000001 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; name = README.md; path = ../README.md; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + B739485F229F194000C47603 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 795A9470795A943000000001 /* Configuration */ = { + isa = PBXGroup; + children = ( + 795AC830795A92E000000001 /* SampleCode.xcconfig */, + ); + name = Configuration; + sourceTree = ""; + }; + 7B5078C07B5070C000000001 /* LICENSE */ = { + isa = PBXGroup; + children = ( + 7B51AA007B507C1000000001 /* LICENSE.txt */, + ); + name = LICENSE; + path = ../LICENSE; + sourceTree = ""; + }; + B7394859229F194000C47603 = { + isa = PBXGroup; + children = ( + C4E4AAA0C4E4035000000001 /* README.md */, + B7394864229F194000C47603 /* Landmarks */, + B7394863229F194000C47603 /* Products */, + 795A9470795A943000000001 /* Configuration */, + 7B5078C07B5070C000000001 /* LICENSE */, + ); + sourceTree = ""; + }; + B7394863229F194000C47603 /* Products */ = { + isa = PBXGroup; + children = ( + B7394862229F194000C47603 /* Landmarks.app */, + ); + name = Products; + sourceTree = ""; + }; + B7394864229F194000C47603 /* Landmarks */ = { + isa = PBXGroup; + children = ( + B7394865229F194000C47603 /* AppDelegate.swift */, + B7394867229F194000C47603 /* SceneDelegate.swift */, + B7394869229F194000C47603 /* ContentView.swift */, + B739487D229F1C0100C47603 /* Supporting Views */, + B739486B229F194200C47603 /* Assets.xcassets */, + B7394870229F194200C47603 /* LaunchScreen.storyboard */, + B7394873229F194200C47603 /* Info.plist */, + B739486D229F194200C47603 /* Preview Content */, + ); + path = Landmarks; + sourceTree = ""; + }; + B739486D229F194200C47603 /* Preview Content */ = { + isa = PBXGroup; + children = ( + B739486E229F194200C47603 /* Preview Assets.xcassets */, + ); + path = "Preview Content"; + sourceTree = ""; + }; + B739487D229F1C0100C47603 /* Supporting Views */ = { + isa = PBXGroup; + children = ( + B7394879229F1B3F00C47603 /* CircleImage.swift */, + B739487B229F1B6800C47603 /* MapView.swift */, + ); + path = "Supporting Views"; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + B7394861229F194000C47603 /* Landmarks */ = { + isa = PBXNativeTarget; + buildConfigurationList = B7394876229F194200C47603 /* Build configuration list for PBXNativeTarget "Landmarks" */; + buildPhases = ( + B739485E229F194000C47603 /* Sources */, + B739485F229F194000C47603 /* Frameworks */, + B7394860229F194000C47603 /* Resources */, + C602AC70C605937000000001, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Landmarks; + productName = Landmarks; + productReference = B7394862229F194000C47603 /* Landmarks.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + B739485A229F194000C47603 /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 1100; + LastUpgradeCheck = 1100; + ORGANIZATIONNAME = Apple; + TargetAttributes = { + B7394861229F194000C47603 = { + CreatedOnToolsVersion = 11.0; + }; + }; + }; + buildConfigurationList = B739485D229F194000C47603 /* Build configuration list for PBXProject "CreatingAndCombiningViews" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = B7394859229F194000C47603; + productRefGroup = B7394863229F194000C47603 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + B7394861229F194000C47603 /* Landmarks */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + B7394860229F194000C47603 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + B7394872229F194200C47603 /* LaunchScreen.storyboard in Resources */, + B739486F229F194200C47603 /* Preview Assets.xcassets in Resources */, + B739486C229F194200C47603 /* Assets.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + B739485E229F194000C47603 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + B7394866229F194000C47603 /* AppDelegate.swift in Sources */, + B739487A229F1B3F00C47603 /* CircleImage.swift in Sources */, + B739487C229F1B6800C47603 /* MapView.swift in Sources */, + B7394868229F194000C47603 /* SceneDelegate.swift in Sources */, + B739486A229F194000C47603 /* ContentView.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + B7394870229F194200C47603 /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + B7394871229F194200C47603 /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + B7394874229F194200C47603 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 795AC830795A92E000000001 /* SampleCode.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + B7394875229F194200C47603 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 795AC830795A92E000000001 /* SampleCode.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + B7394877229F194200C47603 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 795AC830795A92E000000001 /* SampleCode.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_ASSET_PATHS = "Landmarks/Preview\\ Content"; + DEVELOPMENT_TEAM = ""; + ENABLE_PREVIEWS = YES; + INFOPLIST_FILE = Landmarks/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = "com.example.apple-samplecode.Landmarks${SAMPLE_CODE_DISAMBIGUATOR}"; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + B7394878229F194200C47603 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 795AC830795A92E000000001 /* SampleCode.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_ASSET_PATHS = "Landmarks/Preview\\ Content"; + DEVELOPMENT_TEAM = ""; + ENABLE_PREVIEWS = YES; + INFOPLIST_FILE = Landmarks/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = "com.example.apple-samplecode.Landmarks${SAMPLE_CODE_DISAMBIGUATOR}"; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + B739485D229F194000C47603 /* Build configuration list for PBXProject "CreatingAndCombiningViews" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + B7394874229F194200C47603 /* Debug */, + B7394875229F194200C47603 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + B7394876229F194200C47603 /* Build configuration list for PBXNativeTarget "Landmarks" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + B7394877229F194200C47603 /* Debug */, + B7394878229F194200C47603 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = B739485A229F194000C47603 /* Project object */; +} diff --git a/Other Projects/Creating And Combining Views/Complete/Landmarks/CreatingAndCombiningViews.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/Other Projects/Creating And Combining Views/Complete/Landmarks/CreatingAndCombiningViews.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 0000000..3ddf867 --- /dev/null +++ b/Other Projects/Creating And Combining Views/Complete/Landmarks/CreatingAndCombiningViews.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,8 @@ + + + + + BuildSystemType + Latest + + diff --git a/Other Projects/Creating And Combining Views/Complete/Landmarks/Landmarks/AppDelegate.swift b/Other Projects/Creating And Combining Views/Complete/Landmarks/Landmarks/AppDelegate.swift new file mode 100644 index 0000000..e22943b --- /dev/null +++ b/Other Projects/Creating And Combining Views/Complete/Landmarks/Landmarks/AppDelegate.swift @@ -0,0 +1,36 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +The application delegate. +*/ + +import UIKit + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { + // Override point for customization after application launch. + return true + } + + func applicationWillTerminate(_ application: UIApplication) { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. + } + + // MARK: UISceneSession Lifecycle + func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration { + // Called when a new scene session is being created. + // Use this method to select a configuration to create the new scene with. + return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role) + } + + func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) { + // Called when the user discards a scene session. + // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions. + // Use this method to release any resources that were specific to the discarded scenes, as they will not return. + } + +} + diff --git a/Other Projects/Creating And Combining Views/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/Contents.json b/Other Projects/Creating And Combining Views/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..fa0d2db --- /dev/null +++ b/Other Projects/Creating And Combining Views/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,113 @@ +{ + "images" : [ + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "landmark_app_icon_40x40.png", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "3x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "landmark_app_icon_58x58.png", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "landmark_app_icon_87x87.png", + "scale" : "3x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "landmark_app_icon_80x80.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "landmark_app_icon_120x120.png", + "scale" : "3x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "landmark_app_icon_120x120-1.png", + "scale" : "2x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "landmark_app_icon_180x180.png", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "1x" + }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "landmark_app_icon_40x40-1.png", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "landmark_app_icon_58x58-1.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "landmark_app_icon_40x40-2.png", + "scale" : "1x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "landmark_app_icon_80x80-1.png", + "scale" : "2x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "landmark_app_icon_76x76.png", + "scale" : "1x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "landmark_app_icon_152x152.png", + "scale" : "2x" + }, + { + "size" : "83.5x83.5", + "idiom" : "ipad", + "filename" : "landmark_app_icon_167x167.png", + "scale" : "2x" + }, + { + "size" : "1024x1024", + "idiom" : "ios-marketing", + "filename" : "landmark_app_icon_1024x1024.png", + "scale" : "1x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/Creating And Combining Views/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_1024x1024.png b/Other Projects/Creating And Combining Views/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_1024x1024.png new file mode 100644 index 0000000..00d81c1 Binary files /dev/null and b/Other Projects/Creating And Combining Views/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_1024x1024.png differ diff --git a/Other Projects/Creating And Combining Views/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_120x120-1.png b/Other Projects/Creating And Combining Views/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_120x120-1.png new file mode 100644 index 0000000..d382b8b Binary files /dev/null and b/Other Projects/Creating And Combining Views/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_120x120-1.png differ diff --git a/Other Projects/Creating And Combining Views/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_120x120.png b/Other Projects/Creating And Combining Views/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_120x120.png new file mode 100644 index 0000000..d382b8b Binary files /dev/null and b/Other Projects/Creating And Combining Views/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_120x120.png differ diff --git a/Other Projects/Creating And Combining Views/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_152x152.png b/Other Projects/Creating And Combining Views/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_152x152.png new file mode 100644 index 0000000..11057f8 Binary files /dev/null and b/Other Projects/Creating And Combining Views/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_152x152.png differ diff --git a/Other Projects/Creating And Combining Views/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_167x167.png b/Other Projects/Creating And Combining Views/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_167x167.png new file mode 100644 index 0000000..f73bc26 Binary files /dev/null and b/Other Projects/Creating And Combining Views/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_167x167.png differ diff --git a/Other Projects/Creating And Combining Views/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_180x180.png b/Other Projects/Creating And Combining Views/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_180x180.png new file mode 100644 index 0000000..b02738c Binary files /dev/null and b/Other Projects/Creating And Combining Views/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_180x180.png differ diff --git a/Other Projects/Creating And Combining Views/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40-1.png b/Other Projects/Creating And Combining Views/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40-1.png new file mode 100644 index 0000000..abaff0e Binary files /dev/null and b/Other Projects/Creating And Combining Views/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40-1.png differ diff --git a/Other Projects/Creating And Combining Views/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40-2.png b/Other Projects/Creating And Combining Views/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40-2.png new file mode 100644 index 0000000..abaff0e Binary files /dev/null and b/Other Projects/Creating And Combining Views/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40-2.png differ diff --git a/Other Projects/Creating And Combining Views/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40.png b/Other Projects/Creating And Combining Views/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40.png new file mode 100644 index 0000000..abaff0e Binary files /dev/null and b/Other Projects/Creating And Combining Views/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40.png differ diff --git a/Other Projects/Creating And Combining Views/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_58x58-1.png b/Other Projects/Creating And Combining Views/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_58x58-1.png new file mode 100644 index 0000000..cf7c73d Binary files /dev/null and b/Other Projects/Creating And Combining Views/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_58x58-1.png differ diff --git a/Other Projects/Creating And Combining Views/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_58x58.png b/Other Projects/Creating And Combining Views/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_58x58.png new file mode 100644 index 0000000..cf7c73d Binary files /dev/null and b/Other Projects/Creating And Combining Views/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_58x58.png differ diff --git a/Other Projects/Creating And Combining Views/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_76x76.png b/Other Projects/Creating And Combining Views/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_76x76.png new file mode 100644 index 0000000..3eff85b Binary files /dev/null and b/Other Projects/Creating And Combining Views/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_76x76.png differ diff --git a/Other Projects/Creating And Combining Views/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_80x80-1.png b/Other Projects/Creating And Combining Views/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_80x80-1.png new file mode 100644 index 0000000..6f33f66 Binary files /dev/null and b/Other Projects/Creating And Combining Views/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_80x80-1.png differ diff --git a/Other Projects/Creating And Combining Views/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_80x80.png b/Other Projects/Creating And Combining Views/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_80x80.png new file mode 100644 index 0000000..6f33f66 Binary files /dev/null and b/Other Projects/Creating And Combining Views/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_80x80.png differ diff --git a/Other Projects/Creating And Combining Views/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_87x87.png b/Other Projects/Creating And Combining Views/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_87x87.png new file mode 100644 index 0000000..9e1616c Binary files /dev/null and b/Other Projects/Creating And Combining Views/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_87x87.png differ diff --git a/Other Projects/Creating And Combining Views/Complete/Landmarks/Landmarks/Assets.xcassets/Contents.json b/Other Projects/Creating And Combining Views/Complete/Landmarks/Landmarks/Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/Other Projects/Creating And Combining Views/Complete/Landmarks/Landmarks/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/Creating And Combining Views/Complete/Landmarks/Landmarks/Assets.xcassets/turtlerock.imageset/Contents.json b/Other Projects/Creating And Combining Views/Complete/Landmarks/Landmarks/Assets.xcassets/turtlerock.imageset/Contents.json new file mode 100644 index 0000000..5bfd7bf --- /dev/null +++ b/Other Projects/Creating And Combining Views/Complete/Landmarks/Landmarks/Assets.xcassets/turtlerock.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "turtlerock.jpg", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/Creating And Combining Views/Complete/Landmarks/Landmarks/Assets.xcassets/turtlerock.imageset/turtlerock.jpg b/Other Projects/Creating And Combining Views/Complete/Landmarks/Landmarks/Assets.xcassets/turtlerock.imageset/turtlerock.jpg new file mode 100644 index 0000000..68bcd3e Binary files /dev/null and b/Other Projects/Creating And Combining Views/Complete/Landmarks/Landmarks/Assets.xcassets/turtlerock.imageset/turtlerock.jpg differ diff --git a/Other Projects/Creating And Combining Views/Complete/Landmarks/Landmarks/Base.lproj/LaunchScreen.storyboard b/Other Projects/Creating And Combining Views/Complete/Landmarks/Landmarks/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000..865e932 --- /dev/null +++ b/Other Projects/Creating And Combining Views/Complete/Landmarks/Landmarks/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Other Projects/Creating And Combining Views/Complete/Landmarks/Landmarks/ContentView.swift b/Other Projects/Creating And Combining Views/Complete/Landmarks/Landmarks/ContentView.swift new file mode 100644 index 0000000..6e4dea7 --- /dev/null +++ b/Other Projects/Creating And Combining Views/Complete/Landmarks/Landmarks/ContentView.swift @@ -0,0 +1,45 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A view showing the details for a landmark. +*/ + +import SwiftUI + +struct ContentView: View { + var body: some View { + VStack { + MapView() + .edgesIgnoringSafeArea(.top) + .frame(height: 300) + + CircleImage() + .offset(x: 0, y: -130) + .padding(.bottom, -130) + + VStack(alignment: .leading) { + Text("Turtle Rock") + .font(.title) + HStack(alignment: .top) { + Text("Joshua Tree National Park") + .font(.subheadline) + Spacer() + Text("California") + .font(.subheadline) + } + } + .padding() + + Spacer() + } + } +} + +#if DEBUG +struct ContentView_Previews: PreviewProvider { + static var previews: some View { + ContentView() + } +} +#endif diff --git a/Other Projects/Creating And Combining Views/Complete/Landmarks/Landmarks/Info.plist b/Other Projects/Creating And Combining Views/Complete/Landmarks/Landmarks/Info.plist new file mode 100644 index 0000000..e8bb4c6 --- /dev/null +++ b/Other Projects/Creating And Combining Views/Complete/Landmarks/Landmarks/Info.plist @@ -0,0 +1,62 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + $(PRODUCT_BUNDLE_PACKAGE_TYPE) + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UIApplicationSceneManifest + + UIApplicationSupportsMultipleScenes + + UISceneConfigurations + + UIWindowSceneSessionRoleApplication + + + UILaunchStoryboardName + LaunchScreen + UISceneConfigurationName + Default Configuration + UISceneDelegateClassName + $(PRODUCT_MODULE_NAME).SceneDelegate + + + + + UILaunchStoryboardName + LaunchScreen + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/Other Projects/Creating And Combining Views/Complete/Landmarks/Landmarks/Preview Content/Preview Assets.xcassets/Contents.json b/Other Projects/Creating And Combining Views/Complete/Landmarks/Landmarks/Preview Content/Preview Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/Other Projects/Creating And Combining Views/Complete/Landmarks/Landmarks/Preview Content/Preview Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/Creating And Combining Views/Complete/Landmarks/Landmarks/SceneDelegate.swift b/Other Projects/Creating And Combining Views/Complete/Landmarks/Landmarks/SceneDelegate.swift new file mode 100644 index 0000000..3c52902 --- /dev/null +++ b/Other Projects/Creating And Combining Views/Complete/Landmarks/Landmarks/SceneDelegate.swift @@ -0,0 +1,58 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +The scene delegate. +*/ + +import UIKit +import SwiftUI + +class SceneDelegate: UIResponder, UIWindowSceneDelegate { + + var window: UIWindow? + + func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { + // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`. + // If using a storyboard, the `window` property will automatically be initialized and attached to the scene. + // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead). + + // Use a UIHostingController as window root view controller + if let windowScene = scene as? UIWindowScene { + let window = UIWindow(windowScene: windowScene) + window.rootViewController = UIHostingController(rootView: ContentView()) + self.window = window + window.makeKeyAndVisible() + } + } + + func sceneDidDisconnect(_ scene: UIScene) { + // Called as the scene is being released by the system. + // This occurs shortly after the scene enters the background, or when its session is discarded. + // Release any resources associated with this scene that can be re-created the next time the scene connects. + // The scene may re-connect later, as its session was not neccessarily discarded (see `application:didDiscardSceneSessions` instead). + } + + func sceneDidBecomeActive(_ scene: UIScene) { + // Called when the scene has moved from an inactive state to an active state. + // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive. + } + + func sceneWillResignActive(_ scene: UIScene) { + // Called when the scene will move from an active state to an inactive state. + // This may occur due to temporary interruptions (ex. an incoming phone call). + } + + func sceneWillEnterForeground(_ scene: UIScene) { + // Called as the scene transitions from the background to the foreground. + // Use this method to undo the changes made on entering the background. + } + + func sceneDidEnterBackground(_ scene: UIScene) { + // Called as the scene transitions from the foreground to the background. + // Use this method to save data, release shared resources, and store enough scene-specific state information + // to restore the scene back to its current state. + } + +} + diff --git a/Other Projects/Creating And Combining Views/Complete/Landmarks/Landmarks/Supporting Views/CircleImage.swift b/Other Projects/Creating And Combining Views/Complete/Landmarks/Landmarks/Supporting Views/CircleImage.swift new file mode 100644 index 0000000..f32a333 --- /dev/null +++ b/Other Projects/Creating And Combining Views/Complete/Landmarks/Landmarks/Supporting Views/CircleImage.swift @@ -0,0 +1,26 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A view that clips an image to a circle and adds a stroke and shadow. +*/ + +import SwiftUI + +struct CircleImage: View { + var body: some View { + Image("turtlerock") + .clipShape(Circle()) + .overlay( + Circle().stroke(Color.white, lineWidth: 4)) + .shadow(radius: 10) + } +} + +#if DEBUG +struct CircleImage_Previews: PreviewProvider { + static var previews: some View { + CircleImage() + } +} +#endif diff --git a/Other Projects/Creating And Combining Views/Complete/Landmarks/Landmarks/Supporting Views/MapView.swift b/Other Projects/Creating And Combining Views/Complete/Landmarks/Landmarks/Supporting Views/MapView.swift new file mode 100644 index 0000000..ea5716e --- /dev/null +++ b/Other Projects/Creating And Combining Views/Complete/Landmarks/Landmarks/Supporting Views/MapView.swift @@ -0,0 +1,31 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A view that hosts an `MKMapView`. +*/ + +import SwiftUI +import MapKit + +struct MapView: UIViewRepresentable { + func makeUIView(context: Context) -> MKMapView { + MKMapView(frame: .zero) + } + + func updateUIView(_ view: MKMapView, context: Context) { + let coordinate = CLLocationCoordinate2D( + latitude: 34.011_286, longitude: -116.166_868) + let span = MKCoordinateSpan(latitudeDelta: 2.0, longitudeDelta: 2.0) + let region = MKCoordinateRegion(center: coordinate, span: span) + view.setRegion(region, animated: true) + } +} + +#if DEBUG +struct MapView_Previews: PreviewProvider { + static var previews: some View { + MapView() + } +} +#endif diff --git a/Other Projects/Creating And Combining Views/Complete/README.md b/Other Projects/Creating And Combining Views/Complete/README.md new file mode 100644 index 0000000..0dfb812 --- /dev/null +++ b/Other Projects/Creating And Combining Views/Complete/README.md @@ -0,0 +1,3 @@ +# Completed Project: Creating and Combining Views + +Explore the completed project for the [Creating and Combining Views](https://developer.apple.com/tutorials/swiftui/creating-and-combining-views) tutorial. diff --git a/Other Projects/Creating And Combining Views/Resources/LICENSE/LICENSE.txt b/Other Projects/Creating And Combining Views/Resources/LICENSE/LICENSE.txt new file mode 100644 index 0000000..94e3d54 --- /dev/null +++ b/Other Projects/Creating And Combining Views/Resources/LICENSE/LICENSE.txt @@ -0,0 +1,8 @@ +Copyright © 2019 Apple Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + diff --git a/Other Projects/Creating And Combining Views/Resources/turtlerock.jpg b/Other Projects/Creating And Combining Views/Resources/turtlerock.jpg new file mode 100644 index 0000000..68bcd3e Binary files /dev/null and b/Other Projects/Creating And Combining Views/Resources/turtlerock.jpg differ diff --git a/Other Projects/Currency-SwiftUI/Currency-SwiftUI.xcodeproj/project.pbxproj b/Other Projects/Currency-SwiftUI/Currency-SwiftUI.xcodeproj/project.pbxproj new file mode 100644 index 0000000..1e2ce73 --- /dev/null +++ b/Other Projects/Currency-SwiftUI/Currency-SwiftUI.xcodeproj/project.pbxproj @@ -0,0 +1,611 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 50; + objects = { + +/* Begin PBXBuildFile section */ + 5FFA056822C48D0F009057CC /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5FFA056722C48D0F009057CC /* AppDelegate.swift */; }; + 5FFA056A22C48D0F009057CC /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5FFA056922C48D0F009057CC /* SceneDelegate.swift */; }; + 5FFA056E22C48D11009057CC /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 5FFA056D22C48D11009057CC /* Assets.xcassets */; }; + 5FFA057122C48D11009057CC /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 5FFA057022C48D11009057CC /* Preview Assets.xcassets */; }; + 5FFA057422C48D11009057CC /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 5FFA057222C48D11009057CC /* LaunchScreen.storyboard */; }; + 5FFA057F22C48D11009057CC /* Currency_SwiftUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5FFA057E22C48D11009057CC /* Currency_SwiftUITests.swift */; }; + 5FFA058A22C48D11009057CC /* Currency_SwiftUIUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5FFA058922C48D11009057CC /* Currency_SwiftUIUITests.swift */; }; + 5FFA059E22C48D7A009057CC /* ConverterView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5FFA059722C48D7A009057CC /* ConverterView.swift */; }; + 5FFA059F22C48D7A009057CC /* AddCurrencyView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5FFA059822C48D7A009057CC /* AddCurrencyView.swift */; }; + 5FFA05A122C48D7A009057CC /* CurrencyList.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5FFA059A22C48D7A009057CC /* CurrencyList.swift */; }; + 5FFA05A222C48D7A009057CC /* CurrencyItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5FFA059B22C48D7A009057CC /* CurrencyItemView.swift */; }; + 5FFA05A322C48D7A009057CC /* CurrencyData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5FFA059C22C48D7A009057CC /* CurrencyData.swift */; }; + 5FFA05A422C48D7A009057CC /* UserData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5FFA059D22C48D7A009057CC /* UserData.swift */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 5FFA057B22C48D11009057CC /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 5FFA055C22C48D0F009057CC /* Project object */; + proxyType = 1; + remoteGlobalIDString = 5FFA056322C48D0F009057CC; + remoteInfo = "Currency-SwiftUI"; + }; + 5FFA058622C48D11009057CC /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 5FFA055C22C48D0F009057CC /* Project object */; + proxyType = 1; + remoteGlobalIDString = 5FFA056322C48D0F009057CC; + remoteInfo = "Currency-SwiftUI"; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + 5FFA056422C48D0F009057CC /* Currency-SwiftUI.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Currency-SwiftUI.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + 5FFA056722C48D0F009057CC /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 5FFA056922C48D0F009057CC /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; + 5FFA056D22C48D11009057CC /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 5FFA057022C48D11009057CC /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; + 5FFA057322C48D11009057CC /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 5FFA057522C48D11009057CC /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 5FFA057A22C48D11009057CC /* Currency-SwiftUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "Currency-SwiftUITests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; + 5FFA057E22C48D11009057CC /* Currency_SwiftUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Currency_SwiftUITests.swift; sourceTree = ""; }; + 5FFA058022C48D11009057CC /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 5FFA058522C48D11009057CC /* Currency-SwiftUIUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "Currency-SwiftUIUITests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; + 5FFA058922C48D11009057CC /* Currency_SwiftUIUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Currency_SwiftUIUITests.swift; sourceTree = ""; }; + 5FFA058B22C48D11009057CC /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 5FFA059722C48D7A009057CC /* ConverterView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConverterView.swift; sourceTree = ""; }; + 5FFA059822C48D7A009057CC /* AddCurrencyView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AddCurrencyView.swift; sourceTree = ""; }; + 5FFA059A22C48D7A009057CC /* CurrencyList.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CurrencyList.swift; sourceTree = ""; }; + 5FFA059B22C48D7A009057CC /* CurrencyItemView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CurrencyItemView.swift; sourceTree = ""; }; + 5FFA059C22C48D7A009057CC /* CurrencyData.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CurrencyData.swift; sourceTree = ""; }; + 5FFA059D22C48D7A009057CC /* UserData.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UserData.swift; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 5FFA056122C48D0F009057CC /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 5FFA057722C48D11009057CC /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 5FFA058222C48D11009057CC /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 5FFA055B22C48D0F009057CC = { + isa = PBXGroup; + children = ( + 5FFA056622C48D0F009057CC /* Currency-SwiftUI */, + 5FFA057D22C48D11009057CC /* Currency-SwiftUITests */, + 5FFA058822C48D11009057CC /* Currency-SwiftUIUITests */, + 5FFA056522C48D0F009057CC /* Products */, + ); + sourceTree = ""; + }; + 5FFA056522C48D0F009057CC /* Products */ = { + isa = PBXGroup; + children = ( + 5FFA056422C48D0F009057CC /* Currency-SwiftUI.app */, + 5FFA057A22C48D11009057CC /* Currency-SwiftUITests.xctest */, + 5FFA058522C48D11009057CC /* Currency-SwiftUIUITests.xctest */, + ); + name = Products; + sourceTree = ""; + }; + 5FFA056622C48D0F009057CC /* Currency-SwiftUI */ = { + isa = PBXGroup; + children = ( + 5FFA059822C48D7A009057CC /* AddCurrencyView.swift */, + 5FFA059722C48D7A009057CC /* ConverterView.swift */, + 5FFA059C22C48D7A009057CC /* CurrencyData.swift */, + 5FFA059B22C48D7A009057CC /* CurrencyItemView.swift */, + 5FFA059A22C48D7A009057CC /* CurrencyList.swift */, + 5FFA059D22C48D7A009057CC /* UserData.swift */, + 5FFA056722C48D0F009057CC /* AppDelegate.swift */, + 5FFA056922C48D0F009057CC /* SceneDelegate.swift */, + 5FFA056D22C48D11009057CC /* Assets.xcassets */, + 5FFA057222C48D11009057CC /* LaunchScreen.storyboard */, + 5FFA057522C48D11009057CC /* Info.plist */, + 5FFA056F22C48D11009057CC /* Preview Content */, + ); + path = "Currency-SwiftUI"; + sourceTree = ""; + }; + 5FFA056F22C48D11009057CC /* Preview Content */ = { + isa = PBXGroup; + children = ( + 5FFA057022C48D11009057CC /* Preview Assets.xcassets */, + ); + path = "Preview Content"; + sourceTree = ""; + }; + 5FFA057D22C48D11009057CC /* Currency-SwiftUITests */ = { + isa = PBXGroup; + children = ( + 5FFA057E22C48D11009057CC /* Currency_SwiftUITests.swift */, + 5FFA058022C48D11009057CC /* Info.plist */, + ); + path = "Currency-SwiftUITests"; + sourceTree = ""; + }; + 5FFA058822C48D11009057CC /* Currency-SwiftUIUITests */ = { + isa = PBXGroup; + children = ( + 5FFA058922C48D11009057CC /* Currency_SwiftUIUITests.swift */, + 5FFA058B22C48D11009057CC /* Info.plist */, + ); + path = "Currency-SwiftUIUITests"; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 5FFA056322C48D0F009057CC /* Currency-SwiftUI */ = { + isa = PBXNativeTarget; + buildConfigurationList = 5FFA058E22C48D11009057CC /* Build configuration list for PBXNativeTarget "Currency-SwiftUI" */; + buildPhases = ( + 5FFA056022C48D0F009057CC /* Sources */, + 5FFA056122C48D0F009057CC /* Frameworks */, + 5FFA056222C48D0F009057CC /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "Currency-SwiftUI"; + productName = "Currency-SwiftUI"; + productReference = 5FFA056422C48D0F009057CC /* Currency-SwiftUI.app */; + productType = "com.apple.product-type.application"; + }; + 5FFA057922C48D11009057CC /* Currency-SwiftUITests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 5FFA059122C48D11009057CC /* Build configuration list for PBXNativeTarget "Currency-SwiftUITests" */; + buildPhases = ( + 5FFA057622C48D11009057CC /* Sources */, + 5FFA057722C48D11009057CC /* Frameworks */, + 5FFA057822C48D11009057CC /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 5FFA057C22C48D11009057CC /* PBXTargetDependency */, + ); + name = "Currency-SwiftUITests"; + productName = "Currency-SwiftUITests"; + productReference = 5FFA057A22C48D11009057CC /* Currency-SwiftUITests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; + 5FFA058422C48D11009057CC /* Currency-SwiftUIUITests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 5FFA059422C48D11009057CC /* Build configuration list for PBXNativeTarget "Currency-SwiftUIUITests" */; + buildPhases = ( + 5FFA058122C48D11009057CC /* Sources */, + 5FFA058222C48D11009057CC /* Frameworks */, + 5FFA058322C48D11009057CC /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 5FFA058722C48D11009057CC /* PBXTargetDependency */, + ); + name = "Currency-SwiftUIUITests"; + productName = "Currency-SwiftUIUITests"; + productReference = 5FFA058522C48D11009057CC /* Currency-SwiftUIUITests.xctest */; + productType = "com.apple.product-type.bundle.ui-testing"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 5FFA055C22C48D0F009057CC /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 1100; + LastUpgradeCheck = 1100; + ORGANIZATIONNAME = "Alex Liu"; + TargetAttributes = { + 5FFA056322C48D0F009057CC = { + CreatedOnToolsVersion = 11.0; + }; + 5FFA057922C48D11009057CC = { + CreatedOnToolsVersion = 11.0; + TestTargetID = 5FFA056322C48D0F009057CC; + }; + 5FFA058422C48D11009057CC = { + CreatedOnToolsVersion = 11.0; + TestTargetID = 5FFA056322C48D0F009057CC; + }; + }; + }; + buildConfigurationList = 5FFA055F22C48D0F009057CC /* Build configuration list for PBXProject "Currency-SwiftUI" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 5FFA055B22C48D0F009057CC; + productRefGroup = 5FFA056522C48D0F009057CC /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 5FFA056322C48D0F009057CC /* Currency-SwiftUI */, + 5FFA057922C48D11009057CC /* Currency-SwiftUITests */, + 5FFA058422C48D11009057CC /* Currency-SwiftUIUITests */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 5FFA056222C48D0F009057CC /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 5FFA057422C48D11009057CC /* LaunchScreen.storyboard in Resources */, + 5FFA057122C48D11009057CC /* Preview Assets.xcassets in Resources */, + 5FFA056E22C48D11009057CC /* Assets.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 5FFA057822C48D11009057CC /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 5FFA058322C48D11009057CC /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 5FFA056022C48D0F009057CC /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 5FFA05A322C48D7A009057CC /* CurrencyData.swift in Sources */, + 5FFA059F22C48D7A009057CC /* AddCurrencyView.swift in Sources */, + 5FFA056822C48D0F009057CC /* AppDelegate.swift in Sources */, + 5FFA05A122C48D7A009057CC /* CurrencyList.swift in Sources */, + 5FFA059E22C48D7A009057CC /* ConverterView.swift in Sources */, + 5FFA056A22C48D0F009057CC /* SceneDelegate.swift in Sources */, + 5FFA05A222C48D7A009057CC /* CurrencyItemView.swift in Sources */, + 5FFA05A422C48D7A009057CC /* UserData.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 5FFA057622C48D11009057CC /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 5FFA057F22C48D11009057CC /* Currency_SwiftUITests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 5FFA058122C48D11009057CC /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 5FFA058A22C48D11009057CC /* Currency_SwiftUIUITests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 5FFA057C22C48D11009057CC /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 5FFA056322C48D0F009057CC /* Currency-SwiftUI */; + targetProxy = 5FFA057B22C48D11009057CC /* PBXContainerItemProxy */; + }; + 5FFA058722C48D11009057CC /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 5FFA056322C48D0F009057CC /* Currency-SwiftUI */; + targetProxy = 5FFA058622C48D11009057CC /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin PBXVariantGroup section */ + 5FFA057222C48D11009057CC /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 5FFA057322C48D11009057CC /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 5FFA058C22C48D11009057CC /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + 5FFA058D22C48D11009057CC /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 5FFA058F22C48D11009057CC /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_ASSET_PATHS = "Currency-SwiftUI/Preview\\ Content"; + ENABLE_PREVIEWS = YES; + INFOPLIST_FILE = "Currency-SwiftUI/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = "alex.liu.Currency-SwiftUI"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 5FFA059022C48D11009057CC /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_ASSET_PATHS = "Currency-SwiftUI/Preview\\ Content"; + ENABLE_PREVIEWS = YES; + INFOPLIST_FILE = "Currency-SwiftUI/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = "alex.liu.Currency-SwiftUI"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; + 5FFA059222C48D11009057CC /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + INFOPLIST_FILE = "Currency-SwiftUITests/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = "alex.liu.Currency-SwiftUITests"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Currency-SwiftUI.app/Currency-SwiftUI"; + }; + name = Debug; + }; + 5FFA059322C48D11009057CC /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + INFOPLIST_FILE = "Currency-SwiftUITests/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = "alex.liu.Currency-SwiftUITests"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Currency-SwiftUI.app/Currency-SwiftUI"; + }; + name = Release; + }; + 5FFA059522C48D11009057CC /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + CODE_SIGN_STYLE = Automatic; + INFOPLIST_FILE = "Currency-SwiftUIUITests/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = "alex.liu.Currency-SwiftUIUITests"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = "Currency-SwiftUI"; + }; + name = Debug; + }; + 5FFA059622C48D11009057CC /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + CODE_SIGN_STYLE = Automatic; + INFOPLIST_FILE = "Currency-SwiftUIUITests/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = "alex.liu.Currency-SwiftUIUITests"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = "Currency-SwiftUI"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 5FFA055F22C48D0F009057CC /* Build configuration list for PBXProject "Currency-SwiftUI" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 5FFA058C22C48D11009057CC /* Debug */, + 5FFA058D22C48D11009057CC /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 5FFA058E22C48D11009057CC /* Build configuration list for PBXNativeTarget "Currency-SwiftUI" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 5FFA058F22C48D11009057CC /* Debug */, + 5FFA059022C48D11009057CC /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 5FFA059122C48D11009057CC /* Build configuration list for PBXNativeTarget "Currency-SwiftUITests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 5FFA059222C48D11009057CC /* Debug */, + 5FFA059322C48D11009057CC /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 5FFA059422C48D11009057CC /* Build configuration list for PBXNativeTarget "Currency-SwiftUIUITests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 5FFA059522C48D11009057CC /* Debug */, + 5FFA059622C48D11009057CC /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 5FFA055C22C48D0F009057CC /* Project object */; +} diff --git a/Other Projects/Currency-SwiftUI/Currency-SwiftUI.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/Other Projects/Currency-SwiftUI/Currency-SwiftUI.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..3871dcd --- /dev/null +++ b/Other Projects/Currency-SwiftUI/Currency-SwiftUI.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/Other Projects/Currency-SwiftUI/Currency-SwiftUI.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/Other Projects/Currency-SwiftUI/Currency-SwiftUI.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/Other Projects/Currency-SwiftUI/Currency-SwiftUI.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/Other Projects/Currency-SwiftUI/Currency-SwiftUI/AddCurrencyView.swift b/Other Projects/Currency-SwiftUI/Currency-SwiftUI/AddCurrencyView.swift new file mode 100644 index 0000000..52595ce --- /dev/null +++ b/Other Projects/Currency-SwiftUI/Currency-SwiftUI/AddCurrencyView.swift @@ -0,0 +1,62 @@ +// +// AddCurrencyView.swift +// Currency-SwiftUI +// +// Created by Alex Liu on 2019-06-20. +// Copyright © 2018 Alex Liu All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +import Foundation +import SwiftUI + +struct AddCurrencyView : View { + @EnvironmentObject var userData: UserData + + var body: some View { + List { + ForEach(userData.allCurrencies) { currency in + return HStack { + Button(action: { self.select(currency) }) { + Text("\(currency.code) - \(currency.name)") + } + Spacer() + if self.isSelected(currency) { + Image(systemName: "checkmark").foregroundColor(.blue) + } + } + } + }.navigationBarTitle(Text("Add Currency")) + } + + private func select(_ currency: Currency) { + if userData.userCurrency.map({ $0.code }).contains(currency.code) { + userData.userCurrency.removeAll{$0.code == currency.code} + } + else { + userData.userCurrency.append(currency) + } + } + + private func isSelected(_ currency: Currency) -> Bool { + return userData.userCurrency.map({ $0.code }).contains(currency.code) + } +} + + diff --git a/Other Projects/Currency-SwiftUI/Currency-SwiftUI/AppDelegate.swift b/Other Projects/Currency-SwiftUI/Currency-SwiftUI/AppDelegate.swift new file mode 100644 index 0000000..4b393e5 --- /dev/null +++ b/Other Projects/Currency-SwiftUI/Currency-SwiftUI/AppDelegate.swift @@ -0,0 +1,58 @@ +// +// AppDelegate.swift +// Currency-SwiftUI +// +// Created by Alex Liu on 2019-06-27. +// Copyright © 2018 Alex Liu All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +import UIKit + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + + + + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { + // Override point for customization after application launch. + return true + } + + func applicationWillTerminate(_ application: UIApplication) { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. + } + + // MARK: UISceneSession Lifecycle + + func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration { + // Called when a new scene session is being created. + // Use this method to select a configuration to create the new scene with. + return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role) + } + + func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) { + // Called when the user discards a scene session. + // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions. + // Use this method to release any resources that were specific to the discarded scenes, as they will not return. + } + + +} + diff --git a/Other Projects/Currency-SwiftUI/Currency-SwiftUI/Assets.xcassets/AppIcon.appiconset/Contents.json b/Other Projects/Currency-SwiftUI/Currency-SwiftUI/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..d8db8d6 --- /dev/null +++ b/Other Projects/Currency-SwiftUI/Currency-SwiftUI/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,98 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "83.5x83.5", + "scale" : "2x" + }, + { + "idiom" : "ios-marketing", + "size" : "1024x1024", + "scale" : "1x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/Currency-SwiftUI/Currency-SwiftUI/Assets.xcassets/Contents.json b/Other Projects/Currency-SwiftUI/Currency-SwiftUI/Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/Other Projects/Currency-SwiftUI/Currency-SwiftUI/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/Currency-SwiftUI/Currency-SwiftUI/Base.lproj/LaunchScreen.storyboard b/Other Projects/Currency-SwiftUI/Currency-SwiftUI/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000..865e932 --- /dev/null +++ b/Other Projects/Currency-SwiftUI/Currency-SwiftUI/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Other Projects/Currency-SwiftUI/Currency-SwiftUI/ConverterView.swift b/Other Projects/Currency-SwiftUI/Currency-SwiftUI/ConverterView.swift new file mode 100644 index 0000000..a393e50 --- /dev/null +++ b/Other Projects/Currency-SwiftUI/Currency-SwiftUI/ConverterView.swift @@ -0,0 +1,165 @@ +// +// ContentView.swift +// Currency-SwiftUI +// +// Created by Alex Liu on 2019-06-20. +// Copyright © 2018 Alex Liu All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +import Foundation +import SwiftUI + +struct ConverterView : View { + @EnvironmentObject var userData: UserData + @State var baseAmount: String = "1.0" + @State var isEditing: Bool = false + @State var lastUpdated: String = "" + + var body: some View { + let inset = EdgeInsets(top: -8, leading: -20, bottom: -7, trailing: 5) + let doubleValue: Double = Double(self.$baseAmount.wrappedValue) ?? 1.0 + + return ZStack(alignment: Alignment.bottomTrailing) { + NavigationView { + VStack(alignment: .leading){ + Text("From:").bold().foregroundColor(.gray) + HStack{ + // Flag + Text("\(userData.baseCurrency.flag)").padding(5) + // Code and name + VStack(alignment: .leading){ + Text(userData.baseCurrency.code).foregroundColor(.white) + Text(userData.baseCurrency.name).foregroundColor(.white) + } + Spacer() + // Amount and conversion + TextField("1.0", text: $baseAmount, onCommit: { + // TODO: update all currencies on the following list + }).foregroundColor(.white) + .background( + RoundedRectangle(cornerRadius: 5) + .fill(Color.clear) + .background(RoundedRectangle(cornerRadius: 5).strokeBorder(Color(red: 0.7, green: 0.7, blue: 0.7), lineWidth: 1 / UIScreen.main.scale)) + .padding(inset) + ) + }.background(Color.blue).cornerRadius(5) + Text("To:").bold().foregroundColor(.gray) + List { + // TODO: should filter out BaseCurrency from list + ForEach(userData.userCurrency) { currency in + CurrencyItemView(currency: currency, baseAmount: doubleValue, isEditing: self.$isEditing).onTapGesture { + // Swap this and base + self.userData.baseCurrency = currency + } + } + }.onAppear(perform: loadCurrencies) + .navigationBarTitle(Text("Currencies 💱")) + .navigationBarItems(trailing: Button(action: { self.isEditing.toggle() }) { + if !self.isEditing { + Text("Edit") + } else { + Text("Done").bold() + } + }) + HStack { + Text("Last updated: \(self.lastUpdated)") + .foregroundColor(.gray).bold() + Spacer() + + NavigationLink(destination: AddCurrencyView().environmentObject(self.userData)) { + Text("💰") + }.frame(width: 46, height: 46, alignment: .center) + .background( + RoundedRectangle(cornerRadius: 23) + .fill(Color.blue) + .background(RoundedRectangle(cornerRadius: 23).strokeBorder(Color(red: 0.7, green: 0.7, blue: 0.7), lineWidth: 1 / UIScreen.main.scale))) + .foregroundColor(.white).font(.largeTitle) + }.padding() + } + } + } + } + + private func loadCurrencies() { + // Check if last updated is the same date + // if not the same pull from remote with base currency + let url = URL(string: "https://api.exchangeratesapi.io/latest?base=USD")! + + let task = URLSession.shared.dataTask(with: url, completionHandler: { data, _, _ in + if let data = data { + if let decoded: CurrencyList = self.decodeData(CurrencyList.self, data){ + // + self.lastUpdated = decoded.date + + // generate currency data + var newCurrencies = [Currency]() + for key in decoded.rates.keys { + let newCurrency = Currency(name: supportedCurrencies[key]?[0] ?? "Unknown", rate: 1.0 / (decoded.rates[key] ?? 1.0), symbol: supportedCurrencies[key]?[1] ?? "", code: key) + newCurrencies.append(newCurrency) + } + + DispatchQueue.main.async { + self.userData.allCurrencies = newCurrencies + + if let base = self.userData.allCurrencies.filter({ $0.symbol == self.userData.baseCurrency.symbol }).first { + self.userData.baseCurrency = base + } + + var tempNewUserCurrency = [Currency]() + let userCurrencies = self.userData.userCurrency.map{ $0.code } + for c in self.userData.allCurrencies { + if userCurrencies.contains(c.code){ + tempNewUserCurrency.append(c) + } + } + + self.userData.userCurrency = tempNewUserCurrency + } + } + } + }) + task.resume() + } +} + +extension ConverterView +{ + private func decodeData(_ decodeObject: T.Type, _ data: Data) -> T? where T: Codable + { + let decoder = JSONDecoder() + do + { + return try decoder.decode(decodeObject.self, from: data) + } + catch let jsonErr + { + print("Error decoding Json ", jsonErr) + return nil + } + } +} + +#if DEBUG +struct ContentView_Previews : PreviewProvider { + static var previews: some View { + ConverterView().environmentObject(UserData()) + } +} +#endif diff --git a/Other Projects/Currency-SwiftUI/Currency-SwiftUI/CurrencyData.swift b/Other Projects/Currency-SwiftUI/Currency-SwiftUI/CurrencyData.swift new file mode 100644 index 0000000..05c4f57 --- /dev/null +++ b/Other Projects/Currency-SwiftUI/Currency-SwiftUI/CurrencyData.swift @@ -0,0 +1,59 @@ +// +// CurrencyData.swift +// Currency-SwiftUI +// +// Created by Alex Liu on 2019-06-20. +// Copyright © 2018 Alex Liu All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +import Foundation +import SwiftUI + +struct Currency: Equatable, Hashable, Codable, Identifiable{ + let id: UUID + let name: String + + // This is a rate to USD + let rate: Double + let symbol: String + let code: String + + init(name: String, rate: Double, symbol: String = "", code: String) { + self.id = UUID() + self.name = name + self.rate = rate + self.symbol = symbol + self.code = code + } + + // Get unicode flag by currency symbol + var flag: String { + // Hard-code EU for now + if self.symbol == "EU" { return "🇪🇺" } + let base : UInt32 = 127397 + var s = "" + for v in self.symbol.uppercased().unicodeScalars { + s.unicodeScalars.append(UnicodeScalar(base + v.value)!) + } + + return s + } +} + diff --git a/Other Projects/Currency-SwiftUI/Currency-SwiftUI/CurrencyItemView.swift b/Other Projects/Currency-SwiftUI/Currency-SwiftUI/CurrencyItemView.swift new file mode 100644 index 0000000..8e75c62 --- /dev/null +++ b/Other Projects/Currency-SwiftUI/Currency-SwiftUI/CurrencyItemView.swift @@ -0,0 +1,83 @@ +// +// CurrencyItem.swift +// Currency-SwiftUI +// +// Created by Alex Liu on 2019-06-20. +// Copyright © 2018 Alex Liu All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +import SwiftUI + +struct CurrencyItemView: View { + @EnvironmentObject var userData: UserData + let currency: Currency + let baseAmount: Double + @Binding var isEditing: Bool + + var body: some View { + let currency = self.currency + let converstionRate = String(format: "%.4f", currency.rate / userData.baseCurrency.rate) + let totalAmount = String(format: "%.3f", baseAmount * ( userData.baseCurrency.rate / currency.rate)) + + return HStack { + if self.isEditing { + // This is for delete mode + HStack(alignment: .center){ + Image(systemName: "minus.circle") + .foregroundColor(.red) + .onTapGesture(count: 1) { + self.delete() + } + + Text(currency.flag).font(.title) + VStack(alignment: .leading){ + Text(currency.code) + Text(currency.name).foregroundColor(.gray) + } + } + } + else { + // This is normal mode + HStack{ + // Flag + Text(currency.flag).font(.largeTitle) + // Code and name + VStack(alignment: .leading){ + Text(currency.code).font(.headline) + Text(currency.name).font(.footnote).foregroundColor(.gray) + } + Spacer() + // Amount and conversion + VStack(alignment: .trailing){ + Text("\(totalAmount)") + // Would be 1 this currency = xxx base currency + Text("1 \(currency.code) = \(converstionRate) \(userData.baseCurrency.code)") + .foregroundColor(.gray) + } + } + } + } + } + + // TODO: need to implement + private func delete() { + } +} + diff --git a/Other Projects/Currency-SwiftUI/Currency-SwiftUI/CurrencyList.swift b/Other Projects/Currency-SwiftUI/Currency-SwiftUI/CurrencyList.swift new file mode 100644 index 0000000..3891161 --- /dev/null +++ b/Other Projects/Currency-SwiftUI/Currency-SwiftUI/CurrencyList.swift @@ -0,0 +1,69 @@ +// +// CurrencyList.swift +// Currency-SwiftUI +// +// Created by Alex Liu on 2019-06-21. +// Copyright © 2018 Alex Liu All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +import Foundation + +struct CurrencyList: Codable{ + let base: String + let date: String + let rates: [String: Double] +} + +/// All supported currencies +let supportedCurrencies: [String: [String]] = [ + "THB": ["Thai baht", "TH"], + "PHP": ["Philippine peso", "PH"], + "CZK": ["Czech koruna", "CZ"], + "BRL": ["Brazilian real", "BR"], + "CHF": ["Swiss franc", "CH"], + "INR": ["Indian rupee", "IN"], + "ISK": ["Icelandic króna", "IS"], + "HRK": ["Croatian kuna", "HR"], + "PLN": ["Polish złoty", "PL"], + "NOK": ["Norwegian krone", "NO"], + "USD": ["US Dollar", "US"], + "CNY": ["Chinese Renminbi", "CN"], + "RUB": ["Russian ruble", "RU"], + "SEK": ["Swedish krona", "SE"], + "MYR": ["Malaysian ringgit", "MY"], + "SGD": ["Singapore dollar", "SG"], + "ILS": ["Israeli new shekel", "IL"], + "TRY": ["Turkish lira", "TR"], + "BGN": ["Bulgarian lev", "BG"], + "NZD": ["New Zealand dollar", "NZ"], + "HKD": ["Hong Kong dollar", "HK"], + "RON": ["Romanian leu", "RO"], + "EUR": ["Euro", "EU"], + "MXN": ["Mexican peso", "MX"], + "CAD": ["Canadian Dollar", "CA"], + "AUD": ["Australian dollar", "AU"], + "GBP": ["Pound sterling", "GB"], + "KRW": ["South Korean won", "KR"], + "IDR": ["Indonesian rupiah", "ID"], + "JPY": ["Japanese yen", "JP"], + "DKK": ["Danish krone", "DK"], + "ZAR": ["South African rand", "ZA"], + "HUF": ["Hungarian forint", "HU"] +] diff --git a/Other Projects/Currency-SwiftUI/Currency-SwiftUI/Info.plist b/Other Projects/Currency-SwiftUI/Currency-SwiftUI/Info.plist new file mode 100644 index 0000000..e8bb4c6 --- /dev/null +++ b/Other Projects/Currency-SwiftUI/Currency-SwiftUI/Info.plist @@ -0,0 +1,62 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + $(PRODUCT_BUNDLE_PACKAGE_TYPE) + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UIApplicationSceneManifest + + UIApplicationSupportsMultipleScenes + + UISceneConfigurations + + UIWindowSceneSessionRoleApplication + + + UILaunchStoryboardName + LaunchScreen + UISceneConfigurationName + Default Configuration + UISceneDelegateClassName + $(PRODUCT_MODULE_NAME).SceneDelegate + + + + + UILaunchStoryboardName + LaunchScreen + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/Other Projects/Currency-SwiftUI/Currency-SwiftUI/Preview Content/Preview Assets.xcassets/Contents.json b/Other Projects/Currency-SwiftUI/Currency-SwiftUI/Preview Content/Preview Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/Other Projects/Currency-SwiftUI/Currency-SwiftUI/Preview Content/Preview Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/Currency-SwiftUI/Currency-SwiftUI/SceneDelegate.swift b/Other Projects/Currency-SwiftUI/Currency-SwiftUI/SceneDelegate.swift new file mode 100644 index 0000000..d303c30 --- /dev/null +++ b/Other Projects/Currency-SwiftUI/Currency-SwiftUI/SceneDelegate.swift @@ -0,0 +1,78 @@ +// +// SceneDelegate.swift +// Currency-SwiftUI +// +// Created by Alex Liu on 2019-06-27. +// Copyright © 2018 Alex Liu All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +import UIKit +import SwiftUI + +class SceneDelegate: UIResponder, UIWindowSceneDelegate { + + var window: UIWindow? + + + func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { + // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`. + // If using a storyboard, the `window` property will automatically be initialized and attached to the scene. + // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead). + + // Use a UIHostingController as window root view controller + if let windowScene = scene as? UIWindowScene { + let window = UIWindow(windowScene: windowScene) + window.rootViewController = UIHostingController(rootView: ConverterView().environmentObject(UserData())) + self.window = window + window.makeKeyAndVisible() + } + } + + func sceneDidDisconnect(_ scene: UIScene) { + // Called as the scene is being released by the system. + // This occurs shortly after the scene enters the background, or when its session is discarded. + // Release any resources associated with this scene that can be re-created the next time the scene connects. + // The scene may re-connect later, as its session was not neccessarily discarded (see `application:didDiscardSceneSessions` instead). + } + + func sceneDidBecomeActive(_ scene: UIScene) { + // Called when the scene has moved from an inactive state to an active state. + // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive. + } + + func sceneWillResignActive(_ scene: UIScene) { + // Called when the scene will move from an active state to an inactive state. + // This may occur due to temporary interruptions (ex. an incoming phone call). + } + + func sceneWillEnterForeground(_ scene: UIScene) { + // Called as the scene transitions from the background to the foreground. + // Use this method to undo the changes made on entering the background. + } + + func sceneDidEnterBackground(_ scene: UIScene) { + // Called as the scene transitions from the foreground to the background. + // Use this method to save data, release shared resources, and store enough scene-specific state information + // to restore the scene back to its current state. + } + + +} + diff --git a/Other Projects/Currency-SwiftUI/Currency-SwiftUI/UserData.swift b/Other Projects/Currency-SwiftUI/Currency-SwiftUI/UserData.swift new file mode 100644 index 0000000..dff2da2 --- /dev/null +++ b/Other Projects/Currency-SwiftUI/Currency-SwiftUI/UserData.swift @@ -0,0 +1,78 @@ +// +// UserData.swift +// Currency-SwiftUI +// +// Created by Alex Liu on 2019-06-20. +// Copyright © 2018 Alex Liu All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +import Combine +import SwiftUI +import Foundation + +private let defaultCurrencies: [Currency] = [ + Currency(name: "US dollar", rate: 1.0, symbol: "US", code: "USD"), + Currency(name: "Canadian dollar", rate: 1.0, symbol: "CA", code: "CAD") +] + +@propertyWrapper +struct UserDefaultValue { + + let key: String + let defaultValue: Value + + var wrappedValue: Value { + get { + let data = UserDefaults.standard.data(forKey: key) + let value = data.flatMap { try? JSONDecoder().decode(Value.self, from: $0) } + return value ?? defaultValue + } + set { + let data = try? JSONEncoder().encode(newValue) + UserDefaults.standard.set(data, forKey: key) + } + } +} + +final class UserData: ObservableObject { + let objectWillChange = PassthroughSubject() + + @UserDefaultValue(key: "allCurrencies", defaultValue: defaultCurrencies) + var allCurrencies: [Currency] { + didSet { + objectWillChange.send(self) + } + } + + @UserDefaultValue(key: "baseCurrency", defaultValue: defaultCurrencies[0]) + var baseCurrency: Currency { + didSet { + objectWillChange.send(self) + } + } + + @UserDefaultValue(key: "userCurrency", defaultValue: defaultCurrencies) + var userCurrency: [Currency] { + didSet { + objectWillChange.send(self) + } + } +} + diff --git a/Other Projects/Currency-SwiftUI/Currency-SwiftUITests/Currency_SwiftUITests.swift b/Other Projects/Currency-SwiftUI/Currency-SwiftUITests/Currency_SwiftUITests.swift new file mode 100644 index 0000000..c93495b --- /dev/null +++ b/Other Projects/Currency-SwiftUI/Currency-SwiftUITests/Currency_SwiftUITests.swift @@ -0,0 +1,51 @@ +// +// Currency_SwiftUITests.swift +// Currency-SwiftUITests +// +// Created by Alex Liu on 2019-06-27. +// Copyright © 2018 Alex Liu All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +import XCTest +@testable import Currency_SwiftUI + +class Currency_SwiftUITests: XCTestCase { + + override func setUp() { + // Put setup code here. This method is called before the invocation of each test method in the class. + } + + override func tearDown() { + // Put teardown code here. This method is called after the invocation of each test method in the class. + } + + func testExample() { + // This is an example of a functional test case. + // Use XCTAssert and related functions to verify your tests produce the correct results. + } + + func testPerformanceExample() { + // This is an example of a performance test case. + self.measure { + // Put the code you want to measure the time of here. + } + } + +} diff --git a/Other Projects/Currency-SwiftUI/Currency-SwiftUITests/Info.plist b/Other Projects/Currency-SwiftUI/Currency-SwiftUITests/Info.plist new file mode 100644 index 0000000..64d65ca --- /dev/null +++ b/Other Projects/Currency-SwiftUI/Currency-SwiftUITests/Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + $(PRODUCT_BUNDLE_PACKAGE_TYPE) + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + + diff --git a/Other Projects/Currency-SwiftUI/Currency-SwiftUIUITests/Currency_SwiftUIUITests.swift b/Other Projects/Currency-SwiftUI/Currency-SwiftUIUITests/Currency_SwiftUIUITests.swift new file mode 100644 index 0000000..2445296 --- /dev/null +++ b/Other Projects/Currency-SwiftUI/Currency-SwiftUIUITests/Currency_SwiftUIUITests.swift @@ -0,0 +1,51 @@ +// +// Currency_SwiftUIUITests.swift +// Currency-SwiftUIUITests +// +// Created by Alex Liu on 2019-06-27. +// Copyright © 2018 Alex Liu All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +import XCTest + +class Currency_SwiftUIUITests: XCTestCase { + + override func setUp() { + // Put setup code here. This method is called before the invocation of each test method in the class. + + // In UI tests it is usually best to stop immediately when a failure occurs. + continueAfterFailure = false + + // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method. + XCUIApplication().launch() + + // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this. + } + + override func tearDown() { + // Put teardown code here. This method is called after the invocation of each test method in the class. + } + + func testExample() { + // Use recording to get started writing UI tests. + // Use XCTAssert and related functions to verify your tests produce the correct results. + } + +} diff --git a/Other Projects/Currency-SwiftUI/Currency-SwiftUIUITests/Info.plist b/Other Projects/Currency-SwiftUI/Currency-SwiftUIUITests/Info.plist new file mode 100644 index 0000000..64d65ca --- /dev/null +++ b/Other Projects/Currency-SwiftUI/Currency-SwiftUIUITests/Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + $(PRODUCT_BUNDLE_PACKAGE_TYPE) + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + + diff --git a/Other Projects/Drawing Paths And Shapes/Complete/.gitignore b/Other Projects/Drawing Paths And Shapes/Complete/.gitignore new file mode 100644 index 0000000..9e50718 --- /dev/null +++ b/Other Projects/Drawing Paths And Shapes/Complete/.gitignore @@ -0,0 +1,21 @@ +# See LICENSE folder for this sample’s licensing information. +# +# Apple sample code gitignore configuration. + +# Finder +.DS_Store + +# Xcode - User files +xcuserdata/ + +**/*.xcodeproj/project.xcworkspace/* +!**/*.xcodeproj/project.xcworkspace/xcshareddata + +**/*.xcodeproj/project.xcworkspace/xcshareddata/* +!**/*.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings + +**/*.playground/playground.xcworkspace/* +!**/*.playground/playground.xcworkspace/xcshareddata + +**/*.playground/playground.xcworkspace/xcshareddata/* +!**/*.playground/playground.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings diff --git a/Other Projects/Drawing Paths And Shapes/Complete/Configuration/SampleCode.xcconfig b/Other Projects/Drawing Paths And Shapes/Complete/Configuration/SampleCode.xcconfig new file mode 100644 index 0000000..db86c06 --- /dev/null +++ b/Other Projects/Drawing Paths And Shapes/Complete/Configuration/SampleCode.xcconfig @@ -0,0 +1,13 @@ +// +// See LICENSE folder for this sample’s licensing information. +// +// SampleCode.xcconfig +// + +// The `SAMPLE_CODE_DISAMBIGUATOR` configuration is to make it easier to build +// and run a sample code project. Once you set your project's development team, +// you'll have a unique bundle identifier. This is because the bundle identifier +// is derived based on the 'SAMPLE_CODE_DISAMBIGUATOR' value. Do not use this +// approach in your own projects—it's only useful for sample code projects because +// they are frequently downloaded and don't have a development team set. +SAMPLE_CODE_DISAMBIGUATOR=${DEVELOPMENT_TEAM} diff --git a/Other Projects/Drawing Paths And Shapes/Complete/LICENSE/LICENSE.txt b/Other Projects/Drawing Paths And Shapes/Complete/LICENSE/LICENSE.txt new file mode 100644 index 0000000..94e3d54 --- /dev/null +++ b/Other Projects/Drawing Paths And Shapes/Complete/LICENSE/LICENSE.txt @@ -0,0 +1,8 @@ +Copyright © 2019 Apple Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + diff --git a/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/DrawingPathsAndShapes.xcodeproj/.xcodesamplecode.plist b/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/DrawingPathsAndShapes.xcodeproj/.xcodesamplecode.plist new file mode 100644 index 0000000..5dd5da8 --- /dev/null +++ b/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/DrawingPathsAndShapes.xcodeproj/.xcodesamplecode.plist @@ -0,0 +1,5 @@ + + + + + diff --git a/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/DrawingPathsAndShapes.xcodeproj/project.pbxproj b/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/DrawingPathsAndShapes.xcodeproj/project.pbxproj new file mode 100644 index 0000000..efba08b --- /dev/null +++ b/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/DrawingPathsAndShapes.xcodeproj/project.pbxproj @@ -0,0 +1,501 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 50; + objects = { + +/* Begin PBXBuildFile section */ + B7310DD1229F6839001079B9 /* HexagonParameters.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7310DD0229F6839001079B9 /* HexagonParameters.swift */; }; + B7310DD3229F6CA9001079B9 /* Badge.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7310DD2229F6CA9001079B9 /* Badge.swift */; }; + B7394866229F194000C47603 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7394865229F194000C47603 /* AppDelegate.swift */; }; + B7394868229F194000C47603 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7394867229F194000C47603 /* SceneDelegate.swift */; }; + B739486A229F194000C47603 /* LandmarkDetail.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7394869229F194000C47603 /* LandmarkDetail.swift */; }; + B739486C229F194200C47603 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B739486B229F194200C47603 /* Assets.xcassets */; }; + B739486F229F194200C47603 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B739486E229F194200C47603 /* Preview Assets.xcassets */; }; + B7394872229F194200C47603 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B7394870229F194200C47603 /* LaunchScreen.storyboard */; }; + B739487A229F1B3F00C47603 /* CircleImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7394879229F1B3F00C47603 /* CircleImage.swift */; }; + B739487C229F1B6800C47603 /* MapView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B739487B229F1B6800C47603 /* MapView.swift */; }; + B7394881229F28B900C47603 /* Landmark.swift in Sources */ = {isa = PBXBuildFile; fileRef = B739487F229F28B900C47603 /* Landmark.swift */; }; + B7394882229F28B900C47603 /* Data.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7394880229F28B900C47603 /* Data.swift */; }; + B7394891229F292F00C47603 /* rainbowlake.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B7394884229F292D00C47603 /* rainbowlake.jpg */; }; + B7394893229F292F00C47603 /* icybay.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B7394886229F292E00C47603 /* icybay.jpg */; }; + B7394894229F292F00C47603 /* lakemcdonald.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B7394887229F292E00C47603 /* lakemcdonald.jpg */; }; + B7394895229F292F00C47603 /* turtlerock.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B7394888229F292E00C47603 /* turtlerock.jpg */; }; + B7394896229F292F00C47603 /* umbagog.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B7394889229F292E00C47603 /* umbagog.jpg */; }; + B7394897229F292F00C47603 /* hiddenlake.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B739488A229F292E00C47603 /* hiddenlake.jpg */; }; + B7394898229F292F00C47603 /* stmarylake.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B739488B229F292E00C47603 /* stmarylake.jpg */; }; + B7394899229F292F00C47603 /* twinlake.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B739488C229F292E00C47603 /* twinlake.jpg */; }; + B739489A229F292F00C47603 /* silversalmoncreek.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B739488D229F292E00C47603 /* silversalmoncreek.jpg */; }; + B739489B229F292F00C47603 /* landmarkData.json in Resources */ = {isa = PBXBuildFile; fileRef = B739488E229F292E00C47603 /* landmarkData.json */; }; + B739489C229F292F00C47603 /* chincoteague.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B739488F229F292F00C47603 /* chincoteague.jpg */; }; + B739489D229F292F00C47603 /* chilkoottrail.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B7394890229F292F00C47603 /* chilkoottrail.jpg */; }; + B739489F229F2D9700C47603 /* LandmarkRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = B739489E229F2D9700C47603 /* LandmarkRow.swift */; }; + B73948A1229F2E1F00C47603 /* LandmarkList.swift in Sources */ = {isa = PBXBuildFile; fileRef = B73948A0229F2E1F00C47603 /* LandmarkList.swift */; }; + B73948A3229F3E2200C47603 /* charleyrivers.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B73948A2229F3E2200C47603 /* charleyrivers.jpg */; }; + B7D2AAC5229F4D7C0061E5F5 /* UserData.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7D2AAC4229F4D7C0061E5F5 /* UserData.swift */; }; + B7D587AE229F7382006E8DCF /* BadgeBackground.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7D587AD229F7382006E8DCF /* BadgeBackground.swift */; }; + B7D587B0229F73C1006E8DCF /* BadgeSymbol.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7D587AF229F73C1006E8DCF /* BadgeSymbol.swift */; }; + B7D587B2229F7406006E8DCF /* RotatedBadgeSymbol.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7D587B1229F7406006E8DCF /* RotatedBadgeSymbol.swift */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 35D9E74035D9800000000001 /* LICENSE.txt */ = {isa = PBXFileReference; includeInIndex = 1; path = LICENSE.txt; sourceTree = ""; }; + 37184BE037184AA000000001 /* SampleCode.xcconfig */ = {isa = PBXFileReference; name = SampleCode.xcconfig; path = ../Configuration/SampleCode.xcconfig; sourceTree = ""; }; + B7310DD0229F6839001079B9 /* HexagonParameters.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HexagonParameters.swift; sourceTree = ""; }; + B7310DD2229F6CA9001079B9 /* Badge.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Badge.swift; sourceTree = ""; }; + B7394862229F194000C47603 /* Landmarks.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Landmarks.app; sourceTree = BUILT_PRODUCTS_DIR; }; + B7394865229F194000C47603 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + B7394867229F194000C47603 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; + B7394869229F194000C47603 /* LandmarkDetail.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LandmarkDetail.swift; sourceTree = ""; }; + B739486B229F194200C47603 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + B739486E229F194200C47603 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; + B7394871229F194200C47603 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + B7394873229F194200C47603 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + B7394879229F1B3F00C47603 /* CircleImage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CircleImage.swift; sourceTree = ""; }; + B739487B229F1B6800C47603 /* MapView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapView.swift; sourceTree = ""; }; + B739487F229F28B900C47603 /* Landmark.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Landmark.swift; sourceTree = ""; }; + B7394880229F28B900C47603 /* Data.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Data.swift; sourceTree = ""; }; + B7394884229F292D00C47603 /* rainbowlake.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = rainbowlake.jpg; sourceTree = ""; }; + B7394886229F292E00C47603 /* icybay.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = icybay.jpg; sourceTree = ""; }; + B7394887229F292E00C47603 /* lakemcdonald.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = lakemcdonald.jpg; sourceTree = ""; }; + B7394888229F292E00C47603 /* turtlerock.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = turtlerock.jpg; sourceTree = ""; }; + B7394889229F292E00C47603 /* umbagog.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = umbagog.jpg; sourceTree = ""; }; + B739488A229F292E00C47603 /* hiddenlake.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = hiddenlake.jpg; sourceTree = ""; }; + B739488B229F292E00C47603 /* stmarylake.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = stmarylake.jpg; sourceTree = ""; }; + B739488C229F292E00C47603 /* twinlake.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = twinlake.jpg; sourceTree = ""; }; + B739488D229F292E00C47603 /* silversalmoncreek.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = silversalmoncreek.jpg; sourceTree = ""; }; + B739488E229F292E00C47603 /* landmarkData.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = landmarkData.json; sourceTree = ""; }; + B739488F229F292F00C47603 /* chincoteague.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = chincoteague.jpg; sourceTree = ""; }; + B7394890229F292F00C47603 /* chilkoottrail.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = chilkoottrail.jpg; sourceTree = ""; }; + B739489E229F2D9700C47603 /* LandmarkRow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = LandmarkRow.swift; path = "Supporting Views/LandmarkRow.swift"; sourceTree = ""; }; + B73948A0229F2E1F00C47603 /* LandmarkList.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LandmarkList.swift; sourceTree = ""; }; + B73948A2229F3E2200C47603 /* charleyrivers.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = charleyrivers.jpg; sourceTree = ""; }; + B7D2AAC4229F4D7C0061E5F5 /* UserData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserData.swift; sourceTree = ""; }; + B7D587AD229F7382006E8DCF /* BadgeBackground.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BadgeBackground.swift; sourceTree = ""; }; + B7D587AF229F73C1006E8DCF /* BadgeSymbol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BadgeSymbol.swift; sourceTree = ""; }; + B7D587B1229F7406006E8DCF /* RotatedBadgeSymbol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RotatedBadgeSymbol.swift; sourceTree = ""; }; + C4E4AAA0C4E4035000000001 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; name = README.md; path = ../README.md; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + B739485F229F194000C47603 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 35DA7F6035D9B10000000001 /* LICENSE */ = { + isa = PBXGroup; + children = ( + 35D9E74035D9800000000001 /* LICENSE.txt */, + ); + name = LICENSE; + path = ../LICENSE; + sourceTree = ""; + }; + 37184C6037184C2000000001 /* Configuration */ = { + isa = PBXGroup; + children = ( + 37184BE037184AA000000001 /* SampleCode.xcconfig */, + ); + name = Configuration; + sourceTree = ""; + }; + B7394859229F194000C47603 = { + isa = PBXGroup; + children = ( + C4E4AAA0C4E4035000000001 /* README.md */, + B7394864229F194000C47603 /* Landmarks */, + B7394863229F194000C47603 /* Products */, + 37184C6037184C2000000001 /* Configuration */, + 35DA7F6035D9B10000000001 /* LICENSE */, + ); + sourceTree = ""; + }; + B7394863229F194000C47603 /* Products */ = { + isa = PBXGroup; + children = ( + B7394862229F194000C47603 /* Landmarks.app */, + ); + name = Products; + sourceTree = ""; + }; + B7394864229F194000C47603 /* Landmarks */ = { + isa = PBXGroup; + children = ( + B739487E229F282200C47603 /* Models */, + B7394865229F194000C47603 /* AppDelegate.swift */, + B7394867229F194000C47603 /* SceneDelegate.swift */, + B73948A0229F2E1F00C47603 /* LandmarkList.swift */, + B739489E229F2D9700C47603 /* LandmarkRow.swift */, + B7394869229F194000C47603 /* LandmarkDetail.swift */, + B7310DD0229F6839001079B9 /* HexagonParameters.swift */, + B739487D229F1C0100C47603 /* Supporting Views */, + B7394883229F291A00C47603 /* Resources */, + B739486B229F194200C47603 /* Assets.xcassets */, + B7394870229F194200C47603 /* LaunchScreen.storyboard */, + B7394873229F194200C47603 /* Info.plist */, + B739486D229F194200C47603 /* Preview Content */, + ); + path = Landmarks; + sourceTree = ""; + }; + B739486D229F194200C47603 /* Preview Content */ = { + isa = PBXGroup; + children = ( + B739486E229F194200C47603 /* Preview Assets.xcassets */, + ); + path = "Preview Content"; + sourceTree = ""; + }; + B739487D229F1C0100C47603 /* Supporting Views */ = { + isa = PBXGroup; + children = ( + B7394879229F1B3F00C47603 /* CircleImage.swift */, + B739487B229F1B6800C47603 /* MapView.swift */, + B7310DD2229F6CA9001079B9 /* Badge.swift */, + B7D587AF229F73C1006E8DCF /* BadgeSymbol.swift */, + B7D587B1229F7406006E8DCF /* RotatedBadgeSymbol.swift */, + B7D587AD229F7382006E8DCF /* BadgeBackground.swift */, + ); + path = "Supporting Views"; + sourceTree = ""; + }; + B739487E229F282200C47603 /* Models */ = { + isa = PBXGroup; + children = ( + B7394880229F28B900C47603 /* Data.swift */, + B739487F229F28B900C47603 /* Landmark.swift */, + B7D2AAC4229F4D7C0061E5F5 /* UserData.swift */, + ); + path = Models; + sourceTree = ""; + }; + B7394883229F291A00C47603 /* Resources */ = { + isa = PBXGroup; + children = ( + B739488E229F292E00C47603 /* landmarkData.json */, + B7394890229F292F00C47603 /* chilkoottrail.jpg */, + B739488F229F292F00C47603 /* chincoteague.jpg */, + B739488A229F292E00C47603 /* hiddenlake.jpg */, + B7394886229F292E00C47603 /* icybay.jpg */, + B7394887229F292E00C47603 /* lakemcdonald.jpg */, + B7394884229F292D00C47603 /* rainbowlake.jpg */, + B739488D229F292E00C47603 /* silversalmoncreek.jpg */, + B739488B229F292E00C47603 /* stmarylake.jpg */, + B7394888229F292E00C47603 /* turtlerock.jpg */, + B739488C229F292E00C47603 /* twinlake.jpg */, + B7394889229F292E00C47603 /* umbagog.jpg */, + B73948A2229F3E2200C47603 /* charleyrivers.jpg */, + ); + path = Resources; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + B7394861229F194000C47603 /* Landmarks */ = { + isa = PBXNativeTarget; + buildConfigurationList = B7394876229F194200C47603 /* Build configuration list for PBXNativeTarget "Landmarks" */; + buildPhases = ( + B739485E229F194000C47603 /* Sources */, + B739485F229F194000C47603 /* Frameworks */, + B7394860229F194000C47603 /* Resources */, + C602AC70C605937000000001, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Landmarks; + productName = Landmarks; + productReference = B7394862229F194000C47603 /* Landmarks.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + B739485A229F194000C47603 /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 1100; + LastUpgradeCheck = 1100; + ORGANIZATIONNAME = Apple; + TargetAttributes = { + B7394861229F194000C47603 = { + CreatedOnToolsVersion = 11.0; + }; + }; + }; + buildConfigurationList = B739485D229F194000C47603 /* Build configuration list for PBXProject "DrawingPathsAndShapes" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = B7394859229F194000C47603; + productRefGroup = B7394863229F194000C47603 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + B7394861229F194000C47603 /* Landmarks */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + B7394860229F194000C47603 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + B739489A229F292F00C47603 /* silversalmoncreek.jpg in Resources */, + B7394894229F292F00C47603 /* lakemcdonald.jpg in Resources */, + B7394872229F194200C47603 /* LaunchScreen.storyboard in Resources */, + B73948A3229F3E2200C47603 /* charleyrivers.jpg in Resources */, + B7394891229F292F00C47603 /* rainbowlake.jpg in Resources */, + B739486F229F194200C47603 /* Preview Assets.xcassets in Resources */, + B7394895229F292F00C47603 /* turtlerock.jpg in Resources */, + B739486C229F194200C47603 /* Assets.xcassets in Resources */, + B7394899229F292F00C47603 /* twinlake.jpg in Resources */, + B7394896229F292F00C47603 /* umbagog.jpg in Resources */, + B739489D229F292F00C47603 /* chilkoottrail.jpg in Resources */, + B739489C229F292F00C47603 /* chincoteague.jpg in Resources */, + B739489B229F292F00C47603 /* landmarkData.json in Resources */, + B7394893229F292F00C47603 /* icybay.jpg in Resources */, + B7394897229F292F00C47603 /* hiddenlake.jpg in Resources */, + B7394898229F292F00C47603 /* stmarylake.jpg in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + B739485E229F194000C47603 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + B7394882229F28B900C47603 /* Data.swift in Sources */, + B7310DD3229F6CA9001079B9 /* Badge.swift in Sources */, + B7394866229F194000C47603 /* AppDelegate.swift in Sources */, + B739487A229F1B3F00C47603 /* CircleImage.swift in Sources */, + B739487C229F1B6800C47603 /* MapView.swift in Sources */, + B7310DD1229F6839001079B9 /* HexagonParameters.swift in Sources */, + B73948A1229F2E1F00C47603 /* LandmarkList.swift in Sources */, + B7D587B0229F73C1006E8DCF /* BadgeSymbol.swift in Sources */, + B7D587B2229F7406006E8DCF /* RotatedBadgeSymbol.swift in Sources */, + B7394868229F194000C47603 /* SceneDelegate.swift in Sources */, + B7D587AE229F7382006E8DCF /* BadgeBackground.swift in Sources */, + B739486A229F194000C47603 /* LandmarkDetail.swift in Sources */, + B739489F229F2D9700C47603 /* LandmarkRow.swift in Sources */, + B7D2AAC5229F4D7C0061E5F5 /* UserData.swift in Sources */, + B7394881229F28B900C47603 /* Landmark.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + B7394870229F194200C47603 /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + B7394871229F194200C47603 /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + B7394874229F194200C47603 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 37184BE037184AA000000001 /* SampleCode.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + B7394875229F194200C47603 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 37184BE037184AA000000001 /* SampleCode.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + B7394877229F194200C47603 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 37184BE037184AA000000001 /* SampleCode.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_ASSET_PATHS = "Landmarks/Preview\\ Content"; + DEVELOPMENT_TEAM = ""; + ENABLE_PREVIEWS = YES; + INFOPLIST_FILE = Landmarks/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = "com.example.apple-samplecode.Landmarks${SAMPLE_CODE_DISAMBIGUATOR}"; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + B7394878229F194200C47603 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 37184BE037184AA000000001 /* SampleCode.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_ASSET_PATHS = "Landmarks/Preview\\ Content"; + DEVELOPMENT_TEAM = ""; + ENABLE_PREVIEWS = YES; + INFOPLIST_FILE = Landmarks/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = "com.example.apple-samplecode.Landmarks${SAMPLE_CODE_DISAMBIGUATOR}"; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + B739485D229F194000C47603 /* Build configuration list for PBXProject "DrawingPathsAndShapes" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + B7394874229F194200C47603 /* Debug */, + B7394875229F194200C47603 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + B7394876229F194200C47603 /* Build configuration list for PBXNativeTarget "Landmarks" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + B7394877229F194200C47603 /* Debug */, + B7394878229F194200C47603 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = B739485A229F194000C47603 /* Project object */; +} diff --git a/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/DrawingPathsAndShapes.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/DrawingPathsAndShapes.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 0000000..3ddf867 --- /dev/null +++ b/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/DrawingPathsAndShapes.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,8 @@ + + + + + BuildSystemType + Latest + + diff --git a/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/AppDelegate.swift b/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/AppDelegate.swift new file mode 100644 index 0000000..e22943b --- /dev/null +++ b/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/AppDelegate.swift @@ -0,0 +1,36 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +The application delegate. +*/ + +import UIKit + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { + // Override point for customization after application launch. + return true + } + + func applicationWillTerminate(_ application: UIApplication) { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. + } + + // MARK: UISceneSession Lifecycle + func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration { + // Called when a new scene session is being created. + // Use this method to select a configuration to create the new scene with. + return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role) + } + + func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) { + // Called when the user discards a scene session. + // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions. + // Use this method to release any resources that were specific to the discarded scenes, as they will not return. + } + +} + diff --git a/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/Contents.json b/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..fa0d2db --- /dev/null +++ b/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,113 @@ +{ + "images" : [ + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "landmark_app_icon_40x40.png", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "3x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "landmark_app_icon_58x58.png", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "landmark_app_icon_87x87.png", + "scale" : "3x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "landmark_app_icon_80x80.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "landmark_app_icon_120x120.png", + "scale" : "3x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "landmark_app_icon_120x120-1.png", + "scale" : "2x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "landmark_app_icon_180x180.png", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "1x" + }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "landmark_app_icon_40x40-1.png", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "landmark_app_icon_58x58-1.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "landmark_app_icon_40x40-2.png", + "scale" : "1x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "landmark_app_icon_80x80-1.png", + "scale" : "2x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "landmark_app_icon_76x76.png", + "scale" : "1x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "landmark_app_icon_152x152.png", + "scale" : "2x" + }, + { + "size" : "83.5x83.5", + "idiom" : "ipad", + "filename" : "landmark_app_icon_167x167.png", + "scale" : "2x" + }, + { + "size" : "1024x1024", + "idiom" : "ios-marketing", + "filename" : "landmark_app_icon_1024x1024.png", + "scale" : "1x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_1024x1024.png b/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_1024x1024.png new file mode 100644 index 0000000..00d81c1 Binary files /dev/null and b/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_1024x1024.png differ diff --git a/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_120x120-1.png b/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_120x120-1.png new file mode 100644 index 0000000..d382b8b Binary files /dev/null and b/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_120x120-1.png differ diff --git a/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_120x120.png b/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_120x120.png new file mode 100644 index 0000000..d382b8b Binary files /dev/null and b/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_120x120.png differ diff --git a/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_152x152.png b/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_152x152.png new file mode 100644 index 0000000..11057f8 Binary files /dev/null and b/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_152x152.png differ diff --git a/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_167x167.png b/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_167x167.png new file mode 100644 index 0000000..f73bc26 Binary files /dev/null and b/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_167x167.png differ diff --git a/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_180x180.png b/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_180x180.png new file mode 100644 index 0000000..b02738c Binary files /dev/null and b/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_180x180.png differ diff --git a/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40-1.png b/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40-1.png new file mode 100644 index 0000000..abaff0e Binary files /dev/null and b/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40-1.png differ diff --git a/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40-2.png b/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40-2.png new file mode 100644 index 0000000..abaff0e Binary files /dev/null and b/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40-2.png differ diff --git a/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40.png b/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40.png new file mode 100644 index 0000000..abaff0e Binary files /dev/null and b/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40.png differ diff --git a/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_58x58-1.png b/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_58x58-1.png new file mode 100644 index 0000000..cf7c73d Binary files /dev/null and b/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_58x58-1.png differ diff --git a/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_58x58.png b/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_58x58.png new file mode 100644 index 0000000..cf7c73d Binary files /dev/null and b/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_58x58.png differ diff --git a/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_76x76.png b/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_76x76.png new file mode 100644 index 0000000..3eff85b Binary files /dev/null and b/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_76x76.png differ diff --git a/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_80x80-1.png b/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_80x80-1.png new file mode 100644 index 0000000..6f33f66 Binary files /dev/null and b/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_80x80-1.png differ diff --git a/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_80x80.png b/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_80x80.png new file mode 100644 index 0000000..6f33f66 Binary files /dev/null and b/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_80x80.png differ diff --git a/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_87x87.png b/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_87x87.png new file mode 100644 index 0000000..9e1616c Binary files /dev/null and b/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_87x87.png differ diff --git a/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/Assets.xcassets/Contents.json b/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/Assets.xcassets/turtlerock.imageset/Contents.json b/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/Assets.xcassets/turtlerock.imageset/Contents.json new file mode 100644 index 0000000..5bfd7bf --- /dev/null +++ b/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/Assets.xcassets/turtlerock.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "turtlerock.jpg", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/Assets.xcassets/turtlerock.imageset/turtlerock.jpg b/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/Assets.xcassets/turtlerock.imageset/turtlerock.jpg new file mode 100644 index 0000000..68bcd3e Binary files /dev/null and b/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/Assets.xcassets/turtlerock.imageset/turtlerock.jpg differ diff --git a/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/Base.lproj/LaunchScreen.storyboard b/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000..865e932 --- /dev/null +++ b/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/HexagonParameters.swift b/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/HexagonParameters.swift new file mode 100644 index 0000000..8decba4 --- /dev/null +++ b/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/HexagonParameters.swift @@ -0,0 +1,57 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +Size, position, and other information used to draw a badge. +*/ + +import SwiftUI + +struct HexagonParameters { + struct Segment { + let useWidth: (CGFloat, CGFloat, CGFloat) + let xFactors: (CGFloat, CGFloat, CGFloat) + let useHeight: (CGFloat, CGFloat, CGFloat) + let yFactors: (CGFloat, CGFloat, CGFloat) + } + + static let adjustment: CGFloat = 0.085 + static let points = [ + Segment( + useWidth: (1.00, 1.00, 1.00), + xFactors: (0.60, 0.40, 0.50), + useHeight: (1.00, 1.00, 0.00), + yFactors: (0.05, 0.05, 0.00) + ), + Segment( + useWidth: (1.00, 1.00, 0.00), + xFactors: (0.05, 0.00, 0.00), + useHeight: (1.00, 1.00, 1.00), + yFactors: (0.20 + adjustment, 0.30 + adjustment, 0.25 + adjustment) + ), + Segment( + useWidth: (1.00, 1.00, 0.00), + xFactors: (0.00, 0.05, 0.00), + useHeight: (1.00, 1.00, 1.00), + yFactors: (0.70 - adjustment, 0.80 - adjustment, 0.75 - adjustment) + ), + Segment( + useWidth: (1.00, 1.00, 1.00), + xFactors: (0.40, 0.60, 0.50), + useHeight: (1.00, 1.00, 1.00), + yFactors: (0.95, 0.95, 1.00) + ), + Segment( + useWidth: (1.00, 1.00, 1.00), + xFactors: (0.95, 1.00, 1.00), + useHeight: (1.00, 1.00, 1.00), + yFactors: (0.80 - adjustment, 0.70 - adjustment, 0.75 - adjustment) + ), + Segment( + useWidth: (1.00, 1.00, 1.00), + xFactors: (1.00, 0.95, 1.00), + useHeight: (1.00, 1.00, 1.00), + yFactors: (0.30 + adjustment, 0.20 + adjustment, 0.25 + adjustment) + ) + ] +} diff --git a/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/Info.plist b/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/Info.plist new file mode 100644 index 0000000..e8bb4c6 --- /dev/null +++ b/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/Info.plist @@ -0,0 +1,62 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + $(PRODUCT_BUNDLE_PACKAGE_TYPE) + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UIApplicationSceneManifest + + UIApplicationSupportsMultipleScenes + + UISceneConfigurations + + UIWindowSceneSessionRoleApplication + + + UILaunchStoryboardName + LaunchScreen + UISceneConfigurationName + Default Configuration + UISceneDelegateClassName + $(PRODUCT_MODULE_NAME).SceneDelegate + + + + + UILaunchStoryboardName + LaunchScreen + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/LandmarkDetail.swift b/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/LandmarkDetail.swift new file mode 100644 index 0000000..6c290a3 --- /dev/null +++ b/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/LandmarkDetail.swift @@ -0,0 +1,71 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A view showing the details for a landmark. +*/ + +import SwiftUI + +struct LandmarkDetail: View { + @EnvironmentObject var userData: UserData + var landmark: Landmark + + var landmarkIndex: Int { + userData.landmarks.firstIndex(where: { $0.id == landmark.id })! + } + + var body: some View { + VStack { + MapView(coordinate: landmark.locationCoordinate) + .edgesIgnoringSafeArea(.top) + .frame(height: 300) + + CircleImage(image: landmark.image(forSize: 250)) + .offset(x: 0, y: -130) + .padding(.bottom, -130) + + VStack(alignment: .leading) { + HStack { + Text(verbatim: landmark.name) + .font(.title) + + Button(action: { + self.userData.landmarks[self.landmarkIndex] + .isFavorite.toggle() + }) { + if self.userData.landmarks[self.landmarkIndex] + .isFavorite { + Image(systemName: "star.fill") + .foregroundColor(Color.yellow) + } else { + Image(systemName: "star") + .foregroundColor(Color.gray) + } + } + } + + HStack(alignment: .top) { + Text(verbatim: landmark.park) + .font(.subheadline) + Spacer() + Text(verbatim: landmark.state) + .font(.subheadline) + } + } + .padding() + + Spacer() + } + } +} + +#if DEBUG +struct LandmarkDetail_Preview: PreviewProvider { + static var previews: some View { + let userData = UserData() + return LandmarkDetail(landmark: userData.landmarks[0]) + .environmentObject(userData) + } +} +#endif diff --git a/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/LandmarkList.swift b/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/LandmarkList.swift new file mode 100644 index 0000000..665a08e --- /dev/null +++ b/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/LandmarkList.swift @@ -0,0 +1,46 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A view showing a list of landmarks. +*/ + +import SwiftUI + +struct LandmarkList: View { + @EnvironmentObject private var userData: UserData + + var body: some View { + NavigationView { + List { + Toggle(isOn: $userData.showFavoritesOnly) { + Text("Show Favorites Only") + } + + ForEach(userData.landmarks) { landmark in + if !self.userData.showFavoritesOnly || landmark.isFavorite { + NavigationLink( + destination: LandmarkDetail(landmark: landmark) + .environmentObject(self.userData)) { + LandmarkRow(landmark: landmark) + } + } + } + } + .navigationBarTitle(Text("Landmarks"), displayMode: .large) + } + } +} + +#if DEBUG +struct LandmarksList_Previews: PreviewProvider { + static var previews: some View { + ForEach(["iPhone SE", "iPhone XS Max"], id: \.self) { deviceName in + LandmarkList() + .previewDevice(PreviewDevice(rawValue: deviceName)) + .previewDisplayName(deviceName) + } + .environmentObject(UserData()) + } +} +#endif diff --git a/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/Models/Data.swift b/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/Models/Data.swift new file mode 100644 index 0000000..7248384 --- /dev/null +++ b/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/Models/Data.swift @@ -0,0 +1,93 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +Helpers for loading images and data. +*/ + +import UIKit +import SwiftUI +import CoreLocation + +let landmarkData: [Landmark] = load("landmarkData.json") + +func load(_ filename: String, as type: T.Type = T.self) -> T { + let data: Data + + guard let file = Bundle.main.url(forResource: filename, withExtension: nil) + else { + fatalError("Couldn't find \(filename) in main bundle.") + } + + do { + data = try Data(contentsOf: file) + } catch { + fatalError("Couldn't load \(filename) from main bundle:\n\(error)") + } + + do { + let decoder = JSONDecoder() + return try decoder.decode(T.self, from: data) + } catch { + fatalError("Couldn't parse \(filename) as \(T.self):\n\(error)") + } +} + +final class ImageStore { + fileprivate typealias _ImageDictionary = [String: [Int: CGImage]] + fileprivate var images: _ImageDictionary = [:] + + fileprivate static var originalSize = 250 + fileprivate static var scale = 2 + + static var shared = ImageStore() + + func image(name: String, size: Int) -> Image { + let index = _guaranteeInitialImage(name: name) + + let sizedImage = images.values[index][size] + ?? _sizeImage(images.values[index][ImageStore.originalSize]!, to: size * ImageStore.scale) + images.values[index][size] = sizedImage + + return Image(sizedImage, scale: CGFloat(ImageStore.scale), label: Text(verbatim: name)) + } + + fileprivate func _guaranteeInitialImage(name: String) -> _ImageDictionary.Index { + if let index = images.index(forKey: name) { return index } + + guard + let url = Bundle.main.url(forResource: name, withExtension: "jpg"), + let imageSource = CGImageSourceCreateWithURL(url as NSURL, nil), + let image = CGImageSourceCreateImageAtIndex(imageSource, 0, nil) + else { + fatalError("Couldn't load image \(name).jpg from main bundle.") + } + + images[name] = [ImageStore.originalSize: image] + return images.index(forKey: name)! + } + + fileprivate func _sizeImage(_ image: CGImage, to size: Int) -> CGImage { + guard + let colorSpace = image.colorSpace, + let context = CGContext( + data: nil, + width: size, height: size, + bitsPerComponent: image.bitsPerComponent, + bytesPerRow: image.bytesPerRow, + space: colorSpace, + bitmapInfo: image.bitmapInfo.rawValue) + else { + fatalError("Couldn't create graphics context.") + } + context.interpolationQuality = .high + context.draw(image, in: CGRect(x: 0, y: 0, width: size, height: size)) + + if let sizedImage = context.makeImage() { + return sizedImage + } else { + fatalError("Couldn't resize image.") + } + } +} + diff --git a/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/Models/Landmark.swift b/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/Models/Landmark.swift new file mode 100644 index 0000000..79b9aa4 --- /dev/null +++ b/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/Models/Landmark.swift @@ -0,0 +1,42 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +The model for an individual landmark. +*/ + +import SwiftUI +import CoreLocation + +struct Landmark: Hashable, Codable, Identifiable { + var id: Int + var name: String + fileprivate var imageName: String + fileprivate var coordinates: Coordinates + var state: String + var park: String + var category: Category + var isFavorite: Bool + + var locationCoordinate: CLLocationCoordinate2D { + CLLocationCoordinate2D( + latitude: coordinates.latitude, + longitude: coordinates.longitude) + } + + func image(forSize size: Int) -> Image { + ImageStore.shared.image(name: imageName, size: size) + } + + enum Category: String, CaseIterable, Codable, Hashable { + case featured = "Featured" + case lakes = "Lakes" + case rivers = "Rivers" + case mountains = "Mountains" + } +} + +struct Coordinates: Hashable, Codable { + var latitude: Double + var longitude: Double +} diff --git a/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/Models/UserData.swift b/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/Models/UserData.swift new file mode 100644 index 0000000..afc2cca --- /dev/null +++ b/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/Models/UserData.swift @@ -0,0 +1,15 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A model object that stores app data. +*/ + +import Combine +import SwiftUI + +final class UserData: ObservableObject { + @Published var showFavoritesOnly = false + + @Published var landmarks = landmarkData +} diff --git a/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/Preview Content/Preview Assets.xcassets/Contents.json b/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/Preview Content/Preview Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/Preview Content/Preview Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/Resources/charleyrivers.jpg b/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/Resources/charleyrivers.jpg new file mode 100644 index 0000000..17ff44b Binary files /dev/null and b/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/Resources/charleyrivers.jpg differ diff --git a/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/Resources/chilkoottrail.jpg b/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/Resources/chilkoottrail.jpg new file mode 100644 index 0000000..e7f805e Binary files /dev/null and b/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/Resources/chilkoottrail.jpg differ diff --git a/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/Resources/chincoteague.jpg b/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/Resources/chincoteague.jpg new file mode 100644 index 0000000..5f47986 Binary files /dev/null and b/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/Resources/chincoteague.jpg differ diff --git a/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/Resources/hiddenlake.jpg b/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/Resources/hiddenlake.jpg new file mode 100644 index 0000000..d8e804c Binary files /dev/null and b/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/Resources/hiddenlake.jpg differ diff --git a/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/Resources/icybay.jpg b/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/Resources/icybay.jpg new file mode 100644 index 0000000..feb1764 Binary files /dev/null and b/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/Resources/icybay.jpg differ diff --git a/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/Resources/lakemcdonald.jpg b/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/Resources/lakemcdonald.jpg new file mode 100644 index 0000000..bd9d6b9 Binary files /dev/null and b/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/Resources/lakemcdonald.jpg differ diff --git a/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/Resources/landmarkData.json b/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/Resources/landmarkData.json new file mode 100644 index 0000000..e5b14fc --- /dev/null +++ b/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/Resources/landmarkData.json @@ -0,0 +1,182 @@ +[ + { + "name": "Turtle Rock", + "category": "Rivers", + "city": "Twentynine Palms", + "state": "California", + "id": 1001, + "isFeatured": true, + "isFavorite": true, + "park": "Joshua Tree National Park", + "coordinates": { + "longitude": -116.166868, + "latitude": 34.011286 + }, + "imageName": "turtlerock" + }, + { + "name": "Silver Salmon Creek", + "category": "Lakes", + "city": "Port Alsworth", + "state": "Alaska", + "id": 1002, + "isFeatured": false, + "isFavorite": false, + "park": "Lake Clark National Park and Preserve", + "coordinates": { + "longitude": -152.665167, + "latitude": 59.980167 + }, + "imageName": "silversalmoncreek" + }, + { + "name": "Chilkoot Trail", + "category": "Mountains", + "city": "Skagway", + "state": "Alaska", + "id": 1003, + "isFeatured": false, + "isFavorite": true, + "park": "Klondike Gold Rush National Historical Park", + "coordinates": { + "longitude": -135.334571, + "latitude": 59.560551 + }, + "imageName": "chilkoottrail" + }, + { + "name": "St. Mary Lake", + "category": "Lakes", + "city": "Browning", + "state": "Montana", + "id": 1004, + "isFeatured": true, + "isFavorite": true, + "park": "Glacier National Park", + "coordinates": { + "longitude": -113.536248, + "latitude": 48.69423 + }, + "imageName": "stmarylake" + }, + { + "name": "Twin Lake", + "category": "Lakes", + "city": "Twin Lakes", + "state": "Alaska", + "id": 1005, + "isFeatured": false, + "isFavorite": false, + "park": "Lake Clark National Park and Preserve", + "coordinates": { + "longitude": -153.849883, + "latitude": 60.641684 + }, + "imageName": "twinlake" + }, + { + "name": "Lake McDonald", + "category": "Mountains", + "city": "West Glacier", + "state": "Montana", + "id": 1006, + "isFeatured": false, + "isFavorite": false, + "park": "Glacier National Park", + "coordinates": { + "longitude": -113.934831, + "latitude": 48.56002 + }, + "imageName": "lakemcdonald" + }, + { + "name": "Charley Rivers", + "category": "Rivers", + "city": "Eaking", + "state": "Alaska", + "id": 1007, + "isFeatured": true, + "isFavorite": false, + "park": "Charley Rivers National Preserve", + "coordinates": { + "longitude": -143.122586, + "latitude": 65.350021 + }, + "imageName": "charleyrivers", + }, + { + "name": "Icy Bay", + "category": "Mountains", + "city": "Icy Bay", + "state": "Alaska", + "id": 1008, + "isFeatured": false, + "isFavorite": false, + "park": "Wrangell-St. Elias National Park and Preserve", + "coordinates": { + "longitude": -141.518167, + "latitude": 60.089917 + }, + "imageName": "icybay" + }, + { + "name": "Rainbow Lake", + "category": "Lakes", + "city": "Willow", + "state": "Alaska", + "id": 1009, + "isFeatured": false, + "isFavorite": false, + "park": "State Recreation Area", + "coordinates": { + "longitude": -150.086103, + "latitude": 61.694334 + }, + "imageName": "rainbowlake" + }, + { + "name": "Hidden Lake", + "category": "Lakes", + "city": "Newhalem", + "state": "Washington", + "id": 1010, + "isFeatured": false, + "isFavorite": false, + "park": "North Cascades National Park", + "coordinates": { + "longitude": -121.17799, + "latitude": 48.495442 + }, + "imageName": "hiddenlake" + }, + { + "name": "Chincoteague", + "category": "Rivers", + "city": "Chincoteague", + "state": "Virginia", + "id": 1011, + "isFeatured": false, + "isFavorite": false, + "park": "Chincoteague National Wildlife Refuge", + "coordinates": { + "longitude": -75.383212, + "latitude": 37.91531 + }, + "imageName": "chincoteague" + }, + { + "name": "Lake Umbagog", + "category": "Lakes", + "city": "Errol", + "state": "New Hampshire", + "id": 1012, + "isFeatured": true, + "isFavorite": false, + "park": "Umbagog National Wildlife Refuge", + "coordinates": { + "longitude": -71.056816, + "latitude": 44.747408 + }, + "imageName": "umbagog" + } +] diff --git a/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/Resources/rainbowlake.jpg b/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/Resources/rainbowlake.jpg new file mode 100644 index 0000000..6da43dd Binary files /dev/null and b/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/Resources/rainbowlake.jpg differ diff --git a/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/Resources/silversalmoncreek.jpg b/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/Resources/silversalmoncreek.jpg new file mode 100644 index 0000000..f657532 Binary files /dev/null and b/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/Resources/silversalmoncreek.jpg differ diff --git a/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/Resources/stmarylake.jpg b/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/Resources/stmarylake.jpg new file mode 100644 index 0000000..1c71de4 Binary files /dev/null and b/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/Resources/stmarylake.jpg differ diff --git a/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/Resources/turtlerock.jpg b/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/Resources/turtlerock.jpg new file mode 100644 index 0000000..f7a6e6d Binary files /dev/null and b/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/Resources/turtlerock.jpg differ diff --git a/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/Resources/twinlake.jpg b/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/Resources/twinlake.jpg new file mode 100644 index 0000000..3e7a57c Binary files /dev/null and b/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/Resources/twinlake.jpg differ diff --git a/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/Resources/umbagog.jpg b/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/Resources/umbagog.jpg new file mode 100644 index 0000000..56291c6 Binary files /dev/null and b/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/Resources/umbagog.jpg differ diff --git a/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/SceneDelegate.swift b/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/SceneDelegate.swift new file mode 100644 index 0000000..ef7f251 --- /dev/null +++ b/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/SceneDelegate.swift @@ -0,0 +1,58 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +The scene delegate. +*/ + +import UIKit +import SwiftUI + +class SceneDelegate: UIResponder, UIWindowSceneDelegate { + + var window: UIWindow? + + func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { + // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`. + // If using a storyboard, the `window` property will automatically be initialized and attached to the scene. + // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead). + + // Use a UIHostingController as window root view controller + if let windowScene = scene as? UIWindowScene { + let window = UIWindow(windowScene: windowScene) + window.rootViewController = UIHostingController(rootView: LandmarkList().environmentObject(UserData())) + self.window = window + window.makeKeyAndVisible() + } + } + + func sceneDidDisconnect(_ scene: UIScene) { + // Called as the scene is being released by the system. + // This occurs shortly after the scene enters the background, or when its session is discarded. + // Release any resources associated with this scene that can be re-created the next time the scene connects. + // The scene may re-connect later, as its session was not neccessarily discarded (see `application:didDiscardSceneSessions` instead). + } + + func sceneDidBecomeActive(_ scene: UIScene) { + // Called when the scene has moved from an inactive state to an active state. + // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive. + } + + func sceneWillResignActive(_ scene: UIScene) { + // Called when the scene will move from an active state to an inactive state. + // This may occur due to temporary interruptions (ex. an incoming phone call). + } + + func sceneWillEnterForeground(_ scene: UIScene) { + // Called as the scene transitions from the background to the foreground. + // Use this method to undo the changes made on entering the background. + } + + func sceneDidEnterBackground(_ scene: UIScene) { + // Called as the scene transitions from the foreground to the background. + // Use this method to save data, release shared resources, and store enough scene-specific state information + // to restore the scene back to its current state. + } + +} + diff --git a/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/Supporting Views/Badge.swift b/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/Supporting Views/Badge.swift new file mode 100644 index 0000000..59f03b2 --- /dev/null +++ b/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/Supporting Views/Badge.swift @@ -0,0 +1,41 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A view that displays a badge. +*/ + +import SwiftUI + +struct Badge: View { + static let rotationCount = 8 + + var badgeSymbols: some View { + ForEach(0.. MKMapView { + MKMapView(frame: .zero) + } + + func updateUIView(_ view: MKMapView, context: Context) { + let span = MKCoordinateSpan(latitudeDelta: 0.02, longitudeDelta: 0.02) + let region = MKCoordinateRegion(center: coordinate, span: span) + view.setRegion(region, animated: true) + } +} + +#if DEBUG +struct MapView_Previews: PreviewProvider { + static var previews: some View { + MapView(coordinate: landmarkData[0].locationCoordinate) + } +} +#endif diff --git a/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/Supporting Views/RotatedBadgeSymbol.swift b/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/Supporting Views/RotatedBadgeSymbol.swift new file mode 100644 index 0000000..a7e4b53 --- /dev/null +++ b/Other Projects/Drawing Paths And Shapes/Complete/Landmarks/Landmarks/Supporting Views/RotatedBadgeSymbol.swift @@ -0,0 +1,26 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A view that displays a rotated version of a badge symbol. +*/ + +import SwiftUI + +struct RotatedBadgeSymbol: View { + let angle: Angle + + var body: some View { + BadgeSymbol() + .padding(-60) + .rotationEffect(angle, anchor: .bottom) + } +} + +#if DEBUG +struct RotatedBadgeSymbol_Previews: PreviewProvider { + static var previews: some View { + RotatedBadgeSymbol(angle: .init(degrees: 5)) + } +} +#endif diff --git a/Other Projects/Drawing Paths And Shapes/Complete/README.md b/Other Projects/Drawing Paths And Shapes/Complete/README.md new file mode 100644 index 0000000..02bb0f0 --- /dev/null +++ b/Other Projects/Drawing Paths And Shapes/Complete/README.md @@ -0,0 +1,3 @@ +# Completed Project: Drawing Paths and Shapes + +Explore the completed project for the [Drawing Paths and Shapes](https://developer.apple.com/tutorials/swiftui/drawing-paths-and-shapes) tutorial. \ No newline at end of file diff --git a/Other Projects/Drawing Paths And Shapes/StartingPoint/.gitignore b/Other Projects/Drawing Paths And Shapes/StartingPoint/.gitignore new file mode 100644 index 0000000..9e50718 --- /dev/null +++ b/Other Projects/Drawing Paths And Shapes/StartingPoint/.gitignore @@ -0,0 +1,21 @@ +# See LICENSE folder for this sample’s licensing information. +# +# Apple sample code gitignore configuration. + +# Finder +.DS_Store + +# Xcode - User files +xcuserdata/ + +**/*.xcodeproj/project.xcworkspace/* +!**/*.xcodeproj/project.xcworkspace/xcshareddata + +**/*.xcodeproj/project.xcworkspace/xcshareddata/* +!**/*.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings + +**/*.playground/playground.xcworkspace/* +!**/*.playground/playground.xcworkspace/xcshareddata + +**/*.playground/playground.xcworkspace/xcshareddata/* +!**/*.playground/playground.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings diff --git a/Other Projects/Drawing Paths And Shapes/StartingPoint/Configuration/SampleCode.xcconfig b/Other Projects/Drawing Paths And Shapes/StartingPoint/Configuration/SampleCode.xcconfig new file mode 100644 index 0000000..db86c06 --- /dev/null +++ b/Other Projects/Drawing Paths And Shapes/StartingPoint/Configuration/SampleCode.xcconfig @@ -0,0 +1,13 @@ +// +// See LICENSE folder for this sample’s licensing information. +// +// SampleCode.xcconfig +// + +// The `SAMPLE_CODE_DISAMBIGUATOR` configuration is to make it easier to build +// and run a sample code project. Once you set your project's development team, +// you'll have a unique bundle identifier. This is because the bundle identifier +// is derived based on the 'SAMPLE_CODE_DISAMBIGUATOR' value. Do not use this +// approach in your own projects—it's only useful for sample code projects because +// they are frequently downloaded and don't have a development team set. +SAMPLE_CODE_DISAMBIGUATOR=${DEVELOPMENT_TEAM} diff --git a/Other Projects/Drawing Paths And Shapes/StartingPoint/LICENSE/LICENSE.txt b/Other Projects/Drawing Paths And Shapes/StartingPoint/LICENSE/LICENSE.txt new file mode 100644 index 0000000..94e3d54 --- /dev/null +++ b/Other Projects/Drawing Paths And Shapes/StartingPoint/LICENSE/LICENSE.txt @@ -0,0 +1,8 @@ +Copyright © 2019 Apple Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + diff --git a/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/DrawingPathsAndShapes.xcodeproj/.xcodesamplecode.plist b/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/DrawingPathsAndShapes.xcodeproj/.xcodesamplecode.plist new file mode 100644 index 0000000..5dd5da8 --- /dev/null +++ b/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/DrawingPathsAndShapes.xcodeproj/.xcodesamplecode.plist @@ -0,0 +1,5 @@ + + + + + diff --git a/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/DrawingPathsAndShapes.xcodeproj/project.pbxproj b/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/DrawingPathsAndShapes.xcodeproj/project.pbxproj new file mode 100644 index 0000000..c9b94dd --- /dev/null +++ b/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/DrawingPathsAndShapes.xcodeproj/project.pbxproj @@ -0,0 +1,485 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 50; + objects = { + +/* Begin PBXBuildFile section */ + B7310DD1229F6839001079B9 /* HexagonParameters.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7310DD0229F6839001079B9 /* HexagonParameters.swift */; }; + B7394866229F194000C47603 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7394865229F194000C47603 /* AppDelegate.swift */; }; + B7394868229F194000C47603 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7394867229F194000C47603 /* SceneDelegate.swift */; }; + B739486A229F194000C47603 /* LandmarkDetail.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7394869229F194000C47603 /* LandmarkDetail.swift */; }; + B739486C229F194200C47603 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B739486B229F194200C47603 /* Assets.xcassets */; }; + B739486F229F194200C47603 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B739486E229F194200C47603 /* Preview Assets.xcassets */; }; + B7394872229F194200C47603 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B7394870229F194200C47603 /* LaunchScreen.storyboard */; }; + B739487A229F1B3F00C47603 /* CircleImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7394879229F1B3F00C47603 /* CircleImage.swift */; }; + B739487C229F1B6800C47603 /* MapView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B739487B229F1B6800C47603 /* MapView.swift */; }; + B7394881229F28B900C47603 /* Landmark.swift in Sources */ = {isa = PBXBuildFile; fileRef = B739487F229F28B900C47603 /* Landmark.swift */; }; + B7394882229F28B900C47603 /* Data.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7394880229F28B900C47603 /* Data.swift */; }; + B7394891229F292F00C47603 /* rainbowlake.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B7394884229F292D00C47603 /* rainbowlake.jpg */; }; + B7394893229F292F00C47603 /* icybay.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B7394886229F292E00C47603 /* icybay.jpg */; }; + B7394894229F292F00C47603 /* lakemcdonald.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B7394887229F292E00C47603 /* lakemcdonald.jpg */; }; + B7394895229F292F00C47603 /* turtlerock.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B7394888229F292E00C47603 /* turtlerock.jpg */; }; + B7394896229F292F00C47603 /* umbagog.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B7394889229F292E00C47603 /* umbagog.jpg */; }; + B7394897229F292F00C47603 /* hiddenlake.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B739488A229F292E00C47603 /* hiddenlake.jpg */; }; + B7394898229F292F00C47603 /* stmarylake.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B739488B229F292E00C47603 /* stmarylake.jpg */; }; + B7394899229F292F00C47603 /* twinlake.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B739488C229F292E00C47603 /* twinlake.jpg */; }; + B739489A229F292F00C47603 /* silversalmoncreek.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B739488D229F292E00C47603 /* silversalmoncreek.jpg */; }; + B739489B229F292F00C47603 /* landmarkData.json in Resources */ = {isa = PBXBuildFile; fileRef = B739488E229F292E00C47603 /* landmarkData.json */; }; + B739489C229F292F00C47603 /* chincoteague.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B739488F229F292F00C47603 /* chincoteague.jpg */; }; + B739489D229F292F00C47603 /* chilkoottrail.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B7394890229F292F00C47603 /* chilkoottrail.jpg */; }; + B739489F229F2D9700C47603 /* LandmarkRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = B739489E229F2D9700C47603 /* LandmarkRow.swift */; }; + B73948A1229F2E1F00C47603 /* LandmarkList.swift in Sources */ = {isa = PBXBuildFile; fileRef = B73948A0229F2E1F00C47603 /* LandmarkList.swift */; }; + B73948A3229F3E2200C47603 /* charleyrivers.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B73948A2229F3E2200C47603 /* charleyrivers.jpg */; }; + B7D2AAC5229F4D7C0061E5F5 /* UserData.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7D2AAC4229F4D7C0061E5F5 /* UserData.swift */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 2DCE23D02DCC99A000000001 /* SampleCode.xcconfig */ = {isa = PBXFileReference; name = SampleCode.xcconfig; path = ../Configuration/SampleCode.xcconfig; sourceTree = ""; }; + 2FD259902DCF231000000001 /* LICENSE.txt */ = {isa = PBXFileReference; includeInIndex = 1; path = LICENSE.txt; sourceTree = ""; }; + B7310DD0229F6839001079B9 /* HexagonParameters.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HexagonParameters.swift; sourceTree = ""; }; + B7394862229F194000C47603 /* Landmarks.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Landmarks.app; sourceTree = BUILT_PRODUCTS_DIR; }; + B7394865229F194000C47603 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + B7394867229F194000C47603 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; + B7394869229F194000C47603 /* LandmarkDetail.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LandmarkDetail.swift; sourceTree = ""; }; + B739486B229F194200C47603 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + B739486E229F194200C47603 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; + B7394871229F194200C47603 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + B7394873229F194200C47603 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + B7394879229F1B3F00C47603 /* CircleImage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CircleImage.swift; sourceTree = ""; }; + B739487B229F1B6800C47603 /* MapView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapView.swift; sourceTree = ""; }; + B739487F229F28B900C47603 /* Landmark.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Landmark.swift; sourceTree = ""; }; + B7394880229F28B900C47603 /* Data.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Data.swift; sourceTree = ""; }; + B7394884229F292D00C47603 /* rainbowlake.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = rainbowlake.jpg; sourceTree = ""; }; + B7394886229F292E00C47603 /* icybay.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = icybay.jpg; sourceTree = ""; }; + B7394887229F292E00C47603 /* lakemcdonald.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = lakemcdonald.jpg; sourceTree = ""; }; + B7394888229F292E00C47603 /* turtlerock.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = turtlerock.jpg; sourceTree = ""; }; + B7394889229F292E00C47603 /* umbagog.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = umbagog.jpg; sourceTree = ""; }; + B739488A229F292E00C47603 /* hiddenlake.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = hiddenlake.jpg; sourceTree = ""; }; + B739488B229F292E00C47603 /* stmarylake.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = stmarylake.jpg; sourceTree = ""; }; + B739488C229F292E00C47603 /* twinlake.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = twinlake.jpg; sourceTree = ""; }; + B739488D229F292E00C47603 /* silversalmoncreek.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = silversalmoncreek.jpg; sourceTree = ""; }; + B739488E229F292E00C47603 /* landmarkData.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = landmarkData.json; sourceTree = ""; }; + B739488F229F292F00C47603 /* chincoteague.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = chincoteague.jpg; sourceTree = ""; }; + B7394890229F292F00C47603 /* chilkoottrail.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = chilkoottrail.jpg; sourceTree = ""; }; + B739489E229F2D9700C47603 /* LandmarkRow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = LandmarkRow.swift; path = "Supporting Views/LandmarkRow.swift"; sourceTree = ""; }; + B73948A0229F2E1F00C47603 /* LandmarkList.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LandmarkList.swift; sourceTree = ""; }; + B73948A2229F3E2200C47603 /* charleyrivers.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = charleyrivers.jpg; sourceTree = ""; }; + B7D2AAC4229F4D7C0061E5F5 /* UserData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserData.swift; sourceTree = ""; }; + C4E4AAA0C4E4035000000001 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; name = README.md; path = ../README.md; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + B739485F229F194000C47603 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 2DCE23302DCE264000000001 /* Configuration */ = { + isa = PBXGroup; + children = ( + 2DCE23D02DCC99A000000001 /* SampleCode.xcconfig */, + ); + name = Configuration; + sourceTree = ""; + }; + 2DCF20602DCF74E000000001 /* LICENSE */ = { + isa = PBXGroup; + children = ( + 2FD259902DCF231000000001 /* LICENSE.txt */, + ); + name = LICENSE; + path = ../LICENSE; + sourceTree = ""; + }; + B7394859229F194000C47603 = { + isa = PBXGroup; + children = ( + C4E4AAA0C4E4035000000001 /* README.md */, + B7394864229F194000C47603 /* Landmarks */, + B7394863229F194000C47603 /* Products */, + 2DCE23302DCE264000000001 /* Configuration */, + 2DCF20602DCF74E000000001 /* LICENSE */, + ); + sourceTree = ""; + }; + B7394863229F194000C47603 /* Products */ = { + isa = PBXGroup; + children = ( + B7394862229F194000C47603 /* Landmarks.app */, + ); + name = Products; + sourceTree = ""; + }; + B7394864229F194000C47603 /* Landmarks */ = { + isa = PBXGroup; + children = ( + B739487E229F282200C47603 /* Models */, + B7394865229F194000C47603 /* AppDelegate.swift */, + B7394867229F194000C47603 /* SceneDelegate.swift */, + B73948A0229F2E1F00C47603 /* LandmarkList.swift */, + B739489E229F2D9700C47603 /* LandmarkRow.swift */, + B7394869229F194000C47603 /* LandmarkDetail.swift */, + B7310DD0229F6839001079B9 /* HexagonParameters.swift */, + B739487D229F1C0100C47603 /* Supporting Views */, + B7394883229F291A00C47603 /* Resources */, + B739486B229F194200C47603 /* Assets.xcassets */, + B7394870229F194200C47603 /* LaunchScreen.storyboard */, + B7394873229F194200C47603 /* Info.plist */, + B739486D229F194200C47603 /* Preview Content */, + ); + path = Landmarks; + sourceTree = ""; + }; + B739486D229F194200C47603 /* Preview Content */ = { + isa = PBXGroup; + children = ( + B739486E229F194200C47603 /* Preview Assets.xcassets */, + ); + path = "Preview Content"; + sourceTree = ""; + }; + B739487D229F1C0100C47603 /* Supporting Views */ = { + isa = PBXGroup; + children = ( + B7394879229F1B3F00C47603 /* CircleImage.swift */, + B739487B229F1B6800C47603 /* MapView.swift */, + ); + path = "Supporting Views"; + sourceTree = ""; + }; + B739487E229F282200C47603 /* Models */ = { + isa = PBXGroup; + children = ( + B7394880229F28B900C47603 /* Data.swift */, + B739487F229F28B900C47603 /* Landmark.swift */, + B7D2AAC4229F4D7C0061E5F5 /* UserData.swift */, + ); + path = Models; + sourceTree = ""; + }; + B7394883229F291A00C47603 /* Resources */ = { + isa = PBXGroup; + children = ( + B739488E229F292E00C47603 /* landmarkData.json */, + B7394890229F292F00C47603 /* chilkoottrail.jpg */, + B739488F229F292F00C47603 /* chincoteague.jpg */, + B739488A229F292E00C47603 /* hiddenlake.jpg */, + B7394886229F292E00C47603 /* icybay.jpg */, + B7394887229F292E00C47603 /* lakemcdonald.jpg */, + B7394884229F292D00C47603 /* rainbowlake.jpg */, + B739488D229F292E00C47603 /* silversalmoncreek.jpg */, + B739488B229F292E00C47603 /* stmarylake.jpg */, + B7394888229F292E00C47603 /* turtlerock.jpg */, + B739488C229F292E00C47603 /* twinlake.jpg */, + B7394889229F292E00C47603 /* umbagog.jpg */, + B73948A2229F3E2200C47603 /* charleyrivers.jpg */, + ); + path = Resources; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + B7394861229F194000C47603 /* Landmarks */ = { + isa = PBXNativeTarget; + buildConfigurationList = B7394876229F194200C47603 /* Build configuration list for PBXNativeTarget "Landmarks" */; + buildPhases = ( + B739485E229F194000C47603 /* Sources */, + B739485F229F194000C47603 /* Frameworks */, + B7394860229F194000C47603 /* Resources */, + C602AC70C605937000000001, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Landmarks; + productName = Landmarks; + productReference = B7394862229F194000C47603 /* Landmarks.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + B739485A229F194000C47603 /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 1100; + LastUpgradeCheck = 1100; + ORGANIZATIONNAME = Apple; + TargetAttributes = { + B7394861229F194000C47603 = { + CreatedOnToolsVersion = 11.0; + }; + }; + }; + buildConfigurationList = B739485D229F194000C47603 /* Build configuration list for PBXProject "DrawingPathsAndShapes" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = B7394859229F194000C47603; + productRefGroup = B7394863229F194000C47603 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + B7394861229F194000C47603 /* Landmarks */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + B7394860229F194000C47603 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + B739489A229F292F00C47603 /* silversalmoncreek.jpg in Resources */, + B7394894229F292F00C47603 /* lakemcdonald.jpg in Resources */, + B7394872229F194200C47603 /* LaunchScreen.storyboard in Resources */, + B73948A3229F3E2200C47603 /* charleyrivers.jpg in Resources */, + B7394891229F292F00C47603 /* rainbowlake.jpg in Resources */, + B739486F229F194200C47603 /* Preview Assets.xcassets in Resources */, + B7394895229F292F00C47603 /* turtlerock.jpg in Resources */, + B739486C229F194200C47603 /* Assets.xcassets in Resources */, + B7394899229F292F00C47603 /* twinlake.jpg in Resources */, + B7394896229F292F00C47603 /* umbagog.jpg in Resources */, + B739489D229F292F00C47603 /* chilkoottrail.jpg in Resources */, + B739489C229F292F00C47603 /* chincoteague.jpg in Resources */, + B739489B229F292F00C47603 /* landmarkData.json in Resources */, + B7394893229F292F00C47603 /* icybay.jpg in Resources */, + B7394897229F292F00C47603 /* hiddenlake.jpg in Resources */, + B7394898229F292F00C47603 /* stmarylake.jpg in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + B739485E229F194000C47603 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + B7394882229F28B900C47603 /* Data.swift in Sources */, + B7394866229F194000C47603 /* AppDelegate.swift in Sources */, + B739487A229F1B3F00C47603 /* CircleImage.swift in Sources */, + B739487C229F1B6800C47603 /* MapView.swift in Sources */, + B7310DD1229F6839001079B9 /* HexagonParameters.swift in Sources */, + B73948A1229F2E1F00C47603 /* LandmarkList.swift in Sources */, + B7394868229F194000C47603 /* SceneDelegate.swift in Sources */, + B739486A229F194000C47603 /* LandmarkDetail.swift in Sources */, + B739489F229F2D9700C47603 /* LandmarkRow.swift in Sources */, + B7D2AAC5229F4D7C0061E5F5 /* UserData.swift in Sources */, + B7394881229F28B900C47603 /* Landmark.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + B7394870229F194200C47603 /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + B7394871229F194200C47603 /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + B7394874229F194200C47603 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 2DCE23D02DCC99A000000001 /* SampleCode.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + B7394875229F194200C47603 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 2DCE23D02DCC99A000000001 /* SampleCode.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + B7394877229F194200C47603 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 2DCE23D02DCC99A000000001 /* SampleCode.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_ASSET_PATHS = "Landmarks/Preview\\ Content"; + DEVELOPMENT_TEAM = ""; + ENABLE_PREVIEWS = YES; + INFOPLIST_FILE = Landmarks/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = "com.example.apple-samplecode.Landmarks${SAMPLE_CODE_DISAMBIGUATOR}"; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + B7394878229F194200C47603 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 2DCE23D02DCC99A000000001 /* SampleCode.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_ASSET_PATHS = "Landmarks/Preview\\ Content"; + DEVELOPMENT_TEAM = ""; + ENABLE_PREVIEWS = YES; + INFOPLIST_FILE = Landmarks/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = "com.example.apple-samplecode.Landmarks${SAMPLE_CODE_DISAMBIGUATOR}"; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + B739485D229F194000C47603 /* Build configuration list for PBXProject "DrawingPathsAndShapes" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + B7394874229F194200C47603 /* Debug */, + B7394875229F194200C47603 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + B7394876229F194200C47603 /* Build configuration list for PBXNativeTarget "Landmarks" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + B7394877229F194200C47603 /* Debug */, + B7394878229F194200C47603 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = B739485A229F194000C47603 /* Project object */; +} diff --git a/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/DrawingPathsAndShapes.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/DrawingPathsAndShapes.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 0000000..3ddf867 --- /dev/null +++ b/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/DrawingPathsAndShapes.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,8 @@ + + + + + BuildSystemType + Latest + + diff --git a/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/AppDelegate.swift b/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/AppDelegate.swift new file mode 100644 index 0000000..e22943b --- /dev/null +++ b/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/AppDelegate.swift @@ -0,0 +1,36 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +The application delegate. +*/ + +import UIKit + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { + // Override point for customization after application launch. + return true + } + + func applicationWillTerminate(_ application: UIApplication) { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. + } + + // MARK: UISceneSession Lifecycle + func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration { + // Called when a new scene session is being created. + // Use this method to select a configuration to create the new scene with. + return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role) + } + + func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) { + // Called when the user discards a scene session. + // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions. + // Use this method to release any resources that were specific to the discarded scenes, as they will not return. + } + +} + diff --git a/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/Contents.json b/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..6ab6c31 --- /dev/null +++ b/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,112 @@ +{ + "images" : [ + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "landmark_app_icon_40x40.png", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "3x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "landmark_app_icon_58x58.png", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "landmark_app_icon_87x87.png", + "scale" : "3x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "landmark_app_icon_80x80.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "landmark_app_icon_120x120.png", + "scale" : "3x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "landmark_app_icon_120x120-1.png", + "scale" : "2x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "landmark_app_icon_180x180.png", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "1x" + }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "landmark_app_icon_40x40-1.png", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "landmark_app_icon_58x58-1.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "landmark_app_icon_40x40-2.png", + "scale" : "1x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "landmark_app_icon_80x80-1.png", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "1x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "landmark_app_icon_152x152.png", + "scale" : "2x" + }, + { + "size" : "83.5x83.5", + "idiom" : "ipad", + "filename" : "landmark_app_icon_167x167.png", + "scale" : "2x" + }, + { + "size" : "1024x1024", + "idiom" : "ios-marketing", + "filename" : "landmark_app_icon_1024x1024.png", + "scale" : "1x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_1024x1024.png b/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_1024x1024.png new file mode 100644 index 0000000..00d81c1 Binary files /dev/null and b/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_1024x1024.png differ diff --git a/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_120x120-1.png b/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_120x120-1.png new file mode 100644 index 0000000..d382b8b Binary files /dev/null and b/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_120x120-1.png differ diff --git a/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_120x120.png b/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_120x120.png new file mode 100644 index 0000000..d382b8b Binary files /dev/null and b/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_120x120.png differ diff --git a/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_152x152.png b/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_152x152.png new file mode 100644 index 0000000..11057f8 Binary files /dev/null and b/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_152x152.png differ diff --git a/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_167x167.png b/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_167x167.png new file mode 100644 index 0000000..f73bc26 Binary files /dev/null and b/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_167x167.png differ diff --git a/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_180x180.png b/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_180x180.png new file mode 100644 index 0000000..b02738c Binary files /dev/null and b/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_180x180.png differ diff --git a/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40-1.png b/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40-1.png new file mode 100644 index 0000000..abaff0e Binary files /dev/null and b/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40-1.png differ diff --git a/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40-2.png b/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40-2.png new file mode 100644 index 0000000..abaff0e Binary files /dev/null and b/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40-2.png differ diff --git a/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40.png b/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40.png new file mode 100644 index 0000000..abaff0e Binary files /dev/null and b/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40.png differ diff --git a/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_58x58-1.png b/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_58x58-1.png new file mode 100644 index 0000000..cf7c73d Binary files /dev/null and b/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_58x58-1.png differ diff --git a/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_58x58.png b/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_58x58.png new file mode 100644 index 0000000..cf7c73d Binary files /dev/null and b/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_58x58.png differ diff --git a/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_80x80-1.png b/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_80x80-1.png new file mode 100644 index 0000000..6f33f66 Binary files /dev/null and b/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_80x80-1.png differ diff --git a/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_80x80.png b/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_80x80.png new file mode 100644 index 0000000..6f33f66 Binary files /dev/null and b/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_80x80.png differ diff --git a/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_87x87.png b/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_87x87.png new file mode 100644 index 0000000..9e1616c Binary files /dev/null and b/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_87x87.png differ diff --git a/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/Assets.xcassets/Contents.json b/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/Assets.xcassets/turtlerock.imageset/Contents.json b/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/Assets.xcassets/turtlerock.imageset/Contents.json new file mode 100644 index 0000000..5bfd7bf --- /dev/null +++ b/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/Assets.xcassets/turtlerock.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "turtlerock.jpg", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/Assets.xcassets/turtlerock.imageset/turtlerock.jpg b/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/Assets.xcassets/turtlerock.imageset/turtlerock.jpg new file mode 100644 index 0000000..68bcd3e Binary files /dev/null and b/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/Assets.xcassets/turtlerock.imageset/turtlerock.jpg differ diff --git a/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/Base.lproj/LaunchScreen.storyboard b/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000..865e932 --- /dev/null +++ b/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/HexagonParameters.swift b/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/HexagonParameters.swift new file mode 100644 index 0000000..8decba4 --- /dev/null +++ b/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/HexagonParameters.swift @@ -0,0 +1,57 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +Size, position, and other information used to draw a badge. +*/ + +import SwiftUI + +struct HexagonParameters { + struct Segment { + let useWidth: (CGFloat, CGFloat, CGFloat) + let xFactors: (CGFloat, CGFloat, CGFloat) + let useHeight: (CGFloat, CGFloat, CGFloat) + let yFactors: (CGFloat, CGFloat, CGFloat) + } + + static let adjustment: CGFloat = 0.085 + static let points = [ + Segment( + useWidth: (1.00, 1.00, 1.00), + xFactors: (0.60, 0.40, 0.50), + useHeight: (1.00, 1.00, 0.00), + yFactors: (0.05, 0.05, 0.00) + ), + Segment( + useWidth: (1.00, 1.00, 0.00), + xFactors: (0.05, 0.00, 0.00), + useHeight: (1.00, 1.00, 1.00), + yFactors: (0.20 + adjustment, 0.30 + adjustment, 0.25 + adjustment) + ), + Segment( + useWidth: (1.00, 1.00, 0.00), + xFactors: (0.00, 0.05, 0.00), + useHeight: (1.00, 1.00, 1.00), + yFactors: (0.70 - adjustment, 0.80 - adjustment, 0.75 - adjustment) + ), + Segment( + useWidth: (1.00, 1.00, 1.00), + xFactors: (0.40, 0.60, 0.50), + useHeight: (1.00, 1.00, 1.00), + yFactors: (0.95, 0.95, 1.00) + ), + Segment( + useWidth: (1.00, 1.00, 1.00), + xFactors: (0.95, 1.00, 1.00), + useHeight: (1.00, 1.00, 1.00), + yFactors: (0.80 - adjustment, 0.70 - adjustment, 0.75 - adjustment) + ), + Segment( + useWidth: (1.00, 1.00, 1.00), + xFactors: (1.00, 0.95, 1.00), + useHeight: (1.00, 1.00, 1.00), + yFactors: (0.30 + adjustment, 0.20 + adjustment, 0.25 + adjustment) + ) + ] +} diff --git a/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/Info.plist b/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/Info.plist new file mode 100644 index 0000000..e8bb4c6 --- /dev/null +++ b/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/Info.plist @@ -0,0 +1,62 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + $(PRODUCT_BUNDLE_PACKAGE_TYPE) + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UIApplicationSceneManifest + + UIApplicationSupportsMultipleScenes + + UISceneConfigurations + + UIWindowSceneSessionRoleApplication + + + UILaunchStoryboardName + LaunchScreen + UISceneConfigurationName + Default Configuration + UISceneDelegateClassName + $(PRODUCT_MODULE_NAME).SceneDelegate + + + + + UILaunchStoryboardName + LaunchScreen + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/LandmarkDetail.swift b/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/LandmarkDetail.swift new file mode 100644 index 0000000..6c290a3 --- /dev/null +++ b/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/LandmarkDetail.swift @@ -0,0 +1,71 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A view showing the details for a landmark. +*/ + +import SwiftUI + +struct LandmarkDetail: View { + @EnvironmentObject var userData: UserData + var landmark: Landmark + + var landmarkIndex: Int { + userData.landmarks.firstIndex(where: { $0.id == landmark.id })! + } + + var body: some View { + VStack { + MapView(coordinate: landmark.locationCoordinate) + .edgesIgnoringSafeArea(.top) + .frame(height: 300) + + CircleImage(image: landmark.image(forSize: 250)) + .offset(x: 0, y: -130) + .padding(.bottom, -130) + + VStack(alignment: .leading) { + HStack { + Text(verbatim: landmark.name) + .font(.title) + + Button(action: { + self.userData.landmarks[self.landmarkIndex] + .isFavorite.toggle() + }) { + if self.userData.landmarks[self.landmarkIndex] + .isFavorite { + Image(systemName: "star.fill") + .foregroundColor(Color.yellow) + } else { + Image(systemName: "star") + .foregroundColor(Color.gray) + } + } + } + + HStack(alignment: .top) { + Text(verbatim: landmark.park) + .font(.subheadline) + Spacer() + Text(verbatim: landmark.state) + .font(.subheadline) + } + } + .padding() + + Spacer() + } + } +} + +#if DEBUG +struct LandmarkDetail_Preview: PreviewProvider { + static var previews: some View { + let userData = UserData() + return LandmarkDetail(landmark: userData.landmarks[0]) + .environmentObject(userData) + } +} +#endif diff --git a/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/LandmarkList.swift b/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/LandmarkList.swift new file mode 100644 index 0000000..c17b5f3 --- /dev/null +++ b/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/LandmarkList.swift @@ -0,0 +1,45 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A view showing a list of landmarks. +*/ + +import SwiftUI + +struct LandmarkList: View { + @EnvironmentObject private var userData: UserData + + var body: some View { + NavigationView { + List { + Toggle(isOn: $userData.showFavoritesOnly) { + Text("Show Favorites Only") + } + + ForEach(userData.landmarks) { landmark in + if !self.userData.showFavoritesOnly || landmark.isFavorite { + NavigationButton( + destination: LandmarkDetail(landmark: landmark)) { + LandmarkRow(landmark: landmark) + } + } + } + } + .navigationBarTitle(Text("Landmarks"), displayMode: .large) + } + } +} + +#if DEBUG +struct LandmarksList_Previews: PreviewProvider { + static var previews: some View { + ForEach(["iPhone SE", "iPhone XS Max"].identified(by: \.self)) { deviceName in + LandmarkList() + .previewDevice(PreviewDevice(rawValue: deviceName)) + .previewDisplayName(deviceName) + } + .environmentObject(UserData()) + } +} +#endif diff --git a/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/Models/Data.swift b/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/Models/Data.swift new file mode 100644 index 0000000..78837f6 --- /dev/null +++ b/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/Models/Data.swift @@ -0,0 +1,93 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +Helpers for loading images and data. +*/ + +import UIKit +import SwiftUI +import CoreLocation + +let landmarkData: [Landmark] = load("landmarkData.json") + +func load(_ filename: String, as type: T.Type = T.self) -> T { + let data: Data + + guard let file = Bundle.main.url(forResource: filename, withExtension: nil) + else { + fatalError("Couldn't find \(filename) in main bundle.") + } + + do { + data = try Data(contentsOf: file) + } catch { + fatalError("Couldn't load \(filename) from main bundle:\n\(error)") + } + + do { + let decoder = JSONDecoder() + return try decoder.decode(T.self, from: data) + } catch { + fatalError("Couldn't parse \(filename) as \(T.self):\n\(error)") + } +} + +final class ImageStore { + fileprivate typealias _ImageDictionary = [String: [Int: CGImage]] + fileprivate var images: _ImageDictionary = [:] + + fileprivate static var originalSize = 250 + fileprivate static var scale = 2 + + static var shared = ImageStore() + + func image(name: String, size: Int) -> Image { + let index = _guaranteeInitialImage(name: name) + + let sizedImage = images.values[index][size] + ?? _sizeImage(images.values[index][ImageStore.originalSize]!, to: size * ImageStore.scale) + images.values[index][size] = sizedImage + + return Image(sizedImage, scale: Length(ImageStore.scale), label: Text(verbatim: name)) + } + + fileprivate func _guaranteeInitialImage(name: String) -> _ImageDictionary.Index { + if let index = images.index(forKey: name) { return index } + + guard + let url = Bundle.main.url(forResource: name, withExtension: "jpg"), + let imageSource = CGImageSourceCreateWithURL(url as NSURL, nil), + let image = CGImageSourceCreateImageAtIndex(imageSource, 0, nil) + else { + fatalError("Couldn't load image \(name).jpg from main bundle.") + } + + images[name] = [ImageStore.originalSize: image] + return images.index(forKey: name)! + } + + fileprivate func _sizeImage(_ image: CGImage, to size: Int) -> CGImage { + guard + let colorSpace = image.colorSpace, + let context = CGContext( + data: nil, + width: size, height: size, + bitsPerComponent: image.bitsPerComponent, + bytesPerRow: image.bytesPerRow, + space: colorSpace, + bitmapInfo: image.bitmapInfo.rawValue) + else { + fatalError("Couldn't create graphics context.") + } + context.interpolationQuality = .high + context.draw(image, in: CGRect(x: 0, y: 0, width: size, height: size)) + + if let sizedImage = context.makeImage() { + return sizedImage + } else { + fatalError("Couldn't resize image.") + } + } +} + diff --git a/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/Models/Landmark.swift b/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/Models/Landmark.swift new file mode 100644 index 0000000..79b9aa4 --- /dev/null +++ b/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/Models/Landmark.swift @@ -0,0 +1,42 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +The model for an individual landmark. +*/ + +import SwiftUI +import CoreLocation + +struct Landmark: Hashable, Codable, Identifiable { + var id: Int + var name: String + fileprivate var imageName: String + fileprivate var coordinates: Coordinates + var state: String + var park: String + var category: Category + var isFavorite: Bool + + var locationCoordinate: CLLocationCoordinate2D { + CLLocationCoordinate2D( + latitude: coordinates.latitude, + longitude: coordinates.longitude) + } + + func image(forSize size: Int) -> Image { + ImageStore.shared.image(name: imageName, size: size) + } + + enum Category: String, CaseIterable, Codable, Hashable { + case featured = "Featured" + case lakes = "Lakes" + case rivers = "Rivers" + case mountains = "Mountains" + } +} + +struct Coordinates: Hashable, Codable { + var latitude: Double + var longitude: Double +} diff --git a/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/Models/UserData.swift b/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/Models/UserData.swift new file mode 100644 index 0000000..db31fb0 --- /dev/null +++ b/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/Models/UserData.swift @@ -0,0 +1,25 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A model object that stores app data. +*/ + +import Combine +import SwiftUI + +final class UserData: BindableObject { + let didChange = PassthroughSubject() + + var showFavoritesOnly = false { + didSet { + didChange.send(self) + } + } + + var landmarks = landmarkData { + didSet { + didChange.send(self) + } + } +} diff --git a/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/Preview Content/Preview Assets.xcassets/Contents.json b/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/Preview Content/Preview Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/Preview Content/Preview Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/Resources/charleyrivers.jpg b/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/Resources/charleyrivers.jpg new file mode 100644 index 0000000..17ff44b Binary files /dev/null and b/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/Resources/charleyrivers.jpg differ diff --git a/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/Resources/chilkoottrail.jpg b/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/Resources/chilkoottrail.jpg new file mode 100644 index 0000000..e7f805e Binary files /dev/null and b/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/Resources/chilkoottrail.jpg differ diff --git a/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/Resources/chincoteague.jpg b/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/Resources/chincoteague.jpg new file mode 100644 index 0000000..5f47986 Binary files /dev/null and b/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/Resources/chincoteague.jpg differ diff --git a/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/Resources/hiddenlake.jpg b/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/Resources/hiddenlake.jpg new file mode 100644 index 0000000..d8e804c Binary files /dev/null and b/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/Resources/hiddenlake.jpg differ diff --git a/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/Resources/icybay.jpg b/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/Resources/icybay.jpg new file mode 100644 index 0000000..feb1764 Binary files /dev/null and b/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/Resources/icybay.jpg differ diff --git a/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/Resources/lakemcdonald.jpg b/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/Resources/lakemcdonald.jpg new file mode 100644 index 0000000..bd9d6b9 Binary files /dev/null and b/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/Resources/lakemcdonald.jpg differ diff --git a/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/Resources/landmarkData.json b/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/Resources/landmarkData.json new file mode 100644 index 0000000..e5b14fc --- /dev/null +++ b/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/Resources/landmarkData.json @@ -0,0 +1,182 @@ +[ + { + "name": "Turtle Rock", + "category": "Rivers", + "city": "Twentynine Palms", + "state": "California", + "id": 1001, + "isFeatured": true, + "isFavorite": true, + "park": "Joshua Tree National Park", + "coordinates": { + "longitude": -116.166868, + "latitude": 34.011286 + }, + "imageName": "turtlerock" + }, + { + "name": "Silver Salmon Creek", + "category": "Lakes", + "city": "Port Alsworth", + "state": "Alaska", + "id": 1002, + "isFeatured": false, + "isFavorite": false, + "park": "Lake Clark National Park and Preserve", + "coordinates": { + "longitude": -152.665167, + "latitude": 59.980167 + }, + "imageName": "silversalmoncreek" + }, + { + "name": "Chilkoot Trail", + "category": "Mountains", + "city": "Skagway", + "state": "Alaska", + "id": 1003, + "isFeatured": false, + "isFavorite": true, + "park": "Klondike Gold Rush National Historical Park", + "coordinates": { + "longitude": -135.334571, + "latitude": 59.560551 + }, + "imageName": "chilkoottrail" + }, + { + "name": "St. Mary Lake", + "category": "Lakes", + "city": "Browning", + "state": "Montana", + "id": 1004, + "isFeatured": true, + "isFavorite": true, + "park": "Glacier National Park", + "coordinates": { + "longitude": -113.536248, + "latitude": 48.69423 + }, + "imageName": "stmarylake" + }, + { + "name": "Twin Lake", + "category": "Lakes", + "city": "Twin Lakes", + "state": "Alaska", + "id": 1005, + "isFeatured": false, + "isFavorite": false, + "park": "Lake Clark National Park and Preserve", + "coordinates": { + "longitude": -153.849883, + "latitude": 60.641684 + }, + "imageName": "twinlake" + }, + { + "name": "Lake McDonald", + "category": "Mountains", + "city": "West Glacier", + "state": "Montana", + "id": 1006, + "isFeatured": false, + "isFavorite": false, + "park": "Glacier National Park", + "coordinates": { + "longitude": -113.934831, + "latitude": 48.56002 + }, + "imageName": "lakemcdonald" + }, + { + "name": "Charley Rivers", + "category": "Rivers", + "city": "Eaking", + "state": "Alaska", + "id": 1007, + "isFeatured": true, + "isFavorite": false, + "park": "Charley Rivers National Preserve", + "coordinates": { + "longitude": -143.122586, + "latitude": 65.350021 + }, + "imageName": "charleyrivers", + }, + { + "name": "Icy Bay", + "category": "Mountains", + "city": "Icy Bay", + "state": "Alaska", + "id": 1008, + "isFeatured": false, + "isFavorite": false, + "park": "Wrangell-St. Elias National Park and Preserve", + "coordinates": { + "longitude": -141.518167, + "latitude": 60.089917 + }, + "imageName": "icybay" + }, + { + "name": "Rainbow Lake", + "category": "Lakes", + "city": "Willow", + "state": "Alaska", + "id": 1009, + "isFeatured": false, + "isFavorite": false, + "park": "State Recreation Area", + "coordinates": { + "longitude": -150.086103, + "latitude": 61.694334 + }, + "imageName": "rainbowlake" + }, + { + "name": "Hidden Lake", + "category": "Lakes", + "city": "Newhalem", + "state": "Washington", + "id": 1010, + "isFeatured": false, + "isFavorite": false, + "park": "North Cascades National Park", + "coordinates": { + "longitude": -121.17799, + "latitude": 48.495442 + }, + "imageName": "hiddenlake" + }, + { + "name": "Chincoteague", + "category": "Rivers", + "city": "Chincoteague", + "state": "Virginia", + "id": 1011, + "isFeatured": false, + "isFavorite": false, + "park": "Chincoteague National Wildlife Refuge", + "coordinates": { + "longitude": -75.383212, + "latitude": 37.91531 + }, + "imageName": "chincoteague" + }, + { + "name": "Lake Umbagog", + "category": "Lakes", + "city": "Errol", + "state": "New Hampshire", + "id": 1012, + "isFeatured": true, + "isFavorite": false, + "park": "Umbagog National Wildlife Refuge", + "coordinates": { + "longitude": -71.056816, + "latitude": 44.747408 + }, + "imageName": "umbagog" + } +] diff --git a/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/Resources/rainbowlake.jpg b/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/Resources/rainbowlake.jpg new file mode 100644 index 0000000..6da43dd Binary files /dev/null and b/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/Resources/rainbowlake.jpg differ diff --git a/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/Resources/silversalmoncreek.jpg b/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/Resources/silversalmoncreek.jpg new file mode 100644 index 0000000..f657532 Binary files /dev/null and b/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/Resources/silversalmoncreek.jpg differ diff --git a/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/Resources/stmarylake.jpg b/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/Resources/stmarylake.jpg new file mode 100644 index 0000000..1c71de4 Binary files /dev/null and b/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/Resources/stmarylake.jpg differ diff --git a/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/Resources/turtlerock.jpg b/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/Resources/turtlerock.jpg new file mode 100644 index 0000000..f7a6e6d Binary files /dev/null and b/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/Resources/turtlerock.jpg differ diff --git a/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/Resources/twinlake.jpg b/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/Resources/twinlake.jpg new file mode 100644 index 0000000..3e7a57c Binary files /dev/null and b/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/Resources/twinlake.jpg differ diff --git a/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/Resources/umbagog.jpg b/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/Resources/umbagog.jpg new file mode 100644 index 0000000..56291c6 Binary files /dev/null and b/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/Resources/umbagog.jpg differ diff --git a/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/SceneDelegate.swift b/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/SceneDelegate.swift new file mode 100644 index 0000000..96df0dc --- /dev/null +++ b/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/SceneDelegate.swift @@ -0,0 +1,56 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +The scene delegate. +*/ + +import UIKit +import SwiftUI + +class SceneDelegate: UIResponder, UIWindowSceneDelegate { + + var window: UIWindow? + + func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { + // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`. + // If using a storyboard, the `window` property will automatically be initialized and attached to the scene. + // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead). + + // Use a UIHostingController as window root view controller + let window = UIWindow(frame: UIScreen.main.bounds) + window.rootViewController = UIHostingController(rootView: LandmarkList().environmentObject(UserData())) + self.window = window + window.makeKeyAndVisible() + } + + func sceneDidDisconnect(_ scene: UIScene) { + // Called as the scene is being released by the system. + // This occurs shortly after the scene enters the background, or when its session is discarded. + // Release any resources associated with this scene that can be re-created the next time the scene connects. + // The scene may re-connect later, as its session was not neccessarily discarded (see `application:didDiscardSceneSessions` instead). + } + + func sceneDidBecomeActive(_ scene: UIScene) { + // Called when the scene has moved from an inactive state to an active state. + // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive. + } + + func sceneWillResignActive(_ scene: UIScene) { + // Called when the scene will move from an active state to an inactive state. + // This may occur due to temporary interruptions (ex. an incoming phone call). + } + + func sceneWillEnterForeground(_ scene: UIScene) { + // Called as the scene transitions from the background to the foreground. + // Use this method to undo the changes made on entering the background. + } + + func sceneDidEnterBackground(_ scene: UIScene) { + // Called as the scene transitions from the foreground to the background. + // Use this method to save data, release shared resources, and store enough scene-specific state information + // to restore the scene back to its current state. + } + +} + diff --git a/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/Supporting Views/CircleImage.swift b/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/Supporting Views/CircleImage.swift new file mode 100644 index 0000000..ae44439 --- /dev/null +++ b/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/Supporting Views/CircleImage.swift @@ -0,0 +1,27 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A view that clips an image to a circle and adds a stroke and shadow. +*/ + +import SwiftUI + +struct CircleImage: View { + var image: Image + + var body: some View { + image + .clipShape(Circle()) + .overlay(Circle().stroke(Color.white, lineWidth: 4)) + .shadow(radius: 10) + } +} + +#if DEBUG +struct CircleImage_Previews: PreviewProvider { + static var previews: some View { + CircleImage(image: Image("turtlerock")) + } +} +#endif diff --git a/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/Supporting Views/LandmarkRow.swift b/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/Supporting Views/LandmarkRow.swift new file mode 100644 index 0000000..2f8110c --- /dev/null +++ b/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/Supporting Views/LandmarkRow.swift @@ -0,0 +1,38 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A single row to be displayed in a list of landmarks. +*/ + +import SwiftUI + +struct LandmarkRow: View { + var landmark: Landmark + + var body: some View { + HStack { + landmark.image(forSize: 50) + Text(verbatim: landmark.name) + Spacer() + + if landmark.isFavorite { + Image(systemName: "star.fill") + .imageScale(.medium) + .foregroundColor(.yellow) + } + } + } +} + +#if DEBUG +struct LandmarkRow_Previews: PreviewProvider { + static var previews: some View { + Group { + LandmarkRow(landmark: landmarkData[0]) + LandmarkRow(landmark: landmarkData[1]) + } + .previewLayout(.fixed(width: 300, height: 70)) + } +} +#endif diff --git a/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/Supporting Views/MapView.swift b/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/Supporting Views/MapView.swift new file mode 100644 index 0000000..5a8c64b --- /dev/null +++ b/Other Projects/Drawing Paths And Shapes/StartingPoint/Landmarks/Landmarks/Supporting Views/MapView.swift @@ -0,0 +1,31 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A view that hosts an `MKMapView`. +*/ + +import SwiftUI +import MapKit + +struct MapView: UIViewRepresentable { + var coordinate: CLLocationCoordinate2D + + func makeUIView(context: Context) -> MKMapView { + MKMapView(frame: .zero) + } + + func updateUIView(_ view: MKMapView, context: Context) { + let span = MKCoordinateSpan(latitudeDelta: 0.02, longitudeDelta: 0.02) + let region = MKCoordinateRegion(center: coordinate, span: span) + view.setRegion(region, animated: true) + } +} + +#if DEBUG +struct MapView_Previews: PreviewProvider { + static var previews: some View { + MapView(coordinate: landmarkData[0].locationCoordinate) + } +} +#endif diff --git a/Other Projects/Drawing Paths And Shapes/StartingPoint/README.md b/Other Projects/Drawing Paths And Shapes/StartingPoint/README.md new file mode 100644 index 0000000..7e3b548 --- /dev/null +++ b/Other Projects/Drawing Paths And Shapes/StartingPoint/README.md @@ -0,0 +1,3 @@ +# Drawing Paths and Shapes + +Use this project to code along with the [Drawing Paths and Shapes](https://developer.apple.com/tutorials/swiftui/drawing-paths-and-shapes) tutorial. \ No newline at end of file diff --git a/Other Projects/Example To-Do App/SwiftUITodo.xcodeproj/project.pbxproj b/Other Projects/Example To-Do App/SwiftUITodo.xcodeproj/project.pbxproj new file mode 100644 index 0000000..0682e06 --- /dev/null +++ b/Other Projects/Example To-Do App/SwiftUITodo.xcodeproj/project.pbxproj @@ -0,0 +1,367 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 50; + objects = { + +/* Begin PBXBuildFile section */ + 031596AE22A5BDBA001BBA1B /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 031596AD22A5BDBA001BBA1B /* AppDelegate.swift */; }; + 031596B022A5BDBA001BBA1B /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 031596AF22A5BDBA001BBA1B /* SceneDelegate.swift */; }; + 031596B222A5BDBA001BBA1B /* TaskListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 031596B122A5BDBA001BBA1B /* TaskListView.swift */; }; + 031596B422A5BDBB001BBA1B /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 031596B322A5BDBB001BBA1B /* Assets.xcassets */; }; + 031596B722A5BDBB001BBA1B /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 031596B622A5BDBB001BBA1B /* Preview Assets.xcassets */; }; + 031596BA22A5BDBB001BBA1B /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 031596B822A5BDBB001BBA1B /* LaunchScreen.storyboard */; }; + 031596C222A5BDE8001BBA1B /* Task.swift in Sources */ = {isa = PBXBuildFile; fileRef = 031596C122A5BDE8001BBA1B /* Task.swift */; }; + 031596C822A5C661001BBA1B /* UserData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 031596C722A5C661001BBA1B /* UserData.swift */; }; + 031596CA22A5DDE0001BBA1B /* TaskEditView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 031596C922A5DDE0001BBA1B /* TaskEditView.swift */; }; + 031596CC22A5F360001BBA1B /* TaskItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 031596CB22A5F360001BBA1B /* TaskItemView.swift */; }; + C8E0A25922A789D100E940E8 /* UserDefaultsValue.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8E0A25822A789D100E940E8 /* UserDefaultsValue.swift */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 031596AA22A5BDBA001BBA1B /* SwiftUITodo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SwiftUITodo.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 031596AD22A5BDBA001BBA1B /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 031596AF22A5BDBA001BBA1B /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; + 031596B122A5BDBA001BBA1B /* TaskListView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TaskListView.swift; sourceTree = ""; }; + 031596B322A5BDBB001BBA1B /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 031596B622A5BDBB001BBA1B /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; + 031596B922A5BDBB001BBA1B /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 031596BB22A5BDBB001BBA1B /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 031596C122A5BDE8001BBA1B /* Task.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Task.swift; sourceTree = ""; }; + 031596C722A5C661001BBA1B /* UserData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserData.swift; sourceTree = ""; }; + 031596C922A5DDE0001BBA1B /* TaskEditView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TaskEditView.swift; sourceTree = ""; }; + 031596CB22A5F360001BBA1B /* TaskItemView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TaskItemView.swift; sourceTree = ""; }; + C8E0A25822A789D100E940E8 /* UserDefaultsValue.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserDefaultsValue.swift; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 031596A722A5BDBA001BBA1B /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 031596A122A5BDBA001BBA1B = { + isa = PBXGroup; + children = ( + 031596AC22A5BDBA001BBA1B /* SwiftUITodo */, + 031596AB22A5BDBA001BBA1B /* Products */, + ); + sourceTree = ""; + }; + 031596AB22A5BDBA001BBA1B /* Products */ = { + isa = PBXGroup; + children = ( + 031596AA22A5BDBA001BBA1B /* SwiftUITodo.app */, + ); + name = Products; + sourceTree = ""; + }; + 031596AC22A5BDBA001BBA1B /* SwiftUITodo */ = { + isa = PBXGroup; + children = ( + 031596AD22A5BDBA001BBA1B /* AppDelegate.swift */, + 031596AF22A5BDBA001BBA1B /* SceneDelegate.swift */, + 031596C722A5C661001BBA1B /* UserData.swift */, + 031596C122A5BDE8001BBA1B /* Task.swift */, + 031596B122A5BDBA001BBA1B /* TaskListView.swift */, + 031596CB22A5F360001BBA1B /* TaskItemView.swift */, + 031596C922A5DDE0001BBA1B /* TaskEditView.swift */, + C8E0A25822A789D100E940E8 /* UserDefaultsValue.swift */, + 031596B322A5BDBB001BBA1B /* Assets.xcassets */, + 031596B822A5BDBB001BBA1B /* LaunchScreen.storyboard */, + 031596BB22A5BDBB001BBA1B /* Info.plist */, + 031596B522A5BDBB001BBA1B /* Preview Content */, + ); + path = SwiftUITodo; + sourceTree = ""; + }; + 031596B522A5BDBB001BBA1B /* Preview Content */ = { + isa = PBXGroup; + children = ( + 031596B622A5BDBB001BBA1B /* Preview Assets.xcassets */, + ); + path = "Preview Content"; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 031596A922A5BDBA001BBA1B /* SwiftUITodo */ = { + isa = PBXNativeTarget; + buildConfigurationList = 031596BE22A5BDBB001BBA1B /* Build configuration list for PBXNativeTarget "SwiftUITodo" */; + buildPhases = ( + 031596A622A5BDBA001BBA1B /* Sources */, + 031596A722A5BDBA001BBA1B /* Frameworks */, + 031596A822A5BDBA001BBA1B /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = SwiftUITodo; + productName = SwiftUITodo; + productReference = 031596AA22A5BDBA001BBA1B /* SwiftUITodo.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 031596A222A5BDBA001BBA1B /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 1100; + LastUpgradeCheck = 1100; + ORGANIZATIONNAME = "Suyeol Jeon"; + TargetAttributes = { + 031596A922A5BDBA001BBA1B = { + CreatedOnToolsVersion = 11.0; + }; + }; + }; + buildConfigurationList = 031596A522A5BDBA001BBA1B /* Build configuration list for PBXProject "SwiftUITodo" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 031596A122A5BDBA001BBA1B; + productRefGroup = 031596AB22A5BDBA001BBA1B /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 031596A922A5BDBA001BBA1B /* SwiftUITodo */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 031596A822A5BDBA001BBA1B /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 031596BA22A5BDBB001BBA1B /* LaunchScreen.storyboard in Resources */, + 031596B722A5BDBB001BBA1B /* Preview Assets.xcassets in Resources */, + 031596B422A5BDBB001BBA1B /* Assets.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 031596A622A5BDBA001BBA1B /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 031596C222A5BDE8001BBA1B /* Task.swift in Sources */, + 031596AE22A5BDBA001BBA1B /* AppDelegate.swift in Sources */, + 031596C822A5C661001BBA1B /* UserData.swift in Sources */, + 031596CC22A5F360001BBA1B /* TaskItemView.swift in Sources */, + 031596CA22A5DDE0001BBA1B /* TaskEditView.swift in Sources */, + 031596B022A5BDBA001BBA1B /* SceneDelegate.swift in Sources */, + C8E0A25922A789D100E940E8 /* UserDefaultsValue.swift in Sources */, + 031596B222A5BDBA001BBA1B /* TaskListView.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 031596B822A5BDBB001BBA1B /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 031596B922A5BDBB001BBA1B /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 031596BC22A5BDBB001BBA1B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + 031596BD22A5BDBB001BBA1B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 031596BF22A5BDBB001BBA1B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_ASSET_PATHS = "SwiftUITodo/Preview\\ Content"; + DEVELOPMENT_TEAM = N2C267LBVY; + ENABLE_PREVIEWS = YES; + INFOPLIST_FILE = SwiftUITodo/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = kr.xoul.SwiftUITodo; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 031596C022A5BDBB001BBA1B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_ASSET_PATHS = "SwiftUITodo/Preview\\ Content"; + DEVELOPMENT_TEAM = N2C267LBVY; + ENABLE_PREVIEWS = YES; + INFOPLIST_FILE = SwiftUITodo/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = kr.xoul.SwiftUITodo; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 031596A522A5BDBA001BBA1B /* Build configuration list for PBXProject "SwiftUITodo" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 031596BC22A5BDBB001BBA1B /* Debug */, + 031596BD22A5BDBB001BBA1B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 031596BE22A5BDBB001BBA1B /* Build configuration list for PBXNativeTarget "SwiftUITodo" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 031596BF22A5BDBB001BBA1B /* Debug */, + 031596C022A5BDBB001BBA1B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 031596A222A5BDBA001BBA1B /* Project object */; +} diff --git a/Other Projects/Example To-Do App/SwiftUITodo.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/Other Projects/Example To-Do App/SwiftUITodo.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..f60d885 --- /dev/null +++ b/Other Projects/Example To-Do App/SwiftUITodo.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/Other Projects/Example To-Do App/SwiftUITodo.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/Other Projects/Example To-Do App/SwiftUITodo.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/Other Projects/Example To-Do App/SwiftUITodo.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/Other Projects/Example To-Do App/SwiftUITodo/AppDelegate.swift b/Other Projects/Example To-Do App/SwiftUITodo/AppDelegate.swift new file mode 100644 index 0000000..915ca17 --- /dev/null +++ b/Other Projects/Example To-Do App/SwiftUITodo/AppDelegate.swift @@ -0,0 +1,41 @@ +// +// AppDelegate.swift +// SwiftUITodo +// +// Created by Suyeol Jeon on 03/06/2019. +// Copyright © 2019 Suyeol Jeon. All rights reserved. +// + +import UIKit + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + + + + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { + // Override point for customization after application launch. + return true + } + + func applicationWillTerminate(_ application: UIApplication) { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. + } + + // MARK: UISceneSession Lifecycle + + func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration { + // Called when a new scene session is being created. + // Use this method to select a configuration to create the new scene with. + return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role) + } + + func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) { + // Called when the user discards a scene session. + // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions. + // Use this method to release any resources that were specific to the discarded scenes, as they will not return. + } + + +} + diff --git a/Other Projects/Example To-Do App/SwiftUITodo/Assets.xcassets/AppIcon.appiconset/Contents.json b/Other Projects/Example To-Do App/SwiftUITodo/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..d8db8d6 --- /dev/null +++ b/Other Projects/Example To-Do App/SwiftUITodo/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,98 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "83.5x83.5", + "scale" : "2x" + }, + { + "idiom" : "ios-marketing", + "size" : "1024x1024", + "scale" : "1x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/Example To-Do App/SwiftUITodo/Assets.xcassets/Contents.json b/Other Projects/Example To-Do App/SwiftUITodo/Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/Other Projects/Example To-Do App/SwiftUITodo/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/Example To-Do App/SwiftUITodo/Base.lproj/LaunchScreen.storyboard b/Other Projects/Example To-Do App/SwiftUITodo/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000..865e932 --- /dev/null +++ b/Other Projects/Example To-Do App/SwiftUITodo/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Other Projects/Example To-Do App/SwiftUITodo/Info.plist b/Other Projects/Example To-Do App/SwiftUITodo/Info.plist new file mode 100644 index 0000000..e8bb4c6 --- /dev/null +++ b/Other Projects/Example To-Do App/SwiftUITodo/Info.plist @@ -0,0 +1,62 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + $(PRODUCT_BUNDLE_PACKAGE_TYPE) + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UIApplicationSceneManifest + + UIApplicationSupportsMultipleScenes + + UISceneConfigurations + + UIWindowSceneSessionRoleApplication + + + UILaunchStoryboardName + LaunchScreen + UISceneConfigurationName + Default Configuration + UISceneDelegateClassName + $(PRODUCT_MODULE_NAME).SceneDelegate + + + + + UILaunchStoryboardName + LaunchScreen + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/Other Projects/Example To-Do App/SwiftUITodo/Preview Content/Preview Assets.xcassets/Contents.json b/Other Projects/Example To-Do App/SwiftUITodo/Preview Content/Preview Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/Other Projects/Example To-Do App/SwiftUITodo/Preview Content/Preview Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/Example To-Do App/SwiftUITodo/SceneDelegate.swift b/Other Projects/Example To-Do App/SwiftUITodo/SceneDelegate.swift new file mode 100644 index 0000000..a5a403a --- /dev/null +++ b/Other Projects/Example To-Do App/SwiftUITodo/SceneDelegate.swift @@ -0,0 +1,61 @@ +// +// SceneDelegate.swift +// SwiftUITodo +// +// Created by Suyeol Jeon on 03/06/2019. +// Copyright © 2019 Suyeol Jeon. All rights reserved. +// + +import UIKit +import SwiftUI + +class SceneDelegate: UIResponder, UIWindowSceneDelegate { + + var window: UIWindow? + + + func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { + // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`. + // If using a storyboard, the `window` property will automatically be initialized and attached to the scene. + // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead). + + // Use a UIHostingController as window root view controller + if let windowScene = scene as? UIWindowScene { + let window = UIWindow(windowScene: windowScene) + window.rootViewController = UIHostingController(rootView: TaskListView().environmentObject(UserData())) + self.window = window + window.makeKeyAndVisible() + } + } + + func sceneDidDisconnect(_ scene: UIScene) { + // Called as the scene is being released by the system. + // This occurs shortly after the scene enters the background, or when its session is discarded. + // Release any resources associated with this scene that can be re-created the next time the scene connects. + // The scene may re-connect later, as its session was not neccessarily discarded (see `application:didDiscardSceneSessions` instead). + } + + func sceneDidBecomeActive(_ scene: UIScene) { + // Called when the scene has moved from an inactive state to an active state. + // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive. + } + + func sceneWillResignActive(_ scene: UIScene) { + // Called when the scene will move from an active state to an inactive state. + // This may occur due to temporary interruptions (ex. an incoming phone call). + } + + func sceneWillEnterForeground(_ scene: UIScene) { + // Called as the scene transitions from the background to the foreground. + // Use this method to undo the changes made on entering the background. + } + + func sceneDidEnterBackground(_ scene: UIScene) { + // Called as the scene transitions from the foreground to the background. + // Use this method to save data, release shared resources, and store enough scene-specific state information + // to restore the scene back to its current state. + } + + +} + diff --git a/Other Projects/Example To-Do App/SwiftUITodo/Task.swift b/Other Projects/Example To-Do App/SwiftUITodo/Task.swift new file mode 100644 index 0000000..9f83bb0 --- /dev/null +++ b/Other Projects/Example To-Do App/SwiftUITodo/Task.swift @@ -0,0 +1,21 @@ +// +// Task.swift +// SwiftUITodo +// +// Created by Suyeol Jeon on 03/06/2019. +// Copyright © 2019 Suyeol Jeon. All rights reserved. +// + +import SwiftUI + +struct Task: Equatable, Hashable, Codable, Identifiable { + let id: UUID + var title: String + var isDone: Bool + + init(title: String, isDone: Bool) { + self.id = UUID() + self.title = title + self.isDone = isDone + } +} diff --git a/Other Projects/Example To-Do App/SwiftUITodo/TaskEditView.swift b/Other Projects/Example To-Do App/SwiftUITodo/TaskEditView.swift new file mode 100644 index 0000000..e074c47 --- /dev/null +++ b/Other Projects/Example To-Do App/SwiftUITodo/TaskEditView.swift @@ -0,0 +1,51 @@ +// +// TaskEditView.swift +// SwiftUITodo +// +// Created by Suyeol Jeon on 03/06/2019. +// Copyright © 2019 Suyeol Jeon. All rights reserved. +// + +import SwiftUI + +struct TaskEditView: View { + @EnvironmentObject var userData: UserData + private let task: Task + private var draftTitle: State + + init(task: Task) { + self.task = task + self.draftTitle = .init(initialValue: task.title) + } + + var body: some View { + let inset = EdgeInsets(top: -8, leading: -10, bottom: -7, trailing: -10) + return VStack(alignment: .leading, spacing: 0) { + TextField( + "Enter New Title...", text: self.draftTitle.projectedValue, + onEditingChanged: { _ in self.updateTask() }, + onCommit: {} + ) + .background( + RoundedRectangle(cornerRadius: 5) + .fill(Color.clear) + .background(RoundedRectangle(cornerRadius: 5).strokeBorder(Color(red: 0.7, green: 0.7, blue: 0.7), lineWidth: 1 / UIScreen.main.scale)) + .padding(inset) + ) + .padding(EdgeInsets( + top: 15 - inset.top, + leading: 20 - inset.leading, + bottom: 15 - inset.bottom, + trailing: 20 - inset.trailing + )) + + Spacer() + } + .navigationBarTitle(Text("Edit Task 📝")) + } + + private func updateTask() { + guard let index = self.userData.tasks.firstIndex(of: self.task) else { return } + self.userData.tasks[index].title = self.draftTitle.wrappedValue + } +} diff --git a/Other Projects/Example To-Do App/SwiftUITodo/TaskItemView.swift b/Other Projects/Example To-Do App/SwiftUITodo/TaskItemView.swift new file mode 100644 index 0000000..c3e4cf6 --- /dev/null +++ b/Other Projects/Example To-Do App/SwiftUITodo/TaskItemView.swift @@ -0,0 +1,52 @@ +// +// TaskItemView.swift +// SwiftUITodo +// +// Created by Suyeol Jeon on 03/06/2019. +// Copyright © 2019 Suyeol Jeon. All rights reserved. +// + +import SwiftUI + +struct TaskItemView: View { + @EnvironmentObject var userData: UserData + + let task: Task + @Binding var isEditing: Bool + + var body: some View { + return HStack { + if self.isEditing { + Image(systemName: "minus.circle") + .foregroundColor(.red) + .onTapGesture(count: 1) { + self.delete() + } + NavigationLink(destination: TaskEditView(task: task).environmentObject(self.userData)) { + Text(task.title) + } + } else { + Button(action: { self.toggleDone() }) { + Text(self.task.title) + } + Spacer() + if task.isDone { + Image(systemName: "checkmark").foregroundColor(.green) + } + } + } + } + + private func toggleDone() { + guard !self.isEditing else { return } + guard let index = self.userData.tasks.firstIndex(where: { $0.id == self.task.id }) else { return } + self.userData.tasks[index].isDone.toggle() + } + + private func delete() { + self.userData.tasks.removeAll(where: { $0.id == self.task.id }) + if self.userData.tasks.isEmpty { + self.isEditing = false + } + } +} diff --git a/Other Projects/Example To-Do App/SwiftUITodo/TaskListView.swift b/Other Projects/Example To-Do App/SwiftUITodo/TaskListView.swift new file mode 100644 index 0000000..1fe1013 --- /dev/null +++ b/Other Projects/Example To-Do App/SwiftUITodo/TaskListView.swift @@ -0,0 +1,40 @@ +// +// TaskListView.swift +// SwiftUITodo +// +// Created by Suyeol Jeon on 03/06/2019. +// Copyright © 2019 Suyeol Jeon. All rights reserved. +// + +import SwiftUI + +struct TaskListView: View { + @EnvironmentObject var userData: UserData + @State var draftTitle: String = "" + @State var isEditing: Bool = false + + var body: some View { + NavigationView { + List { + TextField("Create a New Task...", text: $draftTitle, onCommit: self.createTask) + ForEach(self.userData.tasks) { task in + TaskItemView(task: task, isEditing: self.$isEditing) + } + } + .navigationBarTitle(Text("Tasks 👀")) + .navigationBarItems(trailing: Button(action: { self.isEditing.toggle() }) { + if !self.isEditing { + Text("Edit") + } else { + Text("Done").bold() + } + }) + } + } + + private func createTask() { + let newTask = Task(title: self.draftTitle, isDone: false) + self.userData.tasks.insert(newTask, at: 0) + self.draftTitle = "" + } +} diff --git a/Other Projects/Example To-Do App/SwiftUITodo/UserData.swift b/Other Projects/Example To-Do App/SwiftUITodo/UserData.swift new file mode 100644 index 0000000..270f2c6 --- /dev/null +++ b/Other Projects/Example To-Do App/SwiftUITodo/UserData.swift @@ -0,0 +1,26 @@ +// +// UserData.swift +// SwiftUITodo +// +// Created by Suyeol Jeon on 03/06/2019. +// Copyright © 2019 Suyeol Jeon. All rights reserved. +// + +import Combine +import SwiftUI + +private let defaultTasks: [Task] = [ + Task(title: "Read SwiftUI Documentation 📚", isDone: false), + Task(title: "Watch WWDC19 Keynote 🎉", isDone: true), +] + +final class UserData: ObservableObject { + let objectWillChange = PassthroughSubject() + + @UserDefaultValue(key: "Tasks", defaultValue: defaultTasks) + var tasks: [Task] { + didSet { + objectWillChange.send(self) + } + } +} diff --git a/Other Projects/Example To-Do App/SwiftUITodo/UserDefaultsValue.swift b/Other Projects/Example To-Do App/SwiftUITodo/UserDefaultsValue.swift new file mode 100644 index 0000000..94e29c8 --- /dev/null +++ b/Other Projects/Example To-Do App/SwiftUITodo/UserDefaultsValue.swift @@ -0,0 +1,28 @@ +// +// UserDefaultsValue.swift +// SwiftUITodo +// +// Created by kemchenj on 2019/6/5. +// Copyright © 2019 Suyeol Jeon. All rights reserved. +// + +import Foundation + +@propertyWrapper +struct UserDefaultValue { + + let key: String + let defaultValue: Value + + var wrappedValue: Value { + get { + let data = UserDefaults.standard.data(forKey: key) + let value = data.flatMap { try? JSONDecoder().decode(Value.self, from: $0) } + return value ?? defaultValue + } + set { + let data = try? JSONEncoder().encode(newValue) + UserDefaults.standard.set(data, forKey: key) + } + } +} diff --git a/Other Projects/Flux/SwiftUI-Flux.xcodeproj/project.pbxproj b/Other Projects/Flux/SwiftUI-Flux.xcodeproj/project.pbxproj new file mode 100644 index 0000000..3c3b710 --- /dev/null +++ b/Other Projects/Flux/SwiftUI-Flux.xcodeproj/project.pbxproj @@ -0,0 +1,349 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 50; + objects = { + +/* Begin PBXBuildFile section */ + 6B90B43122A92BBE0017BE2B /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6B90B43022A92BBE0017BE2B /* AppDelegate.swift */; }; + 6B90B43322A92BBE0017BE2B /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6B90B43222A92BBE0017BE2B /* SceneDelegate.swift */; }; + 6B90B43722A92BBF0017BE2B /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6B90B43622A92BBF0017BE2B /* Assets.xcassets */; }; + 6B90B43A22A92BBF0017BE2B /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6B90B43922A92BBF0017BE2B /* Preview Assets.xcassets */; }; + 6B90B43D22A92BBF0017BE2B /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 6B90B43B22A92BBF0017BE2B /* LaunchScreen.storyboard */; }; + 6B90B44622A92C3B0017BE2B /* Store.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6B90B44422A92C3B0017BE2B /* Store.swift */; }; + 6B90B44722A92C3B0017BE2B /* CounterView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6B90B44522A92C3B0017BE2B /* CounterView.swift */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 6B90B42D22A92BBE0017BE2B /* SwiftUI-Flux.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "SwiftUI-Flux.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + 6B90B43022A92BBE0017BE2B /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 6B90B43222A92BBE0017BE2B /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; + 6B90B43622A92BBF0017BE2B /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 6B90B43922A92BBF0017BE2B /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; + 6B90B43C22A92BBF0017BE2B /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 6B90B43E22A92BBF0017BE2B /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 6B90B44422A92C3B0017BE2B /* Store.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Store.swift; sourceTree = ""; }; + 6B90B44522A92C3B0017BE2B /* CounterView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CounterView.swift; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 6B90B42A22A92BBE0017BE2B /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 6B90B42422A92BBE0017BE2B = { + isa = PBXGroup; + children = ( + 6B90B42F22A92BBE0017BE2B /* SwiftUI-Flux */, + 6B90B42E22A92BBE0017BE2B /* Products */, + ); + sourceTree = ""; + }; + 6B90B42E22A92BBE0017BE2B /* Products */ = { + isa = PBXGroup; + children = ( + 6B90B42D22A92BBE0017BE2B /* SwiftUI-Flux.app */, + ); + name = Products; + sourceTree = ""; + }; + 6B90B42F22A92BBE0017BE2B /* SwiftUI-Flux */ = { + isa = PBXGroup; + children = ( + 6B90B44422A92C3B0017BE2B /* Store.swift */, + 6B90B44522A92C3B0017BE2B /* CounterView.swift */, + 6B90B43022A92BBE0017BE2B /* AppDelegate.swift */, + 6B90B43222A92BBE0017BE2B /* SceneDelegate.swift */, + 6B90B43622A92BBF0017BE2B /* Assets.xcassets */, + 6B90B43B22A92BBF0017BE2B /* LaunchScreen.storyboard */, + 6B90B43E22A92BBF0017BE2B /* Info.plist */, + 6B90B43822A92BBF0017BE2B /* Preview Content */, + ); + path = "SwiftUI-Flux"; + sourceTree = ""; + }; + 6B90B43822A92BBF0017BE2B /* Preview Content */ = { + isa = PBXGroup; + children = ( + 6B90B43922A92BBF0017BE2B /* Preview Assets.xcassets */, + ); + path = "Preview Content"; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 6B90B42C22A92BBE0017BE2B /* SwiftUI-Flux */ = { + isa = PBXNativeTarget; + buildConfigurationList = 6B90B44122A92BBF0017BE2B /* Build configuration list for PBXNativeTarget "SwiftUI-Flux" */; + buildPhases = ( + 6B90B42922A92BBE0017BE2B /* Sources */, + 6B90B42A22A92BBE0017BE2B /* Frameworks */, + 6B90B42B22A92BBE0017BE2B /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "SwiftUI-Flux"; + productName = "SwiftUI-Flux"; + productReference = 6B90B42D22A92BBE0017BE2B /* SwiftUI-Flux.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 6B90B42522A92BBE0017BE2B /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 1100; + LastUpgradeCheck = 1100; + ORGANIZATIONNAME = "Ryo Aoyama"; + TargetAttributes = { + 6B90B42C22A92BBE0017BE2B = { + CreatedOnToolsVersion = 11.0; + }; + }; + }; + buildConfigurationList = 6B90B42822A92BBE0017BE2B /* Build configuration list for PBXProject "SwiftUI-Flux" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 6B90B42422A92BBE0017BE2B; + productRefGroup = 6B90B42E22A92BBE0017BE2B /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 6B90B42C22A92BBE0017BE2B /* SwiftUI-Flux */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 6B90B42B22A92BBE0017BE2B /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 6B90B43D22A92BBF0017BE2B /* LaunchScreen.storyboard in Resources */, + 6B90B43A22A92BBF0017BE2B /* Preview Assets.xcassets in Resources */, + 6B90B43722A92BBF0017BE2B /* Assets.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 6B90B42922A92BBE0017BE2B /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 6B90B43122A92BBE0017BE2B /* AppDelegate.swift in Sources */, + 6B90B43322A92BBE0017BE2B /* SceneDelegate.swift in Sources */, + 6B90B44622A92C3B0017BE2B /* Store.swift in Sources */, + 6B90B44722A92C3B0017BE2B /* CounterView.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 6B90B43B22A92BBF0017BE2B /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 6B90B43C22A92BBF0017BE2B /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 6B90B43F22A92BBF0017BE2B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + 6B90B44022A92BBF0017BE2B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 6B90B44222A92BBF0017BE2B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_ASSET_PATHS = "SwiftUI-Flux/Preview\\ Content"; + ENABLE_PREVIEWS = YES; + INFOPLIST_FILE = "SwiftUI-Flux/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = "com.ryo.SwiftUI-Flux"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 6B90B44322A92BBF0017BE2B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_ASSET_PATHS = "SwiftUI-Flux/Preview\\ Content"; + ENABLE_PREVIEWS = YES; + INFOPLIST_FILE = "SwiftUI-Flux/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = "com.ryo.SwiftUI-Flux"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 6B90B42822A92BBE0017BE2B /* Build configuration list for PBXProject "SwiftUI-Flux" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 6B90B43F22A92BBF0017BE2B /* Debug */, + 6B90B44022A92BBF0017BE2B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 6B90B44122A92BBF0017BE2B /* Build configuration list for PBXNativeTarget "SwiftUI-Flux" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 6B90B44222A92BBF0017BE2B /* Debug */, + 6B90B44322A92BBF0017BE2B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 6B90B42522A92BBE0017BE2B /* Project object */; +} diff --git a/Other Projects/Flux/SwiftUI-Flux.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/Other Projects/Flux/SwiftUI-Flux.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..59f0ffb --- /dev/null +++ b/Other Projects/Flux/SwiftUI-Flux.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/Other Projects/Flux/SwiftUI-Flux.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/Other Projects/Flux/SwiftUI-Flux.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/Other Projects/Flux/SwiftUI-Flux.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/Other Projects/Flux/SwiftUI-Flux/AppDelegate.swift b/Other Projects/Flux/SwiftUI-Flux/AppDelegate.swift new file mode 100644 index 0000000..b259097 --- /dev/null +++ b/Other Projects/Flux/SwiftUI-Flux/AppDelegate.swift @@ -0,0 +1,4 @@ +import UIKit + +@UIApplicationMain +final class AppDelegate: UIResponder, UIApplicationDelegate {} diff --git a/Other Projects/Flux/SwiftUI-Flux/Assets.xcassets/AppIcon.appiconset/Contents.json b/Other Projects/Flux/SwiftUI-Flux/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..d8db8d6 --- /dev/null +++ b/Other Projects/Flux/SwiftUI-Flux/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,98 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "83.5x83.5", + "scale" : "2x" + }, + { + "idiom" : "ios-marketing", + "size" : "1024x1024", + "scale" : "1x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/Flux/SwiftUI-Flux/Assets.xcassets/Contents.json b/Other Projects/Flux/SwiftUI-Flux/Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/Other Projects/Flux/SwiftUI-Flux/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/Flux/SwiftUI-Flux/Base.lproj/LaunchScreen.storyboard b/Other Projects/Flux/SwiftUI-Flux/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000..865e932 --- /dev/null +++ b/Other Projects/Flux/SwiftUI-Flux/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Other Projects/Flux/SwiftUI-Flux/CounterView.swift b/Other Projects/Flux/SwiftUI-Flux/CounterView.swift new file mode 100644 index 0000000..ffb557b --- /dev/null +++ b/Other Projects/Flux/SwiftUI-Flux/CounterView.swift @@ -0,0 +1,34 @@ +import SwiftUI + +struct CounterView : View { + enum Action { + case increment + case decrement + } + + @State var store = Store(initial: 0) { count, action in + switch action { + case .increment: + return count + 1 + + case .decrement: + return max(0, count - 1) + } + } + + var body: some View { + VStack { + Text("\(store.state)") + + HStack { + Button(action: { self.store.dispatch(action: .decrement) }) { + Text("Decrement") + } + + Button(action: { self.store.dispatch(action: .increment) }) { + Text("Increment") + } + } + } + } +} diff --git a/Other Projects/Flux/SwiftUI-Flux/Info.plist b/Other Projects/Flux/SwiftUI-Flux/Info.plist new file mode 100644 index 0000000..e8bb4c6 --- /dev/null +++ b/Other Projects/Flux/SwiftUI-Flux/Info.plist @@ -0,0 +1,62 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + $(PRODUCT_BUNDLE_PACKAGE_TYPE) + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UIApplicationSceneManifest + + UIApplicationSupportsMultipleScenes + + UISceneConfigurations + + UIWindowSceneSessionRoleApplication + + + UILaunchStoryboardName + LaunchScreen + UISceneConfigurationName + Default Configuration + UISceneDelegateClassName + $(PRODUCT_MODULE_NAME).SceneDelegate + + + + + UILaunchStoryboardName + LaunchScreen + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/Other Projects/Flux/SwiftUI-Flux/Preview Content/Preview Assets.xcassets/Contents.json b/Other Projects/Flux/SwiftUI-Flux/Preview Content/Preview Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/Other Projects/Flux/SwiftUI-Flux/Preview Content/Preview Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/Flux/SwiftUI-Flux/SceneDelegate.swift b/Other Projects/Flux/SwiftUI-Flux/SceneDelegate.swift new file mode 100644 index 0000000..65209b4 --- /dev/null +++ b/Other Projects/Flux/SwiftUI-Flux/SceneDelegate.swift @@ -0,0 +1,15 @@ +import UIKit +import SwiftUI + +final class SceneDelegate: UIResponder, UIWindowSceneDelegate { + var window: UIWindow? + + func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { + if let windowScene = scene as? UIWindowScene { + let window = UIWindow(windowScene: windowScene) + window.rootViewController = UIHostingController(rootView: CounterView()) + self.window = window + window.makeKeyAndVisible() + } + } +} diff --git a/Other Projects/Flux/SwiftUI-Flux/Store.swift b/Other Projects/Flux/SwiftUI-Flux/Store.swift new file mode 100644 index 0000000..648e280 --- /dev/null +++ b/Other Projects/Flux/SwiftUI-Flux/Store.swift @@ -0,0 +1,34 @@ +import SwiftUI +import Combine + +final class Store: ObservableObject { + typealias Reducer = (State, Action) -> State + + let objectWillChange = PassthroughSubject() + + var state: State { + lock.lock() + defer { lock.unlock() } + return _state + } + + private let lock = NSLock() + private let reducer: Reducer + private var _state: State + + init(initial state: State, reducer: @escaping Reducer) { + _state = state + self.reducer = reducer + } + + func dispatch(action: Action) { + lock.lock() + + let newState = reducer(_state, action) + _state = newState + + lock.unlock() + + objectWillChange.send(newState) + } +} diff --git a/Other Projects/GitHub Search/GitHubSearchWithSwiftUI.xcodeproj/project.pbxproj b/Other Projects/GitHub Search/GitHubSearchWithSwiftUI.xcodeproj/project.pbxproj new file mode 100644 index 0000000..15040d2 --- /dev/null +++ b/Other Projects/GitHub Search/GitHubSearchWithSwiftUI.xcodeproj/project.pbxproj @@ -0,0 +1,417 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 50; + objects = { + +/* Begin PBXBuildFile section */ + BB3DC0CE22D54717006F0587 /* AnySubscription.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB3DC0CD22D54717006F0587 /* AnySubscription.swift */; }; + BB3DC0D022D54737006F0587 /* ErrorResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB3DC0CF22D54737006F0587 /* ErrorResponse.swift */; }; + BB3DC0D222D54826006F0587 /* WebView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB3DC0D122D54826006F0587 /* WebView.swift */; }; + BB3DC0D422D54927006F0587 /* Publisher.Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB3DC0D322D54927006F0587 /* Publisher.Extension.swift */; }; + ED73146222A6F228004F8DA0 /* RepositoryListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED73146122A6F228004F8DA0 /* RepositoryListView.swift */; }; + EDDADAB122A808D500FEDC01 /* Combine.swift in Sources */ = {isa = PBXBuildFile; fileRef = EDDADAB022A808D500FEDC01 /* Combine.swift */; }; + EDDADAB322A809E600FEDC01 /* URLSession.Combine.swift in Sources */ = {isa = PBXBuildFile; fileRef = EDDADAB222A809E600FEDC01 /* URLSession.Combine.swift */; }; + EDDADAB522A821CD00FEDC01 /* ItemResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = EDDADAB422A821CD00FEDC01 /* ItemResponse.swift */; }; + EDDADAB722A829A300FEDC01 /* RepositoryAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = EDDADAB622A829A300FEDC01 /* RepositoryAPI.swift */; }; + EDDADAB922A82C0400FEDC01 /* RepositoryListViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EDDADAB822A82C0400FEDC01 /* RepositoryListViewModel.swift */; }; + EDDADABB22A82C2500FEDC01 /* JSONDecoder.Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = EDDADABA22A82C2500FEDC01 /* JSONDecoder.Extension.swift */; }; + EDDF06A222A6C61C00B23D44 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = EDDF06A122A6C61C00B23D44 /* AppDelegate.swift */; }; + EDDF06A422A6C61C00B23D44 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = EDDF06A322A6C61C00B23D44 /* SceneDelegate.swift */; }; + EDDF06A822A6C61D00B23D44 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = EDDF06A722A6C61D00B23D44 /* Assets.xcassets */; }; + EDDF06AB22A6C61D00B23D44 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = EDDF06AA22A6C61D00B23D44 /* Preview Assets.xcassets */; }; + EDDF06AE22A6C61D00B23D44 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = EDDF06AC22A6C61D00B23D44 /* LaunchScreen.storyboard */; }; + EDDF06B722A6CD8300B23D44 /* RepositoryView.swift in Sources */ = {isa = PBXBuildFile; fileRef = EDDF06B622A6CD8300B23D44 /* RepositoryView.swift */; }; + EDDF06BA22A6D78200B23D44 /* Repository.swift in Sources */ = {isa = PBXBuildFile; fileRef = EDDF06B922A6D78200B23D44 /* Repository.swift */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + BB3DC0CD22D54717006F0587 /* AnySubscription.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnySubscription.swift; sourceTree = ""; }; + BB3DC0CF22D54737006F0587 /* ErrorResponse.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ErrorResponse.swift; sourceTree = ""; }; + BB3DC0D122D54826006F0587 /* WebView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WebView.swift; sourceTree = ""; }; + BB3DC0D322D54927006F0587 /* Publisher.Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Publisher.Extension.swift; sourceTree = ""; }; + ED73146122A6F228004F8DA0 /* RepositoryListView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RepositoryListView.swift; sourceTree = ""; }; + EDDADAB022A808D500FEDC01 /* Combine.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Combine.swift; sourceTree = ""; }; + EDDADAB222A809E600FEDC01 /* URLSession.Combine.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = URLSession.Combine.swift; sourceTree = ""; }; + EDDADAB422A821CD00FEDC01 /* ItemResponse.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ItemResponse.swift; sourceTree = ""; }; + EDDADAB622A829A300FEDC01 /* RepositoryAPI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RepositoryAPI.swift; sourceTree = ""; }; + EDDADAB822A82C0400FEDC01 /* RepositoryListViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RepositoryListViewModel.swift; sourceTree = ""; }; + EDDADABA22A82C2500FEDC01 /* JSONDecoder.Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JSONDecoder.Extension.swift; sourceTree = ""; }; + EDDF069E22A6C61C00B23D44 /* GitHubSearchWithSwiftUI.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = GitHubSearchWithSwiftUI.app; sourceTree = BUILT_PRODUCTS_DIR; }; + EDDF06A122A6C61C00B23D44 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + EDDF06A322A6C61C00B23D44 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; + EDDF06A722A6C61D00B23D44 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + EDDF06AA22A6C61D00B23D44 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; + EDDF06AD22A6C61D00B23D44 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + EDDF06AF22A6C61D00B23D44 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + EDDF06B622A6CD8300B23D44 /* RepositoryView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RepositoryView.swift; sourceTree = ""; }; + EDDF06B922A6D78200B23D44 /* Repository.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Repository.swift; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + EDDF069B22A6C61C00B23D44 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + EDDADAAF22A808C300FEDC01 /* Extension */ = { + isa = PBXGroup; + children = ( + EDDADAB022A808D500FEDC01 /* Combine.swift */, + EDDADAB222A809E600FEDC01 /* URLSession.Combine.swift */, + EDDADABA22A82C2500FEDC01 /* JSONDecoder.Extension.swift */, + BB3DC0D322D54927006F0587 /* Publisher.Extension.swift */, + ); + path = Extension; + sourceTree = ""; + }; + EDDF069522A6C61C00B23D44 = { + isa = PBXGroup; + children = ( + EDDF06A022A6C61C00B23D44 /* GitHubSearchWithSwiftUI */, + EDDF069F22A6C61C00B23D44 /* Products */, + ); + sourceTree = ""; + }; + EDDF069F22A6C61C00B23D44 /* Products */ = { + isa = PBXGroup; + children = ( + EDDF069E22A6C61C00B23D44 /* GitHubSearchWithSwiftUI.app */, + ); + name = Products; + sourceTree = ""; + }; + EDDF06A022A6C61C00B23D44 /* GitHubSearchWithSwiftUI */ = { + isa = PBXGroup; + children = ( + EDDF06A122A6C61C00B23D44 /* AppDelegate.swift */, + EDDF06A322A6C61C00B23D44 /* SceneDelegate.swift */, + EDDADAAF22A808C300FEDC01 /* Extension */, + EDDF06B822A6D77000B23D44 /* Model */, + EDDF06B522A6CD6400B23D44 /* View */, + EDDF06A722A6C61D00B23D44 /* Assets.xcassets */, + EDDF06AC22A6C61D00B23D44 /* LaunchScreen.storyboard */, + EDDF06AF22A6C61D00B23D44 /* Info.plist */, + EDDF06A922A6C61D00B23D44 /* Preview Content */, + ); + path = GitHubSearchWithSwiftUI; + sourceTree = ""; + }; + EDDF06A922A6C61D00B23D44 /* Preview Content */ = { + isa = PBXGroup; + children = ( + EDDF06AA22A6C61D00B23D44 /* Preview Assets.xcassets */, + ); + path = "Preview Content"; + sourceTree = ""; + }; + EDDF06B522A6CD6400B23D44 /* View */ = { + isa = PBXGroup; + children = ( + ED73146122A6F228004F8DA0 /* RepositoryListView.swift */, + EDDF06B622A6CD8300B23D44 /* RepositoryView.swift */, + EDDADAB822A82C0400FEDC01 /* RepositoryListViewModel.swift */, + BB3DC0D122D54826006F0587 /* WebView.swift */, + ); + path = View; + sourceTree = ""; + }; + EDDF06B822A6D77000B23D44 /* Model */ = { + isa = PBXGroup; + children = ( + EDDF06B922A6D78200B23D44 /* Repository.swift */, + EDDADAB422A821CD00FEDC01 /* ItemResponse.swift */, + EDDADAB622A829A300FEDC01 /* RepositoryAPI.swift */, + BB3DC0CD22D54717006F0587 /* AnySubscription.swift */, + BB3DC0CF22D54737006F0587 /* ErrorResponse.swift */, + ); + path = Model; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + EDDF069D22A6C61C00B23D44 /* GitHubSearchWithSwiftUI */ = { + isa = PBXNativeTarget; + buildConfigurationList = EDDF06B222A6C61D00B23D44 /* Build configuration list for PBXNativeTarget "GitHubSearchWithSwiftUI" */; + buildPhases = ( + EDDF069A22A6C61C00B23D44 /* Sources */, + EDDF069B22A6C61C00B23D44 /* Frameworks */, + EDDF069C22A6C61C00B23D44 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = GitHubSearchWithSwiftUI; + productName = GitHubSearchWithSwiftUI; + productReference = EDDF069E22A6C61C00B23D44 /* GitHubSearchWithSwiftUI.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + EDDF069622A6C61C00B23D44 /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 1100; + LastUpgradeCheck = 1100; + ORGANIZATIONNAME = "jp.marty-suzuki"; + TargetAttributes = { + EDDF069D22A6C61C00B23D44 = { + CreatedOnToolsVersion = 11.0; + }; + }; + }; + buildConfigurationList = EDDF069922A6C61C00B23D44 /* Build configuration list for PBXProject "GitHubSearchWithSwiftUI" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = EDDF069522A6C61C00B23D44; + productRefGroup = EDDF069F22A6C61C00B23D44 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + EDDF069D22A6C61C00B23D44 /* GitHubSearchWithSwiftUI */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + EDDF069C22A6C61C00B23D44 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + EDDF06AE22A6C61D00B23D44 /* LaunchScreen.storyboard in Resources */, + EDDF06AB22A6C61D00B23D44 /* Preview Assets.xcassets in Resources */, + EDDF06A822A6C61D00B23D44 /* Assets.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + EDDF069A22A6C61C00B23D44 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ED73146222A6F228004F8DA0 /* RepositoryListView.swift in Sources */, + BB3DC0CE22D54717006F0587 /* AnySubscription.swift in Sources */, + EDDADAB722A829A300FEDC01 /* RepositoryAPI.swift in Sources */, + EDDF06A222A6C61C00B23D44 /* AppDelegate.swift in Sources */, + BB3DC0D422D54927006F0587 /* Publisher.Extension.swift in Sources */, + EDDADAB522A821CD00FEDC01 /* ItemResponse.swift in Sources */, + EDDF06A422A6C61C00B23D44 /* SceneDelegate.swift in Sources */, + EDDADAB922A82C0400FEDC01 /* RepositoryListViewModel.swift in Sources */, + EDDF06BA22A6D78200B23D44 /* Repository.swift in Sources */, + EDDF06B722A6CD8300B23D44 /* RepositoryView.swift in Sources */, + EDDADAB322A809E600FEDC01 /* URLSession.Combine.swift in Sources */, + EDDADABB22A82C2500FEDC01 /* JSONDecoder.Extension.swift in Sources */, + EDDADAB122A808D500FEDC01 /* Combine.swift in Sources */, + BB3DC0D022D54737006F0587 /* ErrorResponse.swift in Sources */, + BB3DC0D222D54826006F0587 /* WebView.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + EDDF06AC22A6C61D00B23D44 /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + EDDF06AD22A6C61D00B23D44 /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + EDDF06B022A6C61D00B23D44 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + EDDF06B122A6C61D00B23D44 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + EDDF06B322A6C61D00B23D44 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_ASSET_PATHS = "GitHubSearchWithSwiftUI/Preview\\ Content"; + ENABLE_PREVIEWS = YES; + INFOPLIST_FILE = GitHubSearchWithSwiftUI/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = "jp.marty-suzuki.GitHubSearchWithSwiftUI"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + EDDF06B422A6C61D00B23D44 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_ASSET_PATHS = "GitHubSearchWithSwiftUI/Preview\\ Content"; + ENABLE_PREVIEWS = YES; + INFOPLIST_FILE = GitHubSearchWithSwiftUI/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = "jp.marty-suzuki.GitHubSearchWithSwiftUI"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + EDDF069922A6C61C00B23D44 /* Build configuration list for PBXProject "GitHubSearchWithSwiftUI" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + EDDF06B022A6C61D00B23D44 /* Debug */, + EDDF06B122A6C61D00B23D44 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + EDDF06B222A6C61D00B23D44 /* Build configuration list for PBXNativeTarget "GitHubSearchWithSwiftUI" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + EDDF06B322A6C61D00B23D44 /* Debug */, + EDDF06B422A6C61D00B23D44 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = EDDF069622A6C61C00B23D44 /* Project object */; +} diff --git a/Other Projects/GitHub Search/GitHubSearchWithSwiftUI.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/Other Projects/GitHub Search/GitHubSearchWithSwiftUI.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..ea1588f --- /dev/null +++ b/Other Projects/GitHub Search/GitHubSearchWithSwiftUI.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/Other Projects/GitHub Search/GitHubSearchWithSwiftUI.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/Other Projects/GitHub Search/GitHubSearchWithSwiftUI.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/Other Projects/GitHub Search/GitHubSearchWithSwiftUI.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/Other Projects/GitHub Search/GitHubSearchWithSwiftUI.xcodeproj/xcshareddata/xcschemes/GitHubSearchWithSwiftUI.xcscheme b/Other Projects/GitHub Search/GitHubSearchWithSwiftUI.xcodeproj/xcshareddata/xcschemes/GitHubSearchWithSwiftUI.xcscheme new file mode 100644 index 0000000..9dfd1ef --- /dev/null +++ b/Other Projects/GitHub Search/GitHubSearchWithSwiftUI.xcodeproj/xcshareddata/xcschemes/GitHubSearchWithSwiftUI.xcscheme @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Other Projects/GitHub Search/GitHubSearchWithSwiftUI/AppDelegate.swift b/Other Projects/GitHub Search/GitHubSearchWithSwiftUI/AppDelegate.swift new file mode 100644 index 0000000..f0cbb83 --- /dev/null +++ b/Other Projects/GitHub Search/GitHubSearchWithSwiftUI/AppDelegate.swift @@ -0,0 +1,41 @@ +// +// AppDelegate.swift +// GitHubSearchWithSwiftUI +// +// Created by marty-suzuki on 2019/06/05. +// Copyright © 2019 jp.marty-suzuki. All rights reserved. +// + +import UIKit + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + + + + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { + // Override point for customization after application launch. + return true + } + + func applicationWillTerminate(_ application: UIApplication) { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. + } + + // MARK: UISceneSession Lifecycle + + func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration { + // Called when a new scene session is being created. + // Use this method to select a configuration to create the new scene with. + return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role) + } + + func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) { + // Called when the user discards a scene session. + // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions. + // Use this method to release any resources that were specific to the discarded scenes, as they will not return. + } + + +} + diff --git a/Other Projects/GitHub Search/GitHubSearchWithSwiftUI/Assets.xcassets/AppIcon.appiconset/Contents.json b/Other Projects/GitHub Search/GitHubSearchWithSwiftUI/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..d8db8d6 --- /dev/null +++ b/Other Projects/GitHub Search/GitHubSearchWithSwiftUI/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,98 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "83.5x83.5", + "scale" : "2x" + }, + { + "idiom" : "ios-marketing", + "size" : "1024x1024", + "scale" : "1x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/GitHub Search/GitHubSearchWithSwiftUI/Assets.xcassets/Contents.json b/Other Projects/GitHub Search/GitHubSearchWithSwiftUI/Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/Other Projects/GitHub Search/GitHubSearchWithSwiftUI/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/GitHub Search/GitHubSearchWithSwiftUI/Base.lproj/LaunchScreen.storyboard b/Other Projects/GitHub Search/GitHubSearchWithSwiftUI/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000..865e932 --- /dev/null +++ b/Other Projects/GitHub Search/GitHubSearchWithSwiftUI/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Other Projects/GitHub Search/GitHubSearchWithSwiftUI/Extension/Combine.swift b/Other Projects/GitHub Search/GitHubSearchWithSwiftUI/Extension/Combine.swift new file mode 100644 index 0000000..45decef --- /dev/null +++ b/Other Projects/GitHub Search/GitHubSearchWithSwiftUI/Extension/Combine.swift @@ -0,0 +1,41 @@ +// +// Combine.swift +// GitHubSearchWithSwiftUI +// +// Created by marty-suzuki on 2019/06/05. +// Copyright © 2019 jp.marty-suzuki. All rights reserved. +// + +import Foundation + +struct CombineExtension { + let base: Base + + init(_ base: Base) { + self.base = base + } +} + +protocol CombineCompatible { + associatedtype CombineExtensionBase + + static var combine: CombineExtension.Type { get set } + var combine: CombineExtension { get set } +} + +extension CombineCompatible { + + static var combine: CombineExtension.Type { + get { + return CombineExtension.self + } + set {} + } + + var combine: CombineExtension { + get { + return CombineExtension(self) + } + set {} + } +} diff --git a/Other Projects/GitHub Search/GitHubSearchWithSwiftUI/Extension/JSONDecoder.Extension.swift b/Other Projects/GitHub Search/GitHubSearchWithSwiftUI/Extension/JSONDecoder.Extension.swift new file mode 100644 index 0000000..47ade8e --- /dev/null +++ b/Other Projects/GitHub Search/GitHubSearchWithSwiftUI/Extension/JSONDecoder.Extension.swift @@ -0,0 +1,13 @@ +// +// JSONDecoder.Extension.swift +// GitHubSearchWithSwiftUI +// +// Created by marty-suzuki on 2019/06/06. +// Copyright © 2019 jp.marty-suzuki. All rights reserved. +// + +import Combine +import Foundation + +// now in Foundation +//extension JSONDecoder: TopLevelDecoder {} diff --git a/Other Projects/GitHub Search/GitHubSearchWithSwiftUI/Extension/Publisher.Extension.swift b/Other Projects/GitHub Search/GitHubSearchWithSwiftUI/Extension/Publisher.Extension.swift new file mode 100644 index 0000000..0d3db76 --- /dev/null +++ b/Other Projects/GitHub Search/GitHubSearchWithSwiftUI/Extension/Publisher.Extension.swift @@ -0,0 +1,36 @@ +// +// Publisher.Extension.swift +// GitHubSearchWithSwiftUI +// +// Created by John Holdsworth on 09/07/2019. +// Copyright © 2019 jp.marty-suzuki. All rights reserved. +// + +import Combine + +extension Publisher { + + /// - seealso: https://twitter.com/peres/status/1136132104020881408 + func flatMapLatest(_ transform: @escaping (Self.Output) -> T) -> Publishers.SwitchToLatest> where T.Failure == Self.Failure { + map(transform).switchToLatest() + } +} + +extension Publisher { + + static func empty() -> AnyPublisher { + return Empty() + .eraseToAnyPublisher() + } + + static func just(_ output: Output) -> AnyPublisher { + return Just(output) + .catch { _ in AnyPublisher.empty() } + .eraseToAnyPublisher() + } + + static func fail(_ error: Failure) -> AnyPublisher { + return Fail(error: error) + .eraseToAnyPublisher() + } +} diff --git a/Other Projects/GitHub Search/GitHubSearchWithSwiftUI/Extension/URLSession.Combine.swift b/Other Projects/GitHub Search/GitHubSearchWithSwiftUI/Extension/URLSession.Combine.swift new file mode 100644 index 0000000..5d14f14 --- /dev/null +++ b/Other Projects/GitHub Search/GitHubSearchWithSwiftUI/Extension/URLSession.Combine.swift @@ -0,0 +1,40 @@ +// +// URLSession.Combine.swift +// GitHubSearchWithSwiftUI +// +// Created by marty-suzuki on 2019/06/05. +// Copyright © 2019 jp.marty-suzuki. All rights reserved. +// + +import Combine +import Foundation + +extension URLSession: CombineCompatible {} + +extension CombineExtension where Base == URLSession { + + func send(request: URLRequest) -> AnyPublisher { + + base.dataTaskPublisher(for: request) + .mapError { URLSessionError.urlError($0) } + .flatMap { data, response -> AnyPublisher in + guard let response = response as? HTTPURLResponse else { + return .fail(.invalidResponse) + } + + guard 200..<300 ~= response.statusCode else { + return .fail(.serverErrorMessage(statusCode: response.statusCode, + data: data)) + } + + return .just(data) + } + .eraseToAnyPublisher() + } +} + +enum URLSessionError: Error { + case invalidResponse + case serverErrorMessage(statusCode: Int, data: Data) + case urlError(URLError) +} diff --git a/Other Projects/GitHub Search/GitHubSearchWithSwiftUI/Info.plist b/Other Projects/GitHub Search/GitHubSearchWithSwiftUI/Info.plist new file mode 100644 index 0000000..e8bb4c6 --- /dev/null +++ b/Other Projects/GitHub Search/GitHubSearchWithSwiftUI/Info.plist @@ -0,0 +1,62 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + $(PRODUCT_BUNDLE_PACKAGE_TYPE) + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UIApplicationSceneManifest + + UIApplicationSupportsMultipleScenes + + UISceneConfigurations + + UIWindowSceneSessionRoleApplication + + + UILaunchStoryboardName + LaunchScreen + UISceneConfigurationName + Default Configuration + UISceneDelegateClassName + $(PRODUCT_MODULE_NAME).SceneDelegate + + + + + UILaunchStoryboardName + LaunchScreen + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/Other Projects/GitHub Search/GitHubSearchWithSwiftUI/Model/AnySubscription.swift b/Other Projects/GitHub Search/GitHubSearchWithSwiftUI/Model/AnySubscription.swift new file mode 100644 index 0000000..f9776b8 --- /dev/null +++ b/Other Projects/GitHub Search/GitHubSearchWithSwiftUI/Model/AnySubscription.swift @@ -0,0 +1,25 @@ +// +// AnySubscription.swift +// GitHubSearchWithSwiftUI +// +// Created by John Holdsworth on 09/07/2019. +// Copyright © 2019 jp.marty-suzuki. All rights reserved. +// + +import Combine + +/// - seealso: https://twitter.com/peres/status/1135970931153821696 +final class AnySubscription: Subscription { + + private let cancellable: AnyCancellable + + init(_ cancel: @escaping () -> Void) { + self.cancellable = AnyCancellable(cancel) + } + + func request(_ demand: Subscribers.Demand) {} + + func cancel() { + cancellable.cancel() + } +} diff --git a/Other Projects/GitHub Search/GitHubSearchWithSwiftUI/Model/ErrorResponse.swift b/Other Projects/GitHub Search/GitHubSearchWithSwiftUI/Model/ErrorResponse.swift new file mode 100644 index 0000000..44d6ff7 --- /dev/null +++ b/Other Projects/GitHub Search/GitHubSearchWithSwiftUI/Model/ErrorResponse.swift @@ -0,0 +1,13 @@ +// +// ErrorResponse.swift +// GitHubSearchWithSwiftUI +// +// Created by John Holdsworth on 09/07/2019. +// Copyright © 2019 jp.marty-suzuki. All rights reserved. +// + +import Foundation + +struct ErrorResponse: Decodable, Error { + let message: String +} diff --git a/Other Projects/GitHub Search/GitHubSearchWithSwiftUI/Model/ItemResponse.swift b/Other Projects/GitHub Search/GitHubSearchWithSwiftUI/Model/ItemResponse.swift new file mode 100644 index 0000000..fcf3e69 --- /dev/null +++ b/Other Projects/GitHub Search/GitHubSearchWithSwiftUI/Model/ItemResponse.swift @@ -0,0 +1,13 @@ +// +// ItemResponse.swift +// GitHubSearchWithSwiftUI +// +// Created by marty-suzuki on 2019/06/06. +// Copyright © 2019 jp.marty-suzuki. All rights reserved. +// + +import Foundation + +struct ItemResponse: Decodable { + let items: [T] +} diff --git a/Other Projects/GitHub Search/GitHubSearchWithSwiftUI/Model/Repository.swift b/Other Projects/GitHub Search/GitHubSearchWithSwiftUI/Model/Repository.swift new file mode 100644 index 0000000..95f0a40 --- /dev/null +++ b/Other Projects/GitHub Search/GitHubSearchWithSwiftUI/Model/Repository.swift @@ -0,0 +1,17 @@ +// +// Repository.swift +// GitHubSearchWithSwiftUI +// +// Created by marty-suzuki on 2019/06/05. +// Copyright © 2019 jp.marty-suzuki. All rights reserved. +// + +import Foundation + +struct Repository: Decodable { + let id: Int + let fullName: String + let description: String? + let stargazersCount: Int + let htmlUrl: URL +} diff --git a/Other Projects/GitHub Search/GitHubSearchWithSwiftUI/Model/RepositoryAPI.swift b/Other Projects/GitHub Search/GitHubSearchWithSwiftUI/Model/RepositoryAPI.swift new file mode 100644 index 0000000..a056450 --- /dev/null +++ b/Other Projects/GitHub Search/GitHubSearchWithSwiftUI/Model/RepositoryAPI.swift @@ -0,0 +1,51 @@ +// +// RepositoryModel.swift +// GitHubSearchWithSwiftUI +// +// Created by marty-suzuki on 2019/06/06. +// Copyright © 2019 jp.marty-suzuki. All rights reserved. +// + +import Combine +import Foundation + +enum RepositoryAPI { + typealias SearchResponse = AnyPublisher, Never> + typealias SendRequest = (URLRequest) -> AnyPublisher + + static func search(query: String) -> SearchResponse { + search(query: query, sendRequest: URLSession.shared.combine.send) + } + + static func search(query: String, sendRequest: SendRequest) -> SearchResponse { + + guard var components = URLComponents(string: "https://api.github.com/search/repositories") else { + return .empty() + } + components.queryItems = [URLQueryItem(name: "q", value: query)] + + guard let url = components.url else { + return .empty() + } + + var request = URLRequest(url: url) + request.addValue("application/json", forHTTPHeaderField: "Content-Type") + let decoder = JSONDecoder() + decoder.keyDecodingStrategy = .convertFromSnakeCase + return sendRequest(request) + .decode(type: ItemResponse.self, decoder: decoder) + .map { Result<[Repository], ErrorResponse>.success($0.items) } + .catch { error -> SearchResponse in + guard case let .serverErrorMessage(_, data)? = error as? URLSessionError else { + return .just(.success([])) + } + do { + let response = try JSONDecoder().decode(ErrorResponse.self, from: data) + return .just(.failure(response)) + } catch _ { + return .just(.success([])) + } + } + .eraseToAnyPublisher() + } +} diff --git a/Other Projects/GitHub Search/GitHubSearchWithSwiftUI/Preview Content/Preview Assets.xcassets/Contents.json b/Other Projects/GitHub Search/GitHubSearchWithSwiftUI/Preview Content/Preview Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/Other Projects/GitHub Search/GitHubSearchWithSwiftUI/Preview Content/Preview Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/GitHub Search/GitHubSearchWithSwiftUI/SceneDelegate.swift b/Other Projects/GitHub Search/GitHubSearchWithSwiftUI/SceneDelegate.swift new file mode 100644 index 0000000..b49e39b --- /dev/null +++ b/Other Projects/GitHub Search/GitHubSearchWithSwiftUI/SceneDelegate.swift @@ -0,0 +1,61 @@ +// +// SceneDelegate.swift +// GitHubSearchWithSwiftUI +// +// Created by marty-suzuki on 2019/06/05. +// Copyright © 2019 jp.marty-suzuki. All rights reserved. +// + +import UIKit +import SwiftUI + +class SceneDelegate: UIResponder, UIWindowSceneDelegate { + + var window: UIWindow? + + + func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { + // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`. + // If using a storyboard, the `window` property will automatically be initialized and attached to the scene. + // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead). + + // Use a UIHostingController as window root view controller + if let windowScene = scene as? UIWindowScene { + let window = UIWindow(windowScene: windowScene) + window.rootViewController = UIHostingController(rootView: RepositoryListView(viewModel: RepositoryListViewModel(mainScheduler: DispatchQueue.main))) + self.window = window + window.makeKeyAndVisible() + } + } + + func sceneDidDisconnect(_ scene: UIScene) { + // Called as the scene is being released by the system. + // This occurs shortly after the scene enters the background, or when its session is discarded. + // Release any resources associated with this scene that can be re-created the next time the scene connects. + // The scene may re-connect later, as its session was not neccessarily discarded (see `application:didDiscardSceneSessions` instead). + } + + func sceneDidBecomeActive(_ scene: UIScene) { + // Called when the scene has moved from an inactive state to an active state. + // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive. + } + + func sceneWillResignActive(_ scene: UIScene) { + // Called when the scene will move from an active state to an inactive state. + // This may occur due to temporary interruptions (ex. an incoming phone call). + } + + func sceneWillEnterForeground(_ scene: UIScene) { + // Called as the scene transitions from the background to the foreground. + // Use this method to undo the changes made on entering the background. + } + + func sceneDidEnterBackground(_ scene: UIScene) { + // Called as the scene transitions from the foreground to the background. + // Use this method to save data, release shared resources, and store enough scene-specific state information + // to restore the scene back to its current state. + } + + +} + diff --git a/Other Projects/GitHub Search/GitHubSearchWithSwiftUI/View/RepositoryListView.swift b/Other Projects/GitHub Search/GitHubSearchWithSwiftUI/View/RepositoryListView.swift new file mode 100644 index 0000000..bc08f05 --- /dev/null +++ b/Other Projects/GitHub Search/GitHubSearchWithSwiftUI/View/RepositoryListView.swift @@ -0,0 +1,60 @@ +// +// RepositoryListView.swift +// GitHubSearchWithSwiftUI +// +// Created by marty-suzuki on 2019/06/05. +// Copyright © 2019 jp.marty-suzuki. All rights reserved. +// + +import SwiftUI + +struct RepositoryListView : View { + + @ObservedObject + private(set) var viewModel: RepositoryListViewModel + + var body: some View { + + NavigationView { + + VStack { + HStack { + + TextField("Search repositories...", text: $viewModel.text, + onCommit: { self.viewModel.search() }) + .frame(height: 40) + .padding(EdgeInsets(top: 0, leading: 8, bottom: 0, trailing: 8)) + .padding(EdgeInsets(top: 0, leading: 16, bottom: 0, trailing: 16)) + .background(RoundedRectangle(cornerRadius: 8).strokeBorder(Color.gray, lineWidth: 2)) + + Button(action: { self.viewModel.search() }) { + Text("Search") + } + .frame(height: 40) + .padding(EdgeInsets(top: 0, leading: 8, bottom: 0, trailing: 8)) + .background(RoundedRectangle(cornerRadius: 8).strokeBorder(Color.blue, lineWidth: 2)) + .padding(EdgeInsets(top: 0, leading: 0, bottom: 0, trailing: 16)) + } + + List { + + viewModel.errorMessage.map(Text.init)? + .lineLimit(nil) + .multilineTextAlignment(.center) + + ForEach(viewModel.repositories, id: \.id) { repository in + + NavigationLink(destination: + WebView(url: repository.htmlUrl) + .navigationBarTitle(Text(repository.fullName)) + ) { + + RepositoryView(repository: repository) + } + } + } + } + .navigationBarTitle(Text("Search🔍")) + } + } +} diff --git a/Other Projects/GitHub Search/GitHubSearchWithSwiftUI/View/RepositoryListViewModel.swift b/Other Projects/GitHub Search/GitHubSearchWithSwiftUI/View/RepositoryListViewModel.swift new file mode 100644 index 0000000..d783198 --- /dev/null +++ b/Other Projects/GitHub Search/GitHubSearchWithSwiftUI/View/RepositoryListViewModel.swift @@ -0,0 +1,70 @@ +// +// RepositoryListViewModel.swift +// GitHubSearchWithSwiftUI +// +// Created by marty-suzuki on 2019/06/06. +// Copyright © 2019 jp.marty-suzuki. All rights reserved. +// + +import Combine +import Foundation +import SwiftUI + +final class RepositoryListViewModel: ObservableObject { + typealias SearchRepositories = (String) -> AnyPublisher, Never> + + let objectWillChange: AnyPublisher + private let _didChange = PassthroughSubject() + + private let _searchWithQuery = PassthroughSubject() + private var cancellables: [AnyCancellable] = [] + + private(set) var repositories: [Repository] = [] { + didSet { + _didChange.send(self) + } + } + private(set) var errorMessage: String? { + didSet { + _didChange.send(self) + } + } + var text: String = "" + + init(searchRepositories: @escaping SearchRepositories = RepositoryAPI.search, + mainScheduler: S) { + + self.objectWillChange = _didChange.eraseToAnyPublisher() + + let response = _searchWithQuery + .filter { !$0.isEmpty } + .debounce(for: .milliseconds(300), scheduler: mainScheduler) + .flatMapLatest { query -> AnyPublisher<([Repository], String?), Never> in + searchRepositories(query) + .map { result -> ([Repository], String?) in + switch result { + case let .success(repositories): + return (repositories, nil) + case let .failure(response): + return ([], response.message) + } + } + .eraseToAnyPublisher() + } + .receive(on: mainScheduler) + .share() + + cancellables += [ + response + .map { $0.0 } + .assign(to: \.repositories, on: self), + response + .map { $0.1 } + .assign(to: \.errorMessage, on: self) + ] + } + + func search() { + _searchWithQuery.send(text) + } +} diff --git a/Other Projects/GitHub Search/GitHubSearchWithSwiftUI/View/RepositoryView.swift b/Other Projects/GitHub Search/GitHubSearchWithSwiftUI/View/RepositoryView.swift new file mode 100644 index 0000000..d72af46 --- /dev/null +++ b/Other Projects/GitHub Search/GitHubSearchWithSwiftUI/View/RepositoryView.swift @@ -0,0 +1,36 @@ +// +// RepositoryView.swift +// GitHubSearchWithSwiftUI +// +// Created by marty-suzuki on 2019/06/05. +// Copyright © 2019 jp.marty-suzuki. All rights reserved. +// + +import SwiftUI + +struct RepositoryView : View { + + let repository: Repository + + var body: some View { + + VStack(alignment: .leading) { + + HStack { + Image(systemName: "doc.text") + Text(repository.fullName) + .bold() + } + + // Show text if description exists + repository.description + .map(Text.init)? + .lineLimit(nil) + + HStack { + Image(systemName: "star") + Text("\(repository.stargazersCount)") + } + } + } +} diff --git a/Other Projects/GitHub Search/GitHubSearchWithSwiftUI/View/WebView.swift b/Other Projects/GitHub Search/GitHubSearchWithSwiftUI/View/WebView.swift new file mode 100644 index 0000000..61d764a --- /dev/null +++ b/Other Projects/GitHub Search/GitHubSearchWithSwiftUI/View/WebView.swift @@ -0,0 +1,21 @@ +// +// WebView.swift +// GitHubSearchWithSwiftUI +// +// Created by marty-suzuki on 2019/06/11. +// Copyright © 2019 jp.marty-suzuki. All rights reserved. +// + +import SafariServices +import SwiftUI + +struct WebView: UIViewControllerRepresentable { + + let url: URL + + func makeUIViewController(context: UIViewControllerRepresentableContext) -> SFSafariViewController { + return SFSafariViewController(url: url) + } + + func updateUIViewController(_ uiViewController: SFSafariViewController, context: UIViewControllerRepresentableContext) {} +} diff --git a/Other Projects/Handling User Input/Complete/.gitignore b/Other Projects/Handling User Input/Complete/.gitignore new file mode 100644 index 0000000..9e50718 --- /dev/null +++ b/Other Projects/Handling User Input/Complete/.gitignore @@ -0,0 +1,21 @@ +# See LICENSE folder for this sample’s licensing information. +# +# Apple sample code gitignore configuration. + +# Finder +.DS_Store + +# Xcode - User files +xcuserdata/ + +**/*.xcodeproj/project.xcworkspace/* +!**/*.xcodeproj/project.xcworkspace/xcshareddata + +**/*.xcodeproj/project.xcworkspace/xcshareddata/* +!**/*.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings + +**/*.playground/playground.xcworkspace/* +!**/*.playground/playground.xcworkspace/xcshareddata + +**/*.playground/playground.xcworkspace/xcshareddata/* +!**/*.playground/playground.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings diff --git a/Other Projects/Handling User Input/Complete/Configuration/SampleCode.xcconfig b/Other Projects/Handling User Input/Complete/Configuration/SampleCode.xcconfig new file mode 100644 index 0000000..db86c06 --- /dev/null +++ b/Other Projects/Handling User Input/Complete/Configuration/SampleCode.xcconfig @@ -0,0 +1,13 @@ +// +// See LICENSE folder for this sample’s licensing information. +// +// SampleCode.xcconfig +// + +// The `SAMPLE_CODE_DISAMBIGUATOR` configuration is to make it easier to build +// and run a sample code project. Once you set your project's development team, +// you'll have a unique bundle identifier. This is because the bundle identifier +// is derived based on the 'SAMPLE_CODE_DISAMBIGUATOR' value. Do not use this +// approach in your own projects—it's only useful for sample code projects because +// they are frequently downloaded and don't have a development team set. +SAMPLE_CODE_DISAMBIGUATOR=${DEVELOPMENT_TEAM} diff --git a/Other Projects/Handling User Input/Complete/LICENSE/LICENSE.txt b/Other Projects/Handling User Input/Complete/LICENSE/LICENSE.txt new file mode 100644 index 0000000..94e3d54 --- /dev/null +++ b/Other Projects/Handling User Input/Complete/LICENSE/LICENSE.txt @@ -0,0 +1,8 @@ +Copyright © 2019 Apple Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + diff --git a/Other Projects/Handling User Input/Complete/Landmarks/HandlingUserInput.xcodeproj/.xcodesamplecode.plist b/Other Projects/Handling User Input/Complete/Landmarks/HandlingUserInput.xcodeproj/.xcodesamplecode.plist new file mode 100644 index 0000000..5dd5da8 --- /dev/null +++ b/Other Projects/Handling User Input/Complete/Landmarks/HandlingUserInput.xcodeproj/.xcodesamplecode.plist @@ -0,0 +1,5 @@ + + + + + diff --git a/Other Projects/Handling User Input/Complete/Landmarks/HandlingUserInput.xcodeproj/project.pbxproj b/Other Projects/Handling User Input/Complete/Landmarks/HandlingUserInput.xcodeproj/project.pbxproj new file mode 100644 index 0000000..dba058a --- /dev/null +++ b/Other Projects/Handling User Input/Complete/Landmarks/HandlingUserInput.xcodeproj/project.pbxproj @@ -0,0 +1,481 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 50; + objects = { + +/* Begin PBXBuildFile section */ + B7394866229F194000C47603 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7394865229F194000C47603 /* AppDelegate.swift */; }; + B7394868229F194000C47603 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7394867229F194000C47603 /* SceneDelegate.swift */; }; + B739486A229F194000C47603 /* LandmarkDetail.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7394869229F194000C47603 /* LandmarkDetail.swift */; }; + B739486C229F194200C47603 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B739486B229F194200C47603 /* Assets.xcassets */; }; + B739486F229F194200C47603 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B739486E229F194200C47603 /* Preview Assets.xcassets */; }; + B7394872229F194200C47603 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B7394870229F194200C47603 /* LaunchScreen.storyboard */; }; + B739487A229F1B3F00C47603 /* CircleImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7394879229F1B3F00C47603 /* CircleImage.swift */; }; + B739487C229F1B6800C47603 /* MapView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B739487B229F1B6800C47603 /* MapView.swift */; }; + B7394881229F28B900C47603 /* Landmark.swift in Sources */ = {isa = PBXBuildFile; fileRef = B739487F229F28B900C47603 /* Landmark.swift */; }; + B7394882229F28B900C47603 /* Data.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7394880229F28B900C47603 /* Data.swift */; }; + B7394891229F292F00C47603 /* rainbowlake.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B7394884229F292D00C47603 /* rainbowlake.jpg */; }; + B7394893229F292F00C47603 /* icybay.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B7394886229F292E00C47603 /* icybay.jpg */; }; + B7394894229F292F00C47603 /* lakemcdonald.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B7394887229F292E00C47603 /* lakemcdonald.jpg */; }; + B7394895229F292F00C47603 /* turtlerock.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B7394888229F292E00C47603 /* turtlerock.jpg */; }; + B7394896229F292F00C47603 /* umbagog.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B7394889229F292E00C47603 /* umbagog.jpg */; }; + B7394897229F292F00C47603 /* hiddenlake.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B739488A229F292E00C47603 /* hiddenlake.jpg */; }; + B7394898229F292F00C47603 /* stmarylake.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B739488B229F292E00C47603 /* stmarylake.jpg */; }; + B7394899229F292F00C47603 /* twinlake.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B739488C229F292E00C47603 /* twinlake.jpg */; }; + B739489A229F292F00C47603 /* silversalmoncreek.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B739488D229F292E00C47603 /* silversalmoncreek.jpg */; }; + B739489B229F292F00C47603 /* landmarkData.json in Resources */ = {isa = PBXBuildFile; fileRef = B739488E229F292E00C47603 /* landmarkData.json */; }; + B739489C229F292F00C47603 /* chincoteague.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B739488F229F292F00C47603 /* chincoteague.jpg */; }; + B739489D229F292F00C47603 /* chilkoottrail.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B7394890229F292F00C47603 /* chilkoottrail.jpg */; }; + B739489F229F2D9700C47603 /* LandmarkRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = B739489E229F2D9700C47603 /* LandmarkRow.swift */; }; + B73948A1229F2E1F00C47603 /* LandmarkList.swift in Sources */ = {isa = PBXBuildFile; fileRef = B73948A0229F2E1F00C47603 /* LandmarkList.swift */; }; + B73948A3229F3E2200C47603 /* charleyrivers.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B73948A2229F3E2200C47603 /* charleyrivers.jpg */; }; + B7D2AAC5229F4D7C0061E5F5 /* UserData.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7D2AAC4229F4D7C0061E5F5 /* UserData.swift */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + B7394862229F194000C47603 /* Landmarks.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Landmarks.app; sourceTree = BUILT_PRODUCTS_DIR; }; + B7394865229F194000C47603 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + B7394867229F194000C47603 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; + B7394869229F194000C47603 /* LandmarkDetail.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LandmarkDetail.swift; sourceTree = ""; }; + B739486B229F194200C47603 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + B739486E229F194200C47603 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; + B7394871229F194200C47603 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + B7394873229F194200C47603 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + B7394879229F1B3F00C47603 /* CircleImage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CircleImage.swift; sourceTree = ""; }; + B739487B229F1B6800C47603 /* MapView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapView.swift; sourceTree = ""; }; + B739487F229F28B900C47603 /* Landmark.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Landmark.swift; sourceTree = ""; }; + B7394880229F28B900C47603 /* Data.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Data.swift; sourceTree = ""; }; + B7394884229F292D00C47603 /* rainbowlake.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = rainbowlake.jpg; sourceTree = ""; }; + B7394886229F292E00C47603 /* icybay.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = icybay.jpg; sourceTree = ""; }; + B7394887229F292E00C47603 /* lakemcdonald.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = lakemcdonald.jpg; sourceTree = ""; }; + B7394888229F292E00C47603 /* turtlerock.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = turtlerock.jpg; sourceTree = ""; }; + B7394889229F292E00C47603 /* umbagog.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = umbagog.jpg; sourceTree = ""; }; + B739488A229F292E00C47603 /* hiddenlake.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = hiddenlake.jpg; sourceTree = ""; }; + B739488B229F292E00C47603 /* stmarylake.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = stmarylake.jpg; sourceTree = ""; }; + B739488C229F292E00C47603 /* twinlake.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = twinlake.jpg; sourceTree = ""; }; + B739488D229F292E00C47603 /* silversalmoncreek.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = silversalmoncreek.jpg; sourceTree = ""; }; + B739488E229F292E00C47603 /* landmarkData.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = landmarkData.json; sourceTree = ""; }; + B739488F229F292F00C47603 /* chincoteague.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = chincoteague.jpg; sourceTree = ""; }; + B7394890229F292F00C47603 /* chilkoottrail.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = chilkoottrail.jpg; sourceTree = ""; }; + B739489E229F2D9700C47603 /* LandmarkRow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = LandmarkRow.swift; path = "Supporting Views/LandmarkRow.swift"; sourceTree = ""; }; + B73948A0229F2E1F00C47603 /* LandmarkList.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LandmarkList.swift; sourceTree = ""; }; + B73948A2229F3E2200C47603 /* charleyrivers.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = charleyrivers.jpg; sourceTree = ""; }; + B7D2AAC4229F4D7C0061E5F5 /* UserData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserData.swift; sourceTree = ""; }; + C4E4AAA0C4E4035000000001 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; name = README.md; path = ../README.md; sourceTree = ""; }; + E161B9F0E161E81000000001 /* LICENSE.txt */ = {isa = PBXFileReference; includeInIndex = 1; path = LICENSE.txt; sourceTree = ""; }; + E388E810E388DE8000000001 /* SampleCode.xcconfig */ = {isa = PBXFileReference; name = SampleCode.xcconfig; path = ../Configuration/SampleCode.xcconfig; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + B739485F229F194000C47603 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + B7394859229F194000C47603 = { + isa = PBXGroup; + children = ( + C4E4AAA0C4E4035000000001 /* README.md */, + B7394864229F194000C47603 /* Landmarks */, + B7394863229F194000C47603 /* Products */, + E388E310E388E2D000000001 /* Configuration */, + E165E430E166469000000001 /* LICENSE */, + ); + sourceTree = ""; + }; + B7394863229F194000C47603 /* Products */ = { + isa = PBXGroup; + children = ( + B7394862229F194000C47603 /* Landmarks.app */, + ); + name = Products; + sourceTree = ""; + }; + B7394864229F194000C47603 /* Landmarks */ = { + isa = PBXGroup; + children = ( + B739487E229F282200C47603 /* Models */, + B7394865229F194000C47603 /* AppDelegate.swift */, + B7394867229F194000C47603 /* SceneDelegate.swift */, + B73948A0229F2E1F00C47603 /* LandmarkList.swift */, + B739489E229F2D9700C47603 /* LandmarkRow.swift */, + B7394869229F194000C47603 /* LandmarkDetail.swift */, + B739487D229F1C0100C47603 /* Supporting Views */, + B7394883229F291A00C47603 /* Resources */, + B739486B229F194200C47603 /* Assets.xcassets */, + B7394870229F194200C47603 /* LaunchScreen.storyboard */, + B7394873229F194200C47603 /* Info.plist */, + B739486D229F194200C47603 /* Preview Content */, + ); + path = Landmarks; + sourceTree = ""; + }; + B739486D229F194200C47603 /* Preview Content */ = { + isa = PBXGroup; + children = ( + B739486E229F194200C47603 /* Preview Assets.xcassets */, + ); + path = "Preview Content"; + sourceTree = ""; + }; + B739487D229F1C0100C47603 /* Supporting Views */ = { + isa = PBXGroup; + children = ( + B7394879229F1B3F00C47603 /* CircleImage.swift */, + B739487B229F1B6800C47603 /* MapView.swift */, + ); + path = "Supporting Views"; + sourceTree = ""; + }; + B739487E229F282200C47603 /* Models */ = { + isa = PBXGroup; + children = ( + B7394880229F28B900C47603 /* Data.swift */, + B739487F229F28B900C47603 /* Landmark.swift */, + B7D2AAC4229F4D7C0061E5F5 /* UserData.swift */, + ); + path = Models; + sourceTree = ""; + }; + B7394883229F291A00C47603 /* Resources */ = { + isa = PBXGroup; + children = ( + B739488E229F292E00C47603 /* landmarkData.json */, + B7394890229F292F00C47603 /* chilkoottrail.jpg */, + B739488F229F292F00C47603 /* chincoteague.jpg */, + B739488A229F292E00C47603 /* hiddenlake.jpg */, + B7394886229F292E00C47603 /* icybay.jpg */, + B7394887229F292E00C47603 /* lakemcdonald.jpg */, + B7394884229F292D00C47603 /* rainbowlake.jpg */, + B739488D229F292E00C47603 /* silversalmoncreek.jpg */, + B739488B229F292E00C47603 /* stmarylake.jpg */, + B7394888229F292E00C47603 /* turtlerock.jpg */, + B739488C229F292E00C47603 /* twinlake.jpg */, + B7394889229F292E00C47603 /* umbagog.jpg */, + B73948A2229F3E2200C47603 /* charleyrivers.jpg */, + ); + path = Resources; + sourceTree = ""; + }; + E165E430E166469000000001 /* LICENSE */ = { + isa = PBXGroup; + children = ( + E161B9F0E161E81000000001 /* LICENSE.txt */, + ); + name = LICENSE; + path = ../LICENSE; + sourceTree = ""; + }; + E388E310E388E2D000000001 /* Configuration */ = { + isa = PBXGroup; + children = ( + E388E810E388DE8000000001 /* SampleCode.xcconfig */, + ); + name = Configuration; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + B7394861229F194000C47603 /* Landmarks */ = { + isa = PBXNativeTarget; + buildConfigurationList = B7394876229F194200C47603 /* Build configuration list for PBXNativeTarget "Landmarks" */; + buildPhases = ( + B739485E229F194000C47603 /* Sources */, + B739485F229F194000C47603 /* Frameworks */, + B7394860229F194000C47603 /* Resources */, + C602AC70C605937000000001, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Landmarks; + productName = Landmarks; + productReference = B7394862229F194000C47603 /* Landmarks.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + B739485A229F194000C47603 /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 1100; + LastUpgradeCheck = 1100; + ORGANIZATIONNAME = Apple; + TargetAttributes = { + B7394861229F194000C47603 = { + CreatedOnToolsVersion = 11.0; + }; + }; + }; + buildConfigurationList = B739485D229F194000C47603 /* Build configuration list for PBXProject "HandlingUserInput" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = B7394859229F194000C47603; + productRefGroup = B7394863229F194000C47603 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + B7394861229F194000C47603 /* Landmarks */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + B7394860229F194000C47603 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + B739489A229F292F00C47603 /* silversalmoncreek.jpg in Resources */, + B7394894229F292F00C47603 /* lakemcdonald.jpg in Resources */, + B7394872229F194200C47603 /* LaunchScreen.storyboard in Resources */, + B73948A3229F3E2200C47603 /* charleyrivers.jpg in Resources */, + B7394891229F292F00C47603 /* rainbowlake.jpg in Resources */, + B739486F229F194200C47603 /* Preview Assets.xcassets in Resources */, + B7394895229F292F00C47603 /* turtlerock.jpg in Resources */, + B739486C229F194200C47603 /* Assets.xcassets in Resources */, + B7394899229F292F00C47603 /* twinlake.jpg in Resources */, + B7394896229F292F00C47603 /* umbagog.jpg in Resources */, + B739489D229F292F00C47603 /* chilkoottrail.jpg in Resources */, + B739489C229F292F00C47603 /* chincoteague.jpg in Resources */, + B739489B229F292F00C47603 /* landmarkData.json in Resources */, + B7394893229F292F00C47603 /* icybay.jpg in Resources */, + B7394897229F292F00C47603 /* hiddenlake.jpg in Resources */, + B7394898229F292F00C47603 /* stmarylake.jpg in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + B739485E229F194000C47603 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + B7394882229F28B900C47603 /* Data.swift in Sources */, + B7394866229F194000C47603 /* AppDelegate.swift in Sources */, + B739487A229F1B3F00C47603 /* CircleImage.swift in Sources */, + B739487C229F1B6800C47603 /* MapView.swift in Sources */, + B73948A1229F2E1F00C47603 /* LandmarkList.swift in Sources */, + B7394868229F194000C47603 /* SceneDelegate.swift in Sources */, + B739486A229F194000C47603 /* LandmarkDetail.swift in Sources */, + B739489F229F2D9700C47603 /* LandmarkRow.swift in Sources */, + B7D2AAC5229F4D7C0061E5F5 /* UserData.swift in Sources */, + B7394881229F28B900C47603 /* Landmark.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + B7394870229F194200C47603 /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + B7394871229F194200C47603 /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + B7394874229F194200C47603 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = E388E810E388DE8000000001 /* SampleCode.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + B7394875229F194200C47603 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = E388E810E388DE8000000001 /* SampleCode.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + B7394877229F194200C47603 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = E388E810E388DE8000000001 /* SampleCode.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_ASSET_PATHS = "Landmarks/Preview\\ Content"; + DEVELOPMENT_TEAM = ""; + ENABLE_PREVIEWS = YES; + INFOPLIST_FILE = Landmarks/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = "com.example.apple-samplecode.Landmarks${SAMPLE_CODE_DISAMBIGUATOR}"; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + B7394878229F194200C47603 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = E388E810E388DE8000000001 /* SampleCode.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_ASSET_PATHS = "Landmarks/Preview\\ Content"; + DEVELOPMENT_TEAM = ""; + ENABLE_PREVIEWS = YES; + INFOPLIST_FILE = Landmarks/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = "com.example.apple-samplecode.Landmarks${SAMPLE_CODE_DISAMBIGUATOR}"; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + B739485D229F194000C47603 /* Build configuration list for PBXProject "HandlingUserInput" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + B7394874229F194200C47603 /* Debug */, + B7394875229F194200C47603 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + B7394876229F194200C47603 /* Build configuration list for PBXNativeTarget "Landmarks" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + B7394877229F194200C47603 /* Debug */, + B7394878229F194200C47603 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = B739485A229F194000C47603 /* Project object */; +} diff --git a/Other Projects/Handling User Input/Complete/Landmarks/HandlingUserInput.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/Other Projects/Handling User Input/Complete/Landmarks/HandlingUserInput.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 0000000..3ddf867 --- /dev/null +++ b/Other Projects/Handling User Input/Complete/Landmarks/HandlingUserInput.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,8 @@ + + + + + BuildSystemType + Latest + + diff --git a/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/AppDelegate.swift b/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/AppDelegate.swift new file mode 100644 index 0000000..e22943b --- /dev/null +++ b/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/AppDelegate.swift @@ -0,0 +1,36 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +The application delegate. +*/ + +import UIKit + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { + // Override point for customization after application launch. + return true + } + + func applicationWillTerminate(_ application: UIApplication) { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. + } + + // MARK: UISceneSession Lifecycle + func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration { + // Called when a new scene session is being created. + // Use this method to select a configuration to create the new scene with. + return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role) + } + + func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) { + // Called when the user discards a scene session. + // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions. + // Use this method to release any resources that were specific to the discarded scenes, as they will not return. + } + +} + diff --git a/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/Contents.json b/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..fa0d2db --- /dev/null +++ b/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,113 @@ +{ + "images" : [ + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "landmark_app_icon_40x40.png", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "3x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "landmark_app_icon_58x58.png", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "landmark_app_icon_87x87.png", + "scale" : "3x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "landmark_app_icon_80x80.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "landmark_app_icon_120x120.png", + "scale" : "3x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "landmark_app_icon_120x120-1.png", + "scale" : "2x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "landmark_app_icon_180x180.png", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "1x" + }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "landmark_app_icon_40x40-1.png", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "landmark_app_icon_58x58-1.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "landmark_app_icon_40x40-2.png", + "scale" : "1x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "landmark_app_icon_80x80-1.png", + "scale" : "2x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "landmark_app_icon_76x76.png", + "scale" : "1x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "landmark_app_icon_152x152.png", + "scale" : "2x" + }, + { + "size" : "83.5x83.5", + "idiom" : "ipad", + "filename" : "landmark_app_icon_167x167.png", + "scale" : "2x" + }, + { + "size" : "1024x1024", + "idiom" : "ios-marketing", + "filename" : "landmark_app_icon_1024x1024.png", + "scale" : "1x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_1024x1024.png b/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_1024x1024.png new file mode 100644 index 0000000..00d81c1 Binary files /dev/null and b/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_1024x1024.png differ diff --git a/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_120x120-1.png b/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_120x120-1.png new file mode 100644 index 0000000..d382b8b Binary files /dev/null and b/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_120x120-1.png differ diff --git a/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_120x120.png b/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_120x120.png new file mode 100644 index 0000000..d382b8b Binary files /dev/null and b/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_120x120.png differ diff --git a/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_152x152.png b/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_152x152.png new file mode 100644 index 0000000..11057f8 Binary files /dev/null and b/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_152x152.png differ diff --git a/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_167x167.png b/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_167x167.png new file mode 100644 index 0000000..f73bc26 Binary files /dev/null and b/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_167x167.png differ diff --git a/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_180x180.png b/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_180x180.png new file mode 100644 index 0000000..b02738c Binary files /dev/null and b/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_180x180.png differ diff --git a/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40-1.png b/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40-1.png new file mode 100644 index 0000000..abaff0e Binary files /dev/null and b/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40-1.png differ diff --git a/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40-2.png b/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40-2.png new file mode 100644 index 0000000..abaff0e Binary files /dev/null and b/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40-2.png differ diff --git a/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40.png b/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40.png new file mode 100644 index 0000000..abaff0e Binary files /dev/null and b/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40.png differ diff --git a/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_58x58-1.png b/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_58x58-1.png new file mode 100644 index 0000000..cf7c73d Binary files /dev/null and b/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_58x58-1.png differ diff --git a/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_58x58.png b/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_58x58.png new file mode 100644 index 0000000..cf7c73d Binary files /dev/null and b/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_58x58.png differ diff --git a/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_76x76.png b/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_76x76.png new file mode 100644 index 0000000..3eff85b Binary files /dev/null and b/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_76x76.png differ diff --git a/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_80x80-1.png b/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_80x80-1.png new file mode 100644 index 0000000..6f33f66 Binary files /dev/null and b/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_80x80-1.png differ diff --git a/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_80x80.png b/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_80x80.png new file mode 100644 index 0000000..6f33f66 Binary files /dev/null and b/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_80x80.png differ diff --git a/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_87x87.png b/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_87x87.png new file mode 100644 index 0000000..9e1616c Binary files /dev/null and b/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_87x87.png differ diff --git a/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/Assets.xcassets/Contents.json b/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/Assets.xcassets/turtlerock.imageset/Contents.json b/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/Assets.xcassets/turtlerock.imageset/Contents.json new file mode 100644 index 0000000..5bfd7bf --- /dev/null +++ b/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/Assets.xcassets/turtlerock.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "turtlerock.jpg", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/Assets.xcassets/turtlerock.imageset/turtlerock.jpg b/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/Assets.xcassets/turtlerock.imageset/turtlerock.jpg new file mode 100644 index 0000000..68bcd3e Binary files /dev/null and b/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/Assets.xcassets/turtlerock.imageset/turtlerock.jpg differ diff --git a/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/Base.lproj/LaunchScreen.storyboard b/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000..865e932 --- /dev/null +++ b/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/Info.plist b/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/Info.plist new file mode 100644 index 0000000..e8bb4c6 --- /dev/null +++ b/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/Info.plist @@ -0,0 +1,62 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + $(PRODUCT_BUNDLE_PACKAGE_TYPE) + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UIApplicationSceneManifest + + UIApplicationSupportsMultipleScenes + + UISceneConfigurations + + UIWindowSceneSessionRoleApplication + + + UILaunchStoryboardName + LaunchScreen + UISceneConfigurationName + Default Configuration + UISceneDelegateClassName + $(PRODUCT_MODULE_NAME).SceneDelegate + + + + + UILaunchStoryboardName + LaunchScreen + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/LandmarkDetail.swift b/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/LandmarkDetail.swift new file mode 100644 index 0000000..6c290a3 --- /dev/null +++ b/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/LandmarkDetail.swift @@ -0,0 +1,71 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A view showing the details for a landmark. +*/ + +import SwiftUI + +struct LandmarkDetail: View { + @EnvironmentObject var userData: UserData + var landmark: Landmark + + var landmarkIndex: Int { + userData.landmarks.firstIndex(where: { $0.id == landmark.id })! + } + + var body: some View { + VStack { + MapView(coordinate: landmark.locationCoordinate) + .edgesIgnoringSafeArea(.top) + .frame(height: 300) + + CircleImage(image: landmark.image(forSize: 250)) + .offset(x: 0, y: -130) + .padding(.bottom, -130) + + VStack(alignment: .leading) { + HStack { + Text(verbatim: landmark.name) + .font(.title) + + Button(action: { + self.userData.landmarks[self.landmarkIndex] + .isFavorite.toggle() + }) { + if self.userData.landmarks[self.landmarkIndex] + .isFavorite { + Image(systemName: "star.fill") + .foregroundColor(Color.yellow) + } else { + Image(systemName: "star") + .foregroundColor(Color.gray) + } + } + } + + HStack(alignment: .top) { + Text(verbatim: landmark.park) + .font(.subheadline) + Spacer() + Text(verbatim: landmark.state) + .font(.subheadline) + } + } + .padding() + + Spacer() + } + } +} + +#if DEBUG +struct LandmarkDetail_Preview: PreviewProvider { + static var previews: some View { + let userData = UserData() + return LandmarkDetail(landmark: userData.landmarks[0]) + .environmentObject(userData) + } +} +#endif diff --git a/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/LandmarkList.swift b/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/LandmarkList.swift new file mode 100644 index 0000000..665a08e --- /dev/null +++ b/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/LandmarkList.swift @@ -0,0 +1,46 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A view showing a list of landmarks. +*/ + +import SwiftUI + +struct LandmarkList: View { + @EnvironmentObject private var userData: UserData + + var body: some View { + NavigationView { + List { + Toggle(isOn: $userData.showFavoritesOnly) { + Text("Show Favorites Only") + } + + ForEach(userData.landmarks) { landmark in + if !self.userData.showFavoritesOnly || landmark.isFavorite { + NavigationLink( + destination: LandmarkDetail(landmark: landmark) + .environmentObject(self.userData)) { + LandmarkRow(landmark: landmark) + } + } + } + } + .navigationBarTitle(Text("Landmarks"), displayMode: .large) + } + } +} + +#if DEBUG +struct LandmarksList_Previews: PreviewProvider { + static var previews: some View { + ForEach(["iPhone SE", "iPhone XS Max"], id: \.self) { deviceName in + LandmarkList() + .previewDevice(PreviewDevice(rawValue: deviceName)) + .previewDisplayName(deviceName) + } + .environmentObject(UserData()) + } +} +#endif diff --git a/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/Models/Data.swift b/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/Models/Data.swift new file mode 100644 index 0000000..7248384 --- /dev/null +++ b/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/Models/Data.swift @@ -0,0 +1,93 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +Helpers for loading images and data. +*/ + +import UIKit +import SwiftUI +import CoreLocation + +let landmarkData: [Landmark] = load("landmarkData.json") + +func load(_ filename: String, as type: T.Type = T.self) -> T { + let data: Data + + guard let file = Bundle.main.url(forResource: filename, withExtension: nil) + else { + fatalError("Couldn't find \(filename) in main bundle.") + } + + do { + data = try Data(contentsOf: file) + } catch { + fatalError("Couldn't load \(filename) from main bundle:\n\(error)") + } + + do { + let decoder = JSONDecoder() + return try decoder.decode(T.self, from: data) + } catch { + fatalError("Couldn't parse \(filename) as \(T.self):\n\(error)") + } +} + +final class ImageStore { + fileprivate typealias _ImageDictionary = [String: [Int: CGImage]] + fileprivate var images: _ImageDictionary = [:] + + fileprivate static var originalSize = 250 + fileprivate static var scale = 2 + + static var shared = ImageStore() + + func image(name: String, size: Int) -> Image { + let index = _guaranteeInitialImage(name: name) + + let sizedImage = images.values[index][size] + ?? _sizeImage(images.values[index][ImageStore.originalSize]!, to: size * ImageStore.scale) + images.values[index][size] = sizedImage + + return Image(sizedImage, scale: CGFloat(ImageStore.scale), label: Text(verbatim: name)) + } + + fileprivate func _guaranteeInitialImage(name: String) -> _ImageDictionary.Index { + if let index = images.index(forKey: name) { return index } + + guard + let url = Bundle.main.url(forResource: name, withExtension: "jpg"), + let imageSource = CGImageSourceCreateWithURL(url as NSURL, nil), + let image = CGImageSourceCreateImageAtIndex(imageSource, 0, nil) + else { + fatalError("Couldn't load image \(name).jpg from main bundle.") + } + + images[name] = [ImageStore.originalSize: image] + return images.index(forKey: name)! + } + + fileprivate func _sizeImage(_ image: CGImage, to size: Int) -> CGImage { + guard + let colorSpace = image.colorSpace, + let context = CGContext( + data: nil, + width: size, height: size, + bitsPerComponent: image.bitsPerComponent, + bytesPerRow: image.bytesPerRow, + space: colorSpace, + bitmapInfo: image.bitmapInfo.rawValue) + else { + fatalError("Couldn't create graphics context.") + } + context.interpolationQuality = .high + context.draw(image, in: CGRect(x: 0, y: 0, width: size, height: size)) + + if let sizedImage = context.makeImage() { + return sizedImage + } else { + fatalError("Couldn't resize image.") + } + } +} + diff --git a/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/Models/Landmark.swift b/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/Models/Landmark.swift new file mode 100644 index 0000000..79b9aa4 --- /dev/null +++ b/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/Models/Landmark.swift @@ -0,0 +1,42 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +The model for an individual landmark. +*/ + +import SwiftUI +import CoreLocation + +struct Landmark: Hashable, Codable, Identifiable { + var id: Int + var name: String + fileprivate var imageName: String + fileprivate var coordinates: Coordinates + var state: String + var park: String + var category: Category + var isFavorite: Bool + + var locationCoordinate: CLLocationCoordinate2D { + CLLocationCoordinate2D( + latitude: coordinates.latitude, + longitude: coordinates.longitude) + } + + func image(forSize size: Int) -> Image { + ImageStore.shared.image(name: imageName, size: size) + } + + enum Category: String, CaseIterable, Codable, Hashable { + case featured = "Featured" + case lakes = "Lakes" + case rivers = "Rivers" + case mountains = "Mountains" + } +} + +struct Coordinates: Hashable, Codable { + var latitude: Double + var longitude: Double +} diff --git a/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/Models/UserData.swift b/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/Models/UserData.swift new file mode 100644 index 0000000..afc2cca --- /dev/null +++ b/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/Models/UserData.swift @@ -0,0 +1,15 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A model object that stores app data. +*/ + +import Combine +import SwiftUI + +final class UserData: ObservableObject { + @Published var showFavoritesOnly = false + + @Published var landmarks = landmarkData +} diff --git a/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/Preview Content/Preview Assets.xcassets/Contents.json b/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/Preview Content/Preview Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/Preview Content/Preview Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/Resources/charleyrivers.jpg b/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/Resources/charleyrivers.jpg new file mode 100644 index 0000000..17ff44b Binary files /dev/null and b/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/Resources/charleyrivers.jpg differ diff --git a/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/Resources/chilkoottrail.jpg b/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/Resources/chilkoottrail.jpg new file mode 100644 index 0000000..e7f805e Binary files /dev/null and b/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/Resources/chilkoottrail.jpg differ diff --git a/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/Resources/chincoteague.jpg b/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/Resources/chincoteague.jpg new file mode 100644 index 0000000..5f47986 Binary files /dev/null and b/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/Resources/chincoteague.jpg differ diff --git a/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/Resources/hiddenlake.jpg b/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/Resources/hiddenlake.jpg new file mode 100644 index 0000000..d8e804c Binary files /dev/null and b/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/Resources/hiddenlake.jpg differ diff --git a/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/Resources/icybay.jpg b/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/Resources/icybay.jpg new file mode 100644 index 0000000..feb1764 Binary files /dev/null and b/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/Resources/icybay.jpg differ diff --git a/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/Resources/lakemcdonald.jpg b/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/Resources/lakemcdonald.jpg new file mode 100644 index 0000000..bd9d6b9 Binary files /dev/null and b/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/Resources/lakemcdonald.jpg differ diff --git a/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/Resources/landmarkData.json b/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/Resources/landmarkData.json new file mode 100644 index 0000000..e5b14fc --- /dev/null +++ b/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/Resources/landmarkData.json @@ -0,0 +1,182 @@ +[ + { + "name": "Turtle Rock", + "category": "Rivers", + "city": "Twentynine Palms", + "state": "California", + "id": 1001, + "isFeatured": true, + "isFavorite": true, + "park": "Joshua Tree National Park", + "coordinates": { + "longitude": -116.166868, + "latitude": 34.011286 + }, + "imageName": "turtlerock" + }, + { + "name": "Silver Salmon Creek", + "category": "Lakes", + "city": "Port Alsworth", + "state": "Alaska", + "id": 1002, + "isFeatured": false, + "isFavorite": false, + "park": "Lake Clark National Park and Preserve", + "coordinates": { + "longitude": -152.665167, + "latitude": 59.980167 + }, + "imageName": "silversalmoncreek" + }, + { + "name": "Chilkoot Trail", + "category": "Mountains", + "city": "Skagway", + "state": "Alaska", + "id": 1003, + "isFeatured": false, + "isFavorite": true, + "park": "Klondike Gold Rush National Historical Park", + "coordinates": { + "longitude": -135.334571, + "latitude": 59.560551 + }, + "imageName": "chilkoottrail" + }, + { + "name": "St. Mary Lake", + "category": "Lakes", + "city": "Browning", + "state": "Montana", + "id": 1004, + "isFeatured": true, + "isFavorite": true, + "park": "Glacier National Park", + "coordinates": { + "longitude": -113.536248, + "latitude": 48.69423 + }, + "imageName": "stmarylake" + }, + { + "name": "Twin Lake", + "category": "Lakes", + "city": "Twin Lakes", + "state": "Alaska", + "id": 1005, + "isFeatured": false, + "isFavorite": false, + "park": "Lake Clark National Park and Preserve", + "coordinates": { + "longitude": -153.849883, + "latitude": 60.641684 + }, + "imageName": "twinlake" + }, + { + "name": "Lake McDonald", + "category": "Mountains", + "city": "West Glacier", + "state": "Montana", + "id": 1006, + "isFeatured": false, + "isFavorite": false, + "park": "Glacier National Park", + "coordinates": { + "longitude": -113.934831, + "latitude": 48.56002 + }, + "imageName": "lakemcdonald" + }, + { + "name": "Charley Rivers", + "category": "Rivers", + "city": "Eaking", + "state": "Alaska", + "id": 1007, + "isFeatured": true, + "isFavorite": false, + "park": "Charley Rivers National Preserve", + "coordinates": { + "longitude": -143.122586, + "latitude": 65.350021 + }, + "imageName": "charleyrivers", + }, + { + "name": "Icy Bay", + "category": "Mountains", + "city": "Icy Bay", + "state": "Alaska", + "id": 1008, + "isFeatured": false, + "isFavorite": false, + "park": "Wrangell-St. Elias National Park and Preserve", + "coordinates": { + "longitude": -141.518167, + "latitude": 60.089917 + }, + "imageName": "icybay" + }, + { + "name": "Rainbow Lake", + "category": "Lakes", + "city": "Willow", + "state": "Alaska", + "id": 1009, + "isFeatured": false, + "isFavorite": false, + "park": "State Recreation Area", + "coordinates": { + "longitude": -150.086103, + "latitude": 61.694334 + }, + "imageName": "rainbowlake" + }, + { + "name": "Hidden Lake", + "category": "Lakes", + "city": "Newhalem", + "state": "Washington", + "id": 1010, + "isFeatured": false, + "isFavorite": false, + "park": "North Cascades National Park", + "coordinates": { + "longitude": -121.17799, + "latitude": 48.495442 + }, + "imageName": "hiddenlake" + }, + { + "name": "Chincoteague", + "category": "Rivers", + "city": "Chincoteague", + "state": "Virginia", + "id": 1011, + "isFeatured": false, + "isFavorite": false, + "park": "Chincoteague National Wildlife Refuge", + "coordinates": { + "longitude": -75.383212, + "latitude": 37.91531 + }, + "imageName": "chincoteague" + }, + { + "name": "Lake Umbagog", + "category": "Lakes", + "city": "Errol", + "state": "New Hampshire", + "id": 1012, + "isFeatured": true, + "isFavorite": false, + "park": "Umbagog National Wildlife Refuge", + "coordinates": { + "longitude": -71.056816, + "latitude": 44.747408 + }, + "imageName": "umbagog" + } +] diff --git a/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/Resources/rainbowlake.jpg b/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/Resources/rainbowlake.jpg new file mode 100644 index 0000000..6da43dd Binary files /dev/null and b/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/Resources/rainbowlake.jpg differ diff --git a/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/Resources/silversalmoncreek.jpg b/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/Resources/silversalmoncreek.jpg new file mode 100644 index 0000000..f657532 Binary files /dev/null and b/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/Resources/silversalmoncreek.jpg differ diff --git a/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/Resources/stmarylake.jpg b/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/Resources/stmarylake.jpg new file mode 100644 index 0000000..1c71de4 Binary files /dev/null and b/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/Resources/stmarylake.jpg differ diff --git a/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/Resources/turtlerock.jpg b/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/Resources/turtlerock.jpg new file mode 100644 index 0000000..f7a6e6d Binary files /dev/null and b/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/Resources/turtlerock.jpg differ diff --git a/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/Resources/twinlake.jpg b/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/Resources/twinlake.jpg new file mode 100644 index 0000000..3e7a57c Binary files /dev/null and b/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/Resources/twinlake.jpg differ diff --git a/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/Resources/umbagog.jpg b/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/Resources/umbagog.jpg new file mode 100644 index 0000000..56291c6 Binary files /dev/null and b/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/Resources/umbagog.jpg differ diff --git a/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/SceneDelegate.swift b/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/SceneDelegate.swift new file mode 100644 index 0000000..a1104cc --- /dev/null +++ b/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/SceneDelegate.swift @@ -0,0 +1,58 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +The scene delegate. +*/ + +import UIKit +import SwiftUI + +class SceneDelegate: UIResponder, UIWindowSceneDelegate { + + var window: UIWindow? + + func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { + // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`. + // If using a storyboard, the `window` property will automatically be initialized and attached to the scene. + // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead). + + // Use a UIHostingController as window root view controller + if let windowScene = scene as? UIWindowScene { + let window = UIWindow(windowScene: windowScene) + window.rootViewController = UIHostingController(rootView: LandmarkList().environmentObject(UserData())) + self.window = window + window.makeKeyAndVisible() + } + } + + func sceneDidDisconnect(_ scene: UIScene) { + // Called as the scene is being released by the system. + // This occurs shortly after the scene enters the background, or when its session is discarded. + // Release any resources associated with this scene that can be re-created the next time the scene connects. + // The scene may re-connect later, as its session was not neccessarily discarded (see `application:didDiscardSceneSessions` instead). + } + + func sceneDidBecomeActive(_ scene: UIScene) { + // Called when the scene has moved from an inactive state to an active state. + // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive. + } + + func sceneWillResignActive(_ scene: UIScene) { + // Called when the scene will move from an active state to an inactive state. + // This may occur due to temporary interruptions (ex. an incoming phone call). + } + + func sceneWillEnterForeground(_ scene: UIScene) { + // Called as the scene transitions from the background to the foreground. + // Use this method to undo the changes made on entering the background. + } + + func sceneDidEnterBackground(_ scene: UIScene) { + // Called as the scene transitions from the foreground to the background. + // Use this method to save data, release shared resources, and store enough scene-specific state information + // to restore the scene back to its current state. + } + +} + diff --git a/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/Supporting Views/CircleImage.swift b/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/Supporting Views/CircleImage.swift new file mode 100644 index 0000000..ae44439 --- /dev/null +++ b/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/Supporting Views/CircleImage.swift @@ -0,0 +1,27 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A view that clips an image to a circle and adds a stroke and shadow. +*/ + +import SwiftUI + +struct CircleImage: View { + var image: Image + + var body: some View { + image + .clipShape(Circle()) + .overlay(Circle().stroke(Color.white, lineWidth: 4)) + .shadow(radius: 10) + } +} + +#if DEBUG +struct CircleImage_Previews: PreviewProvider { + static var previews: some View { + CircleImage(image: Image("turtlerock")) + } +} +#endif diff --git a/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/Supporting Views/LandmarkRow.swift b/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/Supporting Views/LandmarkRow.swift new file mode 100644 index 0000000..2f8110c --- /dev/null +++ b/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/Supporting Views/LandmarkRow.swift @@ -0,0 +1,38 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A single row to be displayed in a list of landmarks. +*/ + +import SwiftUI + +struct LandmarkRow: View { + var landmark: Landmark + + var body: some View { + HStack { + landmark.image(forSize: 50) + Text(verbatim: landmark.name) + Spacer() + + if landmark.isFavorite { + Image(systemName: "star.fill") + .imageScale(.medium) + .foregroundColor(.yellow) + } + } + } +} + +#if DEBUG +struct LandmarkRow_Previews: PreviewProvider { + static var previews: some View { + Group { + LandmarkRow(landmark: landmarkData[0]) + LandmarkRow(landmark: landmarkData[1]) + } + .previewLayout(.fixed(width: 300, height: 70)) + } +} +#endif diff --git a/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/Supporting Views/MapView.swift b/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/Supporting Views/MapView.swift new file mode 100644 index 0000000..5a8c64b --- /dev/null +++ b/Other Projects/Handling User Input/Complete/Landmarks/Landmarks/Supporting Views/MapView.swift @@ -0,0 +1,31 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A view that hosts an `MKMapView`. +*/ + +import SwiftUI +import MapKit + +struct MapView: UIViewRepresentable { + var coordinate: CLLocationCoordinate2D + + func makeUIView(context: Context) -> MKMapView { + MKMapView(frame: .zero) + } + + func updateUIView(_ view: MKMapView, context: Context) { + let span = MKCoordinateSpan(latitudeDelta: 0.02, longitudeDelta: 0.02) + let region = MKCoordinateRegion(center: coordinate, span: span) + view.setRegion(region, animated: true) + } +} + +#if DEBUG +struct MapView_Previews: PreviewProvider { + static var previews: some View { + MapView(coordinate: landmarkData[0].locationCoordinate) + } +} +#endif diff --git a/Other Projects/Handling User Input/Complete/README.md b/Other Projects/Handling User Input/Complete/README.md new file mode 100644 index 0000000..89559f8 --- /dev/null +++ b/Other Projects/Handling User Input/Complete/README.md @@ -0,0 +1,3 @@ +# Completed Project: Handling User Input + +Explore the completed project for the [Handling User Input](https://developer.apple.com/tutorials/swiftui/handling-user-input) tutorial. diff --git a/Other Projects/Handling User Input/StartingPoint/.gitignore b/Other Projects/Handling User Input/StartingPoint/.gitignore new file mode 100644 index 0000000..9e50718 --- /dev/null +++ b/Other Projects/Handling User Input/StartingPoint/.gitignore @@ -0,0 +1,21 @@ +# See LICENSE folder for this sample’s licensing information. +# +# Apple sample code gitignore configuration. + +# Finder +.DS_Store + +# Xcode - User files +xcuserdata/ + +**/*.xcodeproj/project.xcworkspace/* +!**/*.xcodeproj/project.xcworkspace/xcshareddata + +**/*.xcodeproj/project.xcworkspace/xcshareddata/* +!**/*.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings + +**/*.playground/playground.xcworkspace/* +!**/*.playground/playground.xcworkspace/xcshareddata + +**/*.playground/playground.xcworkspace/xcshareddata/* +!**/*.playground/playground.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings diff --git a/Other Projects/Handling User Input/StartingPoint/Configuration/SampleCode.xcconfig b/Other Projects/Handling User Input/StartingPoint/Configuration/SampleCode.xcconfig new file mode 100644 index 0000000..db86c06 --- /dev/null +++ b/Other Projects/Handling User Input/StartingPoint/Configuration/SampleCode.xcconfig @@ -0,0 +1,13 @@ +// +// See LICENSE folder for this sample’s licensing information. +// +// SampleCode.xcconfig +// + +// The `SAMPLE_CODE_DISAMBIGUATOR` configuration is to make it easier to build +// and run a sample code project. Once you set your project's development team, +// you'll have a unique bundle identifier. This is because the bundle identifier +// is derived based on the 'SAMPLE_CODE_DISAMBIGUATOR' value. Do not use this +// approach in your own projects—it's only useful for sample code projects because +// they are frequently downloaded and don't have a development team set. +SAMPLE_CODE_DISAMBIGUATOR=${DEVELOPMENT_TEAM} diff --git a/Other Projects/Handling User Input/StartingPoint/LICENSE/LICENSE.txt b/Other Projects/Handling User Input/StartingPoint/LICENSE/LICENSE.txt new file mode 100644 index 0000000..94e3d54 --- /dev/null +++ b/Other Projects/Handling User Input/StartingPoint/LICENSE/LICENSE.txt @@ -0,0 +1,8 @@ +Copyright © 2019 Apple Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + diff --git a/Other Projects/Handling User Input/StartingPoint/Landmarks/HandlingUserInput.xcodeproj/.xcodesamplecode.plist b/Other Projects/Handling User Input/StartingPoint/Landmarks/HandlingUserInput.xcodeproj/.xcodesamplecode.plist new file mode 100644 index 0000000..5dd5da8 --- /dev/null +++ b/Other Projects/Handling User Input/StartingPoint/Landmarks/HandlingUserInput.xcodeproj/.xcodesamplecode.plist @@ -0,0 +1,5 @@ + + + + + diff --git a/Other Projects/Handling User Input/StartingPoint/Landmarks/HandlingUserInput.xcodeproj/project.pbxproj b/Other Projects/Handling User Input/StartingPoint/Landmarks/HandlingUserInput.xcodeproj/project.pbxproj new file mode 100644 index 0000000..bb2fb8f --- /dev/null +++ b/Other Projects/Handling User Input/StartingPoint/Landmarks/HandlingUserInput.xcodeproj/project.pbxproj @@ -0,0 +1,477 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 50; + objects = { + +/* Begin PBXBuildFile section */ + B7394866229F194000C47603 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7394865229F194000C47603 /* AppDelegate.swift */; }; + B7394868229F194000C47603 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7394867229F194000C47603 /* SceneDelegate.swift */; }; + B739486A229F194000C47603 /* LandmarkDetail.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7394869229F194000C47603 /* LandmarkDetail.swift */; }; + B739486C229F194200C47603 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B739486B229F194200C47603 /* Assets.xcassets */; }; + B739486F229F194200C47603 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B739486E229F194200C47603 /* Preview Assets.xcassets */; }; + B7394872229F194200C47603 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B7394870229F194200C47603 /* LaunchScreen.storyboard */; }; + B739487A229F1B3F00C47603 /* CircleImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7394879229F1B3F00C47603 /* CircleImage.swift */; }; + B739487C229F1B6800C47603 /* MapView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B739487B229F1B6800C47603 /* MapView.swift */; }; + B7394881229F28B900C47603 /* Landmark.swift in Sources */ = {isa = PBXBuildFile; fileRef = B739487F229F28B900C47603 /* Landmark.swift */; }; + B7394882229F28B900C47603 /* Data.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7394880229F28B900C47603 /* Data.swift */; }; + B7394891229F292F00C47603 /* rainbowlake.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B7394884229F292D00C47603 /* rainbowlake.jpg */; }; + B7394893229F292F00C47603 /* icybay.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B7394886229F292E00C47603 /* icybay.jpg */; }; + B7394894229F292F00C47603 /* lakemcdonald.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B7394887229F292E00C47603 /* lakemcdonald.jpg */; }; + B7394895229F292F00C47603 /* turtlerock.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B7394888229F292E00C47603 /* turtlerock.jpg */; }; + B7394896229F292F00C47603 /* umbagog.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B7394889229F292E00C47603 /* umbagog.jpg */; }; + B7394897229F292F00C47603 /* hiddenlake.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B739488A229F292E00C47603 /* hiddenlake.jpg */; }; + B7394898229F292F00C47603 /* stmarylake.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B739488B229F292E00C47603 /* stmarylake.jpg */; }; + B7394899229F292F00C47603 /* twinlake.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B739488C229F292E00C47603 /* twinlake.jpg */; }; + B739489A229F292F00C47603 /* silversalmoncreek.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B739488D229F292E00C47603 /* silversalmoncreek.jpg */; }; + B739489B229F292F00C47603 /* landmarkData.json in Resources */ = {isa = PBXBuildFile; fileRef = B739488E229F292E00C47603 /* landmarkData.json */; }; + B739489C229F292F00C47603 /* chincoteague.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B739488F229F292F00C47603 /* chincoteague.jpg */; }; + B739489D229F292F00C47603 /* chilkoottrail.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B7394890229F292F00C47603 /* chilkoottrail.jpg */; }; + B739489F229F2D9700C47603 /* LandmarkRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = B739489E229F2D9700C47603 /* LandmarkRow.swift */; }; + B73948A1229F2E1F00C47603 /* LandmarkList.swift in Sources */ = {isa = PBXBuildFile; fileRef = B73948A0229F2E1F00C47603 /* LandmarkList.swift */; }; + B73948A3229F3E2200C47603 /* charleyrivers.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B73948A2229F3E2200C47603 /* charleyrivers.jpg */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 5C0310E05C01FC6000000001 /* SampleCode.xcconfig */ = {isa = PBXFileReference; name = SampleCode.xcconfig; path = ../Configuration/SampleCode.xcconfig; sourceTree = ""; }; + 5C52ED405C52E8B000000001 /* LICENSE.txt */ = {isa = PBXFileReference; includeInIndex = 1; path = LICENSE.txt; sourceTree = ""; }; + B7394862229F194000C47603 /* Landmarks.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Landmarks.app; sourceTree = BUILT_PRODUCTS_DIR; }; + B7394865229F194000C47603 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + B7394867229F194000C47603 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; + B7394869229F194000C47603 /* LandmarkDetail.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LandmarkDetail.swift; sourceTree = ""; }; + B739486B229F194200C47603 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + B739486E229F194200C47603 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; + B7394871229F194200C47603 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + B7394873229F194200C47603 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + B7394879229F1B3F00C47603 /* CircleImage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CircleImage.swift; sourceTree = ""; }; + B739487B229F1B6800C47603 /* MapView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapView.swift; sourceTree = ""; }; + B739487F229F28B900C47603 /* Landmark.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Landmark.swift; sourceTree = ""; }; + B7394880229F28B900C47603 /* Data.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Data.swift; sourceTree = ""; }; + B7394884229F292D00C47603 /* rainbowlake.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = rainbowlake.jpg; sourceTree = ""; }; + B7394886229F292E00C47603 /* icybay.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = icybay.jpg; sourceTree = ""; }; + B7394887229F292E00C47603 /* lakemcdonald.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = lakemcdonald.jpg; sourceTree = ""; }; + B7394888229F292E00C47603 /* turtlerock.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = turtlerock.jpg; sourceTree = ""; }; + B7394889229F292E00C47603 /* umbagog.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = umbagog.jpg; sourceTree = ""; }; + B739488A229F292E00C47603 /* hiddenlake.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = hiddenlake.jpg; sourceTree = ""; }; + B739488B229F292E00C47603 /* stmarylake.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = stmarylake.jpg; sourceTree = ""; }; + B739488C229F292E00C47603 /* twinlake.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = twinlake.jpg; sourceTree = ""; }; + B739488D229F292E00C47603 /* silversalmoncreek.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = silversalmoncreek.jpg; sourceTree = ""; }; + B739488E229F292E00C47603 /* landmarkData.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = landmarkData.json; sourceTree = ""; }; + B739488F229F292F00C47603 /* chincoteague.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = chincoteague.jpg; sourceTree = ""; }; + B7394890229F292F00C47603 /* chilkoottrail.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = chilkoottrail.jpg; sourceTree = ""; }; + B739489E229F2D9700C47603 /* LandmarkRow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = LandmarkRow.swift; path = "Supporting Views/LandmarkRow.swift"; sourceTree = ""; }; + B73948A0229F2E1F00C47603 /* LandmarkList.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LandmarkList.swift; sourceTree = ""; }; + B73948A2229F3E2200C47603 /* charleyrivers.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = charleyrivers.jpg; sourceTree = ""; }; + C4E4AAA0C4E4035000000001 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; name = README.md; path = ../README.md; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + B739485F229F194000C47603 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 5C0225D05C02F54000000001 /* Configuration */ = { + isa = PBXGroup; + children = ( + 5C0310E05C01FC6000000001 /* SampleCode.xcconfig */, + ); + name = Configuration; + sourceTree = ""; + }; + 5C52DEF05C52DC5000000001 /* LICENSE */ = { + isa = PBXGroup; + children = ( + 5C52ED405C52E8B000000001 /* LICENSE.txt */, + ); + name = LICENSE; + path = ../LICENSE; + sourceTree = ""; + }; + B7394859229F194000C47603 = { + isa = PBXGroup; + children = ( + C4E4AAA0C4E4035000000001 /* README.md */, + B7394864229F194000C47603 /* Landmarks */, + B7394863229F194000C47603 /* Products */, + 5C0225D05C02F54000000001 /* Configuration */, + 5C52DEF05C52DC5000000001 /* LICENSE */, + ); + sourceTree = ""; + }; + B7394863229F194000C47603 /* Products */ = { + isa = PBXGroup; + children = ( + B7394862229F194000C47603 /* Landmarks.app */, + ); + name = Products; + sourceTree = ""; + }; + B7394864229F194000C47603 /* Landmarks */ = { + isa = PBXGroup; + children = ( + B739487E229F282200C47603 /* Models */, + B7394865229F194000C47603 /* AppDelegate.swift */, + B7394867229F194000C47603 /* SceneDelegate.swift */, + B73948A0229F2E1F00C47603 /* LandmarkList.swift */, + B739489E229F2D9700C47603 /* LandmarkRow.swift */, + B7394869229F194000C47603 /* LandmarkDetail.swift */, + B739487D229F1C0100C47603 /* Supporting Views */, + B7394883229F291A00C47603 /* Resources */, + B739486B229F194200C47603 /* Assets.xcassets */, + B7394870229F194200C47603 /* LaunchScreen.storyboard */, + B7394873229F194200C47603 /* Info.plist */, + B739486D229F194200C47603 /* Preview Content */, + ); + path = Landmarks; + sourceTree = ""; + }; + B739486D229F194200C47603 /* Preview Content */ = { + isa = PBXGroup; + children = ( + B739486E229F194200C47603 /* Preview Assets.xcassets */, + ); + path = "Preview Content"; + sourceTree = ""; + }; + B739487D229F1C0100C47603 /* Supporting Views */ = { + isa = PBXGroup; + children = ( + B7394879229F1B3F00C47603 /* CircleImage.swift */, + B739487B229F1B6800C47603 /* MapView.swift */, + ); + path = "Supporting Views"; + sourceTree = ""; + }; + B739487E229F282200C47603 /* Models */ = { + isa = PBXGroup; + children = ( + B7394880229F28B900C47603 /* Data.swift */, + B739487F229F28B900C47603 /* Landmark.swift */, + ); + path = Models; + sourceTree = ""; + }; + B7394883229F291A00C47603 /* Resources */ = { + isa = PBXGroup; + children = ( + B739488E229F292E00C47603 /* landmarkData.json */, + B7394890229F292F00C47603 /* chilkoottrail.jpg */, + B739488F229F292F00C47603 /* chincoteague.jpg */, + B739488A229F292E00C47603 /* hiddenlake.jpg */, + B7394886229F292E00C47603 /* icybay.jpg */, + B7394887229F292E00C47603 /* lakemcdonald.jpg */, + B7394884229F292D00C47603 /* rainbowlake.jpg */, + B739488D229F292E00C47603 /* silversalmoncreek.jpg */, + B739488B229F292E00C47603 /* stmarylake.jpg */, + B7394888229F292E00C47603 /* turtlerock.jpg */, + B739488C229F292E00C47603 /* twinlake.jpg */, + B7394889229F292E00C47603 /* umbagog.jpg */, + B73948A2229F3E2200C47603 /* charleyrivers.jpg */, + ); + path = Resources; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + B7394861229F194000C47603 /* Landmarks */ = { + isa = PBXNativeTarget; + buildConfigurationList = B7394876229F194200C47603 /* Build configuration list for PBXNativeTarget "Landmarks" */; + buildPhases = ( + B739485E229F194000C47603 /* Sources */, + B739485F229F194000C47603 /* Frameworks */, + B7394860229F194000C47603 /* Resources */, + C602AC70C605937000000001, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Landmarks; + productName = Landmarks; + productReference = B7394862229F194000C47603 /* Landmarks.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + B739485A229F194000C47603 /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 1100; + LastUpgradeCheck = 1100; + ORGANIZATIONNAME = Apple; + TargetAttributes = { + B7394861229F194000C47603 = { + CreatedOnToolsVersion = 11.0; + }; + }; + }; + buildConfigurationList = B739485D229F194000C47603 /* Build configuration list for PBXProject "HandlingUserInput" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = B7394859229F194000C47603; + productRefGroup = B7394863229F194000C47603 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + B7394861229F194000C47603 /* Landmarks */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + B7394860229F194000C47603 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + B739489A229F292F00C47603 /* silversalmoncreek.jpg in Resources */, + B7394894229F292F00C47603 /* lakemcdonald.jpg in Resources */, + B7394872229F194200C47603 /* LaunchScreen.storyboard in Resources */, + B73948A3229F3E2200C47603 /* charleyrivers.jpg in Resources */, + B7394891229F292F00C47603 /* rainbowlake.jpg in Resources */, + B739486F229F194200C47603 /* Preview Assets.xcassets in Resources */, + B7394895229F292F00C47603 /* turtlerock.jpg in Resources */, + B739486C229F194200C47603 /* Assets.xcassets in Resources */, + B7394899229F292F00C47603 /* twinlake.jpg in Resources */, + B7394896229F292F00C47603 /* umbagog.jpg in Resources */, + B739489D229F292F00C47603 /* chilkoottrail.jpg in Resources */, + B739489C229F292F00C47603 /* chincoteague.jpg in Resources */, + B739489B229F292F00C47603 /* landmarkData.json in Resources */, + B7394893229F292F00C47603 /* icybay.jpg in Resources */, + B7394897229F292F00C47603 /* hiddenlake.jpg in Resources */, + B7394898229F292F00C47603 /* stmarylake.jpg in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + B739485E229F194000C47603 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + B7394882229F28B900C47603 /* Data.swift in Sources */, + B7394866229F194000C47603 /* AppDelegate.swift in Sources */, + B739487A229F1B3F00C47603 /* CircleImage.swift in Sources */, + B739487C229F1B6800C47603 /* MapView.swift in Sources */, + B73948A1229F2E1F00C47603 /* LandmarkList.swift in Sources */, + B7394868229F194000C47603 /* SceneDelegate.swift in Sources */, + B739486A229F194000C47603 /* LandmarkDetail.swift in Sources */, + B739489F229F2D9700C47603 /* LandmarkRow.swift in Sources */, + B7394881229F28B900C47603 /* Landmark.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + B7394870229F194200C47603 /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + B7394871229F194200C47603 /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + B7394874229F194200C47603 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 5C0310E05C01FC6000000001 /* SampleCode.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + B7394875229F194200C47603 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 5C0310E05C01FC6000000001 /* SampleCode.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + B7394877229F194200C47603 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 5C0310E05C01FC6000000001 /* SampleCode.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_ASSET_PATHS = "Landmarks/Preview\\ Content"; + DEVELOPMENT_TEAM = ""; + ENABLE_PREVIEWS = YES; + INFOPLIST_FILE = Landmarks/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = "com.example.apple-samplecode.Landmarks${SAMPLE_CODE_DISAMBIGUATOR}"; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + B7394878229F194200C47603 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 5C0310E05C01FC6000000001 /* SampleCode.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_ASSET_PATHS = "Landmarks/Preview\\ Content"; + DEVELOPMENT_TEAM = ""; + ENABLE_PREVIEWS = YES; + INFOPLIST_FILE = Landmarks/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = "com.example.apple-samplecode.Landmarks${SAMPLE_CODE_DISAMBIGUATOR}"; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + B739485D229F194000C47603 /* Build configuration list for PBXProject "HandlingUserInput" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + B7394874229F194200C47603 /* Debug */, + B7394875229F194200C47603 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + B7394876229F194200C47603 /* Build configuration list for PBXNativeTarget "Landmarks" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + B7394877229F194200C47603 /* Debug */, + B7394878229F194200C47603 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = B739485A229F194000C47603 /* Project object */; +} diff --git a/Other Projects/Handling User Input/StartingPoint/Landmarks/HandlingUserInput.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/Other Projects/Handling User Input/StartingPoint/Landmarks/HandlingUserInput.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 0000000..3ddf867 --- /dev/null +++ b/Other Projects/Handling User Input/StartingPoint/Landmarks/HandlingUserInput.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,8 @@ + + + + + BuildSystemType + Latest + + diff --git a/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/AppDelegate.swift b/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/AppDelegate.swift new file mode 100644 index 0000000..e22943b --- /dev/null +++ b/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/AppDelegate.swift @@ -0,0 +1,36 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +The application delegate. +*/ + +import UIKit + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { + // Override point for customization after application launch. + return true + } + + func applicationWillTerminate(_ application: UIApplication) { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. + } + + // MARK: UISceneSession Lifecycle + func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration { + // Called when a new scene session is being created. + // Use this method to select a configuration to create the new scene with. + return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role) + } + + func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) { + // Called when the user discards a scene session. + // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions. + // Use this method to release any resources that were specific to the discarded scenes, as they will not return. + } + +} + diff --git a/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/Contents.json b/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..fa0d2db --- /dev/null +++ b/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,113 @@ +{ + "images" : [ + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "landmark_app_icon_40x40.png", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "3x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "landmark_app_icon_58x58.png", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "landmark_app_icon_87x87.png", + "scale" : "3x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "landmark_app_icon_80x80.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "landmark_app_icon_120x120.png", + "scale" : "3x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "landmark_app_icon_120x120-1.png", + "scale" : "2x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "landmark_app_icon_180x180.png", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "1x" + }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "landmark_app_icon_40x40-1.png", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "landmark_app_icon_58x58-1.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "landmark_app_icon_40x40-2.png", + "scale" : "1x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "landmark_app_icon_80x80-1.png", + "scale" : "2x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "landmark_app_icon_76x76.png", + "scale" : "1x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "landmark_app_icon_152x152.png", + "scale" : "2x" + }, + { + "size" : "83.5x83.5", + "idiom" : "ipad", + "filename" : "landmark_app_icon_167x167.png", + "scale" : "2x" + }, + { + "size" : "1024x1024", + "idiom" : "ios-marketing", + "filename" : "landmark_app_icon_1024x1024.png", + "scale" : "1x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_1024x1024.png b/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_1024x1024.png new file mode 100644 index 0000000..00d81c1 Binary files /dev/null and b/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_1024x1024.png differ diff --git a/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_120x120-1.png b/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_120x120-1.png new file mode 100644 index 0000000..d382b8b Binary files /dev/null and b/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_120x120-1.png differ diff --git a/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_120x120.png b/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_120x120.png new file mode 100644 index 0000000..d382b8b Binary files /dev/null and b/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_120x120.png differ diff --git a/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_152x152.png b/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_152x152.png new file mode 100644 index 0000000..11057f8 Binary files /dev/null and b/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_152x152.png differ diff --git a/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_167x167.png b/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_167x167.png new file mode 100644 index 0000000..f73bc26 Binary files /dev/null and b/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_167x167.png differ diff --git a/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_180x180.png b/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_180x180.png new file mode 100644 index 0000000..b02738c Binary files /dev/null and b/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_180x180.png differ diff --git a/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40-1.png b/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40-1.png new file mode 100644 index 0000000..abaff0e Binary files /dev/null and b/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40-1.png differ diff --git a/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40-2.png b/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40-2.png new file mode 100644 index 0000000..abaff0e Binary files /dev/null and b/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40-2.png differ diff --git a/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40.png b/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40.png new file mode 100644 index 0000000..abaff0e Binary files /dev/null and b/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40.png differ diff --git a/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_58x58-1.png b/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_58x58-1.png new file mode 100644 index 0000000..cf7c73d Binary files /dev/null and b/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_58x58-1.png differ diff --git a/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_58x58.png b/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_58x58.png new file mode 100644 index 0000000..cf7c73d Binary files /dev/null and b/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_58x58.png differ diff --git a/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_76x76.png b/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_76x76.png new file mode 100644 index 0000000..3eff85b Binary files /dev/null and b/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_76x76.png differ diff --git a/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_80x80-1.png b/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_80x80-1.png new file mode 100644 index 0000000..6f33f66 Binary files /dev/null and b/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_80x80-1.png differ diff --git a/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_80x80.png b/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_80x80.png new file mode 100644 index 0000000..6f33f66 Binary files /dev/null and b/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_80x80.png differ diff --git a/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_87x87.png b/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_87x87.png new file mode 100644 index 0000000..9e1616c Binary files /dev/null and b/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_87x87.png differ diff --git a/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/Assets.xcassets/Contents.json b/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/Assets.xcassets/turtlerock.imageset/Contents.json b/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/Assets.xcassets/turtlerock.imageset/Contents.json new file mode 100644 index 0000000..5bfd7bf --- /dev/null +++ b/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/Assets.xcassets/turtlerock.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "turtlerock.jpg", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/Assets.xcassets/turtlerock.imageset/turtlerock.jpg b/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/Assets.xcassets/turtlerock.imageset/turtlerock.jpg new file mode 100644 index 0000000..68bcd3e Binary files /dev/null and b/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/Assets.xcassets/turtlerock.imageset/turtlerock.jpg differ diff --git a/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/Base.lproj/LaunchScreen.storyboard b/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000..865e932 --- /dev/null +++ b/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/Info.plist b/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/Info.plist new file mode 100644 index 0000000..e8bb4c6 --- /dev/null +++ b/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/Info.plist @@ -0,0 +1,62 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + $(PRODUCT_BUNDLE_PACKAGE_TYPE) + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UIApplicationSceneManifest + + UIApplicationSupportsMultipleScenes + + UISceneConfigurations + + UIWindowSceneSessionRoleApplication + + + UILaunchStoryboardName + LaunchScreen + UISceneConfigurationName + Default Configuration + UISceneDelegateClassName + $(PRODUCT_MODULE_NAME).SceneDelegate + + + + + UILaunchStoryboardName + LaunchScreen + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/LandmarkDetail.swift b/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/LandmarkDetail.swift new file mode 100644 index 0000000..e957172 --- /dev/null +++ b/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/LandmarkDetail.swift @@ -0,0 +1,48 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A view showing the details for a landmark. +*/ + +import SwiftUI + +struct LandmarkDetail: View { + var landmark: Landmark + + var body: some View { + VStack { + MapView(coordinate: landmark.locationCoordinate) + .frame(height: 300) + + CircleImage(image: landmark.image(forSize: 250)) + .offset(x: 0, y: -130) + .padding(.bottom, -130) + + VStack(alignment: .leading) { + Text(landmark.name) + .font(.title) + + HStack(alignment: .top) { + Text(landmark.park) + .font(.subheadline) + Spacer() + Text(landmark.state) + .font(.subheadline) + } + } + .padding() + + Spacer() + } + .navigationBarTitle(Text(verbatim: landmark.name), displayMode: .inline) + } +} + +#if DEBUG +struct LandmarkDetail_Previews: PreviewProvider { + static var previews: some View { + LandmarkDetail(landmark: landmarkData[0]) + } +} +#endif diff --git a/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/LandmarkList.swift b/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/LandmarkList.swift new file mode 100644 index 0000000..1c5b7ee --- /dev/null +++ b/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/LandmarkList.swift @@ -0,0 +1,33 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A view showing a list of landmarks. +*/ + +import SwiftUI + +struct LandmarkList: View { + var body: some View { + NavigationView { + List(landmarkData) { landmark in + NavigationButton(destination: LandmarkDetail(landmark: landmark)) { + LandmarkRow(landmark: landmark) + } + } + .navigationBarTitle(Text("Landmarks"), displayMode: .large) + } + } +} + +#if DEBUG +struct LandmarkList_Previews: PreviewProvider { + static var previews: some View { + ForEach(["iPhone SE", "iPhone XS Max"].identified(by: \.self)) { deviceName in + LandmarkList() + .previewDevice(PreviewDevice(rawValue: deviceName)) + .previewDisplayName(deviceName) + } + } +} +#endif diff --git a/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/Models/Data.swift b/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/Models/Data.swift new file mode 100644 index 0000000..78837f6 --- /dev/null +++ b/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/Models/Data.swift @@ -0,0 +1,93 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +Helpers for loading images and data. +*/ + +import UIKit +import SwiftUI +import CoreLocation + +let landmarkData: [Landmark] = load("landmarkData.json") + +func load(_ filename: String, as type: T.Type = T.self) -> T { + let data: Data + + guard let file = Bundle.main.url(forResource: filename, withExtension: nil) + else { + fatalError("Couldn't find \(filename) in main bundle.") + } + + do { + data = try Data(contentsOf: file) + } catch { + fatalError("Couldn't load \(filename) from main bundle:\n\(error)") + } + + do { + let decoder = JSONDecoder() + return try decoder.decode(T.self, from: data) + } catch { + fatalError("Couldn't parse \(filename) as \(T.self):\n\(error)") + } +} + +final class ImageStore { + fileprivate typealias _ImageDictionary = [String: [Int: CGImage]] + fileprivate var images: _ImageDictionary = [:] + + fileprivate static var originalSize = 250 + fileprivate static var scale = 2 + + static var shared = ImageStore() + + func image(name: String, size: Int) -> Image { + let index = _guaranteeInitialImage(name: name) + + let sizedImage = images.values[index][size] + ?? _sizeImage(images.values[index][ImageStore.originalSize]!, to: size * ImageStore.scale) + images.values[index][size] = sizedImage + + return Image(sizedImage, scale: Length(ImageStore.scale), label: Text(verbatim: name)) + } + + fileprivate func _guaranteeInitialImage(name: String) -> _ImageDictionary.Index { + if let index = images.index(forKey: name) { return index } + + guard + let url = Bundle.main.url(forResource: name, withExtension: "jpg"), + let imageSource = CGImageSourceCreateWithURL(url as NSURL, nil), + let image = CGImageSourceCreateImageAtIndex(imageSource, 0, nil) + else { + fatalError("Couldn't load image \(name).jpg from main bundle.") + } + + images[name] = [ImageStore.originalSize: image] + return images.index(forKey: name)! + } + + fileprivate func _sizeImage(_ image: CGImage, to size: Int) -> CGImage { + guard + let colorSpace = image.colorSpace, + let context = CGContext( + data: nil, + width: size, height: size, + bitsPerComponent: image.bitsPerComponent, + bytesPerRow: image.bytesPerRow, + space: colorSpace, + bitmapInfo: image.bitmapInfo.rawValue) + else { + fatalError("Couldn't create graphics context.") + } + context.interpolationQuality = .high + context.draw(image, in: CGRect(x: 0, y: 0, width: size, height: size)) + + if let sizedImage = context.makeImage() { + return sizedImage + } else { + fatalError("Couldn't resize image.") + } + } +} + diff --git a/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/Models/Landmark.swift b/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/Models/Landmark.swift new file mode 100644 index 0000000..79b9aa4 --- /dev/null +++ b/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/Models/Landmark.swift @@ -0,0 +1,42 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +The model for an individual landmark. +*/ + +import SwiftUI +import CoreLocation + +struct Landmark: Hashable, Codable, Identifiable { + var id: Int + var name: String + fileprivate var imageName: String + fileprivate var coordinates: Coordinates + var state: String + var park: String + var category: Category + var isFavorite: Bool + + var locationCoordinate: CLLocationCoordinate2D { + CLLocationCoordinate2D( + latitude: coordinates.latitude, + longitude: coordinates.longitude) + } + + func image(forSize size: Int) -> Image { + ImageStore.shared.image(name: imageName, size: size) + } + + enum Category: String, CaseIterable, Codable, Hashable { + case featured = "Featured" + case lakes = "Lakes" + case rivers = "Rivers" + case mountains = "Mountains" + } +} + +struct Coordinates: Hashable, Codable { + var latitude: Double + var longitude: Double +} diff --git a/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/Preview Content/Preview Assets.xcassets/Contents.json b/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/Preview Content/Preview Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/Preview Content/Preview Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/Resources/charleyrivers.jpg b/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/Resources/charleyrivers.jpg new file mode 100644 index 0000000..17ff44b Binary files /dev/null and b/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/Resources/charleyrivers.jpg differ diff --git a/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/Resources/chilkoottrail.jpg b/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/Resources/chilkoottrail.jpg new file mode 100644 index 0000000..e7f805e Binary files /dev/null and b/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/Resources/chilkoottrail.jpg differ diff --git a/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/Resources/chincoteague.jpg b/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/Resources/chincoteague.jpg new file mode 100644 index 0000000..5f47986 Binary files /dev/null and b/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/Resources/chincoteague.jpg differ diff --git a/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/Resources/hiddenlake.jpg b/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/Resources/hiddenlake.jpg new file mode 100644 index 0000000..d8e804c Binary files /dev/null and b/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/Resources/hiddenlake.jpg differ diff --git a/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/Resources/icybay.jpg b/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/Resources/icybay.jpg new file mode 100644 index 0000000..feb1764 Binary files /dev/null and b/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/Resources/icybay.jpg differ diff --git a/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/Resources/lakemcdonald.jpg b/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/Resources/lakemcdonald.jpg new file mode 100644 index 0000000..bd9d6b9 Binary files /dev/null and b/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/Resources/lakemcdonald.jpg differ diff --git a/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/Resources/landmarkData.json b/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/Resources/landmarkData.json new file mode 100644 index 0000000..e5b14fc --- /dev/null +++ b/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/Resources/landmarkData.json @@ -0,0 +1,182 @@ +[ + { + "name": "Turtle Rock", + "category": "Rivers", + "city": "Twentynine Palms", + "state": "California", + "id": 1001, + "isFeatured": true, + "isFavorite": true, + "park": "Joshua Tree National Park", + "coordinates": { + "longitude": -116.166868, + "latitude": 34.011286 + }, + "imageName": "turtlerock" + }, + { + "name": "Silver Salmon Creek", + "category": "Lakes", + "city": "Port Alsworth", + "state": "Alaska", + "id": 1002, + "isFeatured": false, + "isFavorite": false, + "park": "Lake Clark National Park and Preserve", + "coordinates": { + "longitude": -152.665167, + "latitude": 59.980167 + }, + "imageName": "silversalmoncreek" + }, + { + "name": "Chilkoot Trail", + "category": "Mountains", + "city": "Skagway", + "state": "Alaska", + "id": 1003, + "isFeatured": false, + "isFavorite": true, + "park": "Klondike Gold Rush National Historical Park", + "coordinates": { + "longitude": -135.334571, + "latitude": 59.560551 + }, + "imageName": "chilkoottrail" + }, + { + "name": "St. Mary Lake", + "category": "Lakes", + "city": "Browning", + "state": "Montana", + "id": 1004, + "isFeatured": true, + "isFavorite": true, + "park": "Glacier National Park", + "coordinates": { + "longitude": -113.536248, + "latitude": 48.69423 + }, + "imageName": "stmarylake" + }, + { + "name": "Twin Lake", + "category": "Lakes", + "city": "Twin Lakes", + "state": "Alaska", + "id": 1005, + "isFeatured": false, + "isFavorite": false, + "park": "Lake Clark National Park and Preserve", + "coordinates": { + "longitude": -153.849883, + "latitude": 60.641684 + }, + "imageName": "twinlake" + }, + { + "name": "Lake McDonald", + "category": "Mountains", + "city": "West Glacier", + "state": "Montana", + "id": 1006, + "isFeatured": false, + "isFavorite": false, + "park": "Glacier National Park", + "coordinates": { + "longitude": -113.934831, + "latitude": 48.56002 + }, + "imageName": "lakemcdonald" + }, + { + "name": "Charley Rivers", + "category": "Rivers", + "city": "Eaking", + "state": "Alaska", + "id": 1007, + "isFeatured": true, + "isFavorite": false, + "park": "Charley Rivers National Preserve", + "coordinates": { + "longitude": -143.122586, + "latitude": 65.350021 + }, + "imageName": "charleyrivers", + }, + { + "name": "Icy Bay", + "category": "Mountains", + "city": "Icy Bay", + "state": "Alaska", + "id": 1008, + "isFeatured": false, + "isFavorite": false, + "park": "Wrangell-St. Elias National Park and Preserve", + "coordinates": { + "longitude": -141.518167, + "latitude": 60.089917 + }, + "imageName": "icybay" + }, + { + "name": "Rainbow Lake", + "category": "Lakes", + "city": "Willow", + "state": "Alaska", + "id": 1009, + "isFeatured": false, + "isFavorite": false, + "park": "State Recreation Area", + "coordinates": { + "longitude": -150.086103, + "latitude": 61.694334 + }, + "imageName": "rainbowlake" + }, + { + "name": "Hidden Lake", + "category": "Lakes", + "city": "Newhalem", + "state": "Washington", + "id": 1010, + "isFeatured": false, + "isFavorite": false, + "park": "North Cascades National Park", + "coordinates": { + "longitude": -121.17799, + "latitude": 48.495442 + }, + "imageName": "hiddenlake" + }, + { + "name": "Chincoteague", + "category": "Rivers", + "city": "Chincoteague", + "state": "Virginia", + "id": 1011, + "isFeatured": false, + "isFavorite": false, + "park": "Chincoteague National Wildlife Refuge", + "coordinates": { + "longitude": -75.383212, + "latitude": 37.91531 + }, + "imageName": "chincoteague" + }, + { + "name": "Lake Umbagog", + "category": "Lakes", + "city": "Errol", + "state": "New Hampshire", + "id": 1012, + "isFeatured": true, + "isFavorite": false, + "park": "Umbagog National Wildlife Refuge", + "coordinates": { + "longitude": -71.056816, + "latitude": 44.747408 + }, + "imageName": "umbagog" + } +] diff --git a/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/Resources/rainbowlake.jpg b/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/Resources/rainbowlake.jpg new file mode 100644 index 0000000..6da43dd Binary files /dev/null and b/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/Resources/rainbowlake.jpg differ diff --git a/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/Resources/silversalmoncreek.jpg b/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/Resources/silversalmoncreek.jpg new file mode 100644 index 0000000..f657532 Binary files /dev/null and b/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/Resources/silversalmoncreek.jpg differ diff --git a/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/Resources/stmarylake.jpg b/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/Resources/stmarylake.jpg new file mode 100644 index 0000000..1c71de4 Binary files /dev/null and b/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/Resources/stmarylake.jpg differ diff --git a/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/Resources/turtlerock.jpg b/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/Resources/turtlerock.jpg new file mode 100644 index 0000000..f7a6e6d Binary files /dev/null and b/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/Resources/turtlerock.jpg differ diff --git a/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/Resources/twinlake.jpg b/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/Resources/twinlake.jpg new file mode 100644 index 0000000..3e7a57c Binary files /dev/null and b/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/Resources/twinlake.jpg differ diff --git a/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/Resources/umbagog.jpg b/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/Resources/umbagog.jpg new file mode 100644 index 0000000..56291c6 Binary files /dev/null and b/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/Resources/umbagog.jpg differ diff --git a/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/SceneDelegate.swift b/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/SceneDelegate.swift new file mode 100644 index 0000000..c4d69a9 --- /dev/null +++ b/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/SceneDelegate.swift @@ -0,0 +1,56 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +The scene delegate. +*/ + +import UIKit +import SwiftUI + +class SceneDelegate: UIResponder, UIWindowSceneDelegate { + + var window: UIWindow? + + func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { + // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`. + // If using a storyboard, the `window` property will automatically be initialized and attached to the scene. + // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead). + + // Use a UIHostingController as window root view controller + let window = UIWindow(frame: UIScreen.main.bounds) + window.rootViewController = UIHostingController(rootView: LandmarkList()) + self.window = window + window.makeKeyAndVisible() + } + + func sceneDidDisconnect(_ scene: UIScene) { + // Called as the scene is being released by the system. + // This occurs shortly after the scene enters the background, or when its session is discarded. + // Release any resources associated with this scene that can be re-created the next time the scene connects. + // The scene may re-connect later, as its session was not neccessarily discarded (see `application:didDiscardSceneSessions` instead). + } + + func sceneDidBecomeActive(_ scene: UIScene) { + // Called when the scene has moved from an inactive state to an active state. + // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive. + } + + func sceneWillResignActive(_ scene: UIScene) { + // Called when the scene will move from an active state to an inactive state. + // This may occur due to temporary interruptions (ex. an incoming phone call). + } + + func sceneWillEnterForeground(_ scene: UIScene) { + // Called as the scene transitions from the background to the foreground. + // Use this method to undo the changes made on entering the background. + } + + func sceneDidEnterBackground(_ scene: UIScene) { + // Called as the scene transitions from the foreground to the background. + // Use this method to save data, release shared resources, and store enough scene-specific state information + // to restore the scene back to its current state. + } + +} + diff --git a/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/Supporting Views/CircleImage.swift b/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/Supporting Views/CircleImage.swift new file mode 100644 index 0000000..ae44439 --- /dev/null +++ b/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/Supporting Views/CircleImage.swift @@ -0,0 +1,27 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A view that clips an image to a circle and adds a stroke and shadow. +*/ + +import SwiftUI + +struct CircleImage: View { + var image: Image + + var body: some View { + image + .clipShape(Circle()) + .overlay(Circle().stroke(Color.white, lineWidth: 4)) + .shadow(radius: 10) + } +} + +#if DEBUG +struct CircleImage_Previews: PreviewProvider { + static var previews: some View { + CircleImage(image: Image("turtlerock")) + } +} +#endif diff --git a/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/Supporting Views/LandmarkRow.swift b/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/Supporting Views/LandmarkRow.swift new file mode 100644 index 0000000..2f8110c --- /dev/null +++ b/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/Supporting Views/LandmarkRow.swift @@ -0,0 +1,38 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A single row to be displayed in a list of landmarks. +*/ + +import SwiftUI + +struct LandmarkRow: View { + var landmark: Landmark + + var body: some View { + HStack { + landmark.image(forSize: 50) + Text(verbatim: landmark.name) + Spacer() + + if landmark.isFavorite { + Image(systemName: "star.fill") + .imageScale(.medium) + .foregroundColor(.yellow) + } + } + } +} + +#if DEBUG +struct LandmarkRow_Previews: PreviewProvider { + static var previews: some View { + Group { + LandmarkRow(landmark: landmarkData[0]) + LandmarkRow(landmark: landmarkData[1]) + } + .previewLayout(.fixed(width: 300, height: 70)) + } +} +#endif diff --git a/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/Supporting Views/MapView.swift b/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/Supporting Views/MapView.swift new file mode 100644 index 0000000..5a8c64b --- /dev/null +++ b/Other Projects/Handling User Input/StartingPoint/Landmarks/Landmarks/Supporting Views/MapView.swift @@ -0,0 +1,31 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A view that hosts an `MKMapView`. +*/ + +import SwiftUI +import MapKit + +struct MapView: UIViewRepresentable { + var coordinate: CLLocationCoordinate2D + + func makeUIView(context: Context) -> MKMapView { + MKMapView(frame: .zero) + } + + func updateUIView(_ view: MKMapView, context: Context) { + let span = MKCoordinateSpan(latitudeDelta: 0.02, longitudeDelta: 0.02) + let region = MKCoordinateRegion(center: coordinate, span: span) + view.setRegion(region, animated: true) + } +} + +#if DEBUG +struct MapView_Previews: PreviewProvider { + static var previews: some View { + MapView(coordinate: landmarkData[0].locationCoordinate) + } +} +#endif diff --git a/Other Projects/Handling User Input/StartingPoint/README.md b/Other Projects/Handling User Input/StartingPoint/README.md new file mode 100644 index 0000000..6d73973 --- /dev/null +++ b/Other Projects/Handling User Input/StartingPoint/README.md @@ -0,0 +1,3 @@ +# Handling User Input + +Use this project to code along with the [Handling User Input](https://developer.apple.com/tutorials/swiftui/handling-user-input) tutorial. diff --git a/Other Projects/InstaFake/Instagram-SWUI.xcodeproj/project.pbxproj b/Other Projects/InstaFake/Instagram-SWUI.xcodeproj/project.pbxproj new file mode 100644 index 0000000..0b678cd --- /dev/null +++ b/Other Projects/InstaFake/Instagram-SWUI.xcodeproj/project.pbxproj @@ -0,0 +1,386 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 50; + objects = { + +/* Begin PBXBuildFile section */ + C313C0B822A6FBAC00FF2AFB /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = C313C0B722A6FBAC00FF2AFB /* AppDelegate.swift */; }; + C313C0BA22A6FBAC00FF2AFB /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = C313C0B922A6FBAC00FF2AFB /* SceneDelegate.swift */; }; + C313C0BD22A6FBAC00FF2AFB /* Instagram_SWUI.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = C313C0BB22A6FBAC00FF2AFB /* Instagram_SWUI.xcdatamodeld */; }; + C313C0BF22A6FBAC00FF2AFB /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C313C0BE22A6FBAC00FF2AFB /* ContentView.swift */; }; + C313C0C122A6FBAE00FF2AFB /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C313C0C022A6FBAE00FF2AFB /* Assets.xcassets */; }; + C313C0C422A6FBAE00FF2AFB /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C313C0C322A6FBAE00FF2AFB /* Preview Assets.xcassets */; }; + C313C0C722A6FBAE00FF2AFB /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = C313C0C522A6FBAE00FF2AFB /* LaunchScreen.storyboard */; }; + C313C0F422A727EE00FF2AFB /* InstaPhoto.swift in Sources */ = {isa = PBXBuildFile; fileRef = C313C0F322A727EE00FF2AFB /* InstaPhoto.swift */; }; + C313C10222A778D100FF2AFB /* PhotoLibrary.swift in Sources */ = {isa = PBXBuildFile; fileRef = C313C10122A778D100FF2AFB /* PhotoLibrary.swift */; }; + C313C10822A8301D00FF2AFB /* CameraView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C313C10722A8301D00FF2AFB /* CameraView.swift */; }; + C34D712822A9B14700E60D50 /* CameraViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C34D712722A9B14700E60D50 /* CameraViewController.swift */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + C313C0B422A6FBAC00FF2AFB /* Instagram-SWUI.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Instagram-SWUI.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + C313C0B722A6FBAC00FF2AFB /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + C313C0B922A6FBAC00FF2AFB /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; + C313C0BC22A6FBAC00FF2AFB /* Instagram_SWUI.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = Instagram_SWUI.xcdatamodel; sourceTree = ""; }; + C313C0BE22A6FBAC00FF2AFB /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; }; + C313C0C022A6FBAE00FF2AFB /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + C313C0C322A6FBAE00FF2AFB /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; + C313C0C622A6FBAE00FF2AFB /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + C313C0C822A6FBAE00FF2AFB /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + C313C0F322A727EE00FF2AFB /* InstaPhoto.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InstaPhoto.swift; sourceTree = ""; }; + C313C10122A778D100FF2AFB /* PhotoLibrary.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PhotoLibrary.swift; sourceTree = ""; }; + C313C10722A8301D00FF2AFB /* CameraView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CameraView.swift; sourceTree = ""; }; + C34D712722A9B14700E60D50 /* CameraViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CameraViewController.swift; sourceTree = ""; }; + C34D712922A9C1CF00E60D50 /* Instagram-SWUI.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = "Instagram-SWUI.entitlements"; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + C313C0B122A6FBAC00FF2AFB /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + C313C0AB22A6FBAC00FF2AFB = { + isa = PBXGroup; + children = ( + C313C0B622A6FBAC00FF2AFB /* Instagram-SWUI */, + C313C0B522A6FBAC00FF2AFB /* Products */, + ); + sourceTree = ""; + }; + C313C0B522A6FBAC00FF2AFB /* Products */ = { + isa = PBXGroup; + children = ( + C313C0B422A6FBAC00FF2AFB /* Instagram-SWUI.app */, + ); + name = Products; + sourceTree = ""; + }; + C313C0B622A6FBAC00FF2AFB /* Instagram-SWUI */ = { + isa = PBXGroup; + children = ( + C34D712922A9C1CF00E60D50 /* Instagram-SWUI.entitlements */, + C313C0B722A6FBAC00FF2AFB /* AppDelegate.swift */, + C313C0B922A6FBAC00FF2AFB /* SceneDelegate.swift */, + C34D712722A9B14700E60D50 /* CameraViewController.swift */, + C313C0BE22A6FBAC00FF2AFB /* ContentView.swift */, + C313C10722A8301D00FF2AFB /* CameraView.swift */, + C313C0F322A727EE00FF2AFB /* InstaPhoto.swift */, + C313C10122A778D100FF2AFB /* PhotoLibrary.swift */, + C313C0C022A6FBAE00FF2AFB /* Assets.xcassets */, + C313C0C522A6FBAE00FF2AFB /* LaunchScreen.storyboard */, + C313C0C822A6FBAE00FF2AFB /* Info.plist */, + C313C0BB22A6FBAC00FF2AFB /* Instagram_SWUI.xcdatamodeld */, + C313C0C222A6FBAE00FF2AFB /* Preview Content */, + ); + path = "Instagram-SWUI"; + sourceTree = ""; + }; + C313C0C222A6FBAE00FF2AFB /* Preview Content */ = { + isa = PBXGroup; + children = ( + C313C0C322A6FBAE00FF2AFB /* Preview Assets.xcassets */, + ); + path = "Preview Content"; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + C313C0B322A6FBAC00FF2AFB /* Instagram-SWUI */ = { + isa = PBXNativeTarget; + buildConfigurationList = C313C0CB22A6FBAE00FF2AFB /* Build configuration list for PBXNativeTarget "Instagram-SWUI" */; + buildPhases = ( + C313C0B022A6FBAC00FF2AFB /* Sources */, + C313C0B122A6FBAC00FF2AFB /* Frameworks */, + C313C0B222A6FBAC00FF2AFB /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "Instagram-SWUI"; + productName = "Instagram-SWUI"; + productReference = C313C0B422A6FBAC00FF2AFB /* Instagram-SWUI.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + C313C0AC22A6FBAC00FF2AFB /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 1100; + LastUpgradeCheck = 1100; + ORGANIZATIONNAME = "leavenstee llc"; + TargetAttributes = { + C313C0B322A6FBAC00FF2AFB = { + CreatedOnToolsVersion = 11.0; + }; + }; + }; + buildConfigurationList = C313C0AF22A6FBAC00FF2AFB /* Build configuration list for PBXProject "Instagram-SWUI" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = C313C0AB22A6FBAC00FF2AFB; + productRefGroup = C313C0B522A6FBAC00FF2AFB /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + C313C0B322A6FBAC00FF2AFB /* Instagram-SWUI */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + C313C0B222A6FBAC00FF2AFB /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + C313C0C722A6FBAE00FF2AFB /* LaunchScreen.storyboard in Resources */, + C313C0C422A6FBAE00FF2AFB /* Preview Assets.xcassets in Resources */, + C313C0C122A6FBAE00FF2AFB /* Assets.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + C313C0B022A6FBAC00FF2AFB /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + C313C0B822A6FBAC00FF2AFB /* AppDelegate.swift in Sources */, + C313C0BD22A6FBAC00FF2AFB /* Instagram_SWUI.xcdatamodeld in Sources */, + C313C0F422A727EE00FF2AFB /* InstaPhoto.swift in Sources */, + C313C10222A778D100FF2AFB /* PhotoLibrary.swift in Sources */, + C313C0BF22A6FBAC00FF2AFB /* ContentView.swift in Sources */, + C34D712822A9B14700E60D50 /* CameraViewController.swift in Sources */, + C313C0BA22A6FBAC00FF2AFB /* SceneDelegate.swift in Sources */, + C313C10822A8301D00FF2AFB /* CameraView.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + C313C0C522A6FBAE00FF2AFB /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + C313C0C622A6FBAE00FF2AFB /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + C313C0C922A6FBAE00FF2AFB /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + C313C0CA22A6FBAE00FF2AFB /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + C313C0CC22A6FBAE00FF2AFB /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_ENTITLEMENTS = "Instagram-SWUI/Instagram-SWUI.entitlements"; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_ASSET_PATHS = "Instagram-SWUI/Preview\\ Content"; + DEVELOPMENT_TEAM = D846Q7V7YL; + ENABLE_PREVIEWS = YES; + INFOPLIST_FILE = "Instagram-SWUI/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = "leavenstee.Instagram-SWUI"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SUPPORTS_UIKITFORMAC = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + C313C0CD22A6FBAE00FF2AFB /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_ENTITLEMENTS = "Instagram-SWUI/Instagram-SWUI.entitlements"; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_ASSET_PATHS = "Instagram-SWUI/Preview\\ Content"; + DEVELOPMENT_TEAM = D846Q7V7YL; + ENABLE_PREVIEWS = YES; + INFOPLIST_FILE = "Instagram-SWUI/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = "leavenstee.Instagram-SWUI"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SUPPORTS_UIKITFORMAC = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + C313C0AF22A6FBAC00FF2AFB /* Build configuration list for PBXProject "Instagram-SWUI" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C313C0C922A6FBAE00FF2AFB /* Debug */, + C313C0CA22A6FBAE00FF2AFB /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + C313C0CB22A6FBAE00FF2AFB /* Build configuration list for PBXNativeTarget "Instagram-SWUI" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C313C0CC22A6FBAE00FF2AFB /* Debug */, + C313C0CD22A6FBAE00FF2AFB /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + +/* Begin XCVersionGroup section */ + C313C0BB22A6FBAC00FF2AFB /* Instagram_SWUI.xcdatamodeld */ = { + isa = XCVersionGroup; + children = ( + C313C0BC22A6FBAC00FF2AFB /* Instagram_SWUI.xcdatamodel */, + ); + currentVersion = C313C0BC22A6FBAC00FF2AFB /* Instagram_SWUI.xcdatamodel */; + path = Instagram_SWUI.xcdatamodeld; + sourceTree = ""; + versionGroupType = wrapper.xcdatamodel; + }; +/* End XCVersionGroup section */ + }; + rootObject = C313C0AC22A6FBAC00FF2AFB /* Project object */; +} diff --git a/Other Projects/InstaFake/Instagram-SWUI.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/Other Projects/InstaFake/Instagram-SWUI.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..c1fd280 --- /dev/null +++ b/Other Projects/InstaFake/Instagram-SWUI.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/Other Projects/InstaFake/Instagram-SWUI.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/Other Projects/InstaFake/Instagram-SWUI.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/Other Projects/InstaFake/Instagram-SWUI.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/Other Projects/InstaFake/Instagram-SWUI/AppDelegate.swift b/Other Projects/InstaFake/Instagram-SWUI/AppDelegate.swift new file mode 100644 index 0000000..d4a81ce --- /dev/null +++ b/Other Projects/InstaFake/Instagram-SWUI/AppDelegate.swift @@ -0,0 +1,88 @@ +// +// AppDelegate.swift +// Instagram-SWUI +// +// Created by Steven Lee on 6/4/19. +// Copyright © 2019 leavenstee llc. All rights reserved. +// + +import UIKit +import CoreData + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + + + + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { + // Override point for customization after application launch. + return true + } + + func applicationWillTerminate(_ application: UIApplication) { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. + // Saves changes in the application's managed object context before the application terminates. + self.saveContext() + } + + // MARK: UISceneSession Lifecycle + + func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration { + // Called when a new scene session is being created. + // Use this method to select a configuration to create the new scene with. + return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role) + } + + func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) { + // Called when the user discards a scene session. + // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions. + // Use this method to release any resources that were specific to the discarded scenes, as they will not return. + } + + // MARK: - Core Data stack + + lazy var persistentContainer: NSPersistentContainer = { + /* + The persistent container for the application. This implementation + creates and returns a container, having loaded the store for the + application to it. This property is optional since there are legitimate + error conditions that could cause the creation of the store to fail. + */ + let container = NSPersistentContainer(name: "Instagram_SWUI") + container.loadPersistentStores(completionHandler: { (storeDescription, error) in + if let error = error as NSError? { + // Replace this implementation with code to handle the error appropriately. + // fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. + + /* + Typical reasons for an error here include: + * The parent directory does not exist, cannot be created, or disallows writing. + * The persistent store is not accessible, due to permissions or data protection when the device is locked. + * The device is out of space. + * The store could not be migrated to the current model version. + Check the error message to determine what the actual problem was. + */ + fatalError("Unresolved error \(error), \(error.userInfo)") + } + }) + return container + }() + + // MARK: - Core Data Saving support + + func saveContext () { + let context = persistentContainer.viewContext + if context.hasChanges { + do { + try context.save() + } catch { + // Replace this implementation with code to handle the error appropriately. + // fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. + let nserror = error as NSError + fatalError("Unresolved error \(nserror), \(nserror.userInfo)") + } + } + } + +} + diff --git a/Other Projects/InstaFake/Instagram-SWUI/Assets.xcassets/AppIcon.appiconset/Contents.json b/Other Projects/InstaFake/Instagram-SWUI/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..d8db8d6 --- /dev/null +++ b/Other Projects/InstaFake/Instagram-SWUI/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,98 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "83.5x83.5", + "scale" : "2x" + }, + { + "idiom" : "ios-marketing", + "size" : "1024x1024", + "scale" : "1x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/InstaFake/Instagram-SWUI/Assets.xcassets/Contents.json b/Other Projects/InstaFake/Instagram-SWUI/Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/Other Projects/InstaFake/Instagram-SWUI/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/InstaFake/Instagram-SWUI/Assets.xcassets/badge.imageset/58120000553__7091B1D4-F645-4760-B5EE-D38E53D53F54.JPG b/Other Projects/InstaFake/Instagram-SWUI/Assets.xcassets/badge.imageset/58120000553__7091B1D4-F645-4760-B5EE-D38E53D53F54.JPG new file mode 100644 index 0000000..fd4e843 Binary files /dev/null and b/Other Projects/InstaFake/Instagram-SWUI/Assets.xcassets/badge.imageset/58120000553__7091B1D4-F645-4760-B5EE-D38E53D53F54.JPG differ diff --git a/Other Projects/InstaFake/Instagram-SWUI/Assets.xcassets/badge.imageset/Contents.json b/Other Projects/InstaFake/Instagram-SWUI/Assets.xcassets/badge.imageset/Contents.json new file mode 100644 index 0000000..4b0d7cc --- /dev/null +++ b/Other Projects/InstaFake/Instagram-SWUI/Assets.xcassets/badge.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "58120000553__7091B1D4-F645-4760-B5EE-D38E53D53F54.JPG", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/InstaFake/Instagram-SWUI/Assets.xcassets/burrito.imageset/Contents.json b/Other Projects/InstaFake/Instagram-SWUI/Assets.xcassets/burrito.imageset/Contents.json new file mode 100644 index 0000000..bfad3a5 --- /dev/null +++ b/Other Projects/InstaFake/Instagram-SWUI/Assets.xcassets/burrito.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "IMG_0163.jpeg", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/InstaFake/Instagram-SWUI/Assets.xcassets/burrito.imageset/IMG_0163.jpeg b/Other Projects/InstaFake/Instagram-SWUI/Assets.xcassets/burrito.imageset/IMG_0163.jpeg new file mode 100644 index 0000000..2bc4520 Binary files /dev/null and b/Other Projects/InstaFake/Instagram-SWUI/Assets.xcassets/burrito.imageset/IMG_0163.jpeg differ diff --git a/Other Projects/InstaFake/Instagram-SWUI/Assets.xcassets/photo-camera.imageset/Contents.json b/Other Projects/InstaFake/Instagram-SWUI/Assets.xcassets/photo-camera.imageset/Contents.json new file mode 100644 index 0000000..f142475 --- /dev/null +++ b/Other Projects/InstaFake/Instagram-SWUI/Assets.xcassets/photo-camera.imageset/Contents.json @@ -0,0 +1,15 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "photo-camera.png" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + }, + "properties" : { + "template-rendering-intent" : "original" + } +} \ No newline at end of file diff --git a/Other Projects/InstaFake/Instagram-SWUI/Assets.xcassets/photo-camera.imageset/photo-camera.png b/Other Projects/InstaFake/Instagram-SWUI/Assets.xcassets/photo-camera.imageset/photo-camera.png new file mode 100644 index 0000000..088ba4b Binary files /dev/null and b/Other Projects/InstaFake/Instagram-SWUI/Assets.xcassets/photo-camera.imageset/photo-camera.png differ diff --git a/Other Projects/InstaFake/Instagram-SWUI/Assets.xcassets/pizza.imageset/Contents.json b/Other Projects/InstaFake/Instagram-SWUI/Assets.xcassets/pizza.imageset/Contents.json new file mode 100644 index 0000000..f6fb91f --- /dev/null +++ b/Other Projects/InstaFake/Instagram-SWUI/Assets.xcassets/pizza.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "IMG_0156.jpeg", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/InstaFake/Instagram-SWUI/Assets.xcassets/pizza.imageset/IMG_0156.jpeg b/Other Projects/InstaFake/Instagram-SWUI/Assets.xcassets/pizza.imageset/IMG_0156.jpeg new file mode 100644 index 0000000..ab13537 Binary files /dev/null and b/Other Projects/InstaFake/Instagram-SWUI/Assets.xcassets/pizza.imageset/IMG_0156.jpeg differ diff --git a/Other Projects/InstaFake/Instagram-SWUI/Assets.xcassets/wwdc.imageset/Contents.json b/Other Projects/InstaFake/Instagram-SWUI/Assets.xcassets/wwdc.imageset/Contents.json new file mode 100644 index 0000000..c49c7b9 --- /dev/null +++ b/Other Projects/InstaFake/Instagram-SWUI/Assets.xcassets/wwdc.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "wwdc.JPG" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/InstaFake/Instagram-SWUI/Assets.xcassets/wwdc.imageset/wwdc.JPG b/Other Projects/InstaFake/Instagram-SWUI/Assets.xcassets/wwdc.imageset/wwdc.JPG new file mode 100644 index 0000000..015d8f8 Binary files /dev/null and b/Other Projects/InstaFake/Instagram-SWUI/Assets.xcassets/wwdc.imageset/wwdc.JPG differ diff --git a/Other Projects/InstaFake/Instagram-SWUI/Base.lproj/LaunchScreen.storyboard b/Other Projects/InstaFake/Instagram-SWUI/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000..865e932 --- /dev/null +++ b/Other Projects/InstaFake/Instagram-SWUI/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Other Projects/InstaFake/Instagram-SWUI/CameraView.swift b/Other Projects/InstaFake/Instagram-SWUI/CameraView.swift new file mode 100644 index 0000000..a8be12d --- /dev/null +++ b/Other Projects/InstaFake/Instagram-SWUI/CameraView.swift @@ -0,0 +1,25 @@ +// +// CameraView.swift +// Instagram-SWUI +// +// Created by Steven Lee on 6/5/19. +// Copyright © 2019 leavenstee llc. All rights reserved. +// + +import SwiftUI +import UIKit + +struct CameraView : UIViewControllerRepresentable { + func makeUIViewController(context: UIViewControllerRepresentableContext) -> CameraViewController { + return CameraViewController() + } + + func updateUIViewController(_ uiViewController: CameraViewController, context: UIViewControllerRepresentableContext) { + + } + + typealias UIViewControllerType = CameraViewController + + +} + diff --git a/Other Projects/InstaFake/Instagram-SWUI/CameraViewController.swift b/Other Projects/InstaFake/Instagram-SWUI/CameraViewController.swift new file mode 100644 index 0000000..c452592 --- /dev/null +++ b/Other Projects/InstaFake/Instagram-SWUI/CameraViewController.swift @@ -0,0 +1,152 @@ +// +// CameraViewController.swift +// Instagram-SWUI +// +// Created by Steven Lee on 6/6/19. +// Copyright © 2019 leavenstee llc. All rights reserved. +// + +import UIKit + +import AVFoundation + +class CameraViewController: UIViewController { + + var previewView: UIView! + var captureButton: UIButton! + + var captureSession: AVCaptureSession? + var videoPreviewLayer: AVCaptureVideoPreviewLayer? + var capturePhotoOutput: AVCapturePhotoOutput? + var qrCodeFrameView: UIView? + + override func viewDidLoad() { + super.viewDidLoad() + + previewView = UIView(frame: view.frame) + captureButton = UIButton(frame: CGRect(x: 100, y: 100, width: 300, height: 300)) + captureButton.backgroundColor = .green + + captureButton.layer.cornerRadius = captureButton.frame.size.width / 2 + captureButton.clipsToBounds = true + + // Get an instance of the AVCaptureDevice class to initialize a device object and provide the video as the media type parameter + guard let captureDevice = AVCaptureDevice.default(for: .video) else { + fatalError("No video device found") + } + + do { + // Get an instance of the AVCaptureDeviceInput class using the previous deivce object + let input = try AVCaptureDeviceInput(device: captureDevice) + + // Initialize the captureSession object + captureSession = AVCaptureSession() + + // Set the input devcie on the capture session + captureSession?.addInput(input) + + // Get an instance of ACCapturePhotoOutput class + capturePhotoOutput = AVCapturePhotoOutput() + capturePhotoOutput?.isHighResolutionCaptureEnabled = true + + // Set the output on the capture session + captureSession?.addOutput(capturePhotoOutput!) + + // Initialize a AVCaptureMetadataOutput object and set it as the input device + let captureMetadataOutput = AVCaptureMetadataOutput() + captureSession?.addOutput(captureMetadataOutput) + + //Initialise the video preview layer and add it as a sublayer to the viewPreview view's layer + videoPreviewLayer = AVCaptureVideoPreviewLayer(session: captureSession!) + videoPreviewLayer?.videoGravity = AVLayerVideoGravity.resizeAspectFill + videoPreviewLayer?.frame = view.layer.bounds + previewView.layer.addSublayer(videoPreviewLayer!) + + //start video capture + captureSession?.startRunning() + + //Initialize QR Code Frame to highlight the QR code + qrCodeFrameView = UIView() + + if let qrCodeFrameView = qrCodeFrameView { + qrCodeFrameView.layer.borderColor = UIColor.green.cgColor + qrCodeFrameView.layer.borderWidth = 2 + view.addSubview(qrCodeFrameView) + view.bringSubviewToFront(qrCodeFrameView) + } + } catch { + //If any error occurs, simply print it out + print(error) + return + } + + } + + override func viewDidLayoutSubviews() { + videoPreviewLayer?.frame = view.bounds + if let previewLayer = videoPreviewLayer ,(previewLayer.connection?.isVideoOrientationSupported)! { + previewLayer.connection?.videoOrientation = UIApplication.shared.statusBarOrientation.videoOrientation ?? .portrait + } + } + + override func didReceiveMemoryWarning() { + super.didReceiveMemoryWarning() + // Dispose of any resources that can be recreated. + } + + @IBAction func onTapTakePhoto(_ sender: Any) { + // Make sure capturePhotoOutput is valid + guard let capturePhotoOutput = self.capturePhotoOutput else { return } + + // Get an instance of AVCapturePhotoSettings class + let photoSettings = AVCapturePhotoSettings() + + // Set photo settings for our need + photoSettings.isAutoStillImageStabilizationEnabled = true + photoSettings.isHighResolutionPhotoEnabled = true + photoSettings.flashMode = .auto + + // Call capturePhoto method by passing our photo settings and a delegate implementing AVCapturePhotoCaptureDelegate + capturePhotoOutput.capturePhoto(with: photoSettings, delegate: self) + } +} + +extension CameraViewController : AVCapturePhotoCaptureDelegate { + func photoOutput(_ captureOutput: AVCapturePhotoOutput, + didFinishProcessingPhoto photoSampleBuffer: CMSampleBuffer?, + previewPhoto previewPhotoSampleBuffer: CMSampleBuffer?, + resolvedSettings: AVCaptureResolvedPhotoSettings, + bracketSettings: AVCaptureBracketedStillImageSettings?, + error: Error?) { + // Make sure we get some photo sample buffer + guard error == nil, + let photoSampleBuffer = photoSampleBuffer else { + print("Error capturing photo: \(String(describing: error))") + return + } + + // Convert photo same buffer to a jpeg image data by using AVCapturePhotoOutput + guard let imageData = AVCapturePhotoOutput.jpegPhotoDataRepresentation(forJPEGSampleBuffer: photoSampleBuffer, previewPhotoSampleBuffer: previewPhotoSampleBuffer) else { + return + } + + // Initialise an UIImage with our image data + let capturedImage = UIImage.init(data: imageData , scale: 1.0) + if let image = capturedImage { + // Save our captured image to photos album + UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil) + } + } +} + +extension UIInterfaceOrientation { + var videoOrientation: AVCaptureVideoOrientation? { + switch self { + case .portraitUpsideDown: return .portraitUpsideDown + case .landscapeRight: return .landscapeRight + case .landscapeLeft: return .landscapeLeft + case .portrait: return .portrait + default: return nil + } + } +} diff --git a/Other Projects/InstaFake/Instagram-SWUI/ContentView.swift b/Other Projects/InstaFake/Instagram-SWUI/ContentView.swift new file mode 100644 index 0000000..ddbcd02 --- /dev/null +++ b/Other Projects/InstaFake/Instagram-SWUI/ContentView.swift @@ -0,0 +1,127 @@ +// +// ContentView.swift +// Instagram-SWUI +// +// Created by Steven Lee on 6/4/19. +// Copyright © 2019 leavenstee llc. All rights reserved. +// + +import SwiftUI +import AVKit +import CoreLocation + +struct ContentView : View { + @State private var isCameraPresented = false + var instaPhotos: [InstaPhoto] + + var body: some View { + NavigationView { + List { + ForEach(instaPhotos, id: \.id) { + ImageCell(photo: $0) + } + }.navigationBarTitle("WWDC").navigationBarItems(trailing: + Button(action: { + self.isCameraPresented = true + }) { + Image(systemName: "person.crop.circle") + .imageScale(.large) + .accessibility(label: Text("User Profile")) + .padding() + } + ).sheet(isPresented: $isCameraPresented, + content: { CameraView() }) + } + } + + func takePhoto() { + // Open Camera + + } + +} + +#if DEBUG +struct ContentView_Previews : PreviewProvider { + static var previews: some View { + ContentView(instaPhotos: [InstaPhoto(id: 0, username: "leavenstee", comments: ["Nice", "Cool","Lame"], likes: 100, image: "wwdc"),InstaPhoto(id: 0, username: "leavenstee", comments: ["Nice", "Cool","Lame","Nice", "Cool","Lame"], likes: 200, image: "pizza"), + InstaPhoto(id: 0, username: "leavenstee", comments: ["Nice", "Cool","Lame","Nice", "Cool","Lame","Nice", "Cool","Lame","Nice", "Cool","Lame"], likes: 4440, image: "wwdc"),InstaPhoto(id: 0, username: "leavenstee", comments: ["Nice", "Cool"], likes: 20, image: "badge")]) + } +} +#endif + +struct ImageCell : View { + @State var expanded = false + @State var liked = false + + var photo: InstaPhoto + + var body: some View { + return VStack(alignment: .leading) { + HStack { + Image("badge").resizable().scaledToFit().cornerRadius(100) + Text(photo.username) + Button(action: {}, label: { + Text("...") + }) + }.frame(height: 40) + + Image(photo.image) + .resizable() + .scaledToFit() + .cornerRadius(10) + // Control Buttons + HStack { + Button(action: withAnimation { likeButtonPressed }, label: { + Text( self.liked ? "❤️" :"💔") + }) + Button(action: commentButtonPressed, label: { + Text("🗣") + }) + Button(action: likeButtonPressed, label: { + Text("📪") + }) + Spacer() + Button(action: likeButtonPressed, label: { + Text("📕") + }) + } + Text("\(photo.likes) Likes") + .multilineTextAlignment(.leading) + Text(photo.username) + .multilineTextAlignment(.leading) + Button(action: moreCommentsPressed, label: { + Text("View All \(photo.comments.count) Comments") + .fontWeight(.light) + }) + if expanded { + VStack { + Text("Test Comment") + Text("Test Comment") + Text("Test Comment") + Text("Test Comment") + } + } + } + } + + func moreCommentsPressed() { + expanded.toggle() + } + + func likeButtonPressed() { + liked.toggle() + } + + func commentButtonPressed() { + + } + + func shareButtonPressed() { + + } + + func bookMarkButtonPressed() { + + } +} diff --git a/Other Projects/InstaFake/Instagram-SWUI/Info.plist b/Other Projects/InstaFake/Instagram-SWUI/Info.plist new file mode 100644 index 0000000..c9b98e5 --- /dev/null +++ b/Other Projects/InstaFake/Instagram-SWUI/Info.plist @@ -0,0 +1,64 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + $(PRODUCT_BUNDLE_PACKAGE_TYPE) + CFBundleShortVersionString + 1.0 + NSCameraUsageDescription + Let me use your camer for pics + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UIApplicationSceneManifest + + UIApplicationSupportsMultipleScenes + + UISceneConfigurations + + UIWindowSceneSessionRoleApplication + + + UILaunchStoryboardName + LaunchScreen + UISceneConfigurationName + Default Configuration + UISceneDelegateClassName + $(PRODUCT_MODULE_NAME).SceneDelegate + + + + + UILaunchStoryboardName + LaunchScreen + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/Other Projects/InstaFake/Instagram-SWUI/InstaPhoto.swift b/Other Projects/InstaFake/Instagram-SWUI/InstaPhoto.swift new file mode 100644 index 0000000..3b8cbda --- /dev/null +++ b/Other Projects/InstaFake/Instagram-SWUI/InstaPhoto.swift @@ -0,0 +1,18 @@ +// +// InstaPhoto.swift +// Instagram-SWUI +// +// Created by Steven Lee on 6/4/19. +// Copyright © 2019 leavenstee llc. All rights reserved. +// + +import Foundation +import SwiftUI + +struct InstaPhoto: Identifiable { + let id: Int + let username: String + let comments: [String] + let likes: Int + let image: String +} diff --git a/Other Projects/InstaFake/Instagram-SWUI/Instagram-SWUI.entitlements b/Other Projects/InstaFake/Instagram-SWUI/Instagram-SWUI.entitlements new file mode 100644 index 0000000..dc677b9 --- /dev/null +++ b/Other Projects/InstaFake/Instagram-SWUI/Instagram-SWUI.entitlements @@ -0,0 +1,12 @@ + + + + + com.apple.security.app-sandbox + + com.apple.security.device.camera + + com.apple.security.network.client + + + diff --git a/Other Projects/InstaFake/Instagram-SWUI/Instagram_SWUI.xcdatamodeld/.xccurrentversion b/Other Projects/InstaFake/Instagram-SWUI/Instagram_SWUI.xcdatamodeld/.xccurrentversion new file mode 100644 index 0000000..85b5b24 --- /dev/null +++ b/Other Projects/InstaFake/Instagram-SWUI/Instagram_SWUI.xcdatamodeld/.xccurrentversion @@ -0,0 +1,8 @@ + + + + + _XCCurrentVersionName + Instagram_SWUI.xcdatamodel + + diff --git a/Other Projects/InstaFake/Instagram-SWUI/Instagram_SWUI.xcdatamodeld/Instagram_SWUI.xcdatamodel/contents b/Other Projects/InstaFake/Instagram-SWUI/Instagram_SWUI.xcdatamodeld/Instagram_SWUI.xcdatamodel/contents new file mode 100644 index 0000000..50d2514 --- /dev/null +++ b/Other Projects/InstaFake/Instagram-SWUI/Instagram_SWUI.xcdatamodeld/Instagram_SWUI.xcdatamodel/contents @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/Other Projects/InstaFake/Instagram-SWUI/PhotoLibrary.swift b/Other Projects/InstaFake/Instagram-SWUI/PhotoLibrary.swift new file mode 100644 index 0000000..209ddd9 --- /dev/null +++ b/Other Projects/InstaFake/Instagram-SWUI/PhotoLibrary.swift @@ -0,0 +1,13 @@ +// +// PhotoLibrary.swift +// Instagram-SWUI +// +// Created by Steven Lee on 6/4/19. +// Copyright © 2019 leavenstee llc. All rights reserved. +// + +import Foundation + +struct PhotoLibrary { + let photos: [InstaPhoto] +} diff --git a/Other Projects/InstaFake/Instagram-SWUI/Preview Content/Preview Assets.xcassets/Contents.json b/Other Projects/InstaFake/Instagram-SWUI/Preview Content/Preview Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/Other Projects/InstaFake/Instagram-SWUI/Preview Content/Preview Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/InstaFake/Instagram-SWUI/SceneDelegate.swift b/Other Projects/InstaFake/Instagram-SWUI/SceneDelegate.swift new file mode 100644 index 0000000..5c84857 --- /dev/null +++ b/Other Projects/InstaFake/Instagram-SWUI/SceneDelegate.swift @@ -0,0 +1,65 @@ +// +// SceneDelegate.swift +// Instagram-SWUI +// +// Created by Steven Lee on 6/4/19. +// Copyright © 2019 leavenstee llc. All rights reserved. +// + +import UIKit +import SwiftUI + +class SceneDelegate: UIResponder, UIWindowSceneDelegate { + + var window: UIWindow? + + + func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { + // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`. + // If using a storyboard, the `window` property will automatically be initialized and attached to the scene. + // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead). + + // Use a UIHostingController as window root view controller + if let windowScene = scene as? UIWindowScene { + let window = UIWindow(windowScene: windowScene) + window.rootViewController = UIHostingController(rootView: ContentView(instaPhotos: [InstaPhoto(id: 0, username: "leavenstee", comments: ["Nice", "Cool","Lame"], likes: 100, image: "wwdc"),InstaPhoto(id: 0, username: "leavenstee", comments: ["Nice", "Cool","Lame","Nice", "Cool","Lame"], likes: 200, image: "pizza"), + InstaPhoto(id: 0, username: "leavenstee", comments: ["Nice", "Cool","Lame","Nice", "Cool","Lame","Nice", "Cool","Lame","Nice", "Cool","Lame"], likes: 4440, image: "wwdc"),InstaPhoto(id: 0, username: "leavenstee", comments: ["Nice", "Cool"], likes: 20, image: "badge")])) + self.window = window + window.makeKeyAndVisible() + } + } + + func sceneDidDisconnect(_ scene: UIScene) { + // Called as the scene is being released by the system. + // This occurs shortly after the scene enters the background, or when its session is discarded. + // Release any resources associated with this scene that can be re-created the next time the scene connects. + // The scene may re-connect later, as its session was not neccessarily discarded (see `application:didDiscardSceneSessions` instead). + } + + func sceneDidBecomeActive(_ scene: UIScene) { + // Called when the scene has moved from an inactive state to an active state. + // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive. + } + + func sceneWillResignActive(_ scene: UIScene) { + // Called when the scene will move from an active state to an inactive state. + // This may occur due to temporary interruptions (ex. an incoming phone call). + } + + func sceneWillEnterForeground(_ scene: UIScene) { + // Called as the scene transitions from the background to the foreground. + // Use this method to undo the changes made on entering the background. + } + + func sceneDidEnterBackground(_ scene: UIScene) { + // Called as the scene transitions from the foreground to the background. + // Use this method to save data, release shared resources, and store enough scene-specific state information + // to restore the scene back to its current state. + + // Save changes in the application's managed object context when the application transitions to the background. + (UIApplication.shared.delegate as? AppDelegate)?.saveContext() + } + + +} + diff --git a/Other Projects/Interfacing With UIKit/Complete/.gitignore b/Other Projects/Interfacing With UIKit/Complete/.gitignore new file mode 100644 index 0000000..9e50718 --- /dev/null +++ b/Other Projects/Interfacing With UIKit/Complete/.gitignore @@ -0,0 +1,21 @@ +# See LICENSE folder for this sample’s licensing information. +# +# Apple sample code gitignore configuration. + +# Finder +.DS_Store + +# Xcode - User files +xcuserdata/ + +**/*.xcodeproj/project.xcworkspace/* +!**/*.xcodeproj/project.xcworkspace/xcshareddata + +**/*.xcodeproj/project.xcworkspace/xcshareddata/* +!**/*.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings + +**/*.playground/playground.xcworkspace/* +!**/*.playground/playground.xcworkspace/xcshareddata + +**/*.playground/playground.xcworkspace/xcshareddata/* +!**/*.playground/playground.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings diff --git a/Other Projects/Interfacing With UIKit/Complete/Configuration/SampleCode.xcconfig b/Other Projects/Interfacing With UIKit/Complete/Configuration/SampleCode.xcconfig new file mode 100644 index 0000000..db86c06 --- /dev/null +++ b/Other Projects/Interfacing With UIKit/Complete/Configuration/SampleCode.xcconfig @@ -0,0 +1,13 @@ +// +// See LICENSE folder for this sample’s licensing information. +// +// SampleCode.xcconfig +// + +// The `SAMPLE_CODE_DISAMBIGUATOR` configuration is to make it easier to build +// and run a sample code project. Once you set your project's development team, +// you'll have a unique bundle identifier. This is because the bundle identifier +// is derived based on the 'SAMPLE_CODE_DISAMBIGUATOR' value. Do not use this +// approach in your own projects—it's only useful for sample code projects because +// they are frequently downloaded and don't have a development team set. +SAMPLE_CODE_DISAMBIGUATOR=${DEVELOPMENT_TEAM} diff --git a/Other Projects/Interfacing With UIKit/Complete/LICENSE/LICENSE.txt b/Other Projects/Interfacing With UIKit/Complete/LICENSE/LICENSE.txt new file mode 100644 index 0000000..94e3d54 --- /dev/null +++ b/Other Projects/Interfacing With UIKit/Complete/LICENSE/LICENSE.txt @@ -0,0 +1,8 @@ +Copyright © 2019 Apple Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + diff --git a/Other Projects/Interfacing With UIKit/Complete/Landmarks/InterfacingWithUIKit.xcodeproj/.xcodesamplecode.plist b/Other Projects/Interfacing With UIKit/Complete/Landmarks/InterfacingWithUIKit.xcodeproj/.xcodesamplecode.plist new file mode 100644 index 0000000..5dd5da8 --- /dev/null +++ b/Other Projects/Interfacing With UIKit/Complete/Landmarks/InterfacingWithUIKit.xcodeproj/.xcodesamplecode.plist @@ -0,0 +1,5 @@ + + + + + diff --git a/Other Projects/Interfacing With UIKit/Complete/Landmarks/InterfacingWithUIKit.xcodeproj/project.pbxproj b/Other Projects/Interfacing With UIKit/Complete/Landmarks/InterfacingWithUIKit.xcodeproj/project.pbxproj new file mode 100644 index 0000000..1905aaf --- /dev/null +++ b/Other Projects/Interfacing With UIKit/Complete/Landmarks/InterfacingWithUIKit.xcodeproj/project.pbxproj @@ -0,0 +1,589 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 50; + objects = { + +/* Begin PBXBuildFile section */ + B7310DD1229F6839001079B9 /* HexagonParameters.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7310DD0229F6839001079B9 /* HexagonParameters.swift */; }; + B7310DD3229F6CA9001079B9 /* Badge.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7310DD2229F6CA9001079B9 /* Badge.swift */; }; + B7394866229F194000C47603 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7394865229F194000C47603 /* AppDelegate.swift */; }; + B7394868229F194000C47603 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7394867229F194000C47603 /* SceneDelegate.swift */; }; + B739486A229F194000C47603 /* LandmarkDetail.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7394869229F194000C47603 /* LandmarkDetail.swift */; }; + B739486C229F194200C47603 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B739486B229F194200C47603 /* Assets.xcassets */; }; + B739486F229F194200C47603 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B739486E229F194200C47603 /* Preview Assets.xcassets */; }; + B7394872229F194200C47603 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B7394870229F194200C47603 /* LaunchScreen.storyboard */; }; + B739487A229F1B3F00C47603 /* CircleImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7394879229F1B3F00C47603 /* CircleImage.swift */; }; + B739487C229F1B6800C47603 /* MapView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B739487B229F1B6800C47603 /* MapView.swift */; }; + B7394881229F28B900C47603 /* Landmark.swift in Sources */ = {isa = PBXBuildFile; fileRef = B739487F229F28B900C47603 /* Landmark.swift */; }; + B7394891229F292F00C47603 /* rainbowlake.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B7394884229F292D00C47603 /* rainbowlake.jpg */; }; + B7394893229F292F00C47603 /* icybay.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B7394886229F292E00C47603 /* icybay.jpg */; }; + B7394894229F292F00C47603 /* lakemcdonald.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B7394887229F292E00C47603 /* lakemcdonald.jpg */; }; + B7394895229F292F00C47603 /* turtlerock.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B7394888229F292E00C47603 /* turtlerock.jpg */; }; + B7394896229F292F00C47603 /* umbagog.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B7394889229F292E00C47603 /* umbagog.jpg */; }; + B7394897229F292F00C47603 /* hiddenlake.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B739488A229F292E00C47603 /* hiddenlake.jpg */; }; + B7394898229F292F00C47603 /* stmarylake.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B739488B229F292E00C47603 /* stmarylake.jpg */; }; + B7394899229F292F00C47603 /* twinlake.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B739488C229F292E00C47603 /* twinlake.jpg */; }; + B739489A229F292F00C47603 /* silversalmoncreek.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B739488D229F292E00C47603 /* silversalmoncreek.jpg */; }; + B739489B229F292F00C47603 /* landmarkData.json in Resources */ = {isa = PBXBuildFile; fileRef = B739488E229F292E00C47603 /* landmarkData.json */; }; + B739489C229F292F00C47603 /* chincoteague.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B739488F229F292F00C47603 /* chincoteague.jpg */; }; + B739489D229F292F00C47603 /* chilkoottrail.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B7394890229F292F00C47603 /* chilkoottrail.jpg */; }; + B739489F229F2D9700C47603 /* LandmarkRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = B739489E229F2D9700C47603 /* LandmarkRow.swift */; }; + B73948A1229F2E1F00C47603 /* LandmarkList.swift in Sources */ = {isa = PBXBuildFile; fileRef = B73948A0229F2E1F00C47603 /* LandmarkList.swift */; }; + B73948A3229F3E2200C47603 /* charleyrivers.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B73948A2229F3E2200C47603 /* charleyrivers.jpg */; }; + B7D2AAC5229F4D7C0061E5F5 /* UserData.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7D2AAC4229F4D7C0061E5F5 /* UserData.swift */; }; + B7D587AE229F7382006E8DCF /* BadgeBackground.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7D587AD229F7382006E8DCF /* BadgeBackground.swift */; }; + B7D587B0229F73C1006E8DCF /* BadgeSymbol.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7D587AF229F73C1006E8DCF /* BadgeSymbol.swift */; }; + B7D587B2229F7406006E8DCF /* RotatedBadgeSymbol.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7D587B1229F7406006E8DCF /* RotatedBadgeSymbol.swift */; }; + B7D587B6229F825D006E8DCF /* HikeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7D587B5229F825D006E8DCF /* HikeView.swift */; }; + B7D587B8229F826D006E8DCF /* GraphCapsule.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7D587B7229F826D006E8DCF /* GraphCapsule.swift */; }; + B7D587BA229F8288006E8DCF /* Hike.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7D587B9229F8288006E8DCF /* Hike.swift */; }; + B7D587BC229F82EB006E8DCF /* HikeDetail.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7D587BB229F82EB006E8DCF /* HikeDetail.swift */; }; + B7D587BE229F82FF006E8DCF /* HikeGraph.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7D587BD229F82FF006E8DCF /* HikeGraph.swift */; }; + B7D587C0229F830B006E8DCF /* hikeData.json in Resources */ = {isa = PBXBuildFile; fileRef = B7D587BF229F830B006E8DCF /* hikeData.json */; }; + B7D587D222A0892C006E8DCF /* Home.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7D587D122A0892C006E8DCF /* Home.swift */; }; + B7D587D422A08965006E8DCF /* CategoryRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7D587D322A08965006E8DCF /* CategoryRow.swift */; }; + B7D587D622A08C97006E8DCF /* Profile.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7D587D522A08C97006E8DCF /* Profile.swift */; }; + B7D587D922A08D33006E8DCF /* ProfileHost.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7D587D822A08D33006E8DCF /* ProfileHost.swift */; }; + B7D587DB22A08D67006E8DCF /* ProfileSummary.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7D587DA22A08D67006E8DCF /* ProfileSummary.swift */; }; + B7D587DD22A08DD6006E8DCF /* HikeBadge.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7D587DC22A08DD6006E8DCF /* HikeBadge.swift */; }; + B7D587DF22A08E1A006E8DCF /* ProfileEditor.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7D587DE22A08E1A006E8DCF /* ProfileEditor.swift */; }; + B7D587E122A0914D006E8DCF /* FeatureCard.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7D587E022A0914D006E8DCF /* FeatureCard.swift */; }; + B7D587E522A097E2006E8DCF /* charleyrivers_feature.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B7D587E222A097E2006E8DCF /* charleyrivers_feature.jpg */; }; + B7D587E622A097E2006E8DCF /* stmarylake_feature.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B7D587E322A097E2006E8DCF /* stmarylake_feature.jpg */; }; + B7D587E722A097E2006E8DCF /* turtlerock_feature.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B7D587E422A097E2006E8DCF /* turtlerock_feature.jpg */; }; + B7D587E922A09809006E8DCF /* Data.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7D587E822A09809006E8DCF /* Data.swift */; }; + B7D587EB22A09A86006E8DCF /* PageViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7D587EA22A09A86006E8DCF /* PageViewController.swift */; }; + B7D587ED22A09B79006E8DCF /* PageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7D587EC22A09B79006E8DCF /* PageView.swift */; }; + B7D587EF22A09D0C006E8DCF /* PageControl.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7D587EE22A09D0C006E8DCF /* PageControl.swift */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 7D5949007D59D84000000001 /* LICENSE.txt */ = {isa = PBXFileReference; includeInIndex = 1; path = LICENSE.txt; sourceTree = ""; }; + 7D7349B07D72194000000001 /* SampleCode.xcconfig */ = {isa = PBXFileReference; name = SampleCode.xcconfig; path = ../Configuration/SampleCode.xcconfig; sourceTree = ""; }; + B7310DD0229F6839001079B9 /* HexagonParameters.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HexagonParameters.swift; sourceTree = ""; }; + B7310DD2229F6CA9001079B9 /* Badge.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Badge.swift; sourceTree = ""; }; + B7394862229F194000C47603 /* Landmarks.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Landmarks.app; sourceTree = BUILT_PRODUCTS_DIR; }; + B7394865229F194000C47603 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + B7394867229F194000C47603 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; + B7394869229F194000C47603 /* LandmarkDetail.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LandmarkDetail.swift; sourceTree = ""; }; + B739486B229F194200C47603 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + B739486E229F194200C47603 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; + B7394871229F194200C47603 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + B7394873229F194200C47603 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + B7394879229F1B3F00C47603 /* CircleImage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CircleImage.swift; sourceTree = ""; }; + B739487B229F1B6800C47603 /* MapView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapView.swift; sourceTree = ""; }; + B739487F229F28B900C47603 /* Landmark.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Landmark.swift; sourceTree = ""; }; + B7394884229F292D00C47603 /* rainbowlake.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = rainbowlake.jpg; sourceTree = ""; }; + B7394886229F292E00C47603 /* icybay.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = icybay.jpg; sourceTree = ""; }; + B7394887229F292E00C47603 /* lakemcdonald.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = lakemcdonald.jpg; sourceTree = ""; }; + B7394888229F292E00C47603 /* turtlerock.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = turtlerock.jpg; sourceTree = ""; }; + B7394889229F292E00C47603 /* umbagog.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = umbagog.jpg; sourceTree = ""; }; + B739488A229F292E00C47603 /* hiddenlake.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = hiddenlake.jpg; sourceTree = ""; }; + B739488B229F292E00C47603 /* stmarylake.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = stmarylake.jpg; sourceTree = ""; }; + B739488C229F292E00C47603 /* twinlake.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = twinlake.jpg; sourceTree = ""; }; + B739488D229F292E00C47603 /* silversalmoncreek.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = silversalmoncreek.jpg; sourceTree = ""; }; + B739488E229F292E00C47603 /* landmarkData.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = landmarkData.json; sourceTree = ""; }; + B739488F229F292F00C47603 /* chincoteague.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = chincoteague.jpg; sourceTree = ""; }; + B7394890229F292F00C47603 /* chilkoottrail.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = chilkoottrail.jpg; sourceTree = ""; }; + B739489E229F2D9700C47603 /* LandmarkRow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = LandmarkRow.swift; path = "Supporting Views/LandmarkRow.swift"; sourceTree = ""; }; + B73948A0229F2E1F00C47603 /* LandmarkList.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LandmarkList.swift; sourceTree = ""; }; + B73948A2229F3E2200C47603 /* charleyrivers.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = charleyrivers.jpg; sourceTree = ""; }; + B7D2AAC4229F4D7C0061E5F5 /* UserData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserData.swift; sourceTree = ""; }; + B7D587AD229F7382006E8DCF /* BadgeBackground.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BadgeBackground.swift; sourceTree = ""; }; + B7D587AF229F73C1006E8DCF /* BadgeSymbol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BadgeSymbol.swift; sourceTree = ""; }; + B7D587B1229F7406006E8DCF /* RotatedBadgeSymbol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RotatedBadgeSymbol.swift; sourceTree = ""; }; + B7D587B5229F825D006E8DCF /* HikeView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HikeView.swift; sourceTree = ""; }; + B7D587B7229F826D006E8DCF /* GraphCapsule.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GraphCapsule.swift; sourceTree = ""; }; + B7D587B9229F8288006E8DCF /* Hike.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Hike.swift; sourceTree = ""; }; + B7D587BB229F82EB006E8DCF /* HikeDetail.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HikeDetail.swift; sourceTree = ""; }; + B7D587BD229F82FF006E8DCF /* HikeGraph.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HikeGraph.swift; sourceTree = ""; }; + B7D587BF229F830B006E8DCF /* hikeData.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = hikeData.json; sourceTree = ""; }; + B7D587D122A0892C006E8DCF /* Home.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Home.swift; sourceTree = ""; }; + B7D587D322A08965006E8DCF /* CategoryRow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CategoryRow.swift; sourceTree = ""; }; + B7D587D522A08C97006E8DCF /* Profile.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Profile.swift; sourceTree = ""; }; + B7D587D822A08D33006E8DCF /* ProfileHost.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileHost.swift; sourceTree = ""; }; + B7D587DA22A08D67006E8DCF /* ProfileSummary.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileSummary.swift; sourceTree = ""; }; + B7D587DC22A08DD6006E8DCF /* HikeBadge.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HikeBadge.swift; sourceTree = ""; }; + B7D587DE22A08E1A006E8DCF /* ProfileEditor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileEditor.swift; sourceTree = ""; }; + B7D587E022A0914D006E8DCF /* FeatureCard.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FeatureCard.swift; sourceTree = ""; }; + B7D587E222A097E2006E8DCF /* charleyrivers_feature.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = charleyrivers_feature.jpg; sourceTree = ""; }; + B7D587E322A097E2006E8DCF /* stmarylake_feature.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = stmarylake_feature.jpg; sourceTree = ""; }; + B7D587E422A097E2006E8DCF /* turtlerock_feature.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = turtlerock_feature.jpg; sourceTree = ""; }; + B7D587E822A09809006E8DCF /* Data.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Data.swift; sourceTree = ""; }; + B7D587EA22A09A86006E8DCF /* PageViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PageViewController.swift; sourceTree = ""; }; + B7D587EC22A09B79006E8DCF /* PageView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PageView.swift; sourceTree = ""; }; + B7D587EE22A09D0C006E8DCF /* PageControl.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PageControl.swift; sourceTree = ""; }; + C4E4AAA0C4E4035000000001 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; name = README.md; path = ../README.md; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + B739485F229F194000C47603 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 7D59C6607D59CD8000000001 /* LICENSE */ = { + isa = PBXGroup; + children = ( + 7D5949007D59D84000000001 /* LICENSE.txt */, + ); + name = LICENSE; + path = ../LICENSE; + sourceTree = ""; + }; + 7D7215E07D7215A000000001 /* Configuration */ = { + isa = PBXGroup; + children = ( + 7D7349B07D72194000000001 /* SampleCode.xcconfig */, + ); + name = Configuration; + sourceTree = ""; + }; + B7394859229F194000C47603 = { + isa = PBXGroup; + children = ( + C4E4AAA0C4E4035000000001 /* README.md */, + B7394864229F194000C47603 /* Landmarks */, + B7394863229F194000C47603 /* Products */, + 7D7215E07D7215A000000001 /* Configuration */, + 7D59C6607D59CD8000000001 /* LICENSE */, + ); + sourceTree = ""; + }; + B7394863229F194000C47603 /* Products */ = { + isa = PBXGroup; + children = ( + B7394862229F194000C47603 /* Landmarks.app */, + ); + name = Products; + sourceTree = ""; + }; + B7394864229F194000C47603 /* Landmarks */ = { + isa = PBXGroup; + children = ( + B739487E229F282200C47603 /* Models */, + B7D587D722A08D16006E8DCF /* Profiles */, + B7394865229F194000C47603 /* AppDelegate.swift */, + B7394867229F194000C47603 /* SceneDelegate.swift */, + B7D587D122A0892C006E8DCF /* Home.swift */, + B7D587D322A08965006E8DCF /* CategoryRow.swift */, + B7D587EA22A09A86006E8DCF /* PageViewController.swift */, + B7D587EC22A09B79006E8DCF /* PageView.swift */, + B7D587EE22A09D0C006E8DCF /* PageControl.swift */, + B73948A0229F2E1F00C47603 /* LandmarkList.swift */, + B739489E229F2D9700C47603 /* LandmarkRow.swift */, + B7394869229F194000C47603 /* LandmarkDetail.swift */, + B7D587B5229F825D006E8DCF /* HikeView.swift */, + B7D587BB229F82EB006E8DCF /* HikeDetail.swift */, + B7D587DC22A08DD6006E8DCF /* HikeBadge.swift */, + B7310DD0229F6839001079B9 /* HexagonParameters.swift */, + B739487D229F1C0100C47603 /* Supporting Views */, + B7394883229F291A00C47603 /* Resources */, + B739486B229F194200C47603 /* Assets.xcassets */, + B7394870229F194200C47603 /* LaunchScreen.storyboard */, + B7394873229F194200C47603 /* Info.plist */, + B739486D229F194200C47603 /* Preview Content */, + ); + path = Landmarks; + sourceTree = ""; + }; + B739486D229F194200C47603 /* Preview Content */ = { + isa = PBXGroup; + children = ( + B739486E229F194200C47603 /* Preview Assets.xcassets */, + ); + path = "Preview Content"; + sourceTree = ""; + }; + B739487D229F1C0100C47603 /* Supporting Views */ = { + isa = PBXGroup; + children = ( + B7D587E022A0914D006E8DCF /* FeatureCard.swift */, + B7394879229F1B3F00C47603 /* CircleImage.swift */, + B739487B229F1B6800C47603 /* MapView.swift */, + B7310DD2229F6CA9001079B9 /* Badge.swift */, + B7D587AF229F73C1006E8DCF /* BadgeSymbol.swift */, + B7D587B1229F7406006E8DCF /* RotatedBadgeSymbol.swift */, + B7D587AD229F7382006E8DCF /* BadgeBackground.swift */, + B7D587BD229F82FF006E8DCF /* HikeGraph.swift */, + B7D587B7229F826D006E8DCF /* GraphCapsule.swift */, + ); + path = "Supporting Views"; + sourceTree = ""; + }; + B739487E229F282200C47603 /* Models */ = { + isa = PBXGroup; + children = ( + B7D587D522A08C97006E8DCF /* Profile.swift */, + B739487F229F28B900C47603 /* Landmark.swift */, + B7D587E822A09809006E8DCF /* Data.swift */, + B7D587B9229F8288006E8DCF /* Hike.swift */, + B7D2AAC4229F4D7C0061E5F5 /* UserData.swift */, + ); + path = Models; + sourceTree = ""; + }; + B7394883229F291A00C47603 /* Resources */ = { + isa = PBXGroup; + children = ( + B739488E229F292E00C47603 /* landmarkData.json */, + B7D587BF229F830B006E8DCF /* hikeData.json */, + B7D587E222A097E2006E8DCF /* charleyrivers_feature.jpg */, + B7D587E322A097E2006E8DCF /* stmarylake_feature.jpg */, + B7D587E422A097E2006E8DCF /* turtlerock_feature.jpg */, + B7394890229F292F00C47603 /* chilkoottrail.jpg */, + B739488F229F292F00C47603 /* chincoteague.jpg */, + B739488A229F292E00C47603 /* hiddenlake.jpg */, + B7394886229F292E00C47603 /* icybay.jpg */, + B7394887229F292E00C47603 /* lakemcdonald.jpg */, + B7394884229F292D00C47603 /* rainbowlake.jpg */, + B739488D229F292E00C47603 /* silversalmoncreek.jpg */, + B739488B229F292E00C47603 /* stmarylake.jpg */, + B7394888229F292E00C47603 /* turtlerock.jpg */, + B739488C229F292E00C47603 /* twinlake.jpg */, + B7394889229F292E00C47603 /* umbagog.jpg */, + B73948A2229F3E2200C47603 /* charleyrivers.jpg */, + ); + path = Resources; + sourceTree = ""; + }; + B7D587D722A08D16006E8DCF /* Profiles */ = { + isa = PBXGroup; + children = ( + B7D587D822A08D33006E8DCF /* ProfileHost.swift */, + B7D587DA22A08D67006E8DCF /* ProfileSummary.swift */, + B7D587DE22A08E1A006E8DCF /* ProfileEditor.swift */, + ); + path = Profiles; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + B7394861229F194000C47603 /* Landmarks */ = { + isa = PBXNativeTarget; + buildConfigurationList = B7394876229F194200C47603 /* Build configuration list for PBXNativeTarget "Landmarks" */; + buildPhases = ( + B739485E229F194000C47603 /* Sources */, + B739485F229F194000C47603 /* Frameworks */, + B7394860229F194000C47603 /* Resources */, + C602AC70C605937000000001, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Landmarks; + productName = Landmarks; + productReference = B7394862229F194000C47603 /* Landmarks.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + B739485A229F194000C47603 /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 1100; + LastUpgradeCheck = 1100; + ORGANIZATIONNAME = Apple; + TargetAttributes = { + B7394861229F194000C47603 = { + CreatedOnToolsVersion = 11.0; + }; + }; + }; + buildConfigurationList = B739485D229F194000C47603 /* Build configuration list for PBXProject "InterfacingWithUIKit" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = B7394859229F194000C47603; + productRefGroup = B7394863229F194000C47603 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + B7394861229F194000C47603 /* Landmarks */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + B7394860229F194000C47603 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + B739489A229F292F00C47603 /* silversalmoncreek.jpg in Resources */, + B7394894229F292F00C47603 /* lakemcdonald.jpg in Resources */, + B7D587C0229F830B006E8DCF /* hikeData.json in Resources */, + B7394872229F194200C47603 /* LaunchScreen.storyboard in Resources */, + B73948A3229F3E2200C47603 /* charleyrivers.jpg in Resources */, + B7394891229F292F00C47603 /* rainbowlake.jpg in Resources */, + B7D587E522A097E2006E8DCF /* charleyrivers_feature.jpg in Resources */, + B739486F229F194200C47603 /* Preview Assets.xcassets in Resources */, + B7394895229F292F00C47603 /* turtlerock.jpg in Resources */, + B739486C229F194200C47603 /* Assets.xcassets in Resources */, + B7394899229F292F00C47603 /* twinlake.jpg in Resources */, + B7D587E622A097E2006E8DCF /* stmarylake_feature.jpg in Resources */, + B7394896229F292F00C47603 /* umbagog.jpg in Resources */, + B739489D229F292F00C47603 /* chilkoottrail.jpg in Resources */, + B739489C229F292F00C47603 /* chincoteague.jpg in Resources */, + B739489B229F292F00C47603 /* landmarkData.json in Resources */, + B7394893229F292F00C47603 /* icybay.jpg in Resources */, + B7394897229F292F00C47603 /* hiddenlake.jpg in Resources */, + B7394898229F292F00C47603 /* stmarylake.jpg in Resources */, + B7D587E722A097E2006E8DCF /* turtlerock_feature.jpg in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + B739485E229F194000C47603 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + B7310DD3229F6CA9001079B9 /* Badge.swift in Sources */, + B7D587E122A0914D006E8DCF /* FeatureCard.swift in Sources */, + B7394866229F194000C47603 /* AppDelegate.swift in Sources */, + B7D587D922A08D33006E8DCF /* ProfileHost.swift in Sources */, + B7D587D622A08C97006E8DCF /* Profile.swift in Sources */, + B7D587B8229F826D006E8DCF /* GraphCapsule.swift in Sources */, + B7D587D422A08965006E8DCF /* CategoryRow.swift in Sources */, + B7D587E922A09809006E8DCF /* Data.swift in Sources */, + B739487A229F1B3F00C47603 /* CircleImage.swift in Sources */, + B739487C229F1B6800C47603 /* MapView.swift in Sources */, + B7D587BA229F8288006E8DCF /* Hike.swift in Sources */, + B7D587BC229F82EB006E8DCF /* HikeDetail.swift in Sources */, + B7D587B6229F825D006E8DCF /* HikeView.swift in Sources */, + B7310DD1229F6839001079B9 /* HexagonParameters.swift in Sources */, + B73948A1229F2E1F00C47603 /* LandmarkList.swift in Sources */, + B7D587B0229F73C1006E8DCF /* BadgeSymbol.swift in Sources */, + B7D587B2229F7406006E8DCF /* RotatedBadgeSymbol.swift in Sources */, + B7D587DD22A08DD6006E8DCF /* HikeBadge.swift in Sources */, + B7D587D222A0892C006E8DCF /* Home.swift in Sources */, + B7D587BE229F82FF006E8DCF /* HikeGraph.swift in Sources */, + B7394868229F194000C47603 /* SceneDelegate.swift in Sources */, + B7D587AE229F7382006E8DCF /* BadgeBackground.swift in Sources */, + B7D587EB22A09A86006E8DCF /* PageViewController.swift in Sources */, + B739486A229F194000C47603 /* LandmarkDetail.swift in Sources */, + B739489F229F2D9700C47603 /* LandmarkRow.swift in Sources */, + B7D587ED22A09B79006E8DCF /* PageView.swift in Sources */, + B7D587DB22A08D67006E8DCF /* ProfileSummary.swift in Sources */, + B7D587EF22A09D0C006E8DCF /* PageControl.swift in Sources */, + B7D2AAC5229F4D7C0061E5F5 /* UserData.swift in Sources */, + B7394881229F28B900C47603 /* Landmark.swift in Sources */, + B7D587DF22A08E1A006E8DCF /* ProfileEditor.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + B7394870229F194200C47603 /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + B7394871229F194200C47603 /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + B7394874229F194200C47603 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7D7349B07D72194000000001 /* SampleCode.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + B7394875229F194200C47603 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7D7349B07D72194000000001 /* SampleCode.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + B7394877229F194200C47603 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7D7349B07D72194000000001 /* SampleCode.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_ASSET_PATHS = "Landmarks/Preview\\ Content"; + DEVELOPMENT_TEAM = ""; + ENABLE_PREVIEWS = YES; + INFOPLIST_FILE = Landmarks/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = "com.example.apple-samplecode.Landmarks${SAMPLE_CODE_DISAMBIGUATOR}"; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + B7394878229F194200C47603 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7D7349B07D72194000000001 /* SampleCode.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_ASSET_PATHS = "Landmarks/Preview\\ Content"; + DEVELOPMENT_TEAM = ""; + ENABLE_PREVIEWS = YES; + INFOPLIST_FILE = Landmarks/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = "com.example.apple-samplecode.Landmarks${SAMPLE_CODE_DISAMBIGUATOR}"; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + B739485D229F194000C47603 /* Build configuration list for PBXProject "InterfacingWithUIKit" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + B7394874229F194200C47603 /* Debug */, + B7394875229F194200C47603 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + B7394876229F194200C47603 /* Build configuration list for PBXNativeTarget "Landmarks" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + B7394877229F194200C47603 /* Debug */, + B7394878229F194200C47603 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = B739485A229F194000C47603 /* Project object */; +} diff --git a/Other Projects/Interfacing With UIKit/Complete/Landmarks/InterfacingWithUIKit.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/Other Projects/Interfacing With UIKit/Complete/Landmarks/InterfacingWithUIKit.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 0000000..3ddf867 --- /dev/null +++ b/Other Projects/Interfacing With UIKit/Complete/Landmarks/InterfacingWithUIKit.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,8 @@ + + + + + BuildSystemType + Latest + + diff --git a/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/AppDelegate.swift b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/AppDelegate.swift new file mode 100644 index 0000000..e22943b --- /dev/null +++ b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/AppDelegate.swift @@ -0,0 +1,36 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +The application delegate. +*/ + +import UIKit + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { + // Override point for customization after application launch. + return true + } + + func applicationWillTerminate(_ application: UIApplication) { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. + } + + // MARK: UISceneSession Lifecycle + func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration { + // Called when a new scene session is being created. + // Use this method to select a configuration to create the new scene with. + return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role) + } + + func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) { + // Called when the user discards a scene session. + // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions. + // Use this method to release any resources that were specific to the discarded scenes, as they will not return. + } + +} + diff --git a/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/Contents.json b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..fa0d2db --- /dev/null +++ b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,113 @@ +{ + "images" : [ + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "landmark_app_icon_40x40.png", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "3x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "landmark_app_icon_58x58.png", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "landmark_app_icon_87x87.png", + "scale" : "3x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "landmark_app_icon_80x80.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "landmark_app_icon_120x120.png", + "scale" : "3x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "landmark_app_icon_120x120-1.png", + "scale" : "2x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "landmark_app_icon_180x180.png", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "1x" + }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "landmark_app_icon_40x40-1.png", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "landmark_app_icon_58x58-1.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "landmark_app_icon_40x40-2.png", + "scale" : "1x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "landmark_app_icon_80x80-1.png", + "scale" : "2x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "landmark_app_icon_76x76.png", + "scale" : "1x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "landmark_app_icon_152x152.png", + "scale" : "2x" + }, + { + "size" : "83.5x83.5", + "idiom" : "ipad", + "filename" : "landmark_app_icon_167x167.png", + "scale" : "2x" + }, + { + "size" : "1024x1024", + "idiom" : "ios-marketing", + "filename" : "landmark_app_icon_1024x1024.png", + "scale" : "1x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_1024x1024.png b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_1024x1024.png new file mode 100644 index 0000000..00d81c1 Binary files /dev/null and b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_1024x1024.png differ diff --git a/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_120x120-1.png b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_120x120-1.png new file mode 100644 index 0000000..d382b8b Binary files /dev/null and b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_120x120-1.png differ diff --git a/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_120x120.png b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_120x120.png new file mode 100644 index 0000000..d382b8b Binary files /dev/null and b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_120x120.png differ diff --git a/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_152x152.png b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_152x152.png new file mode 100644 index 0000000..11057f8 Binary files /dev/null and b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_152x152.png differ diff --git a/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_167x167.png b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_167x167.png new file mode 100644 index 0000000..f73bc26 Binary files /dev/null and b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_167x167.png differ diff --git a/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_180x180.png b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_180x180.png new file mode 100644 index 0000000..b02738c Binary files /dev/null and b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_180x180.png differ diff --git a/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40-1.png b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40-1.png new file mode 100644 index 0000000..abaff0e Binary files /dev/null and b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40-1.png differ diff --git a/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40-2.png b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40-2.png new file mode 100644 index 0000000..abaff0e Binary files /dev/null and b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40-2.png differ diff --git a/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40.png b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40.png new file mode 100644 index 0000000..abaff0e Binary files /dev/null and b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40.png differ diff --git a/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_58x58-1.png b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_58x58-1.png new file mode 100644 index 0000000..cf7c73d Binary files /dev/null and b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_58x58-1.png differ diff --git a/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_58x58.png b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_58x58.png new file mode 100644 index 0000000..cf7c73d Binary files /dev/null and b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_58x58.png differ diff --git a/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_76x76.png b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_76x76.png new file mode 100644 index 0000000..3eff85b Binary files /dev/null and b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_76x76.png differ diff --git a/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_80x80-1.png b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_80x80-1.png new file mode 100644 index 0000000..6f33f66 Binary files /dev/null and b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_80x80-1.png differ diff --git a/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_80x80.png b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_80x80.png new file mode 100644 index 0000000..6f33f66 Binary files /dev/null and b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_80x80.png differ diff --git a/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_87x87.png b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_87x87.png new file mode 100644 index 0000000..9e1616c Binary files /dev/null and b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_87x87.png differ diff --git a/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Assets.xcassets/Contents.json b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Assets.xcassets/turtlerock.imageset/Contents.json b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Assets.xcassets/turtlerock.imageset/Contents.json new file mode 100644 index 0000000..5bfd7bf --- /dev/null +++ b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Assets.xcassets/turtlerock.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "turtlerock.jpg", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Assets.xcassets/turtlerock.imageset/turtlerock.jpg b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Assets.xcassets/turtlerock.imageset/turtlerock.jpg new file mode 100644 index 0000000..68bcd3e Binary files /dev/null and b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Assets.xcassets/turtlerock.imageset/turtlerock.jpg differ diff --git a/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Base.lproj/LaunchScreen.storyboard b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000..865e932 --- /dev/null +++ b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/CategoryRow.swift b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/CategoryRow.swift new file mode 100644 index 0000000..e3d5760 --- /dev/null +++ b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/CategoryRow.swift @@ -0,0 +1,64 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A view showing a scrollable list of landmarks. +*/ + +import SwiftUI + +struct CategoryRow: View { + var categoryName: String + var items: [Landmark] + + var body: some View { + VStack(alignment: .leading) { + Text(self.categoryName) + .font(.headline) + .padding(.leading, 15) + .padding(.top, 5) + + ScrollView(.horizontal) { + HStack(alignment: .top, spacing: 0) { + ForEach(self.items, id: \.name) { landmark in + NavigationLink( + destination: LandmarkDetail( + landmark: landmark + ) + ) { + CategoryItem(landmark: landmark) + } + } + } + } + .frame(height: 185) + } + } +} + +struct CategoryItem: View { + var landmark: Landmark + var body: some View { + VStack(alignment: .leading) { + landmark + .image(forSize: 155) + .renderingMode(.original) + .cornerRadius(5) + Text(landmark.name) + .foregroundColor(.primary) + .font(.caption) + } + .padding(.leading, 15) + } +} + +#if DEBUG +struct CategoryRow_Previews: PreviewProvider { + static var previews: some View { + CategoryRow( + categoryName: landmarkData[0].category.rawValue, + items: Array(landmarkData.prefix(4)) + ) + } +} +#endif diff --git a/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/HexagonParameters.swift b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/HexagonParameters.swift new file mode 100644 index 0000000..8decba4 --- /dev/null +++ b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/HexagonParameters.swift @@ -0,0 +1,57 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +Size, position, and other information used to draw a badge. +*/ + +import SwiftUI + +struct HexagonParameters { + struct Segment { + let useWidth: (CGFloat, CGFloat, CGFloat) + let xFactors: (CGFloat, CGFloat, CGFloat) + let useHeight: (CGFloat, CGFloat, CGFloat) + let yFactors: (CGFloat, CGFloat, CGFloat) + } + + static let adjustment: CGFloat = 0.085 + static let points = [ + Segment( + useWidth: (1.00, 1.00, 1.00), + xFactors: (0.60, 0.40, 0.50), + useHeight: (1.00, 1.00, 0.00), + yFactors: (0.05, 0.05, 0.00) + ), + Segment( + useWidth: (1.00, 1.00, 0.00), + xFactors: (0.05, 0.00, 0.00), + useHeight: (1.00, 1.00, 1.00), + yFactors: (0.20 + adjustment, 0.30 + adjustment, 0.25 + adjustment) + ), + Segment( + useWidth: (1.00, 1.00, 0.00), + xFactors: (0.00, 0.05, 0.00), + useHeight: (1.00, 1.00, 1.00), + yFactors: (0.70 - adjustment, 0.80 - adjustment, 0.75 - adjustment) + ), + Segment( + useWidth: (1.00, 1.00, 1.00), + xFactors: (0.40, 0.60, 0.50), + useHeight: (1.00, 1.00, 1.00), + yFactors: (0.95, 0.95, 1.00) + ), + Segment( + useWidth: (1.00, 1.00, 1.00), + xFactors: (0.95, 1.00, 1.00), + useHeight: (1.00, 1.00, 1.00), + yFactors: (0.80 - adjustment, 0.70 - adjustment, 0.75 - adjustment) + ), + Segment( + useWidth: (1.00, 1.00, 1.00), + xFactors: (1.00, 0.95, 1.00), + useHeight: (1.00, 1.00, 1.00), + yFactors: (0.30 + adjustment, 0.20 + adjustment, 0.25 + adjustment) + ) + ] +} diff --git a/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/HikeBadge.swift b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/HikeBadge.swift new file mode 100644 index 0000000..52716cf --- /dev/null +++ b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/HikeBadge.swift @@ -0,0 +1,31 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A view that shows a badge for hiking. +*/ + +import SwiftUI + +struct HikeBadge: View { + var name: String + var body: some View { + VStack(alignment: .center) { + Badge() + .frame(width: 300, height: 300) + .scaleEffect(1.0 / 3.0) + .frame(width: 100, height: 100) + Text(name) + .font(.caption) + .accessibility(label: Text("Badge for \(name).")) + } + } +} + +#if DEBUG +struct HikeBadge_Previews: PreviewProvider { + static var previews: some View { + HikeBadge(name: "Preview Testing") + } +} +#endif diff --git a/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/HikeDetail.swift b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/HikeDetail.swift new file mode 100644 index 0000000..1d63904 --- /dev/null +++ b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/HikeDetail.swift @@ -0,0 +1,49 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A view showing the details for a hike. +*/ + +import SwiftUI + +struct HikeDetail: View { + let hike: Hike + @State var dataToShow = \Hike.Observation.elevation + + var buttons = [ + ("Elevation", \Hike.Observation.elevation), + ("Heart Rate", \Hike.Observation.heartRate), + ("Pace", \Hike.Observation.pace), + ] + + var body: some View { + return VStack { + HikeGraph(hike: hike, path: dataToShow) + .frame(height: 200, alignment: .center) + + HStack(spacing: 25) { + ForEach(buttons, id: \.0) { value in + Button(action: { + self.dataToShow = value.1 + }) { + Text(verbatim: value.0) + .font(.system(size: 15)) + .foregroundColor(value.1 == self.dataToShow + ? Color.gray + : Color.accentColor) + .animation(nil) + } + } + } + } + } +} + +#if DEBUG +struct HikeDetail_Previews: PreviewProvider { + static var previews: some View { + HikeDetail(hike: hikeData[0]) + } +} +#endif diff --git a/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/HikeView.swift b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/HikeView.swift new file mode 100644 index 0000000..b9964c7 --- /dev/null +++ b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/HikeView.swift @@ -0,0 +1,68 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A view displaying inforamtion about a hike, including an elevation graph. +*/ + +import SwiftUI + +struct HikeView: View { + var hike: Hike + @State private var showDetail = false + + var transition: AnyTransition { + let insertion = AnyTransition.move(edge: .trailing) + .combined(with: .opacity) + let removal = AnyTransition.scale(scale: 0.0) + .combined(with: .opacity) + return .asymmetric(insertion: insertion, removal: removal) + } + + var body: some View { + VStack { + HStack { + HikeGraph(hike: hike, path: \.elevation) + .frame(width: 50, height: 30) + .animation(nil) + + VStack(alignment: .leading) { + Text(verbatim: hike.name) + .font(.headline) + Text(verbatim: hike.distanceText) + } + + Spacer() + + Button(action: { + withAnimation { + self.showDetail.toggle() + } + }) { + Image(systemName: "chevron.right.circle") + .imageScale(.large) + .rotationEffect(.degrees(showDetail ? 90 : 0)) + .scaleEffect(showDetail ? 1.5 : 1) + .padding() + } + } + + if showDetail { + HikeDetail(hike: hike) + .transition(transition) + } + } + } +} + +#if DEBUG +struct HikeView_Previews: PreviewProvider { + static var previews: some View { + VStack { + HikeView(hike: hikeData[0]) + .padding() + Spacer() + } + } +} +#endif diff --git a/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Home.swift b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Home.swift new file mode 100644 index 0000000..9614cf6 --- /dev/null +++ b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Home.swift @@ -0,0 +1,71 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A view showing featured landmarks above a list of all of the landmarks. +*/ + +import SwiftUI + +struct CategoryHome: View { + @State private var isProfilePresented = false + + var categories: [String: [Landmark]] { + .init( + grouping: landmarkData, + by: { $0.category.rawValue } + ) + } + + var featured: [Landmark] { + landmarkData.filter { $0.isFeatured } + } + + var body: some View { + NavigationView { + List { + FeaturedLandmarks(landmarks: featured) + .scaledToFill() + .frame(height: 200) + .clipped() + .listRowInsets(EdgeInsets()) + + ForEach(categories.keys.sorted(), id: \.self) { key in + CategoryRow(categoryName: key, items: self.categories[key]!) + } + .listRowInsets(EdgeInsets()) + + NavigationLink(destination: LandmarkList()) { + Text("See All") + } + } + .navigationBarTitle(Text("Featured")) + .navigationBarItems(trailing: + Button(action: { + self.isProfilePresented = true + }) { + Image(systemName: "person.crop.circle") + .imageScale(.large) + .accessibility(label: Text("User Profile")) + .padding() + } + ).sheet(isPresented: $isProfilePresented, + content: { ProfileHost().environmentObject(UserData()) }) + } + } +} + +struct FeaturedLandmarks: View { + var landmarks: [Landmark] + var body: some View { + landmarks[0].image(forSize: 250).resizable() + } +} + +#if DEBUG +struct CategoryHome_Previews: PreviewProvider { + static var previews: some View { + CategoryHome() + } +} +#endif diff --git a/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Info.plist b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Info.plist new file mode 100644 index 0000000..e8bb4c6 --- /dev/null +++ b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Info.plist @@ -0,0 +1,62 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + $(PRODUCT_BUNDLE_PACKAGE_TYPE) + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UIApplicationSceneManifest + + UIApplicationSupportsMultipleScenes + + UISceneConfigurations + + UIWindowSceneSessionRoleApplication + + + UILaunchStoryboardName + LaunchScreen + UISceneConfigurationName + Default Configuration + UISceneDelegateClassName + $(PRODUCT_MODULE_NAME).SceneDelegate + + + + + UILaunchStoryboardName + LaunchScreen + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/LandmarkDetail.swift b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/LandmarkDetail.swift new file mode 100644 index 0000000..6c290a3 --- /dev/null +++ b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/LandmarkDetail.swift @@ -0,0 +1,71 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A view showing the details for a landmark. +*/ + +import SwiftUI + +struct LandmarkDetail: View { + @EnvironmentObject var userData: UserData + var landmark: Landmark + + var landmarkIndex: Int { + userData.landmarks.firstIndex(where: { $0.id == landmark.id })! + } + + var body: some View { + VStack { + MapView(coordinate: landmark.locationCoordinate) + .edgesIgnoringSafeArea(.top) + .frame(height: 300) + + CircleImage(image: landmark.image(forSize: 250)) + .offset(x: 0, y: -130) + .padding(.bottom, -130) + + VStack(alignment: .leading) { + HStack { + Text(verbatim: landmark.name) + .font(.title) + + Button(action: { + self.userData.landmarks[self.landmarkIndex] + .isFavorite.toggle() + }) { + if self.userData.landmarks[self.landmarkIndex] + .isFavorite { + Image(systemName: "star.fill") + .foregroundColor(Color.yellow) + } else { + Image(systemName: "star") + .foregroundColor(Color.gray) + } + } + } + + HStack(alignment: .top) { + Text(verbatim: landmark.park) + .font(.subheadline) + Spacer() + Text(verbatim: landmark.state) + .font(.subheadline) + } + } + .padding() + + Spacer() + } + } +} + +#if DEBUG +struct LandmarkDetail_Preview: PreviewProvider { + static var previews: some View { + let userData = UserData() + return LandmarkDetail(landmark: userData.landmarks[0]) + .environmentObject(userData) + } +} +#endif diff --git a/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/LandmarkList.swift b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/LandmarkList.swift new file mode 100644 index 0000000..be4b764 --- /dev/null +++ b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/LandmarkList.swift @@ -0,0 +1,46 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A view showing a list of landmarks. +*/ + +import SwiftUI + +struct LandmarkList: View { + @EnvironmentObject private var userData: UserData + + var body: some View { + NavigationView { + List { + Toggle(isOn: $userData.showFavoritesOnly) { + Text("Show Favorites Only") + } + + ForEach(userData.landmarks) { landmark in + if !self.userData.showFavoritesOnly || landmark.isFavorite { + NavigationLink( + destination: LandmarkDetail(landmark: landmark) + .environmentObject(self.userData)) { + LandmarkRow(landmark: landmark) + } + } + } + } + .navigationBarTitle(Text("Landmarks"), displayMode: .large) + } + } +} + +#if DEBUG +struct LandmarksList_Previews: PreviewProvider { + static var previews: some View { + ForEach(["iPhone SE", "iPhone XS Max"], id: \.self) { deviceName in + LandmarkList() + .previewDevice(PreviewDevice(rawValue: deviceName)) + .previewDisplayName(deviceName) + } + .environmentObject(UserData()) + } +} +#endif diff --git a/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Models/Data.swift b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Models/Data.swift new file mode 100644 index 0000000..5fd193e --- /dev/null +++ b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Models/Data.swift @@ -0,0 +1,100 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +Helpers for loading images and data. +*/ + +import Foundation +import CoreLocation +import UIKit +import SwiftUI + +let landmarkData: [Landmark] = load("landmarkData.json") +let features = landmarkData.filter { $0.isFeatured } +let hikeData: [Hike] = load("hikeData.json") + +func load(_ filename: String, as type: T.Type = T.self) -> T { + let data: Data + + guard let file = Bundle.main.url(forResource: filename, withExtension: nil) + else { + fatalError("Couldn't find \(filename) in main bundle.") + } + + do { + data = try Data(contentsOf: file) + } catch { + fatalError("Couldn't load \(filename) from main bundle:\n\(error)") + } + + do { + let decoder = JSONDecoder() + return try decoder.decode(T.self, from: data) + } catch { + fatalError("Couldn't parse \(filename) as \(T.self):\n\(error)") + } +} + +final class ImageStore { + fileprivate typealias _ImageDictionary = [String: [Int: CGImage]] + fileprivate var images: _ImageDictionary = [:] + + fileprivate static var originalSize = 250 + fileprivate static var scale = 2 + + static var shared = ImageStore() + + func image(name: String, size: Int) -> Image { + let index = _guaranteeInitialImage(name: name) + + let sizedImage = images.values[index][size] + ?? _sizeImage(images.values[index][ImageStore.originalSize]!, to: size * ImageStore.scale) + images.values[index][size] = sizedImage + + return Image(sizedImage, scale: CGFloat(ImageStore.scale), label: Text(verbatim: name)) + } + + static func loadImage(name: String) -> CGImage { + guard + let url = Bundle.main.url(forResource: name, withExtension: "jpg"), + let imageSource = CGImageSourceCreateWithURL(url as NSURL, nil), + let image = CGImageSourceCreateImageAtIndex(imageSource, 0, nil) + else { + fatalError("Couldn't load image \(name).jpg from main bundle.") + } + return image + } + + fileprivate func _guaranteeInitialImage(name: String) -> _ImageDictionary.Index { + if let index = images.index(forKey: name) { return index } + + let image = ImageStore.loadImage(name: name) + images[name] = [ImageStore.originalSize: image] + return images.index(forKey: name)! + } + + fileprivate func _sizeImage(_ image: CGImage, to size: Int) -> CGImage { + guard + let colorSpace = image.colorSpace, + let context = CGContext( + data: nil, + width: size, height: size, + bitsPerComponent: image.bitsPerComponent, + bytesPerRow: image.bytesPerRow, + space: colorSpace, + bitmapInfo: image.bitmapInfo.rawValue) + else { + fatalError("Couldn't create graphics context.") + } + context.interpolationQuality = .high + context.draw(image, in: CGRect(x: 0, y: 0, width: size, height: size)) + + if let sizedImage = context.makeImage() { + return sizedImage + } else { + fatalError("Couldn't resize image.") + } + } +} + diff --git a/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Models/Hike.swift b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Models/Hike.swift new file mode 100644 index 0000000..dfd2bb8 --- /dev/null +++ b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Models/Hike.swift @@ -0,0 +1,31 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +The model for a hike. +*/ + +import SwiftUI + +struct Hike: Codable, Hashable, Identifiable { + var name: String + var id: Int + var distance: Double + var difficulty: Int + var observations: [Observation] + + static var formatter = LengthFormatter() + + var distanceText: String { + return Hike.formatter + .string(fromValue: distance, unit: .kilometer) + } + + struct Observation: Codable, Hashable { + var distanceFromStart: Double + + var elevation: Range + var pace: Range + var heartRate: Range + } +} diff --git a/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Models/Landmark.swift b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Models/Landmark.swift new file mode 100644 index 0000000..fafe700 --- /dev/null +++ b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Models/Landmark.swift @@ -0,0 +1,52 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +The model for an individual landmark. +*/ + +import SwiftUI +import CoreLocation + +struct Landmark: Hashable, Codable, Identifiable { + var id: Int + var name: String + fileprivate var imageName: String + fileprivate var coordinates: Coordinates + var state: String + var park: String + var category: Category + var isFavorite: Bool + var isFeatured: Bool + + var locationCoordinate: CLLocationCoordinate2D { + CLLocationCoordinate2D( + latitude: coordinates.latitude, + longitude: coordinates.longitude) + } + + var featureImage: Image? { + guard isFeatured else { return nil } + + return Image( + ImageStore.loadImage(name: "\(imageName)_feature"), + scale: 2, + label: Text(verbatim: name)) + } + + func image(forSize size: Int) -> Image { + ImageStore.shared.image(name: imageName, size: size) + } + + enum Category: String, CaseIterable, Codable, Hashable { + case featured = "Featured" + case lakes = "Lakes" + case rivers = "Rivers" + case mountains = "Mountains" + } +} + +struct Coordinates: Hashable, Codable { + var latitude: Double + var longitude: Double +} diff --git a/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Models/Profile.swift b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Models/Profile.swift new file mode 100644 index 0000000..7c30519 --- /dev/null +++ b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Models/Profile.swift @@ -0,0 +1,30 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +An object that models a user profile. +*/ +import Foundation + +struct Profile { + var username: String + var prefersNotifications: Bool + var seasonalPhoto: Season + var goalDate: Date + + static let `default` = Self(username: "g_kumar", prefersNotifications: true, seasonalPhoto: .winter) + + init(username: String, prefersNotifications: Bool = true, seasonalPhoto: Season = .winter) { + self.username = username + self.prefersNotifications = prefersNotifications + self.seasonalPhoto = seasonalPhoto + self.goalDate = Date() + } + + enum Season: String, CaseIterable { + case spring = "🌷" + case summer = "🌞" + case autumn = "🍂" + case winter = "☃️" + } +} diff --git a/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Models/UserData.swift b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Models/UserData.swift new file mode 100644 index 0000000..afc2cca --- /dev/null +++ b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Models/UserData.swift @@ -0,0 +1,15 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A model object that stores app data. +*/ + +import Combine +import SwiftUI + +final class UserData: ObservableObject { + @Published var showFavoritesOnly = false + + @Published var landmarks = landmarkData +} diff --git a/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/PageControl.swift b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/PageControl.swift new file mode 100644 index 0000000..40c3259 --- /dev/null +++ b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/PageControl.swift @@ -0,0 +1,47 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A view wrapping a UIPageControl. +*/ + +import SwiftUI + +import UIKit + +struct PageControl: UIViewRepresentable { + var numberOfPages: Int + @Binding var currentPage: Int + + func makeCoordinator() -> Coordinator { + Coordinator(self) + } + + func makeUIView(context: Context) -> UIPageControl { + let control = UIPageControl() + control.numberOfPages = numberOfPages + control.addTarget( + context.coordinator, + action: #selector(Coordinator.updateCurrentPage(sender:)), + for: .valueChanged) + + return control + } + + func updateUIView(_ uiView: UIPageControl, context: Context) { + uiView.currentPage = currentPage + } + + class Coordinator: NSObject { + var control: PageControl + + init(_ control: PageControl) { + self.control = control + } + + @objc + func updateCurrentPage(sender: UIPageControl) { + control.currentPage = sender.currentPage + } + } +} diff --git a/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/PageView.swift b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/PageView.swift new file mode 100644 index 0000000..16e1f00 --- /dev/null +++ b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/PageView.swift @@ -0,0 +1,33 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A view for bridging a UIPageViewController. +*/ + +import SwiftUI + +struct PageView: View { + var viewControllers: [UIHostingController] + @State var currentPage = 0 + + init(_ views: [Page]) { + self.viewControllers = views.map { UIHostingController(rootView: $0) } + } + + var body: some View { + ZStack(alignment: .bottomTrailing) { + PageViewController(controllers: viewControllers, currentPage: $currentPage) + PageControl(numberOfPages: viewControllers.count, currentPage: $currentPage) + .padding(.trailing) + } + } +} + +#if DEBUG +struct PageView_Previews: PreviewProvider { + static var previews: some View { + PageView(features.map { FeatureCard(landmark: $0) }) + } +} +#endif diff --git a/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/PageViewController.swift b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/PageViewController.swift new file mode 100644 index 0000000..a9410cb --- /dev/null +++ b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/PageViewController.swift @@ -0,0 +1,73 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A view that wraps a UIPageViewController. +*/ + +import SwiftUI +import UIKit + +struct PageViewController: UIViewControllerRepresentable { + var controllers: [UIViewController] + @Binding var currentPage: Int + + func makeCoordinator() -> Coordinator { + Coordinator(self) + } + + func makeUIViewController(context: Context) -> UIPageViewController { + let pageViewController = UIPageViewController( + transitionStyle: .scroll, + navigationOrientation: .horizontal) + pageViewController.dataSource = context.coordinator + pageViewController.delegate = context.coordinator + + return pageViewController + } + + func updateUIViewController(_ pageViewController: UIPageViewController, context: Context) { + pageViewController.setViewControllers( + [controllers[currentPage]], direction: .forward, animated: true) + } + + class Coordinator: NSObject, UIPageViewControllerDataSource, UIPageViewControllerDelegate { + var parent: PageViewController + + init(_ pageViewController: PageViewController) { + self.parent = pageViewController + } + + func pageViewController( + _ pageViewController: UIPageViewController, + viewControllerBefore viewController: UIViewController) -> UIViewController? { + guard let index = parent.controllers.firstIndex(of: viewController) else { + return nil + } + if index == 0 { + return parent.controllers.last + } + return parent.controllers[index - 1] + } + + func pageViewController( + _ pageViewController: UIPageViewController, + viewControllerAfter viewController: UIViewController) -> UIViewController? { + guard let index = parent.controllers.firstIndex(of: viewController) else { + return nil + } + if index + 1 == parent.controllers.count { + return parent.controllers.first + } + return parent.controllers[index + 1] + } + + func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) { + if completed, + let visibleViewController = pageViewController.viewControllers?.first, + let index = parent.controllers.firstIndex(of: visibleViewController) { + parent.currentPage = index + } + } + } +} diff --git a/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Preview Content/Preview Assets.xcassets/Contents.json b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Preview Content/Preview Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Preview Content/Preview Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Profiles/ProfileEditor.swift b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Profiles/ProfileEditor.swift new file mode 100644 index 0000000..e0fc032 --- /dev/null +++ b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Profiles/ProfileEditor.swift @@ -0,0 +1,55 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +An editable profile view. +*/ + +import SwiftUI + +struct ProfileEditor: View { + @Binding var profile: Profile + + var body: some View { + List { + HStack { + Text("Username").bold() + Divider() + TextField("", text: $profile.username) + } + + Toggle(isOn: $profile.prefersNotifications) { + Text("Enable Notifications") + } + + VStack(alignment: .leading, spacing: 20) { + Text("Seasonal Photo").bold() + + Picker("", selection: $profile.seasonalPhoto) { + ForEach(Profile.Season.allCases, id: \.self) { season in + Text(season.rawValue).tag(season) + } + }.pickerStyle(SegmentedPickerStyle()) + } + .padding(.top) + + VStack(alignment: .leading, spacing: 20) { + Text("Goal Date").bold() + DatePicker( + "", selection: $profile.goalDate, + in: Calendar.current.date(byAdding: .year, value: -1, to: profile.goalDate)! ... Calendar.current.date(byAdding: .year, value: 1, to: profile.goalDate)!, + displayedComponents: .date + ) + } + .padding(.top) + } + } +} + +#if DEBUG +struct ProfileEditor_Previews: PreviewProvider { + static var previews: some View { + ProfileEditor(profile: .constant(.default)) + } +} +#endif diff --git a/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Profiles/ProfileHost.swift b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Profiles/ProfileHost.swift new file mode 100644 index 0000000..8fb3e81 --- /dev/null +++ b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Profiles/ProfileHost.swift @@ -0,0 +1,50 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A view that hosts the profile viewer and editor. +*/ + +import SwiftUI + +struct ProfileHost: View { + @Environment(\.editMode) var mode + @State var profile = Profile.default + @State var draftProfile = Profile.default + + var body: some View { + VStack(alignment: .leading, spacing: 20) { + HStack { + if self.mode?.wrappedValue == .active { + Button(action: { + self.draftProfile = self.profile + self.mode?.animation().wrappedValue = .inactive + }) { + Text("Done") + } + } + + Spacer() + + EditButton() + } + if self.mode?.wrappedValue == .inactive { + ProfileSummary(profile: profile) + } else { + ProfileEditor(profile: $draftProfile) + .onDisappear { + self.profile = self.draftProfile + } + } + } + .padding() + } +} + +#if DEBUG +struct ProfileHost_Previews: PreviewProvider { + static var previews: some View { + ProfileHost() + } +} +#endif diff --git a/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Profiles/ProfileSummary.swift b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Profiles/ProfileSummary.swift new file mode 100644 index 0000000..b63ac4e --- /dev/null +++ b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Profiles/ProfileSummary.swift @@ -0,0 +1,65 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A view that summarizes a profile. +*/ + +import SwiftUI + +struct ProfileSummary: View { + var profile: Profile + + static var goalFormat: DateFormatter { + let formatter = DateFormatter() + formatter.dateFormat = "MMMM d, yyyy" + return formatter + } + + var body: some View { + List { + Text(profile.username) + .bold() + .font(.title) + + Text("Notifications: \(self.profile.prefersNotifications ? "Onn": "Off" )") + + Text("Seasonal Photos: \(self.profile.seasonalPhoto.rawValue)") + + Text("Goal Date: \(self.profile.goalDate, formatter: Self.goalFormat)") + + VStack(alignment: .leading) { + Text("Completed Badges") + .font(.headline) + ScrollView(.horizontal) { + HStack { + HikeBadge(name: "First Hike") + + HikeBadge(name: "Earth Day") + .hueRotation(Angle(degrees: 90)) + + HikeBadge(name: "Tenth Hike") + .grayscale(0.5) + .hueRotation(Angle(degrees: 45)) + } + } + .frame(height: 140) + } + + VStack(alignment: .leading) { + Text("Recent Hikes") + .font(.headline) + + HikeView(hike: hikeData[0]) + } + } + } +} + +#if DEBUG +struct ProfileSummary_Previews: PreviewProvider { + static var previews: some View { + ProfileSummary(profile: Profile.default) + } +} +#endif diff --git a/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Resources/charleyrivers.jpg b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Resources/charleyrivers.jpg new file mode 100644 index 0000000..17ff44b Binary files /dev/null and b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Resources/charleyrivers.jpg differ diff --git a/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Resources/charleyrivers_feature.jpg b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Resources/charleyrivers_feature.jpg new file mode 100644 index 0000000..af1d114 Binary files /dev/null and b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Resources/charleyrivers_feature.jpg differ diff --git a/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Resources/chilkoottrail.jpg b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Resources/chilkoottrail.jpg new file mode 100644 index 0000000..e7f805e Binary files /dev/null and b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Resources/chilkoottrail.jpg differ diff --git a/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Resources/chincoteague.jpg b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Resources/chincoteague.jpg new file mode 100644 index 0000000..5f47986 Binary files /dev/null and b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Resources/chincoteague.jpg differ diff --git a/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Resources/hiddenlake.jpg b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Resources/hiddenlake.jpg new file mode 100644 index 0000000..d8e804c Binary files /dev/null and b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Resources/hiddenlake.jpg differ diff --git a/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Resources/hikeData.json b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Resources/hikeData.json new file mode 100644 index 0000000..3fb1e96 --- /dev/null +++ b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Resources/hikeData.json @@ -0,0 +1,1882 @@ +[ + { + "name":"Lonesome Ridge Trail", + "id":1001, + "distance":4.5, + "difficulty":3, + "observations":[ + { + "elevation":[ + 291.65263635636268, + 309.26016677925196 + ], + "pace":[ + 396.08716481908732, + 403.68937873525232 + ], + "heartRate":[ + 117.16351898665887, + 121.95815455919609 + ], + "distanceFromStart":0 + }, + { + "elevation":[ + 299.24001936628116, + 317.44584350790012 + ], + "pace":[ + 380.19020240756623, + 395.3978319010256 + ], + "heartRate":[ + 117.6410892152911, + 124.82185220506081 + ], + "distanceFromStart":0.375 + }, + { + "elevation":[ + 303.62145464574394, + 336.05569457646544 + ], + "pace":[ + 380.55927782266116, + 397.60789726832775 + ], + "heartRate":[ + 121.52696452049059, + 127.31525441110122 + ], + "distanceFromStart":0.75 + }, + { + "elevation":[ + 319.90393365162629, + 346.26966025518789 + ], + "pace":[ + 357.94116421258531, + 398.0750288648062 + ], + "heartRate":[ + 123.75908585923588, + 132.77069404486801 + ], + "distanceFromStart":1.125 + }, + { + "elevation":[ + 354.17104439267905, + 403.57031216972939 + ], + "pace":[ + 335.07385149392701, + 397.82674381875808 + ], + "heartRate":[ + 130.8235194572915, + 140.55700591418218 + ], + "distanceFromStart":1.5 + }, + { + "elevation":[ + 357.42992871175124, + 385.92155620623635 + ], + "pace":[ + 395.16168913839374, + 404.60294066527558 + ], + "heartRate":[ + 131.5456052446734, + 134.65984504627627 + ], + "distanceFromStart":1.875 + }, + { + "elevation":[ + 345.47736721935661, + 363.18776661379422 + ], + "pace":[ + 340.82303041339082, + 404.71689228682374 + ], + "heartRate":[ + 125.1949698433959, + 131.31354363122026 + ], + "distanceFromStart":2.25 + }, + { + "elevation":[ + 346.23343025200535, + 497.23376445462401 + ], + "pace":[ + 261.27629148816021, + 331.68516208719467 + ], + "heartRate":[ + 131.67810544238606, + 154.26779645311458 + ], + "distanceFromStart":2.625 + }, + { + "elevation":[ + 491.57378483134391, + 547.49535224251053 + ], + "pace":[ + 296.05298644112088, + 401.14092967732398 + ], + "heartRate":[ + 151.36398089694217, + 166.20454793289232 + ], + "distanceFromStart":3 + }, + { + "elevation":[ + 472.06803233416338, + 531.92570520228401 + ], + "pace":[ + 395.50830663514012, + 401.67837917543591 + ], + "heartRate":[ + 134.41798110234078, + 151.90886697564241 + ], + "distanceFromStart":3.375 + }, + { + "elevation":[ + 339.81419476005283, + 461.03832527824829 + ], + "pace":[ + 395.31160487975183, + 404.49550455974907 + ], + "heartRate":[ + 129.97753472415462, + 138.13531094848992 + ], + "distanceFromStart":3.75 + }, + { + "elevation":[ + 303.1495508565697, + 342.3532820173541 + ], + "pace":[ + 395.02844559698116, + 402.65878340653796 + ], + "heartRate":[ + 127.72304232462609, + 133.26322270764186 + ], + "distanceFromStart":4.125 + } + ] + }, + { + "name":"Lonesome Ridge Trail", + "id":1002, + "distance":4.5, + "difficulty":3, + "observations":[ + { + "elevation":[ + 291.65263635636268, + 309.26016677925196 + ], + "pace":[ + 396.08716481908732, + 403.68937873525232 + ], + "heartRate":[ + 117.16351898665887, + 121.95815455919609 + ], + "distanceFromStart":0 + }, + { + "elevation":[ + 299.24001936628116, + 317.44584350790012 + ], + "pace":[ + 380.19020240756623, + 395.3978319010256 + ], + "heartRate":[ + 117.6410892152911, + 124.82185220506081 + ], + "distanceFromStart":0.375 + }, + { + "elevation":[ + 303.62145464574394, + 336.05569457646544 + ], + "pace":[ + 380.55927782266116, + 397.60789726832775 + ], + "heartRate":[ + 121.52696452049059, + 127.31525441110122 + ], + "distanceFromStart":0.75 + }, + { + "elevation":[ + 319.90393365162629, + 346.26966025518789 + ], + "pace":[ + 357.94116421258531, + 398.0750288648062 + ], + "heartRate":[ + 123.75908585923588, + 132.77069404486801 + ], + "distanceFromStart":1.125 + }, + { + "elevation":[ + 354.17104439267905, + 403.57031216972939 + ], + "pace":[ + 335.07385149392701, + 397.82674381875808 + ], + "heartRate":[ + 130.8235194572915, + 140.55700591418218 + ], + "distanceFromStart":1.5 + }, + { + "elevation":[ + 357.42992871175124, + 385.92155620623635 + ], + "pace":[ + 395.16168913839374, + 404.60294066527558 + ], + "heartRate":[ + 131.5456052446734, + 134.65984504627627 + ], + "distanceFromStart":1.875 + }, + { + "elevation":[ + 345.47736721935661, + 363.18776661379422 + ], + "pace":[ + 340.82303041339082, + 404.71689228682374 + ], + "heartRate":[ + 125.1949698433959, + 131.31354363122026 + ], + "distanceFromStart":2.25 + }, + { + "elevation":[ + 346.23343025200535, + 497.23376445462401 + ], + "pace":[ + 261.27629148816021, + 331.68516208719467 + ], + "heartRate":[ + 131.67810544238606, + 154.26779645311458 + ], + "distanceFromStart":2.625 + }, + { + "elevation":[ + 491.57378483134391, + 547.49535224251053 + ], + "pace":[ + 296.05298644112088, + 401.14092967732398 + ], + "heartRate":[ + 151.36398089694217, + 166.20454793289232 + ], + "distanceFromStart":3 + }, + { + "elevation":[ + 472.06803233416338, + 531.92570520228401 + ], + "pace":[ + 395.50830663514012, + 401.67837917543591 + ], + "heartRate":[ + 134.41798110234078, + 151.90886697564241 + ], + "distanceFromStart":3.375 + }, + { + "elevation":[ + 339.81419476005283, + 461.03832527824829 + ], + "pace":[ + 395.31160487975183, + 404.49550455974907 + ], + "heartRate":[ + 129.97753472415462, + 138.13531094848992 + ], + "distanceFromStart":3.75 + }, + { + "elevation":[ + 303.1495508565697, + 342.3532820173541 + ], + "pace":[ + 395.02844559698116, + 402.65878340653796 + ], + "heartRate":[ + 127.72304232462609, + 133.26322270764186 + ], + "distanceFromStart":4.125 + } + ] + }, + { + "name":"Lonesome Ridge Trail", + "id":1003, + "distance":4.5, + "difficulty":3, + "observations":[ + { + "elevation":[ + 291.65263635636268, + 309.26016677925196 + ], + "pace":[ + 396.08716481908732, + 403.68937873525232 + ], + "heartRate":[ + 117.16351898665887, + 121.95815455919609 + ], + "distanceFromStart":0 + }, + { + "elevation":[ + 299.24001936628116, + 317.44584350790012 + ], + "pace":[ + 380.19020240756623, + 395.3978319010256 + ], + "heartRate":[ + 117.6410892152911, + 124.82185220506081 + ], + "distanceFromStart":0.375 + }, + { + "elevation":[ + 303.62145464574394, + 336.05569457646544 + ], + "pace":[ + 380.55927782266116, + 397.60789726832775 + ], + "heartRate":[ + 121.52696452049059, + 127.31525441110122 + ], + "distanceFromStart":0.75 + }, + { + "elevation":[ + 319.90393365162629, + 346.26966025518789 + ], + "pace":[ + 357.94116421258531, + 398.0750288648062 + ], + "heartRate":[ + 123.75908585923588, + 132.77069404486801 + ], + "distanceFromStart":1.125 + }, + { + "elevation":[ + 354.17104439267905, + 403.57031216972939 + ], + "pace":[ + 335.07385149392701, + 397.82674381875808 + ], + "heartRate":[ + 130.8235194572915, + 140.55700591418218 + ], + "distanceFromStart":1.5 + }, + { + "elevation":[ + 357.42992871175124, + 385.92155620623635 + ], + "pace":[ + 395.16168913839374, + 404.60294066527558 + ], + "heartRate":[ + 131.5456052446734, + 134.65984504627627 + ], + "distanceFromStart":1.875 + }, + { + "elevation":[ + 345.47736721935661, + 363.18776661379422 + ], + "pace":[ + 340.82303041339082, + 404.71689228682374 + ], + "heartRate":[ + 125.1949698433959, + 131.31354363122026 + ], + "distanceFromStart":2.25 + }, + { + "elevation":[ + 346.23343025200535, + 497.23376445462401 + ], + "pace":[ + 261.27629148816021, + 331.68516208719467 + ], + "heartRate":[ + 131.67810544238606, + 154.26779645311458 + ], + "distanceFromStart":2.625 + }, + { + "elevation":[ + 491.57378483134391, + 547.49535224251053 + ], + "pace":[ + 296.05298644112088, + 401.14092967732398 + ], + "heartRate":[ + 151.36398089694217, + 166.20454793289232 + ], + "distanceFromStart":3 + }, + { + "elevation":[ + 472.06803233416338, + 531.92570520228401 + ], + "pace":[ + 395.50830663514012, + 401.67837917543591 + ], + "heartRate":[ + 134.41798110234078, + 151.90886697564241 + ], + "distanceFromStart":3.375 + }, + { + "elevation":[ + 339.81419476005283, + 461.03832527824829 + ], + "pace":[ + 395.31160487975183, + 404.49550455974907 + ], + "heartRate":[ + 129.97753472415462, + 138.13531094848992 + ], + "distanceFromStart":3.75 + }, + { + "elevation":[ + 303.1495508565697, + 342.3532820173541 + ], + "pace":[ + 395.02844559698116, + 402.65878340653796 + ], + "heartRate":[ + 127.72304232462609, + 133.26322270764186 + ], + "distanceFromStart":4.125 + } + ] + }, + { + "name":"Lonesome Ridge Trail", + "id":1004, + "distance":4.5, + "difficulty":3, + "observations":[ + { + "elevation":[ + 291.65263635636268, + 309.26016677925196 + ], + "pace":[ + 396.08716481908732, + 403.68937873525232 + ], + "heartRate":[ + 117.16351898665887, + 121.95815455919609 + ], + "distanceFromStart":0 + }, + { + "elevation":[ + 299.24001936628116, + 317.44584350790012 + ], + "pace":[ + 380.19020240756623, + 395.3978319010256 + ], + "heartRate":[ + 117.6410892152911, + 124.82185220506081 + ], + "distanceFromStart":0.375 + }, + { + "elevation":[ + 303.62145464574394, + 336.05569457646544 + ], + "pace":[ + 380.55927782266116, + 397.60789726832775 + ], + "heartRate":[ + 121.52696452049059, + 127.31525441110122 + ], + "distanceFromStart":0.75 + }, + { + "elevation":[ + 319.90393365162629, + 346.26966025518789 + ], + "pace":[ + 357.94116421258531, + 398.0750288648062 + ], + "heartRate":[ + 123.75908585923588, + 132.77069404486801 + ], + "distanceFromStart":1.125 + }, + { + "elevation":[ + 354.17104439267905, + 403.57031216972939 + ], + "pace":[ + 335.07385149392701, + 397.82674381875808 + ], + "heartRate":[ + 130.8235194572915, + 140.55700591418218 + ], + "distanceFromStart":1.5 + }, + { + "elevation":[ + 357.42992871175124, + 385.92155620623635 + ], + "pace":[ + 395.16168913839374, + 404.60294066527558 + ], + "heartRate":[ + 131.5456052446734, + 134.65984504627627 + ], + "distanceFromStart":1.875 + }, + { + "elevation":[ + 345.47736721935661, + 363.18776661379422 + ], + "pace":[ + 340.82303041339082, + 404.71689228682374 + ], + "heartRate":[ + 125.1949698433959, + 131.31354363122026 + ], + "distanceFromStart":2.25 + }, + { + "elevation":[ + 346.23343025200535, + 497.23376445462401 + ], + "pace":[ + 261.27629148816021, + 331.68516208719467 + ], + "heartRate":[ + 131.67810544238606, + 154.26779645311458 + ], + "distanceFromStart":2.625 + }, + { + "elevation":[ + 491.57378483134391, + 547.49535224251053 + ], + "pace":[ + 296.05298644112088, + 401.14092967732398 + ], + "heartRate":[ + 151.36398089694217, + 166.20454793289232 + ], + "distanceFromStart":3 + }, + { + "elevation":[ + 472.06803233416338, + 531.92570520228401 + ], + "pace":[ + 395.50830663514012, + 401.67837917543591 + ], + "heartRate":[ + 134.41798110234078, + 151.90886697564241 + ], + "distanceFromStart":3.375 + }, + { + "elevation":[ + 339.81419476005283, + 461.03832527824829 + ], + "pace":[ + 395.31160487975183, + 404.49550455974907 + ], + "heartRate":[ + 129.97753472415462, + 138.13531094848992 + ], + "distanceFromStart":3.75 + }, + { + "elevation":[ + 303.1495508565697, + 342.3532820173541 + ], + "pace":[ + 395.02844559698116, + 402.65878340653796 + ], + "heartRate":[ + 127.72304232462609, + 133.26322270764186 + ], + "distanceFromStart":4.125 + } + ] + }, + { + "name":"Lonesome Ridge Trail", + "id":1005, + "distance":4.5, + "difficulty":3, + "observations":[ + { + "elevation":[ + 291.65263635636268, + 309.26016677925196 + ], + "pace":[ + 396.08716481908732, + 403.68937873525232 + ], + "heartRate":[ + 117.16351898665887, + 121.95815455919609 + ], + "distanceFromStart":0 + }, + { + "elevation":[ + 299.24001936628116, + 317.44584350790012 + ], + "pace":[ + 380.19020240756623, + 395.3978319010256 + ], + "heartRate":[ + 117.6410892152911, + 124.82185220506081 + ], + "distanceFromStart":0.375 + }, + { + "elevation":[ + 303.62145464574394, + 336.05569457646544 + ], + "pace":[ + 380.55927782266116, + 397.60789726832775 + ], + "heartRate":[ + 121.52696452049059, + 127.31525441110122 + ], + "distanceFromStart":0.75 + }, + { + "elevation":[ + 319.90393365162629, + 346.26966025518789 + ], + "pace":[ + 357.94116421258531, + 398.0750288648062 + ], + "heartRate":[ + 123.75908585923588, + 132.77069404486801 + ], + "distanceFromStart":1.125 + }, + { + "elevation":[ + 354.17104439267905, + 403.57031216972939 + ], + "pace":[ + 335.07385149392701, + 397.82674381875808 + ], + "heartRate":[ + 130.8235194572915, + 140.55700591418218 + ], + "distanceFromStart":1.5 + }, + { + "elevation":[ + 357.42992871175124, + 385.92155620623635 + ], + "pace":[ + 395.16168913839374, + 404.60294066527558 + ], + "heartRate":[ + 131.5456052446734, + 134.65984504627627 + ], + "distanceFromStart":1.875 + }, + { + "elevation":[ + 345.47736721935661, + 363.18776661379422 + ], + "pace":[ + 340.82303041339082, + 404.71689228682374 + ], + "heartRate":[ + 125.1949698433959, + 131.31354363122026 + ], + "distanceFromStart":2.25 + }, + { + "elevation":[ + 346.23343025200535, + 497.23376445462401 + ], + "pace":[ + 261.27629148816021, + 331.68516208719467 + ], + "heartRate":[ + 131.67810544238606, + 154.26779645311458 + ], + "distanceFromStart":2.625 + }, + { + "elevation":[ + 491.57378483134391, + 547.49535224251053 + ], + "pace":[ + 296.05298644112088, + 401.14092967732398 + ], + "heartRate":[ + 151.36398089694217, + 166.20454793289232 + ], + "distanceFromStart":3 + }, + { + "elevation":[ + 472.06803233416338, + 531.92570520228401 + ], + "pace":[ + 395.50830663514012, + 401.67837917543591 + ], + "heartRate":[ + 134.41798110234078, + 151.90886697564241 + ], + "distanceFromStart":3.375 + }, + { + "elevation":[ + 339.81419476005283, + 461.03832527824829 + ], + "pace":[ + 395.31160487975183, + 404.49550455974907 + ], + "heartRate":[ + 129.97753472415462, + 138.13531094848992 + ], + "distanceFromStart":3.75 + }, + { + "elevation":[ + 303.1495508565697, + 342.3532820173541 + ], + "pace":[ + 395.02844559698116, + 402.65878340653796 + ], + "heartRate":[ + 127.72304232462609, + 133.26322270764186 + ], + "distanceFromStart":4.125 + } + ] + }, + { + "name":"Lonesome Ridge Trail", + "id":1006, + "distance":4.5, + "difficulty":3, + "observations":[ + { + "elevation":[ + 291.65263635636268, + 309.26016677925196 + ], + "pace":[ + 396.08716481908732, + 403.68937873525232 + ], + "heartRate":[ + 117.16351898665887, + 121.95815455919609 + ], + "distanceFromStart":0 + }, + { + "elevation":[ + 299.24001936628116, + 317.44584350790012 + ], + "pace":[ + 380.19020240756623, + 395.3978319010256 + ], + "heartRate":[ + 117.6410892152911, + 124.82185220506081 + ], + "distanceFromStart":0.375 + }, + { + "elevation":[ + 303.62145464574394, + 336.05569457646544 + ], + "pace":[ + 380.55927782266116, + 397.60789726832775 + ], + "heartRate":[ + 121.52696452049059, + 127.31525441110122 + ], + "distanceFromStart":0.75 + }, + { + "elevation":[ + 319.90393365162629, + 346.26966025518789 + ], + "pace":[ + 357.94116421258531, + 398.0750288648062 + ], + "heartRate":[ + 123.75908585923588, + 132.77069404486801 + ], + "distanceFromStart":1.125 + }, + { + "elevation":[ + 354.17104439267905, + 403.57031216972939 + ], + "pace":[ + 335.07385149392701, + 397.82674381875808 + ], + "heartRate":[ + 130.8235194572915, + 140.55700591418218 + ], + "distanceFromStart":1.5 + }, + { + "elevation":[ + 357.42992871175124, + 385.92155620623635 + ], + "pace":[ + 395.16168913839374, + 404.60294066527558 + ], + "heartRate":[ + 131.5456052446734, + 134.65984504627627 + ], + "distanceFromStart":1.875 + }, + { + "elevation":[ + 345.47736721935661, + 363.18776661379422 + ], + "pace":[ + 340.82303041339082, + 404.71689228682374 + ], + "heartRate":[ + 125.1949698433959, + 131.31354363122026 + ], + "distanceFromStart":2.25 + }, + { + "elevation":[ + 346.23343025200535, + 497.23376445462401 + ], + "pace":[ + 261.27629148816021, + 331.68516208719467 + ], + "heartRate":[ + 131.67810544238606, + 154.26779645311458 + ], + "distanceFromStart":2.625 + }, + { + "elevation":[ + 491.57378483134391, + 547.49535224251053 + ], + "pace":[ + 296.05298644112088, + 401.14092967732398 + ], + "heartRate":[ + 151.36398089694217, + 166.20454793289232 + ], + "distanceFromStart":3 + }, + { + "elevation":[ + 472.06803233416338, + 531.92570520228401 + ], + "pace":[ + 395.50830663514012, + 401.67837917543591 + ], + "heartRate":[ + 134.41798110234078, + 151.90886697564241 + ], + "distanceFromStart":3.375 + }, + { + "elevation":[ + 339.81419476005283, + 461.03832527824829 + ], + "pace":[ + 395.31160487975183, + 404.49550455974907 + ], + "heartRate":[ + 129.97753472415462, + 138.13531094848992 + ], + "distanceFromStart":3.75 + }, + { + "elevation":[ + 303.1495508565697, + 342.3532820173541 + ], + "pace":[ + 395.02844559698116, + 402.65878340653796 + ], + "heartRate":[ + 127.72304232462609, + 133.26322270764186 + ], + "distanceFromStart":4.125 + } + ] + }, + { + "name":"Lonesome Ridge Trail", + "id":1007, + "distance":4.5, + "difficulty":3, + "observations":[ + { + "elevation":[ + 291.65263635636268, + 309.26016677925196 + ], + "pace":[ + 396.08716481908732, + 403.68937873525232 + ], + "heartRate":[ + 117.16351898665887, + 121.95815455919609 + ], + "distanceFromStart":0 + }, + { + "elevation":[ + 299.24001936628116, + 317.44584350790012 + ], + "pace":[ + 380.19020240756623, + 395.3978319010256 + ], + "heartRate":[ + 117.6410892152911, + 124.82185220506081 + ], + "distanceFromStart":0.375 + }, + { + "elevation":[ + 303.62145464574394, + 336.05569457646544 + ], + "pace":[ + 380.55927782266116, + 397.60789726832775 + ], + "heartRate":[ + 121.52696452049059, + 127.31525441110122 + ], + "distanceFromStart":0.75 + }, + { + "elevation":[ + 319.90393365162629, + 346.26966025518789 + ], + "pace":[ + 357.94116421258531, + 398.0750288648062 + ], + "heartRate":[ + 123.75908585923588, + 132.77069404486801 + ], + "distanceFromStart":1.125 + }, + { + "elevation":[ + 354.17104439267905, + 403.57031216972939 + ], + "pace":[ + 335.07385149392701, + 397.82674381875808 + ], + "heartRate":[ + 130.8235194572915, + 140.55700591418218 + ], + "distanceFromStart":1.5 + }, + { + "elevation":[ + 357.42992871175124, + 385.92155620623635 + ], + "pace":[ + 395.16168913839374, + 404.60294066527558 + ], + "heartRate":[ + 131.5456052446734, + 134.65984504627627 + ], + "distanceFromStart":1.875 + }, + { + "elevation":[ + 345.47736721935661, + 363.18776661379422 + ], + "pace":[ + 340.82303041339082, + 404.71689228682374 + ], + "heartRate":[ + 125.1949698433959, + 131.31354363122026 + ], + "distanceFromStart":2.25 + }, + { + "elevation":[ + 346.23343025200535, + 497.23376445462401 + ], + "pace":[ + 261.27629148816021, + 331.68516208719467 + ], + "heartRate":[ + 131.67810544238606, + 154.26779645311458 + ], + "distanceFromStart":2.625 + }, + { + "elevation":[ + 491.57378483134391, + 547.49535224251053 + ], + "pace":[ + 296.05298644112088, + 401.14092967732398 + ], + "heartRate":[ + 151.36398089694217, + 166.20454793289232 + ], + "distanceFromStart":3 + }, + { + "elevation":[ + 472.06803233416338, + 531.92570520228401 + ], + "pace":[ + 395.50830663514012, + 401.67837917543591 + ], + "heartRate":[ + 134.41798110234078, + 151.90886697564241 + ], + "distanceFromStart":3.375 + }, + { + "elevation":[ + 339.81419476005283, + 461.03832527824829 + ], + "pace":[ + 395.31160487975183, + 404.49550455974907 + ], + "heartRate":[ + 129.97753472415462, + 138.13531094848992 + ], + "distanceFromStart":3.75 + }, + { + "elevation":[ + 303.1495508565697, + 342.3532820173541 + ], + "pace":[ + 395.02844559698116, + 402.65878340653796 + ], + "heartRate":[ + 127.72304232462609, + 133.26322270764186 + ], + "distanceFromStart":4.125 + } + ] + }, + { + "name":"Lonesome Ridge Trail", + "id":1008, + "distance":4.5, + "difficulty":3, + "observations":[ + { + "elevation":[ + 291.65263635636268, + 309.26016677925196 + ], + "pace":[ + 396.08716481908732, + 403.68937873525232 + ], + "heartRate":[ + 117.16351898665887, + 121.95815455919609 + ], + "distanceFromStart":0 + }, + { + "elevation":[ + 299.24001936628116, + 317.44584350790012 + ], + "pace":[ + 380.19020240756623, + 395.3978319010256 + ], + "heartRate":[ + 117.6410892152911, + 124.82185220506081 + ], + "distanceFromStart":0.375 + }, + { + "elevation":[ + 303.62145464574394, + 336.05569457646544 + ], + "pace":[ + 380.55927782266116, + 397.60789726832775 + ], + "heartRate":[ + 121.52696452049059, + 127.31525441110122 + ], + "distanceFromStart":0.75 + }, + { + "elevation":[ + 319.90393365162629, + 346.26966025518789 + ], + "pace":[ + 357.94116421258531, + 398.0750288648062 + ], + "heartRate":[ + 123.75908585923588, + 132.77069404486801 + ], + "distanceFromStart":1.125 + }, + { + "elevation":[ + 354.17104439267905, + 403.57031216972939 + ], + "pace":[ + 335.07385149392701, + 397.82674381875808 + ], + "heartRate":[ + 130.8235194572915, + 140.55700591418218 + ], + "distanceFromStart":1.5 + }, + { + "elevation":[ + 357.42992871175124, + 385.92155620623635 + ], + "pace":[ + 395.16168913839374, + 404.60294066527558 + ], + "heartRate":[ + 131.5456052446734, + 134.65984504627627 + ], + "distanceFromStart":1.875 + }, + { + "elevation":[ + 345.47736721935661, + 363.18776661379422 + ], + "pace":[ + 340.82303041339082, + 404.71689228682374 + ], + "heartRate":[ + 125.1949698433959, + 131.31354363122026 + ], + "distanceFromStart":2.25 + }, + { + "elevation":[ + 346.23343025200535, + 497.23376445462401 + ], + "pace":[ + 261.27629148816021, + 331.68516208719467 + ], + "heartRate":[ + 131.67810544238606, + 154.26779645311458 + ], + "distanceFromStart":2.625 + }, + { + "elevation":[ + 491.57378483134391, + 547.49535224251053 + ], + "pace":[ + 296.05298644112088, + 401.14092967732398 + ], + "heartRate":[ + 151.36398089694217, + 166.20454793289232 + ], + "distanceFromStart":3 + }, + { + "elevation":[ + 472.06803233416338, + 531.92570520228401 + ], + "pace":[ + 395.50830663514012, + 401.67837917543591 + ], + "heartRate":[ + 134.41798110234078, + 151.90886697564241 + ], + "distanceFromStart":3.375 + }, + { + "elevation":[ + 339.81419476005283, + 461.03832527824829 + ], + "pace":[ + 395.31160487975183, + 404.49550455974907 + ], + "heartRate":[ + 129.97753472415462, + 138.13531094848992 + ], + "distanceFromStart":3.75 + }, + { + "elevation":[ + 303.1495508565697, + 342.3532820173541 + ], + "pace":[ + 395.02844559698116, + 402.65878340653796 + ], + "heartRate":[ + 127.72304232462609, + 133.26322270764186 + ], + "distanceFromStart":4.125 + } + ] + }, + { + "name":"Lonesome Ridge Trail", + "id":1009, + "distance":4.5, + "difficulty":3, + "observations":[ + { + "elevation":[ + 291.65263635636268, + 309.26016677925196 + ], + "pace":[ + 396.08716481908732, + 403.68937873525232 + ], + "heartRate":[ + 117.16351898665887, + 121.95815455919609 + ], + "distanceFromStart":0 + }, + { + "elevation":[ + 299.24001936628116, + 317.44584350790012 + ], + "pace":[ + 380.19020240756623, + 395.3978319010256 + ], + "heartRate":[ + 117.6410892152911, + 124.82185220506081 + ], + "distanceFromStart":0.375 + }, + { + "elevation":[ + 303.62145464574394, + 336.05569457646544 + ], + "pace":[ + 380.55927782266116, + 397.60789726832775 + ], + "heartRate":[ + 121.52696452049059, + 127.31525441110122 + ], + "distanceFromStart":0.75 + }, + { + "elevation":[ + 319.90393365162629, + 346.26966025518789 + ], + "pace":[ + 357.94116421258531, + 398.0750288648062 + ], + "heartRate":[ + 123.75908585923588, + 132.77069404486801 + ], + "distanceFromStart":1.125 + }, + { + "elevation":[ + 354.17104439267905, + 403.57031216972939 + ], + "pace":[ + 335.07385149392701, + 397.82674381875808 + ], + "heartRate":[ + 130.8235194572915, + 140.55700591418218 + ], + "distanceFromStart":1.5 + }, + { + "elevation":[ + 357.42992871175124, + 385.92155620623635 + ], + "pace":[ + 395.16168913839374, + 404.60294066527558 + ], + "heartRate":[ + 131.5456052446734, + 134.65984504627627 + ], + "distanceFromStart":1.875 + }, + { + "elevation":[ + 345.47736721935661, + 363.18776661379422 + ], + "pace":[ + 340.82303041339082, + 404.71689228682374 + ], + "heartRate":[ + 125.1949698433959, + 131.31354363122026 + ], + "distanceFromStart":2.25 + }, + { + "elevation":[ + 346.23343025200535, + 497.23376445462401 + ], + "pace":[ + 261.27629148816021, + 331.68516208719467 + ], + "heartRate":[ + 131.67810544238606, + 154.26779645311458 + ], + "distanceFromStart":2.625 + }, + { + "elevation":[ + 491.57378483134391, + 547.49535224251053 + ], + "pace":[ + 296.05298644112088, + 401.14092967732398 + ], + "heartRate":[ + 151.36398089694217, + 166.20454793289232 + ], + "distanceFromStart":3 + }, + { + "elevation":[ + 472.06803233416338, + 531.92570520228401 + ], + "pace":[ + 395.50830663514012, + 401.67837917543591 + ], + "heartRate":[ + 134.41798110234078, + 151.90886697564241 + ], + "distanceFromStart":3.375 + }, + { + "elevation":[ + 339.81419476005283, + 461.03832527824829 + ], + "pace":[ + 395.31160487975183, + 404.49550455974907 + ], + "heartRate":[ + 129.97753472415462, + 138.13531094848992 + ], + "distanceFromStart":3.75 + }, + { + "elevation":[ + 303.1495508565697, + 342.3532820173541 + ], + "pace":[ + 395.02844559698116, + 402.65878340653796 + ], + "heartRate":[ + 127.72304232462609, + 133.26322270764186 + ], + "distanceFromStart":4.125 + } + ] + }, + { + "name":"Lonesome Ridge Trail", + "id":1010, + "distance":4.5, + "difficulty":3, + "observations":[ + { + "elevation":[ + 291.65263635636268, + 309.26016677925196 + ], + "pace":[ + 396.08716481908732, + 403.68937873525232 + ], + "heartRate":[ + 117.16351898665887, + 121.95815455919609 + ], + "distanceFromStart":0 + }, + { + "elevation":[ + 299.24001936628116, + 317.44584350790012 + ], + "pace":[ + 380.19020240756623, + 395.3978319010256 + ], + "heartRate":[ + 117.6410892152911, + 124.82185220506081 + ], + "distanceFromStart":0.375 + }, + { + "elevation":[ + 303.62145464574394, + 336.05569457646544 + ], + "pace":[ + 380.55927782266116, + 397.60789726832775 + ], + "heartRate":[ + 121.52696452049059, + 127.31525441110122 + ], + "distanceFromStart":0.75 + }, + { + "elevation":[ + 319.90393365162629, + 346.26966025518789 + ], + "pace":[ + 357.94116421258531, + 398.0750288648062 + ], + "heartRate":[ + 123.75908585923588, + 132.77069404486801 + ], + "distanceFromStart":1.125 + }, + { + "elevation":[ + 354.17104439267905, + 403.57031216972939 + ], + "pace":[ + 335.07385149392701, + 397.82674381875808 + ], + "heartRate":[ + 130.8235194572915, + 140.55700591418218 + ], + "distanceFromStart":1.5 + }, + { + "elevation":[ + 357.42992871175124, + 385.92155620623635 + ], + "pace":[ + 395.16168913839374, + 404.60294066527558 + ], + "heartRate":[ + 131.5456052446734, + 134.65984504627627 + ], + "distanceFromStart":1.875 + }, + { + "elevation":[ + 345.47736721935661, + 363.18776661379422 + ], + "pace":[ + 340.82303041339082, + 404.71689228682374 + ], + "heartRate":[ + 125.1949698433959, + 131.31354363122026 + ], + "distanceFromStart":2.25 + }, + { + "elevation":[ + 346.23343025200535, + 497.23376445462401 + ], + "pace":[ + 261.27629148816021, + 331.68516208719467 + ], + "heartRate":[ + 131.67810544238606, + 154.26779645311458 + ], + "distanceFromStart":2.625 + }, + { + "elevation":[ + 491.57378483134391, + 547.49535224251053 + ], + "pace":[ + 296.05298644112088, + 401.14092967732398 + ], + "heartRate":[ + 151.36398089694217, + 166.20454793289232 + ], + "distanceFromStart":3 + }, + { + "elevation":[ + 472.06803233416338, + 531.92570520228401 + ], + "pace":[ + 395.50830663514012, + 401.67837917543591 + ], + "heartRate":[ + 134.41798110234078, + 151.90886697564241 + ], + "distanceFromStart":3.375 + }, + { + "elevation":[ + 339.81419476005283, + 461.03832527824829 + ], + "pace":[ + 395.31160487975183, + 404.49550455974907 + ], + "heartRate":[ + 129.97753472415462, + 138.13531094848992 + ], + "distanceFromStart":3.75 + }, + { + "elevation":[ + 303.1495508565697, + 342.3532820173541 + ], + "pace":[ + 395.02844559698116, + 402.65878340653796 + ], + "heartRate":[ + 127.72304232462609, + 133.26322270764186 + ], + "distanceFromStart":4.125 + } + ] + } +] diff --git a/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Resources/icybay.jpg b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Resources/icybay.jpg new file mode 100644 index 0000000..feb1764 Binary files /dev/null and b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Resources/icybay.jpg differ diff --git a/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Resources/lakemcdonald.jpg b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Resources/lakemcdonald.jpg new file mode 100644 index 0000000..bd9d6b9 Binary files /dev/null and b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Resources/lakemcdonald.jpg differ diff --git a/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Resources/landmarkData.json b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Resources/landmarkData.json new file mode 100644 index 0000000..a25b4e4 --- /dev/null +++ b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Resources/landmarkData.json @@ -0,0 +1,182 @@ +[ + { + "name": "Turtle Rock", + "category": "Rivers", + "city": "Twentynine Palms", + "state": "California", + "id": 1001, + "isFeatured": true, + "isFavorite": true, + "park": "Joshua Tree National Park", + "coordinates": { + "longitude": -116.166868, + "latitude": 34.011286 + }, + "imageName": "turtlerock" + }, + { + "name": "Silver Salmon Creek", + "category": "Lakes", + "city": "Port Alsworth", + "state": "Alaska", + "id": 1002, + "isFeatured": false, + "isFavorite": false, + "park": "Lake Clark National Park and Preserve", + "coordinates": { + "longitude": -152.665167, + "latitude": 59.980167 + }, + "imageName": "silversalmoncreek" + }, + { + "name": "Chilkoot Trail", + "category": "Mountains", + "city": "Skagway", + "state": "Alaska", + "id": 1003, + "isFeatured": false, + "isFavorite": true, + "park": "Klondike Gold Rush National Historical Park", + "coordinates": { + "longitude": -135.334571, + "latitude": 59.560551 + }, + "imageName": "chilkoottrail" + }, + { + "name": "St. Mary Lake", + "category": "Lakes", + "city": "Browning", + "state": "Montana", + "id": 1004, + "isFeatured": true, + "isFavorite": true, + "park": "Glacier National Park", + "coordinates": { + "longitude": -113.536248, + "latitude": 48.69423 + }, + "imageName": "stmarylake" + }, + { + "name": "Twin Lake", + "category": "Lakes", + "city": "Twin Lakes", + "state": "Alaska", + "id": 1005, + "isFeatured": false, + "isFavorite": false, + "park": "Lake Clark National Park and Preserve", + "coordinates": { + "longitude": -153.849883, + "latitude": 60.641684 + }, + "imageName": "twinlake" + }, + { + "name": "Lake McDonald", + "category": "Mountains", + "city": "West Glacier", + "state": "Montana", + "id": 1006, + "isFeatured": false, + "isFavorite": false, + "park": "Glacier National Park", + "coordinates": { + "longitude": -113.934831, + "latitude": 48.56002 + }, + "imageName": "lakemcdonald" + }, + { + "name": "Charley Rivers", + "category": "Rivers", + "city": "Eaking", + "state": "Alaska", + "id": 1007, + "isFeatured": true, + "isFavorite": false, + "park": "Charley Rivers National Preserve", + "coordinates": { + "longitude": -143.122586, + "latitude": 65.350021 + }, + "imageName": "charleyrivers", + }, + { + "name": "Icy Bay", + "category": "Mountains", + "city": "Icy Bay", + "state": "Alaska", + "id": 1008, + "isFeatured": false, + "isFavorite": false, + "park": "Wrangell-St. Elias National Park and Preserve", + "coordinates": { + "longitude": -141.518167, + "latitude": 60.089917 + }, + "imageName": "icybay" + }, + { + "name": "Rainbow Lake", + "category": "Lakes", + "city": "Willow", + "state": "Alaska", + "id": 1009, + "isFeatured": false, + "isFavorite": false, + "park": "State Recreation Area", + "coordinates": { + "longitude": -150.086103, + "latitude": 61.694334 + }, + "imageName": "rainbowlake" + }, + { + "name": "Hidden Lake", + "category": "Lakes", + "city": "Newhalem", + "state": "Washington", + "id": 1010, + "isFeatured": false, + "isFavorite": false, + "park": "North Cascades National Park", + "coordinates": { + "longitude": -121.17799, + "latitude": 48.495442 + }, + "imageName": "hiddenlake" + }, + { + "name": "Chincoteague", + "category": "Rivers", + "city": "Chincoteague", + "state": "Virginia", + "id": 1011, + "isFeatured": false, + "isFavorite": false, + "park": "Chincoteague National Wildlife Refuge", + "coordinates": { + "longitude": -75.383212, + "latitude": 37.91531 + }, + "imageName": "chincoteague" + }, + { + "name": "Lake Umbagog", + "category": "Lakes", + "city": "Errol", + "state": "New Hampshire", + "id": 1012, + "isFeatured": false, + "isFavorite": false, + "park": "Umbagog National Wildlife Refuge", + "coordinates": { + "longitude": -71.056816, + "latitude": 44.747408 + }, + "imageName": "umbagog" + } +] diff --git a/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Resources/rainbowlake.jpg b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Resources/rainbowlake.jpg new file mode 100644 index 0000000..6da43dd Binary files /dev/null and b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Resources/rainbowlake.jpg differ diff --git a/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Resources/silversalmoncreek.jpg b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Resources/silversalmoncreek.jpg new file mode 100644 index 0000000..f657532 Binary files /dev/null and b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Resources/silversalmoncreek.jpg differ diff --git a/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Resources/stmarylake.jpg b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Resources/stmarylake.jpg new file mode 100644 index 0000000..1c71de4 Binary files /dev/null and b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Resources/stmarylake.jpg differ diff --git a/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Resources/stmarylake_feature.jpg b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Resources/stmarylake_feature.jpg new file mode 100644 index 0000000..5eb97b1 Binary files /dev/null and b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Resources/stmarylake_feature.jpg differ diff --git a/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Resources/turtlerock.jpg b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Resources/turtlerock.jpg new file mode 100644 index 0000000..f7a6e6d Binary files /dev/null and b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Resources/turtlerock.jpg differ diff --git a/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Resources/turtlerock_feature.jpg b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Resources/turtlerock_feature.jpg new file mode 100644 index 0000000..448c70f Binary files /dev/null and b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Resources/turtlerock_feature.jpg differ diff --git a/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Resources/twinlake.jpg b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Resources/twinlake.jpg new file mode 100644 index 0000000..3e7a57c Binary files /dev/null and b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Resources/twinlake.jpg differ diff --git a/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Resources/umbagog.jpg b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Resources/umbagog.jpg new file mode 100644 index 0000000..56291c6 Binary files /dev/null and b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Resources/umbagog.jpg differ diff --git a/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/SceneDelegate.swift b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/SceneDelegate.swift new file mode 100644 index 0000000..51057d3 --- /dev/null +++ b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/SceneDelegate.swift @@ -0,0 +1,58 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +The scene delegate. +*/ + +import UIKit +import SwiftUI + +class SceneDelegate: UIResponder, UIWindowSceneDelegate { + + var window: UIWindow? + + func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { + // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`. + // If using a storyboard, the `window` property will automatically be initialized and attached to the scene. + // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead). + + // Use a UIHostingController as window root view controller + if let windowScene = scene as? UIWindowScene { + let window = UIWindow(windowScene: windowScene) + window.rootViewController = UIHostingController(rootView: CategoryHome().environmentObject(UserData())) + self.window = window + window.makeKeyAndVisible() + } + } + + func sceneDidDisconnect(_ scene: UIScene) { + // Called as the scene is being released by the system. + // This occurs shortly after the scene enters the background, or when its session is discarded. + // Release any resources associated with this scene that can be re-created the next time the scene connects. + // The scene may re-connect later, as its session was not neccessarily discarded (see `application:didDiscardSceneSessions` instead). + } + + func sceneDidBecomeActive(_ scene: UIScene) { + // Called when the scene has moved from an inactive state to an active state. + // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive. + } + + func sceneWillResignActive(_ scene: UIScene) { + // Called when the scene will move from an active state to an inactive state. + // This may occur due to temporary interruptions (ex. an incoming phone call). + } + + func sceneWillEnterForeground(_ scene: UIScene) { + // Called as the scene transitions from the background to the foreground. + // Use this method to undo the changes made on entering the background. + } + + func sceneDidEnterBackground(_ scene: UIScene) { + // Called as the scene transitions from the foreground to the background. + // Use this method to save data, release shared resources, and store enough scene-specific state information + // to restore the scene back to its current state. + } + +} + diff --git a/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Supporting Views/Badge.swift b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Supporting Views/Badge.swift new file mode 100644 index 0000000..59f03b2 --- /dev/null +++ b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Supporting Views/Badge.swift @@ -0,0 +1,41 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A view that displays a badge. +*/ + +import SwiftUI + +struct Badge: View { + static let rotationCount = 8 + + var badgeSymbols: some View { + ForEach(0.. + var overallRange: Range + + var heightRatio: CGFloat { + max(CGFloat(magnitude(of: range) / magnitude(of: overallRange)), 0.15) + } + + var offsetRatio: CGFloat { + CGFloat((range.lowerBound - overallRange.lowerBound) / magnitude(of: overallRange)) + } + + var animation: Animation { + Animation.spring() + .speed(2) + .delay(0.03 * Double(index)) + } + + var body: some View { + Capsule() + .fill(Color.white) + .frame(height: height * heightRatio, alignment: .bottom) + .offset(x: 0, y: height * -offsetRatio) + .animation(animation) + } +} + +#if DEBUG +struct GraphCapsule_Previews: PreviewProvider { + static var previews: some View { + GraphCapsule(index: 0, height: 150, range: 10..<50, overallRange: 0..<100) + } +} +#endif diff --git a/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Supporting Views/HikeGraph.swift b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Supporting Views/HikeGraph.swift new file mode 100644 index 0000000..2a4ff27 --- /dev/null +++ b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Supporting Views/HikeGraph.swift @@ -0,0 +1,74 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +The elevation, heart rate, and pace of a hike plotted on a graph. +*/ + +import SwiftUI + +func rangeOfRanges(_ ranges: C) -> Range + where C.Element == Range { + guard !ranges.isEmpty else { return 0..<0 } + let low = ranges.lazy.map { $0.lowerBound }.min()! + let high = ranges.lazy.map { $0.upperBound }.max()! + return low..) -> Double { + return range.upperBound - range.lowerBound +} + +struct HikeGraph: View { + var hike: Hike + var path: KeyPath> + + var color: Color { + switch path { + case \.elevation: + return .gray + case \.heartRate: + return Color(hue: 0, saturation: 0.5, brightness: 0.7) + case \.pace: + return Color(hue: 0.7, saturation: 0.4, brightness: 0.7) + default: + return .black + } + } + + var body: some View { + let data = hike.observations + let overallRange = rangeOfRanges(data.lazy.map { $0[keyPath: self.path] }) + let maxMagnitude = data.map { magnitude(of: $0[keyPath: path]) }.max()! + let heightRatio = 1 - CGFloat(maxMagnitude / magnitude(of: overallRange)) + + return GeometryReader { proxy in + HStack(alignment: .bottom, spacing: proxy.size.width / 120) { + ForEach(data.indices) { index in + GraphCapsule( + index: index, + height: proxy.size.height, + range: data[index][keyPath: self.path], + overallRange: overallRange) + .colorMultiply(self.color) + } + .offset(x: 0, y: proxy.size.height * heightRatio) + } + } + } +} + +#if DEBUG +struct HikeGraph_Previews: PreviewProvider { + static var previews: some View { + Group { + HikeGraph(hike: hikeData[0], path: \.elevation) + .frame(height: 200) + HikeGraph(hike: hikeData[0], path: \.heartRate) + .frame(height: 200) + HikeGraph(hike: hikeData[0], path: \.pace) + .frame(height: 200) + } + } +} +#endif diff --git a/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Supporting Views/LandmarkRow.swift b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Supporting Views/LandmarkRow.swift new file mode 100644 index 0000000..2f8110c --- /dev/null +++ b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Supporting Views/LandmarkRow.swift @@ -0,0 +1,38 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A single row to be displayed in a list of landmarks. +*/ + +import SwiftUI + +struct LandmarkRow: View { + var landmark: Landmark + + var body: some View { + HStack { + landmark.image(forSize: 50) + Text(verbatim: landmark.name) + Spacer() + + if landmark.isFavorite { + Image(systemName: "star.fill") + .imageScale(.medium) + .foregroundColor(.yellow) + } + } + } +} + +#if DEBUG +struct LandmarkRow_Previews: PreviewProvider { + static var previews: some View { + Group { + LandmarkRow(landmark: landmarkData[0]) + LandmarkRow(landmark: landmarkData[1]) + } + .previewLayout(.fixed(width: 300, height: 70)) + } +} +#endif diff --git a/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Supporting Views/MapView.swift b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Supporting Views/MapView.swift new file mode 100644 index 0000000..5a8c64b --- /dev/null +++ b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Supporting Views/MapView.swift @@ -0,0 +1,31 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A view that hosts an `MKMapView`. +*/ + +import SwiftUI +import MapKit + +struct MapView: UIViewRepresentable { + var coordinate: CLLocationCoordinate2D + + func makeUIView(context: Context) -> MKMapView { + MKMapView(frame: .zero) + } + + func updateUIView(_ view: MKMapView, context: Context) { + let span = MKCoordinateSpan(latitudeDelta: 0.02, longitudeDelta: 0.02) + let region = MKCoordinateRegion(center: coordinate, span: span) + view.setRegion(region, animated: true) + } +} + +#if DEBUG +struct MapView_Previews: PreviewProvider { + static var previews: some View { + MapView(coordinate: landmarkData[0].locationCoordinate) + } +} +#endif diff --git a/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Supporting Views/RotatedBadgeSymbol.swift b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Supporting Views/RotatedBadgeSymbol.swift new file mode 100644 index 0000000..a7e4b53 --- /dev/null +++ b/Other Projects/Interfacing With UIKit/Complete/Landmarks/Landmarks/Supporting Views/RotatedBadgeSymbol.swift @@ -0,0 +1,26 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A view that displays a rotated version of a badge symbol. +*/ + +import SwiftUI + +struct RotatedBadgeSymbol: View { + let angle: Angle + + var body: some View { + BadgeSymbol() + .padding(-60) + .rotationEffect(angle, anchor: .bottom) + } +} + +#if DEBUG +struct RotatedBadgeSymbol_Previews: PreviewProvider { + static var previews: some View { + RotatedBadgeSymbol(angle: .init(degrees: 5)) + } +} +#endif diff --git a/Other Projects/Interfacing With UIKit/Complete/README.md b/Other Projects/Interfacing With UIKit/Complete/README.md new file mode 100644 index 0000000..4bfcd0b --- /dev/null +++ b/Other Projects/Interfacing With UIKit/Complete/README.md @@ -0,0 +1,3 @@ +# Completed Project: Interfacing with UIKit + +Explore the completed project for the [Interfacing with UIKit](https://developer.apple.com/tutorials/swiftui/interfacing-with-uikit) tutorial. \ No newline at end of file diff --git a/Other Projects/Interfacing With UIKit/StartingPoint/.gitignore b/Other Projects/Interfacing With UIKit/StartingPoint/.gitignore new file mode 100644 index 0000000..9e50718 --- /dev/null +++ b/Other Projects/Interfacing With UIKit/StartingPoint/.gitignore @@ -0,0 +1,21 @@ +# See LICENSE folder for this sample’s licensing information. +# +# Apple sample code gitignore configuration. + +# Finder +.DS_Store + +# Xcode - User files +xcuserdata/ + +**/*.xcodeproj/project.xcworkspace/* +!**/*.xcodeproj/project.xcworkspace/xcshareddata + +**/*.xcodeproj/project.xcworkspace/xcshareddata/* +!**/*.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings + +**/*.playground/playground.xcworkspace/* +!**/*.playground/playground.xcworkspace/xcshareddata + +**/*.playground/playground.xcworkspace/xcshareddata/* +!**/*.playground/playground.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings diff --git a/Other Projects/Interfacing With UIKit/StartingPoint/Configuration/SampleCode.xcconfig b/Other Projects/Interfacing With UIKit/StartingPoint/Configuration/SampleCode.xcconfig new file mode 100644 index 0000000..db86c06 --- /dev/null +++ b/Other Projects/Interfacing With UIKit/StartingPoint/Configuration/SampleCode.xcconfig @@ -0,0 +1,13 @@ +// +// See LICENSE folder for this sample’s licensing information. +// +// SampleCode.xcconfig +// + +// The `SAMPLE_CODE_DISAMBIGUATOR` configuration is to make it easier to build +// and run a sample code project. Once you set your project's development team, +// you'll have a unique bundle identifier. This is because the bundle identifier +// is derived based on the 'SAMPLE_CODE_DISAMBIGUATOR' value. Do not use this +// approach in your own projects—it's only useful for sample code projects because +// they are frequently downloaded and don't have a development team set. +SAMPLE_CODE_DISAMBIGUATOR=${DEVELOPMENT_TEAM} diff --git a/Other Projects/Interfacing With UIKit/StartingPoint/LICENSE/LICENSE.txt b/Other Projects/Interfacing With UIKit/StartingPoint/LICENSE/LICENSE.txt new file mode 100644 index 0000000..94e3d54 --- /dev/null +++ b/Other Projects/Interfacing With UIKit/StartingPoint/LICENSE/LICENSE.txt @@ -0,0 +1,8 @@ +Copyright © 2019 Apple Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + diff --git a/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/InterfacingWithUIKit.xcodeproj/.xcodesamplecode.plist b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/InterfacingWithUIKit.xcodeproj/.xcodesamplecode.plist new file mode 100644 index 0000000..5dd5da8 --- /dev/null +++ b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/InterfacingWithUIKit.xcodeproj/.xcodesamplecode.plist @@ -0,0 +1,5 @@ + + + + + diff --git a/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/InterfacingWithUIKit.xcodeproj/project.pbxproj b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/InterfacingWithUIKit.xcodeproj/project.pbxproj new file mode 100644 index 0000000..34c3ca1 --- /dev/null +++ b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/InterfacingWithUIKit.xcodeproj/project.pbxproj @@ -0,0 +1,577 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 50; + objects = { + +/* Begin PBXBuildFile section */ + B7310DD1229F6839001079B9 /* HexagonParameters.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7310DD0229F6839001079B9 /* HexagonParameters.swift */; }; + B7310DD3229F6CA9001079B9 /* Badge.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7310DD2229F6CA9001079B9 /* Badge.swift */; }; + B7394866229F194000C47603 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7394865229F194000C47603 /* AppDelegate.swift */; }; + B7394868229F194000C47603 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7394867229F194000C47603 /* SceneDelegate.swift */; }; + B739486A229F194000C47603 /* LandmarkDetail.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7394869229F194000C47603 /* LandmarkDetail.swift */; }; + B739486C229F194200C47603 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B739486B229F194200C47603 /* Assets.xcassets */; }; + B739486F229F194200C47603 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B739486E229F194200C47603 /* Preview Assets.xcassets */; }; + B7394872229F194200C47603 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B7394870229F194200C47603 /* LaunchScreen.storyboard */; }; + B739487A229F1B3F00C47603 /* CircleImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7394879229F1B3F00C47603 /* CircleImage.swift */; }; + B739487C229F1B6800C47603 /* MapView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B739487B229F1B6800C47603 /* MapView.swift */; }; + B7394881229F28B900C47603 /* Landmark.swift in Sources */ = {isa = PBXBuildFile; fileRef = B739487F229F28B900C47603 /* Landmark.swift */; }; + B7394891229F292F00C47603 /* rainbowlake.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B7394884229F292D00C47603 /* rainbowlake.jpg */; }; + B7394893229F292F00C47603 /* icybay.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B7394886229F292E00C47603 /* icybay.jpg */; }; + B7394894229F292F00C47603 /* lakemcdonald.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B7394887229F292E00C47603 /* lakemcdonald.jpg */; }; + B7394895229F292F00C47603 /* turtlerock.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B7394888229F292E00C47603 /* turtlerock.jpg */; }; + B7394896229F292F00C47603 /* umbagog.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B7394889229F292E00C47603 /* umbagog.jpg */; }; + B7394897229F292F00C47603 /* hiddenlake.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B739488A229F292E00C47603 /* hiddenlake.jpg */; }; + B7394898229F292F00C47603 /* stmarylake.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B739488B229F292E00C47603 /* stmarylake.jpg */; }; + B7394899229F292F00C47603 /* twinlake.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B739488C229F292E00C47603 /* twinlake.jpg */; }; + B739489A229F292F00C47603 /* silversalmoncreek.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B739488D229F292E00C47603 /* silversalmoncreek.jpg */; }; + B739489B229F292F00C47603 /* landmarkData.json in Resources */ = {isa = PBXBuildFile; fileRef = B739488E229F292E00C47603 /* landmarkData.json */; }; + B739489C229F292F00C47603 /* chincoteague.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B739488F229F292F00C47603 /* chincoteague.jpg */; }; + B739489D229F292F00C47603 /* chilkoottrail.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B7394890229F292F00C47603 /* chilkoottrail.jpg */; }; + B739489F229F2D9700C47603 /* LandmarkRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = B739489E229F2D9700C47603 /* LandmarkRow.swift */; }; + B73948A1229F2E1F00C47603 /* LandmarkList.swift in Sources */ = {isa = PBXBuildFile; fileRef = B73948A0229F2E1F00C47603 /* LandmarkList.swift */; }; + B73948A3229F3E2200C47603 /* charleyrivers.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B73948A2229F3E2200C47603 /* charleyrivers.jpg */; }; + B7D2AAC5229F4D7C0061E5F5 /* UserData.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7D2AAC4229F4D7C0061E5F5 /* UserData.swift */; }; + B7D587AE229F7382006E8DCF /* BadgeBackground.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7D587AD229F7382006E8DCF /* BadgeBackground.swift */; }; + B7D587B0229F73C1006E8DCF /* BadgeSymbol.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7D587AF229F73C1006E8DCF /* BadgeSymbol.swift */; }; + B7D587B2229F7406006E8DCF /* RotatedBadgeSymbol.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7D587B1229F7406006E8DCF /* RotatedBadgeSymbol.swift */; }; + B7D587B6229F825D006E8DCF /* HikeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7D587B5229F825D006E8DCF /* HikeView.swift */; }; + B7D587B8229F826D006E8DCF /* GraphCapsule.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7D587B7229F826D006E8DCF /* GraphCapsule.swift */; }; + B7D587BA229F8288006E8DCF /* Hike.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7D587B9229F8288006E8DCF /* Hike.swift */; }; + B7D587BC229F82EB006E8DCF /* HikeDetail.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7D587BB229F82EB006E8DCF /* HikeDetail.swift */; }; + B7D587BE229F82FF006E8DCF /* HikeGraph.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7D587BD229F82FF006E8DCF /* HikeGraph.swift */; }; + B7D587C0229F830B006E8DCF /* hikeData.json in Resources */ = {isa = PBXBuildFile; fileRef = B7D587BF229F830B006E8DCF /* hikeData.json */; }; + B7D587D222A0892C006E8DCF /* Home.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7D587D122A0892C006E8DCF /* Home.swift */; }; + B7D587D422A08965006E8DCF /* CategoryRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7D587D322A08965006E8DCF /* CategoryRow.swift */; }; + B7D587D622A08C97006E8DCF /* Profile.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7D587D522A08C97006E8DCF /* Profile.swift */; }; + B7D587D922A08D33006E8DCF /* ProfileHost.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7D587D822A08D33006E8DCF /* ProfileHost.swift */; }; + B7D587DB22A08D67006E8DCF /* ProfileSummary.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7D587DA22A08D67006E8DCF /* ProfileSummary.swift */; }; + B7D587DD22A08DD6006E8DCF /* HikeBadge.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7D587DC22A08DD6006E8DCF /* HikeBadge.swift */; }; + B7D587DF22A08E1A006E8DCF /* ProfileEditor.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7D587DE22A08E1A006E8DCF /* ProfileEditor.swift */; }; + B7D587E122A0914D006E8DCF /* FeatureCard.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7D587E022A0914D006E8DCF /* FeatureCard.swift */; }; + B7D587E522A097E2006E8DCF /* charleyrivers_feature.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B7D587E222A097E2006E8DCF /* charleyrivers_feature.jpg */; }; + B7D587E622A097E2006E8DCF /* stmarylake_feature.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B7D587E322A097E2006E8DCF /* stmarylake_feature.jpg */; }; + B7D587E722A097E2006E8DCF /* turtlerock_feature.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B7D587E422A097E2006E8DCF /* turtlerock_feature.jpg */; }; + B7D587E922A09809006E8DCF /* Data.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7D587E822A09809006E8DCF /* Data.swift */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 184943801849325000000001 /* SampleCode.xcconfig */ = {isa = PBXFileReference; name = SampleCode.xcconfig; path = ../Configuration/SampleCode.xcconfig; sourceTree = ""; }; + 187E8B20187E899000000001 /* LICENSE.txt */ = {isa = PBXFileReference; includeInIndex = 1; path = LICENSE.txt; sourceTree = ""; }; + B7310DD0229F6839001079B9 /* HexagonParameters.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HexagonParameters.swift; sourceTree = ""; }; + B7310DD2229F6CA9001079B9 /* Badge.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Badge.swift; sourceTree = ""; }; + B7394862229F194000C47603 /* Landmarks.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Landmarks.app; sourceTree = BUILT_PRODUCTS_DIR; }; + B7394865229F194000C47603 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + B7394867229F194000C47603 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; + B7394869229F194000C47603 /* LandmarkDetail.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LandmarkDetail.swift; sourceTree = ""; }; + B739486B229F194200C47603 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + B739486E229F194200C47603 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; + B7394871229F194200C47603 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + B7394873229F194200C47603 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + B7394879229F1B3F00C47603 /* CircleImage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CircleImage.swift; sourceTree = ""; }; + B739487B229F1B6800C47603 /* MapView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapView.swift; sourceTree = ""; }; + B739487F229F28B900C47603 /* Landmark.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Landmark.swift; sourceTree = ""; }; + B7394884229F292D00C47603 /* rainbowlake.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = rainbowlake.jpg; sourceTree = ""; }; + B7394886229F292E00C47603 /* icybay.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = icybay.jpg; sourceTree = ""; }; + B7394887229F292E00C47603 /* lakemcdonald.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = lakemcdonald.jpg; sourceTree = ""; }; + B7394888229F292E00C47603 /* turtlerock.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = turtlerock.jpg; sourceTree = ""; }; + B7394889229F292E00C47603 /* umbagog.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = umbagog.jpg; sourceTree = ""; }; + B739488A229F292E00C47603 /* hiddenlake.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = hiddenlake.jpg; sourceTree = ""; }; + B739488B229F292E00C47603 /* stmarylake.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = stmarylake.jpg; sourceTree = ""; }; + B739488C229F292E00C47603 /* twinlake.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = twinlake.jpg; sourceTree = ""; }; + B739488D229F292E00C47603 /* silversalmoncreek.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = silversalmoncreek.jpg; sourceTree = ""; }; + B739488E229F292E00C47603 /* landmarkData.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = landmarkData.json; sourceTree = ""; }; + B739488F229F292F00C47603 /* chincoteague.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = chincoteague.jpg; sourceTree = ""; }; + B7394890229F292F00C47603 /* chilkoottrail.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = chilkoottrail.jpg; sourceTree = ""; }; + B739489E229F2D9700C47603 /* LandmarkRow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = LandmarkRow.swift; path = "Supporting Views/LandmarkRow.swift"; sourceTree = ""; }; + B73948A0229F2E1F00C47603 /* LandmarkList.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LandmarkList.swift; sourceTree = ""; }; + B73948A2229F3E2200C47603 /* charleyrivers.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = charleyrivers.jpg; sourceTree = ""; }; + B7D2AAC4229F4D7C0061E5F5 /* UserData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserData.swift; sourceTree = ""; }; + B7D587AD229F7382006E8DCF /* BadgeBackground.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BadgeBackground.swift; sourceTree = ""; }; + B7D587AF229F73C1006E8DCF /* BadgeSymbol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BadgeSymbol.swift; sourceTree = ""; }; + B7D587B1229F7406006E8DCF /* RotatedBadgeSymbol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RotatedBadgeSymbol.swift; sourceTree = ""; }; + B7D587B5229F825D006E8DCF /* HikeView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HikeView.swift; sourceTree = ""; }; + B7D587B7229F826D006E8DCF /* GraphCapsule.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GraphCapsule.swift; sourceTree = ""; }; + B7D587B9229F8288006E8DCF /* Hike.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Hike.swift; sourceTree = ""; }; + B7D587BB229F82EB006E8DCF /* HikeDetail.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HikeDetail.swift; sourceTree = ""; }; + B7D587BD229F82FF006E8DCF /* HikeGraph.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HikeGraph.swift; sourceTree = ""; }; + B7D587BF229F830B006E8DCF /* hikeData.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = hikeData.json; sourceTree = ""; }; + B7D587D122A0892C006E8DCF /* Home.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Home.swift; sourceTree = ""; }; + B7D587D322A08965006E8DCF /* CategoryRow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CategoryRow.swift; sourceTree = ""; }; + B7D587D522A08C97006E8DCF /* Profile.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Profile.swift; sourceTree = ""; }; + B7D587D822A08D33006E8DCF /* ProfileHost.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileHost.swift; sourceTree = ""; }; + B7D587DA22A08D67006E8DCF /* ProfileSummary.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileSummary.swift; sourceTree = ""; }; + B7D587DC22A08DD6006E8DCF /* HikeBadge.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HikeBadge.swift; sourceTree = ""; }; + B7D587DE22A08E1A006E8DCF /* ProfileEditor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileEditor.swift; sourceTree = ""; }; + B7D587E022A0914D006E8DCF /* FeatureCard.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FeatureCard.swift; sourceTree = ""; }; + B7D587E222A097E2006E8DCF /* charleyrivers_feature.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = charleyrivers_feature.jpg; sourceTree = ""; }; + B7D587E322A097E2006E8DCF /* stmarylake_feature.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = stmarylake_feature.jpg; sourceTree = ""; }; + B7D587E422A097E2006E8DCF /* turtlerock_feature.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = turtlerock_feature.jpg; sourceTree = ""; }; + B7D587E822A09809006E8DCF /* Data.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Data.swift; sourceTree = ""; }; + C4E4AAA0C4E4035000000001 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; name = README.md; path = ../README.md; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + B739485F229F194000C47603 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 1848B9A01848B96000000001 /* Configuration */ = { + isa = PBXGroup; + children = ( + 184943801849325000000001 /* SampleCode.xcconfig */, + ); + name = Configuration; + sourceTree = ""; + }; + 187E7D00187E74D000000001 /* LICENSE */ = { + isa = PBXGroup; + children = ( + 187E8B20187E899000000001 /* LICENSE.txt */, + ); + name = LICENSE; + path = ../LICENSE; + sourceTree = ""; + }; + B7394859229F194000C47603 = { + isa = PBXGroup; + children = ( + C4E4AAA0C4E4035000000001 /* README.md */, + B7394864229F194000C47603 /* Landmarks */, + B7394863229F194000C47603 /* Products */, + 1848B9A01848B96000000001 /* Configuration */, + 187E7D00187E74D000000001 /* LICENSE */, + ); + sourceTree = ""; + }; + B7394863229F194000C47603 /* Products */ = { + isa = PBXGroup; + children = ( + B7394862229F194000C47603 /* Landmarks.app */, + ); + name = Products; + sourceTree = ""; + }; + B7394864229F194000C47603 /* Landmarks */ = { + isa = PBXGroup; + children = ( + B739487E229F282200C47603 /* Models */, + B7D587D722A08D16006E8DCF /* Profiles */, + B7394865229F194000C47603 /* AppDelegate.swift */, + B7394867229F194000C47603 /* SceneDelegate.swift */, + B7D587D122A0892C006E8DCF /* Home.swift */, + B7D587D322A08965006E8DCF /* CategoryRow.swift */, + B73948A0229F2E1F00C47603 /* LandmarkList.swift */, + B739489E229F2D9700C47603 /* LandmarkRow.swift */, + B7394869229F194000C47603 /* LandmarkDetail.swift */, + B7D587B5229F825D006E8DCF /* HikeView.swift */, + B7D587BB229F82EB006E8DCF /* HikeDetail.swift */, + B7D587DC22A08DD6006E8DCF /* HikeBadge.swift */, + B7310DD0229F6839001079B9 /* HexagonParameters.swift */, + B739487D229F1C0100C47603 /* Supporting Views */, + B7394883229F291A00C47603 /* Resources */, + B739486B229F194200C47603 /* Assets.xcassets */, + B7394870229F194200C47603 /* LaunchScreen.storyboard */, + B7394873229F194200C47603 /* Info.plist */, + B739486D229F194200C47603 /* Preview Content */, + ); + path = Landmarks; + sourceTree = ""; + }; + B739486D229F194200C47603 /* Preview Content */ = { + isa = PBXGroup; + children = ( + B739486E229F194200C47603 /* Preview Assets.xcassets */, + ); + path = "Preview Content"; + sourceTree = ""; + }; + B739487D229F1C0100C47603 /* Supporting Views */ = { + isa = PBXGroup; + children = ( + B7D587E022A0914D006E8DCF /* FeatureCard.swift */, + B7394879229F1B3F00C47603 /* CircleImage.swift */, + B739487B229F1B6800C47603 /* MapView.swift */, + B7310DD2229F6CA9001079B9 /* Badge.swift */, + B7D587AF229F73C1006E8DCF /* BadgeSymbol.swift */, + B7D587B1229F7406006E8DCF /* RotatedBadgeSymbol.swift */, + B7D587AD229F7382006E8DCF /* BadgeBackground.swift */, + B7D587BD229F82FF006E8DCF /* HikeGraph.swift */, + B7D587B7229F826D006E8DCF /* GraphCapsule.swift */, + ); + path = "Supporting Views"; + sourceTree = ""; + }; + B739487E229F282200C47603 /* Models */ = { + isa = PBXGroup; + children = ( + B7D587D522A08C97006E8DCF /* Profile.swift */, + B739487F229F28B900C47603 /* Landmark.swift */, + B7D587E822A09809006E8DCF /* Data.swift */, + B7D587B9229F8288006E8DCF /* Hike.swift */, + B7D2AAC4229F4D7C0061E5F5 /* UserData.swift */, + ); + path = Models; + sourceTree = ""; + }; + B7394883229F291A00C47603 /* Resources */ = { + isa = PBXGroup; + children = ( + B739488E229F292E00C47603 /* landmarkData.json */, + B7D587BF229F830B006E8DCF /* hikeData.json */, + B7D587E222A097E2006E8DCF /* charleyrivers_feature.jpg */, + B7D587E322A097E2006E8DCF /* stmarylake_feature.jpg */, + B7D587E422A097E2006E8DCF /* turtlerock_feature.jpg */, + B7394890229F292F00C47603 /* chilkoottrail.jpg */, + B739488F229F292F00C47603 /* chincoteague.jpg */, + B739488A229F292E00C47603 /* hiddenlake.jpg */, + B7394886229F292E00C47603 /* icybay.jpg */, + B7394887229F292E00C47603 /* lakemcdonald.jpg */, + B7394884229F292D00C47603 /* rainbowlake.jpg */, + B739488D229F292E00C47603 /* silversalmoncreek.jpg */, + B739488B229F292E00C47603 /* stmarylake.jpg */, + B7394888229F292E00C47603 /* turtlerock.jpg */, + B739488C229F292E00C47603 /* twinlake.jpg */, + B7394889229F292E00C47603 /* umbagog.jpg */, + B73948A2229F3E2200C47603 /* charleyrivers.jpg */, + ); + path = Resources; + sourceTree = ""; + }; + B7D587D722A08D16006E8DCF /* Profiles */ = { + isa = PBXGroup; + children = ( + B7D587D822A08D33006E8DCF /* ProfileHost.swift */, + B7D587DA22A08D67006E8DCF /* ProfileSummary.swift */, + B7D587DE22A08E1A006E8DCF /* ProfileEditor.swift */, + ); + path = Profiles; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + B7394861229F194000C47603 /* Landmarks */ = { + isa = PBXNativeTarget; + buildConfigurationList = B7394876229F194200C47603 /* Build configuration list for PBXNativeTarget "Landmarks" */; + buildPhases = ( + B739485E229F194000C47603 /* Sources */, + B739485F229F194000C47603 /* Frameworks */, + B7394860229F194000C47603 /* Resources */, + C602AC70C605937000000001, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Landmarks; + productName = Landmarks; + productReference = B7394862229F194000C47603 /* Landmarks.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + B739485A229F194000C47603 /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 1100; + LastUpgradeCheck = 1100; + ORGANIZATIONNAME = Apple; + TargetAttributes = { + B7394861229F194000C47603 = { + CreatedOnToolsVersion = 11.0; + }; + }; + }; + buildConfigurationList = B739485D229F194000C47603 /* Build configuration list for PBXProject "InterfacingWithUIKit" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = B7394859229F194000C47603; + productRefGroup = B7394863229F194000C47603 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + B7394861229F194000C47603 /* Landmarks */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + B7394860229F194000C47603 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + B739489A229F292F00C47603 /* silversalmoncreek.jpg in Resources */, + B7394894229F292F00C47603 /* lakemcdonald.jpg in Resources */, + B7D587C0229F830B006E8DCF /* hikeData.json in Resources */, + B7394872229F194200C47603 /* LaunchScreen.storyboard in Resources */, + B73948A3229F3E2200C47603 /* charleyrivers.jpg in Resources */, + B7394891229F292F00C47603 /* rainbowlake.jpg in Resources */, + B7D587E522A097E2006E8DCF /* charleyrivers_feature.jpg in Resources */, + B739486F229F194200C47603 /* Preview Assets.xcassets in Resources */, + B7394895229F292F00C47603 /* turtlerock.jpg in Resources */, + B739486C229F194200C47603 /* Assets.xcassets in Resources */, + B7394899229F292F00C47603 /* twinlake.jpg in Resources */, + B7D587E622A097E2006E8DCF /* stmarylake_feature.jpg in Resources */, + B7394896229F292F00C47603 /* umbagog.jpg in Resources */, + B739489D229F292F00C47603 /* chilkoottrail.jpg in Resources */, + B739489C229F292F00C47603 /* chincoteague.jpg in Resources */, + B739489B229F292F00C47603 /* landmarkData.json in Resources */, + B7394893229F292F00C47603 /* icybay.jpg in Resources */, + B7394897229F292F00C47603 /* hiddenlake.jpg in Resources */, + B7394898229F292F00C47603 /* stmarylake.jpg in Resources */, + B7D587E722A097E2006E8DCF /* turtlerock_feature.jpg in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + B739485E229F194000C47603 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + B7310DD3229F6CA9001079B9 /* Badge.swift in Sources */, + B7D587E122A0914D006E8DCF /* FeatureCard.swift in Sources */, + B7394866229F194000C47603 /* AppDelegate.swift in Sources */, + B7D587D922A08D33006E8DCF /* ProfileHost.swift in Sources */, + B7D587D622A08C97006E8DCF /* Profile.swift in Sources */, + B7D587B8229F826D006E8DCF /* GraphCapsule.swift in Sources */, + B7D587D422A08965006E8DCF /* CategoryRow.swift in Sources */, + B7D587E922A09809006E8DCF /* Data.swift in Sources */, + B739487A229F1B3F00C47603 /* CircleImage.swift in Sources */, + B739487C229F1B6800C47603 /* MapView.swift in Sources */, + B7D587BA229F8288006E8DCF /* Hike.swift in Sources */, + B7D587BC229F82EB006E8DCF /* HikeDetail.swift in Sources */, + B7D587B6229F825D006E8DCF /* HikeView.swift in Sources */, + B7310DD1229F6839001079B9 /* HexagonParameters.swift in Sources */, + B73948A1229F2E1F00C47603 /* LandmarkList.swift in Sources */, + B7D587B0229F73C1006E8DCF /* BadgeSymbol.swift in Sources */, + B7D587B2229F7406006E8DCF /* RotatedBadgeSymbol.swift in Sources */, + B7D587DD22A08DD6006E8DCF /* HikeBadge.swift in Sources */, + B7D587D222A0892C006E8DCF /* Home.swift in Sources */, + B7D587BE229F82FF006E8DCF /* HikeGraph.swift in Sources */, + B7394868229F194000C47603 /* SceneDelegate.swift in Sources */, + B7D587AE229F7382006E8DCF /* BadgeBackground.swift in Sources */, + B739486A229F194000C47603 /* LandmarkDetail.swift in Sources */, + B739489F229F2D9700C47603 /* LandmarkRow.swift in Sources */, + B7D587DB22A08D67006E8DCF /* ProfileSummary.swift in Sources */, + B7D2AAC5229F4D7C0061E5F5 /* UserData.swift in Sources */, + B7394881229F28B900C47603 /* Landmark.swift in Sources */, + B7D587DF22A08E1A006E8DCF /* ProfileEditor.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + B7394870229F194200C47603 /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + B7394871229F194200C47603 /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + B7394874229F194200C47603 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 184943801849325000000001 /* SampleCode.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + B7394875229F194200C47603 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 184943801849325000000001 /* SampleCode.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + B7394877229F194200C47603 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 184943801849325000000001 /* SampleCode.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_ASSET_PATHS = "Landmarks/Preview\\ Content"; + DEVELOPMENT_TEAM = ""; + ENABLE_PREVIEWS = YES; + INFOPLIST_FILE = Landmarks/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = "com.example.apple-samplecode.Landmarks${SAMPLE_CODE_DISAMBIGUATOR}"; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + B7394878229F194200C47603 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 184943801849325000000001 /* SampleCode.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_ASSET_PATHS = "Landmarks/Preview\\ Content"; + DEVELOPMENT_TEAM = ""; + ENABLE_PREVIEWS = YES; + INFOPLIST_FILE = Landmarks/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = "com.example.apple-samplecode.Landmarks${SAMPLE_CODE_DISAMBIGUATOR}"; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + B739485D229F194000C47603 /* Build configuration list for PBXProject "InterfacingWithUIKit" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + B7394874229F194200C47603 /* Debug */, + B7394875229F194200C47603 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + B7394876229F194200C47603 /* Build configuration list for PBXNativeTarget "Landmarks" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + B7394877229F194200C47603 /* Debug */, + B7394878229F194200C47603 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = B739485A229F194000C47603 /* Project object */; +} diff --git a/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/InterfacingWithUIKit.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/InterfacingWithUIKit.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 0000000..3ddf867 --- /dev/null +++ b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/InterfacingWithUIKit.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,8 @@ + + + + + BuildSystemType + Latest + + diff --git a/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/AppDelegate.swift b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/AppDelegate.swift new file mode 100644 index 0000000..e22943b --- /dev/null +++ b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/AppDelegate.swift @@ -0,0 +1,36 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +The application delegate. +*/ + +import UIKit + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { + // Override point for customization after application launch. + return true + } + + func applicationWillTerminate(_ application: UIApplication) { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. + } + + // MARK: UISceneSession Lifecycle + func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration { + // Called when a new scene session is being created. + // Use this method to select a configuration to create the new scene with. + return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role) + } + + func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) { + // Called when the user discards a scene session. + // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions. + // Use this method to release any resources that were specific to the discarded scenes, as they will not return. + } + +} + diff --git a/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/Contents.json b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..fa0d2db --- /dev/null +++ b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,113 @@ +{ + "images" : [ + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "landmark_app_icon_40x40.png", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "3x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "landmark_app_icon_58x58.png", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "landmark_app_icon_87x87.png", + "scale" : "3x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "landmark_app_icon_80x80.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "landmark_app_icon_120x120.png", + "scale" : "3x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "landmark_app_icon_120x120-1.png", + "scale" : "2x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "landmark_app_icon_180x180.png", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "1x" + }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "landmark_app_icon_40x40-1.png", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "landmark_app_icon_58x58-1.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "landmark_app_icon_40x40-2.png", + "scale" : "1x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "landmark_app_icon_80x80-1.png", + "scale" : "2x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "landmark_app_icon_76x76.png", + "scale" : "1x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "landmark_app_icon_152x152.png", + "scale" : "2x" + }, + { + "size" : "83.5x83.5", + "idiom" : "ipad", + "filename" : "landmark_app_icon_167x167.png", + "scale" : "2x" + }, + { + "size" : "1024x1024", + "idiom" : "ios-marketing", + "filename" : "landmark_app_icon_1024x1024.png", + "scale" : "1x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_1024x1024.png b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_1024x1024.png new file mode 100644 index 0000000..00d81c1 Binary files /dev/null and b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_1024x1024.png differ diff --git a/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_120x120-1.png b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_120x120-1.png new file mode 100644 index 0000000..d382b8b Binary files /dev/null and b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_120x120-1.png differ diff --git a/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_120x120.png b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_120x120.png new file mode 100644 index 0000000..d382b8b Binary files /dev/null and b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_120x120.png differ diff --git a/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_152x152.png b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_152x152.png new file mode 100644 index 0000000..11057f8 Binary files /dev/null and b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_152x152.png differ diff --git a/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_167x167.png b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_167x167.png new file mode 100644 index 0000000..f73bc26 Binary files /dev/null and b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_167x167.png differ diff --git a/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_180x180.png b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_180x180.png new file mode 100644 index 0000000..b02738c Binary files /dev/null and b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_180x180.png differ diff --git a/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40-1.png b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40-1.png new file mode 100644 index 0000000..abaff0e Binary files /dev/null and b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40-1.png differ diff --git a/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40-2.png b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40-2.png new file mode 100644 index 0000000..abaff0e Binary files /dev/null and b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40-2.png differ diff --git a/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40.png b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40.png new file mode 100644 index 0000000..abaff0e Binary files /dev/null and b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40.png differ diff --git a/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_58x58-1.png b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_58x58-1.png new file mode 100644 index 0000000..cf7c73d Binary files /dev/null and b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_58x58-1.png differ diff --git a/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_58x58.png b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_58x58.png new file mode 100644 index 0000000..cf7c73d Binary files /dev/null and b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_58x58.png differ diff --git a/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_76x76.png b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_76x76.png new file mode 100644 index 0000000..3eff85b Binary files /dev/null and b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_76x76.png differ diff --git a/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_80x80-1.png b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_80x80-1.png new file mode 100644 index 0000000..6f33f66 Binary files /dev/null and b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_80x80-1.png differ diff --git a/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_80x80.png b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_80x80.png new file mode 100644 index 0000000..6f33f66 Binary files /dev/null and b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_80x80.png differ diff --git a/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_87x87.png b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_87x87.png new file mode 100644 index 0000000..9e1616c Binary files /dev/null and b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_87x87.png differ diff --git a/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Assets.xcassets/Contents.json b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Assets.xcassets/turtlerock.imageset/Contents.json b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Assets.xcassets/turtlerock.imageset/Contents.json new file mode 100644 index 0000000..5bfd7bf --- /dev/null +++ b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Assets.xcassets/turtlerock.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "turtlerock.jpg", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Assets.xcassets/turtlerock.imageset/turtlerock.jpg b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Assets.xcassets/turtlerock.imageset/turtlerock.jpg new file mode 100644 index 0000000..68bcd3e Binary files /dev/null and b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Assets.xcassets/turtlerock.imageset/turtlerock.jpg differ diff --git a/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Base.lproj/LaunchScreen.storyboard b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000..865e932 --- /dev/null +++ b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/CategoryRow.swift b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/CategoryRow.swift new file mode 100644 index 0000000..1f4fbd8 --- /dev/null +++ b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/CategoryRow.swift @@ -0,0 +1,64 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A view showing a scrollable list of landmarks. +*/ + +import SwiftUI + +struct CategoryRow: View { + var categoryName: String + var items: [Landmark] + + var body: some View { + VStack(alignment: .leading) { + Text(self.categoryName) + .font(.headline) + .padding(.leading, 15) + .padding(.top, 5) + + ScrollView(showsHorizontalIndicator: false) { + HStack(alignment: .top, spacing: 0) { + ForEach(self.items.identified(by: \.name)) { landmark in + NavigationButton( + destination: LandmarkDetail( + landmark: landmark + ) + ) { + CategoryItem(landmark: landmark) + } + } + } + } + .frame(height: 185) + } + } +} + +struct CategoryItem: View { + var landmark: Landmark + var body: some View { + VStack(alignment: .leading) { + landmark + .image(forSize: 155) + .renderingMode(.original) + .cornerRadius(5) + Text(landmark.name) + .color(.primary) + .font(.caption) + } + .padding(.leading, 15) + } +} + +#if DEBUG +struct CategoryRow_Previews: PreviewProvider { + static var previews: some View { + CategoryRow( + categoryName: landmarkData[0].category.rawValue, + items: Array(landmarkData.prefix(4)) + ) + } +} +#endif diff --git a/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/HexagonParameters.swift b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/HexagonParameters.swift new file mode 100644 index 0000000..8decba4 --- /dev/null +++ b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/HexagonParameters.swift @@ -0,0 +1,57 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +Size, position, and other information used to draw a badge. +*/ + +import SwiftUI + +struct HexagonParameters { + struct Segment { + let useWidth: (CGFloat, CGFloat, CGFloat) + let xFactors: (CGFloat, CGFloat, CGFloat) + let useHeight: (CGFloat, CGFloat, CGFloat) + let yFactors: (CGFloat, CGFloat, CGFloat) + } + + static let adjustment: CGFloat = 0.085 + static let points = [ + Segment( + useWidth: (1.00, 1.00, 1.00), + xFactors: (0.60, 0.40, 0.50), + useHeight: (1.00, 1.00, 0.00), + yFactors: (0.05, 0.05, 0.00) + ), + Segment( + useWidth: (1.00, 1.00, 0.00), + xFactors: (0.05, 0.00, 0.00), + useHeight: (1.00, 1.00, 1.00), + yFactors: (0.20 + adjustment, 0.30 + adjustment, 0.25 + adjustment) + ), + Segment( + useWidth: (1.00, 1.00, 0.00), + xFactors: (0.00, 0.05, 0.00), + useHeight: (1.00, 1.00, 1.00), + yFactors: (0.70 - adjustment, 0.80 - adjustment, 0.75 - adjustment) + ), + Segment( + useWidth: (1.00, 1.00, 1.00), + xFactors: (0.40, 0.60, 0.50), + useHeight: (1.00, 1.00, 1.00), + yFactors: (0.95, 0.95, 1.00) + ), + Segment( + useWidth: (1.00, 1.00, 1.00), + xFactors: (0.95, 1.00, 1.00), + useHeight: (1.00, 1.00, 1.00), + yFactors: (0.80 - adjustment, 0.70 - adjustment, 0.75 - adjustment) + ), + Segment( + useWidth: (1.00, 1.00, 1.00), + xFactors: (1.00, 0.95, 1.00), + useHeight: (1.00, 1.00, 1.00), + yFactors: (0.30 + adjustment, 0.20 + adjustment, 0.25 + adjustment) + ) + ] +} diff --git a/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/HikeBadge.swift b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/HikeBadge.swift new file mode 100644 index 0000000..52716cf --- /dev/null +++ b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/HikeBadge.swift @@ -0,0 +1,31 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A view that shows a badge for hiking. +*/ + +import SwiftUI + +struct HikeBadge: View { + var name: String + var body: some View { + VStack(alignment: .center) { + Badge() + .frame(width: 300, height: 300) + .scaleEffect(1.0 / 3.0) + .frame(width: 100, height: 100) + Text(name) + .font(.caption) + .accessibility(label: Text("Badge for \(name).")) + } + } +} + +#if DEBUG +struct HikeBadge_Previews: PreviewProvider { + static var previews: some View { + HikeBadge(name: "Preview Testing") + } +} +#endif diff --git a/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/HikeDetail.swift b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/HikeDetail.swift new file mode 100644 index 0000000..3406a6d --- /dev/null +++ b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/HikeDetail.swift @@ -0,0 +1,49 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A view showing the details for a hike. +*/ + +import SwiftUI + +struct HikeDetail: View { + let hike: Hike + @State var dataToShow = \Hike.Observation.elevation + + var buttons = [ + ("Elevation", \Hike.Observation.elevation), + ("Heart Rate", \Hike.Observation.heartRate), + ("Pace", \Hike.Observation.pace), + ] + + var body: some View { + return VStack { + HikeGraph(hike: hike, path: dataToShow) + .frame(height: 200, alignment: .center) + + HStack(spacing: 25) { + ForEach(buttons.identified(by: \.0)) { value in + Button(action: { + self.dataToShow = value.1 + }) { + Text(verbatim: value.0) + .font(.system(size: 15)) + .color(value.1 == self.dataToShow + ? Color.gray + : Color.accentColor) + .animation(nil) + } + } + } + } + } +} + +#if DEBUG +struct HikeDetail_Previews: PreviewProvider { + static var previews: some View { + HikeDetail(hike: hikeData[0]) + } +} +#endif diff --git a/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/HikeView.swift b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/HikeView.swift new file mode 100644 index 0000000..f4c02cc --- /dev/null +++ b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/HikeView.swift @@ -0,0 +1,68 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A view displaying inforamtion about a hike, including an elevation graph. +*/ + +import SwiftUI + +struct HikeView: View { + var hike: Hike + @State private var showDetail = false + + var transition: AnyTransition { + let insertion = AnyTransition.move(edge: .trailing) + .combined(with: .opacity) + let removal = AnyTransition.scale() + .combined(with: .opacity) + return .asymmetric(insertion: insertion, removal: removal) + } + + var body: some View { + VStack { + HStack { + HikeGraph(hike: hike, path: \.elevation) + .frame(width: 50, height: 30) + .animation(nil) + + VStack(alignment: .leading) { + Text(verbatim: hike.name) + .font(.headline) + Text(verbatim: hike.distanceText) + } + + Spacer() + + Button(action: { + withAnimation { + self.showDetail.toggle() + } + }) { + Image(systemName: "chevron.right.circle") + .imageScale(.large) + .rotationEffect(.degrees(showDetail ? 90 : 0)) + .scaleEffect(showDetail ? 1.5 : 1) + .padding() + } + } + + if showDetail { + HikeDetail(hike: hike) + .transition(transition) + } + } + } +} + +#if DEBUG +struct HikeView_Previews: PreviewProvider { + static var previews: some View { + VStack { + HikeView(hike: hikeData[0]) + .padding() + Spacer() + } + } +} +#endif diff --git a/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Home.swift b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Home.swift new file mode 100644 index 0000000..5237246 --- /dev/null +++ b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Home.swift @@ -0,0 +1,67 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A view showing featured landmarks above a list of all of the landmarks. +*/ + +import SwiftUI + +struct CategoryHome: View { + var categories: [String: [Landmark]] { + .init( + grouping: landmarkData, + by: { $0.category.rawValue } + ) + } + + var featured: [Landmark] { + landmarkData.filter { $0.isFeatured } + } + + var body: some View { + NavigationView { + List { + FeaturedLandmarks(landmarks: featured) + .scaledToFill() + .frame(height: 200) + .clipped() + .listRowInsets(EdgeInsets()) + + ForEach(categories.keys.sorted().identified(by: \.self)) { key in + CategoryRow(categoryName: key, items: self.categories[key]!) + } + .listRowInsets(EdgeInsets()) + + NavigationButton(destination: LandmarkList()) { + Text("See All") + } + } + .navigationBarTitle(Text("Featured")) + .navigationBarItems(trailing: + PresentationButton( + Image(systemName: "person.crop.circle") + .imageScale(.large) + .accessibility(label: Text("User Profile")) + .padding(), + destination: ProfileHost() + ) + ) + } + } +} + +struct FeaturedLandmarks: View { + var landmarks: [Landmark] + var body: some View { + landmarks[0].image(forSize: 250).resizable() + } +} + +#if DEBUG +struct CategoryHome_Previews: PreviewProvider { + static var previews: some View { + CategoryHome() + } +} +#endif diff --git a/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Info.plist b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Info.plist new file mode 100644 index 0000000..e8bb4c6 --- /dev/null +++ b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Info.plist @@ -0,0 +1,62 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + $(PRODUCT_BUNDLE_PACKAGE_TYPE) + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UIApplicationSceneManifest + + UIApplicationSupportsMultipleScenes + + UISceneConfigurations + + UIWindowSceneSessionRoleApplication + + + UILaunchStoryboardName + LaunchScreen + UISceneConfigurationName + Default Configuration + UISceneDelegateClassName + $(PRODUCT_MODULE_NAME).SceneDelegate + + + + + UILaunchStoryboardName + LaunchScreen + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/LandmarkDetail.swift b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/LandmarkDetail.swift new file mode 100644 index 0000000..6c290a3 --- /dev/null +++ b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/LandmarkDetail.swift @@ -0,0 +1,71 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A view showing the details for a landmark. +*/ + +import SwiftUI + +struct LandmarkDetail: View { + @EnvironmentObject var userData: UserData + var landmark: Landmark + + var landmarkIndex: Int { + userData.landmarks.firstIndex(where: { $0.id == landmark.id })! + } + + var body: some View { + VStack { + MapView(coordinate: landmark.locationCoordinate) + .edgesIgnoringSafeArea(.top) + .frame(height: 300) + + CircleImage(image: landmark.image(forSize: 250)) + .offset(x: 0, y: -130) + .padding(.bottom, -130) + + VStack(alignment: .leading) { + HStack { + Text(verbatim: landmark.name) + .font(.title) + + Button(action: { + self.userData.landmarks[self.landmarkIndex] + .isFavorite.toggle() + }) { + if self.userData.landmarks[self.landmarkIndex] + .isFavorite { + Image(systemName: "star.fill") + .foregroundColor(Color.yellow) + } else { + Image(systemName: "star") + .foregroundColor(Color.gray) + } + } + } + + HStack(alignment: .top) { + Text(verbatim: landmark.park) + .font(.subheadline) + Spacer() + Text(verbatim: landmark.state) + .font(.subheadline) + } + } + .padding() + + Spacer() + } + } +} + +#if DEBUG +struct LandmarkDetail_Preview: PreviewProvider { + static var previews: some View { + let userData = UserData() + return LandmarkDetail(landmark: userData.landmarks[0]) + .environmentObject(userData) + } +} +#endif diff --git a/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/LandmarkList.swift b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/LandmarkList.swift new file mode 100644 index 0000000..c17b5f3 --- /dev/null +++ b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/LandmarkList.swift @@ -0,0 +1,45 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A view showing a list of landmarks. +*/ + +import SwiftUI + +struct LandmarkList: View { + @EnvironmentObject private var userData: UserData + + var body: some View { + NavigationView { + List { + Toggle(isOn: $userData.showFavoritesOnly) { + Text("Show Favorites Only") + } + + ForEach(userData.landmarks) { landmark in + if !self.userData.showFavoritesOnly || landmark.isFavorite { + NavigationButton( + destination: LandmarkDetail(landmark: landmark)) { + LandmarkRow(landmark: landmark) + } + } + } + } + .navigationBarTitle(Text("Landmarks"), displayMode: .large) + } + } +} + +#if DEBUG +struct LandmarksList_Previews: PreviewProvider { + static var previews: some View { + ForEach(["iPhone SE", "iPhone XS Max"].identified(by: \.self)) { deviceName in + LandmarkList() + .previewDevice(PreviewDevice(rawValue: deviceName)) + .previewDisplayName(deviceName) + } + .environmentObject(UserData()) + } +} +#endif diff --git a/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Models/Data.swift b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Models/Data.swift new file mode 100644 index 0000000..761ce0a --- /dev/null +++ b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Models/Data.swift @@ -0,0 +1,100 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +Helpers for loading images and data. +*/ + +import Foundation +import CoreLocation +import UIKit +import SwiftUI + +let landmarkData: [Landmark] = load("landmarkData.json") +let features = landmarkData.filter { $0.isFeatured } +let hikeData: [Hike] = load("hikeData.json") + +func load(_ filename: String, as type: T.Type = T.self) -> T { + let data: Data + + guard let file = Bundle.main.url(forResource: filename, withExtension: nil) + else { + fatalError("Couldn't find \(filename) in main bundle.") + } + + do { + data = try Data(contentsOf: file) + } catch { + fatalError("Couldn't load \(filename) from main bundle:\n\(error)") + } + + do { + let decoder = JSONDecoder() + return try decoder.decode(T.self, from: data) + } catch { + fatalError("Couldn't parse \(filename) as \(T.self):\n\(error)") + } +} + +final class ImageStore { + fileprivate typealias _ImageDictionary = [String: [Int: CGImage]] + fileprivate var images: _ImageDictionary = [:] + + fileprivate static var originalSize = 250 + fileprivate static var scale = 2 + + static var shared = ImageStore() + + func image(name: String, size: Int) -> Image { + let index = _guaranteeInitialImage(name: name) + + let sizedImage = images.values[index][size] + ?? _sizeImage(images.values[index][ImageStore.originalSize]!, to: size * ImageStore.scale) + images.values[index][size] = sizedImage + + return Image(sizedImage, scale: Length(ImageStore.scale), label: Text(verbatim: name)) + } + + static func loadImage(name: String) -> CGImage { + guard + let url = Bundle.main.url(forResource: name, withExtension: "jpg"), + let imageSource = CGImageSourceCreateWithURL(url as NSURL, nil), + let image = CGImageSourceCreateImageAtIndex(imageSource, 0, nil) + else { + fatalError("Couldn't load image \(name).jpg from main bundle.") + } + return image + } + + fileprivate func _guaranteeInitialImage(name: String) -> _ImageDictionary.Index { + if let index = images.index(forKey: name) { return index } + + let image = ImageStore.loadImage(name: name) + images[name] = [ImageStore.originalSize: image] + return images.index(forKey: name)! + } + + fileprivate func _sizeImage(_ image: CGImage, to size: Int) -> CGImage { + guard + let colorSpace = image.colorSpace, + let context = CGContext( + data: nil, + width: size, height: size, + bitsPerComponent: image.bitsPerComponent, + bytesPerRow: image.bytesPerRow, + space: colorSpace, + bitmapInfo: image.bitmapInfo.rawValue) + else { + fatalError("Couldn't create graphics context.") + } + context.interpolationQuality = .high + context.draw(image, in: CGRect(x: 0, y: 0, width: size, height: size)) + + if let sizedImage = context.makeImage() { + return sizedImage + } else { + fatalError("Couldn't resize image.") + } + } +} + diff --git a/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Models/Hike.swift b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Models/Hike.swift new file mode 100644 index 0000000..dfd2bb8 --- /dev/null +++ b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Models/Hike.swift @@ -0,0 +1,31 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +The model for a hike. +*/ + +import SwiftUI + +struct Hike: Codable, Hashable, Identifiable { + var name: String + var id: Int + var distance: Double + var difficulty: Int + var observations: [Observation] + + static var formatter = LengthFormatter() + + var distanceText: String { + return Hike.formatter + .string(fromValue: distance, unit: .kilometer) + } + + struct Observation: Codable, Hashable { + var distanceFromStart: Double + + var elevation: Range + var pace: Range + var heartRate: Range + } +} diff --git a/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Models/Landmark.swift b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Models/Landmark.swift new file mode 100644 index 0000000..fafe700 --- /dev/null +++ b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Models/Landmark.swift @@ -0,0 +1,52 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +The model for an individual landmark. +*/ + +import SwiftUI +import CoreLocation + +struct Landmark: Hashable, Codable, Identifiable { + var id: Int + var name: String + fileprivate var imageName: String + fileprivate var coordinates: Coordinates + var state: String + var park: String + var category: Category + var isFavorite: Bool + var isFeatured: Bool + + var locationCoordinate: CLLocationCoordinate2D { + CLLocationCoordinate2D( + latitude: coordinates.latitude, + longitude: coordinates.longitude) + } + + var featureImage: Image? { + guard isFeatured else { return nil } + + return Image( + ImageStore.loadImage(name: "\(imageName)_feature"), + scale: 2, + label: Text(verbatim: name)) + } + + func image(forSize size: Int) -> Image { + ImageStore.shared.image(name: imageName, size: size) + } + + enum Category: String, CaseIterable, Codable, Hashable { + case featured = "Featured" + case lakes = "Lakes" + case rivers = "Rivers" + case mountains = "Mountains" + } +} + +struct Coordinates: Hashable, Codable { + var latitude: Double + var longitude: Double +} diff --git a/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Models/Profile.swift b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Models/Profile.swift new file mode 100644 index 0000000..7c30519 --- /dev/null +++ b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Models/Profile.swift @@ -0,0 +1,30 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +An object that models a user profile. +*/ +import Foundation + +struct Profile { + var username: String + var prefersNotifications: Bool + var seasonalPhoto: Season + var goalDate: Date + + static let `default` = Self(username: "g_kumar", prefersNotifications: true, seasonalPhoto: .winter) + + init(username: String, prefersNotifications: Bool = true, seasonalPhoto: Season = .winter) { + self.username = username + self.prefersNotifications = prefersNotifications + self.seasonalPhoto = seasonalPhoto + self.goalDate = Date() + } + + enum Season: String, CaseIterable { + case spring = "🌷" + case summer = "🌞" + case autumn = "🍂" + case winter = "☃️" + } +} diff --git a/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Models/UserData.swift b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Models/UserData.swift new file mode 100644 index 0000000..db31fb0 --- /dev/null +++ b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Models/UserData.swift @@ -0,0 +1,25 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A model object that stores app data. +*/ + +import Combine +import SwiftUI + +final class UserData: BindableObject { + let didChange = PassthroughSubject() + + var showFavoritesOnly = false { + didSet { + didChange.send(self) + } + } + + var landmarks = landmarkData { + didSet { + didChange.send(self) + } + } +} diff --git a/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Preview Content/Preview Assets.xcassets/Contents.json b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Preview Content/Preview Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Preview Content/Preview Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Profiles/ProfileEditor.swift b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Profiles/ProfileEditor.swift new file mode 100644 index 0000000..ca4cdda --- /dev/null +++ b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Profiles/ProfileEditor.swift @@ -0,0 +1,56 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +An editable profile view. +*/ + +import SwiftUI + +struct ProfileEditor: View { + @Binding var profile: Profile + + var body: some View { + List { + HStack { + Text("Username").bold() + Divider() + TextField($profile.username) + } + + Toggle(isOn: $profile.prefersNotifications) { + Text("Enable Notifications") + } + + VStack(alignment: .leading, spacing: 20) { + Text("Seasonal Photo").bold() + + SegmentedControl(selection: $profile.seasonalPhoto) { + ForEach(Profile.Season.allCases.identified(by: \.self)) { season in + Text(season.rawValue).tag(season) + } + } + } + .padding(.top) + + VStack(alignment: .leading, spacing: 20) { + Text("Goal Date").bold() + DatePicker( + $profile.goalDate, + minimumDate: Calendar.current.date(byAdding: .year, value: -1, to: profile.goalDate), + maximumDate: Calendar.current.date(byAdding: .year, value: 1, to: profile.goalDate), + displayedComponents: .date + ) + } + .padding(.top) + } + } +} + +#if DEBUG +struct ProfileEditor_Previews: PreviewProvider { + static var previews: some View { + ProfileEditor(profile: .constant(.default)) + } +} +#endif diff --git a/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Profiles/ProfileHost.swift b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Profiles/ProfileHost.swift new file mode 100644 index 0000000..534c771 --- /dev/null +++ b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Profiles/ProfileHost.swift @@ -0,0 +1,50 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A view that hosts the profile viewer and editor. +*/ + +import SwiftUI + +struct ProfileHost: View { + @Environment(\.editMode) var mode + @State var profile = Profile.default + @State var draftProfile = Profile.default + + var body: some View { + VStack(alignment: .leading, spacing: 20) { + HStack { + if self.mode?.value == .active { + Button(action: { + self.profile = self.draftProfile + self.mode?.animation().value = .inactive + }) { + Text("Done") + } + } + + Spacer() + + EditButton() + } + if self.mode?.value == .inactive { + ProfileSummary(profile: profile) + } else { + ProfileEditor(profile: $draftProfile) + .onDisappear { + self.draftProfile = self.profile + } + } + } + .padding() + } +} + +#if DEBUG +struct ProfileHost_Previews: PreviewProvider { + static var previews: some View { + ProfileHost() + } +} +#endif diff --git a/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Profiles/ProfileSummary.swift b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Profiles/ProfileSummary.swift new file mode 100644 index 0000000..6d31231 --- /dev/null +++ b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Profiles/ProfileSummary.swift @@ -0,0 +1,65 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A view that summarizes a profile. +*/ + +import SwiftUI + +struct ProfileSummary: View { + var profile: Profile + + static var goalFormat: DateFormatter { + let formatter = DateFormatter() + formatter.dateFormat = "MMMM d, yyyy" + return formatter + } + + var body: some View { + List { + Text(profile.username) + .bold() + .font(.title) + + Text("Notifications: \(self.profile.prefersNotifications ? "On": "Off" )") + + Text("Seasonal Photos: \(self.profile.seasonalPhoto.rawValue)") + + Text("Goal Date: \(self.profile.goalDate, formatter: Self.goalFormat)") + + VStack(alignment: .leading) { + Text("Completed Badges") + .font(.headline) + ScrollView { + HStack { + HikeBadge(name: "First Hike") + + HikeBadge(name: "Earth Day") + .hueRotation(Angle(degrees: 90)) + + HikeBadge(name: "Tenth Hike") + .grayscale(0.5) + .hueRotation(Angle(degrees: 45)) + } + } + .frame(height: 140) + } + + VStack(alignment: .leading) { + Text("Recent Hikes") + .font(.headline) + + HikeView(hike: hikeData[0]) + } + } + } +} + +#if DEBUG +struct ProfileSummary_Previews: PreviewProvider { + static var previews: some View { + ProfileSummary(profile: Profile.default) + } +} +#endif diff --git a/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Resources/charleyrivers.jpg b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Resources/charleyrivers.jpg new file mode 100644 index 0000000..17ff44b Binary files /dev/null and b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Resources/charleyrivers.jpg differ diff --git a/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Resources/charleyrivers_feature.jpg b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Resources/charleyrivers_feature.jpg new file mode 100644 index 0000000..af1d114 Binary files /dev/null and b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Resources/charleyrivers_feature.jpg differ diff --git a/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Resources/chilkoottrail.jpg b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Resources/chilkoottrail.jpg new file mode 100644 index 0000000..e7f805e Binary files /dev/null and b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Resources/chilkoottrail.jpg differ diff --git a/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Resources/chincoteague.jpg b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Resources/chincoteague.jpg new file mode 100644 index 0000000..5f47986 Binary files /dev/null and b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Resources/chincoteague.jpg differ diff --git a/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Resources/hiddenlake.jpg b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Resources/hiddenlake.jpg new file mode 100644 index 0000000..d8e804c Binary files /dev/null and b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Resources/hiddenlake.jpg differ diff --git a/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Resources/hikeData.json b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Resources/hikeData.json new file mode 100644 index 0000000..3fb1e96 --- /dev/null +++ b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Resources/hikeData.json @@ -0,0 +1,1882 @@ +[ + { + "name":"Lonesome Ridge Trail", + "id":1001, + "distance":4.5, + "difficulty":3, + "observations":[ + { + "elevation":[ + 291.65263635636268, + 309.26016677925196 + ], + "pace":[ + 396.08716481908732, + 403.68937873525232 + ], + "heartRate":[ + 117.16351898665887, + 121.95815455919609 + ], + "distanceFromStart":0 + }, + { + "elevation":[ + 299.24001936628116, + 317.44584350790012 + ], + "pace":[ + 380.19020240756623, + 395.3978319010256 + ], + "heartRate":[ + 117.6410892152911, + 124.82185220506081 + ], + "distanceFromStart":0.375 + }, + { + "elevation":[ + 303.62145464574394, + 336.05569457646544 + ], + "pace":[ + 380.55927782266116, + 397.60789726832775 + ], + "heartRate":[ + 121.52696452049059, + 127.31525441110122 + ], + "distanceFromStart":0.75 + }, + { + "elevation":[ + 319.90393365162629, + 346.26966025518789 + ], + "pace":[ + 357.94116421258531, + 398.0750288648062 + ], + "heartRate":[ + 123.75908585923588, + 132.77069404486801 + ], + "distanceFromStart":1.125 + }, + { + "elevation":[ + 354.17104439267905, + 403.57031216972939 + ], + "pace":[ + 335.07385149392701, + 397.82674381875808 + ], + "heartRate":[ + 130.8235194572915, + 140.55700591418218 + ], + "distanceFromStart":1.5 + }, + { + "elevation":[ + 357.42992871175124, + 385.92155620623635 + ], + "pace":[ + 395.16168913839374, + 404.60294066527558 + ], + "heartRate":[ + 131.5456052446734, + 134.65984504627627 + ], + "distanceFromStart":1.875 + }, + { + "elevation":[ + 345.47736721935661, + 363.18776661379422 + ], + "pace":[ + 340.82303041339082, + 404.71689228682374 + ], + "heartRate":[ + 125.1949698433959, + 131.31354363122026 + ], + "distanceFromStart":2.25 + }, + { + "elevation":[ + 346.23343025200535, + 497.23376445462401 + ], + "pace":[ + 261.27629148816021, + 331.68516208719467 + ], + "heartRate":[ + 131.67810544238606, + 154.26779645311458 + ], + "distanceFromStart":2.625 + }, + { + "elevation":[ + 491.57378483134391, + 547.49535224251053 + ], + "pace":[ + 296.05298644112088, + 401.14092967732398 + ], + "heartRate":[ + 151.36398089694217, + 166.20454793289232 + ], + "distanceFromStart":3 + }, + { + "elevation":[ + 472.06803233416338, + 531.92570520228401 + ], + "pace":[ + 395.50830663514012, + 401.67837917543591 + ], + "heartRate":[ + 134.41798110234078, + 151.90886697564241 + ], + "distanceFromStart":3.375 + }, + { + "elevation":[ + 339.81419476005283, + 461.03832527824829 + ], + "pace":[ + 395.31160487975183, + 404.49550455974907 + ], + "heartRate":[ + 129.97753472415462, + 138.13531094848992 + ], + "distanceFromStart":3.75 + }, + { + "elevation":[ + 303.1495508565697, + 342.3532820173541 + ], + "pace":[ + 395.02844559698116, + 402.65878340653796 + ], + "heartRate":[ + 127.72304232462609, + 133.26322270764186 + ], + "distanceFromStart":4.125 + } + ] + }, + { + "name":"Lonesome Ridge Trail", + "id":1002, + "distance":4.5, + "difficulty":3, + "observations":[ + { + "elevation":[ + 291.65263635636268, + 309.26016677925196 + ], + "pace":[ + 396.08716481908732, + 403.68937873525232 + ], + "heartRate":[ + 117.16351898665887, + 121.95815455919609 + ], + "distanceFromStart":0 + }, + { + "elevation":[ + 299.24001936628116, + 317.44584350790012 + ], + "pace":[ + 380.19020240756623, + 395.3978319010256 + ], + "heartRate":[ + 117.6410892152911, + 124.82185220506081 + ], + "distanceFromStart":0.375 + }, + { + "elevation":[ + 303.62145464574394, + 336.05569457646544 + ], + "pace":[ + 380.55927782266116, + 397.60789726832775 + ], + "heartRate":[ + 121.52696452049059, + 127.31525441110122 + ], + "distanceFromStart":0.75 + }, + { + "elevation":[ + 319.90393365162629, + 346.26966025518789 + ], + "pace":[ + 357.94116421258531, + 398.0750288648062 + ], + "heartRate":[ + 123.75908585923588, + 132.77069404486801 + ], + "distanceFromStart":1.125 + }, + { + "elevation":[ + 354.17104439267905, + 403.57031216972939 + ], + "pace":[ + 335.07385149392701, + 397.82674381875808 + ], + "heartRate":[ + 130.8235194572915, + 140.55700591418218 + ], + "distanceFromStart":1.5 + }, + { + "elevation":[ + 357.42992871175124, + 385.92155620623635 + ], + "pace":[ + 395.16168913839374, + 404.60294066527558 + ], + "heartRate":[ + 131.5456052446734, + 134.65984504627627 + ], + "distanceFromStart":1.875 + }, + { + "elevation":[ + 345.47736721935661, + 363.18776661379422 + ], + "pace":[ + 340.82303041339082, + 404.71689228682374 + ], + "heartRate":[ + 125.1949698433959, + 131.31354363122026 + ], + "distanceFromStart":2.25 + }, + { + "elevation":[ + 346.23343025200535, + 497.23376445462401 + ], + "pace":[ + 261.27629148816021, + 331.68516208719467 + ], + "heartRate":[ + 131.67810544238606, + 154.26779645311458 + ], + "distanceFromStart":2.625 + }, + { + "elevation":[ + 491.57378483134391, + 547.49535224251053 + ], + "pace":[ + 296.05298644112088, + 401.14092967732398 + ], + "heartRate":[ + 151.36398089694217, + 166.20454793289232 + ], + "distanceFromStart":3 + }, + { + "elevation":[ + 472.06803233416338, + 531.92570520228401 + ], + "pace":[ + 395.50830663514012, + 401.67837917543591 + ], + "heartRate":[ + 134.41798110234078, + 151.90886697564241 + ], + "distanceFromStart":3.375 + }, + { + "elevation":[ + 339.81419476005283, + 461.03832527824829 + ], + "pace":[ + 395.31160487975183, + 404.49550455974907 + ], + "heartRate":[ + 129.97753472415462, + 138.13531094848992 + ], + "distanceFromStart":3.75 + }, + { + "elevation":[ + 303.1495508565697, + 342.3532820173541 + ], + "pace":[ + 395.02844559698116, + 402.65878340653796 + ], + "heartRate":[ + 127.72304232462609, + 133.26322270764186 + ], + "distanceFromStart":4.125 + } + ] + }, + { + "name":"Lonesome Ridge Trail", + "id":1003, + "distance":4.5, + "difficulty":3, + "observations":[ + { + "elevation":[ + 291.65263635636268, + 309.26016677925196 + ], + "pace":[ + 396.08716481908732, + 403.68937873525232 + ], + "heartRate":[ + 117.16351898665887, + 121.95815455919609 + ], + "distanceFromStart":0 + }, + { + "elevation":[ + 299.24001936628116, + 317.44584350790012 + ], + "pace":[ + 380.19020240756623, + 395.3978319010256 + ], + "heartRate":[ + 117.6410892152911, + 124.82185220506081 + ], + "distanceFromStart":0.375 + }, + { + "elevation":[ + 303.62145464574394, + 336.05569457646544 + ], + "pace":[ + 380.55927782266116, + 397.60789726832775 + ], + "heartRate":[ + 121.52696452049059, + 127.31525441110122 + ], + "distanceFromStart":0.75 + }, + { + "elevation":[ + 319.90393365162629, + 346.26966025518789 + ], + "pace":[ + 357.94116421258531, + 398.0750288648062 + ], + "heartRate":[ + 123.75908585923588, + 132.77069404486801 + ], + "distanceFromStart":1.125 + }, + { + "elevation":[ + 354.17104439267905, + 403.57031216972939 + ], + "pace":[ + 335.07385149392701, + 397.82674381875808 + ], + "heartRate":[ + 130.8235194572915, + 140.55700591418218 + ], + "distanceFromStart":1.5 + }, + { + "elevation":[ + 357.42992871175124, + 385.92155620623635 + ], + "pace":[ + 395.16168913839374, + 404.60294066527558 + ], + "heartRate":[ + 131.5456052446734, + 134.65984504627627 + ], + "distanceFromStart":1.875 + }, + { + "elevation":[ + 345.47736721935661, + 363.18776661379422 + ], + "pace":[ + 340.82303041339082, + 404.71689228682374 + ], + "heartRate":[ + 125.1949698433959, + 131.31354363122026 + ], + "distanceFromStart":2.25 + }, + { + "elevation":[ + 346.23343025200535, + 497.23376445462401 + ], + "pace":[ + 261.27629148816021, + 331.68516208719467 + ], + "heartRate":[ + 131.67810544238606, + 154.26779645311458 + ], + "distanceFromStart":2.625 + }, + { + "elevation":[ + 491.57378483134391, + 547.49535224251053 + ], + "pace":[ + 296.05298644112088, + 401.14092967732398 + ], + "heartRate":[ + 151.36398089694217, + 166.20454793289232 + ], + "distanceFromStart":3 + }, + { + "elevation":[ + 472.06803233416338, + 531.92570520228401 + ], + "pace":[ + 395.50830663514012, + 401.67837917543591 + ], + "heartRate":[ + 134.41798110234078, + 151.90886697564241 + ], + "distanceFromStart":3.375 + }, + { + "elevation":[ + 339.81419476005283, + 461.03832527824829 + ], + "pace":[ + 395.31160487975183, + 404.49550455974907 + ], + "heartRate":[ + 129.97753472415462, + 138.13531094848992 + ], + "distanceFromStart":3.75 + }, + { + "elevation":[ + 303.1495508565697, + 342.3532820173541 + ], + "pace":[ + 395.02844559698116, + 402.65878340653796 + ], + "heartRate":[ + 127.72304232462609, + 133.26322270764186 + ], + "distanceFromStart":4.125 + } + ] + }, + { + "name":"Lonesome Ridge Trail", + "id":1004, + "distance":4.5, + "difficulty":3, + "observations":[ + { + "elevation":[ + 291.65263635636268, + 309.26016677925196 + ], + "pace":[ + 396.08716481908732, + 403.68937873525232 + ], + "heartRate":[ + 117.16351898665887, + 121.95815455919609 + ], + "distanceFromStart":0 + }, + { + "elevation":[ + 299.24001936628116, + 317.44584350790012 + ], + "pace":[ + 380.19020240756623, + 395.3978319010256 + ], + "heartRate":[ + 117.6410892152911, + 124.82185220506081 + ], + "distanceFromStart":0.375 + }, + { + "elevation":[ + 303.62145464574394, + 336.05569457646544 + ], + "pace":[ + 380.55927782266116, + 397.60789726832775 + ], + "heartRate":[ + 121.52696452049059, + 127.31525441110122 + ], + "distanceFromStart":0.75 + }, + { + "elevation":[ + 319.90393365162629, + 346.26966025518789 + ], + "pace":[ + 357.94116421258531, + 398.0750288648062 + ], + "heartRate":[ + 123.75908585923588, + 132.77069404486801 + ], + "distanceFromStart":1.125 + }, + { + "elevation":[ + 354.17104439267905, + 403.57031216972939 + ], + "pace":[ + 335.07385149392701, + 397.82674381875808 + ], + "heartRate":[ + 130.8235194572915, + 140.55700591418218 + ], + "distanceFromStart":1.5 + }, + { + "elevation":[ + 357.42992871175124, + 385.92155620623635 + ], + "pace":[ + 395.16168913839374, + 404.60294066527558 + ], + "heartRate":[ + 131.5456052446734, + 134.65984504627627 + ], + "distanceFromStart":1.875 + }, + { + "elevation":[ + 345.47736721935661, + 363.18776661379422 + ], + "pace":[ + 340.82303041339082, + 404.71689228682374 + ], + "heartRate":[ + 125.1949698433959, + 131.31354363122026 + ], + "distanceFromStart":2.25 + }, + { + "elevation":[ + 346.23343025200535, + 497.23376445462401 + ], + "pace":[ + 261.27629148816021, + 331.68516208719467 + ], + "heartRate":[ + 131.67810544238606, + 154.26779645311458 + ], + "distanceFromStart":2.625 + }, + { + "elevation":[ + 491.57378483134391, + 547.49535224251053 + ], + "pace":[ + 296.05298644112088, + 401.14092967732398 + ], + "heartRate":[ + 151.36398089694217, + 166.20454793289232 + ], + "distanceFromStart":3 + }, + { + "elevation":[ + 472.06803233416338, + 531.92570520228401 + ], + "pace":[ + 395.50830663514012, + 401.67837917543591 + ], + "heartRate":[ + 134.41798110234078, + 151.90886697564241 + ], + "distanceFromStart":3.375 + }, + { + "elevation":[ + 339.81419476005283, + 461.03832527824829 + ], + "pace":[ + 395.31160487975183, + 404.49550455974907 + ], + "heartRate":[ + 129.97753472415462, + 138.13531094848992 + ], + "distanceFromStart":3.75 + }, + { + "elevation":[ + 303.1495508565697, + 342.3532820173541 + ], + "pace":[ + 395.02844559698116, + 402.65878340653796 + ], + "heartRate":[ + 127.72304232462609, + 133.26322270764186 + ], + "distanceFromStart":4.125 + } + ] + }, + { + "name":"Lonesome Ridge Trail", + "id":1005, + "distance":4.5, + "difficulty":3, + "observations":[ + { + "elevation":[ + 291.65263635636268, + 309.26016677925196 + ], + "pace":[ + 396.08716481908732, + 403.68937873525232 + ], + "heartRate":[ + 117.16351898665887, + 121.95815455919609 + ], + "distanceFromStart":0 + }, + { + "elevation":[ + 299.24001936628116, + 317.44584350790012 + ], + "pace":[ + 380.19020240756623, + 395.3978319010256 + ], + "heartRate":[ + 117.6410892152911, + 124.82185220506081 + ], + "distanceFromStart":0.375 + }, + { + "elevation":[ + 303.62145464574394, + 336.05569457646544 + ], + "pace":[ + 380.55927782266116, + 397.60789726832775 + ], + "heartRate":[ + 121.52696452049059, + 127.31525441110122 + ], + "distanceFromStart":0.75 + }, + { + "elevation":[ + 319.90393365162629, + 346.26966025518789 + ], + "pace":[ + 357.94116421258531, + 398.0750288648062 + ], + "heartRate":[ + 123.75908585923588, + 132.77069404486801 + ], + "distanceFromStart":1.125 + }, + { + "elevation":[ + 354.17104439267905, + 403.57031216972939 + ], + "pace":[ + 335.07385149392701, + 397.82674381875808 + ], + "heartRate":[ + 130.8235194572915, + 140.55700591418218 + ], + "distanceFromStart":1.5 + }, + { + "elevation":[ + 357.42992871175124, + 385.92155620623635 + ], + "pace":[ + 395.16168913839374, + 404.60294066527558 + ], + "heartRate":[ + 131.5456052446734, + 134.65984504627627 + ], + "distanceFromStart":1.875 + }, + { + "elevation":[ + 345.47736721935661, + 363.18776661379422 + ], + "pace":[ + 340.82303041339082, + 404.71689228682374 + ], + "heartRate":[ + 125.1949698433959, + 131.31354363122026 + ], + "distanceFromStart":2.25 + }, + { + "elevation":[ + 346.23343025200535, + 497.23376445462401 + ], + "pace":[ + 261.27629148816021, + 331.68516208719467 + ], + "heartRate":[ + 131.67810544238606, + 154.26779645311458 + ], + "distanceFromStart":2.625 + }, + { + "elevation":[ + 491.57378483134391, + 547.49535224251053 + ], + "pace":[ + 296.05298644112088, + 401.14092967732398 + ], + "heartRate":[ + 151.36398089694217, + 166.20454793289232 + ], + "distanceFromStart":3 + }, + { + "elevation":[ + 472.06803233416338, + 531.92570520228401 + ], + "pace":[ + 395.50830663514012, + 401.67837917543591 + ], + "heartRate":[ + 134.41798110234078, + 151.90886697564241 + ], + "distanceFromStart":3.375 + }, + { + "elevation":[ + 339.81419476005283, + 461.03832527824829 + ], + "pace":[ + 395.31160487975183, + 404.49550455974907 + ], + "heartRate":[ + 129.97753472415462, + 138.13531094848992 + ], + "distanceFromStart":3.75 + }, + { + "elevation":[ + 303.1495508565697, + 342.3532820173541 + ], + "pace":[ + 395.02844559698116, + 402.65878340653796 + ], + "heartRate":[ + 127.72304232462609, + 133.26322270764186 + ], + "distanceFromStart":4.125 + } + ] + }, + { + "name":"Lonesome Ridge Trail", + "id":1006, + "distance":4.5, + "difficulty":3, + "observations":[ + { + "elevation":[ + 291.65263635636268, + 309.26016677925196 + ], + "pace":[ + 396.08716481908732, + 403.68937873525232 + ], + "heartRate":[ + 117.16351898665887, + 121.95815455919609 + ], + "distanceFromStart":0 + }, + { + "elevation":[ + 299.24001936628116, + 317.44584350790012 + ], + "pace":[ + 380.19020240756623, + 395.3978319010256 + ], + "heartRate":[ + 117.6410892152911, + 124.82185220506081 + ], + "distanceFromStart":0.375 + }, + { + "elevation":[ + 303.62145464574394, + 336.05569457646544 + ], + "pace":[ + 380.55927782266116, + 397.60789726832775 + ], + "heartRate":[ + 121.52696452049059, + 127.31525441110122 + ], + "distanceFromStart":0.75 + }, + { + "elevation":[ + 319.90393365162629, + 346.26966025518789 + ], + "pace":[ + 357.94116421258531, + 398.0750288648062 + ], + "heartRate":[ + 123.75908585923588, + 132.77069404486801 + ], + "distanceFromStart":1.125 + }, + { + "elevation":[ + 354.17104439267905, + 403.57031216972939 + ], + "pace":[ + 335.07385149392701, + 397.82674381875808 + ], + "heartRate":[ + 130.8235194572915, + 140.55700591418218 + ], + "distanceFromStart":1.5 + }, + { + "elevation":[ + 357.42992871175124, + 385.92155620623635 + ], + "pace":[ + 395.16168913839374, + 404.60294066527558 + ], + "heartRate":[ + 131.5456052446734, + 134.65984504627627 + ], + "distanceFromStart":1.875 + }, + { + "elevation":[ + 345.47736721935661, + 363.18776661379422 + ], + "pace":[ + 340.82303041339082, + 404.71689228682374 + ], + "heartRate":[ + 125.1949698433959, + 131.31354363122026 + ], + "distanceFromStart":2.25 + }, + { + "elevation":[ + 346.23343025200535, + 497.23376445462401 + ], + "pace":[ + 261.27629148816021, + 331.68516208719467 + ], + "heartRate":[ + 131.67810544238606, + 154.26779645311458 + ], + "distanceFromStart":2.625 + }, + { + "elevation":[ + 491.57378483134391, + 547.49535224251053 + ], + "pace":[ + 296.05298644112088, + 401.14092967732398 + ], + "heartRate":[ + 151.36398089694217, + 166.20454793289232 + ], + "distanceFromStart":3 + }, + { + "elevation":[ + 472.06803233416338, + 531.92570520228401 + ], + "pace":[ + 395.50830663514012, + 401.67837917543591 + ], + "heartRate":[ + 134.41798110234078, + 151.90886697564241 + ], + "distanceFromStart":3.375 + }, + { + "elevation":[ + 339.81419476005283, + 461.03832527824829 + ], + "pace":[ + 395.31160487975183, + 404.49550455974907 + ], + "heartRate":[ + 129.97753472415462, + 138.13531094848992 + ], + "distanceFromStart":3.75 + }, + { + "elevation":[ + 303.1495508565697, + 342.3532820173541 + ], + "pace":[ + 395.02844559698116, + 402.65878340653796 + ], + "heartRate":[ + 127.72304232462609, + 133.26322270764186 + ], + "distanceFromStart":4.125 + } + ] + }, + { + "name":"Lonesome Ridge Trail", + "id":1007, + "distance":4.5, + "difficulty":3, + "observations":[ + { + "elevation":[ + 291.65263635636268, + 309.26016677925196 + ], + "pace":[ + 396.08716481908732, + 403.68937873525232 + ], + "heartRate":[ + 117.16351898665887, + 121.95815455919609 + ], + "distanceFromStart":0 + }, + { + "elevation":[ + 299.24001936628116, + 317.44584350790012 + ], + "pace":[ + 380.19020240756623, + 395.3978319010256 + ], + "heartRate":[ + 117.6410892152911, + 124.82185220506081 + ], + "distanceFromStart":0.375 + }, + { + "elevation":[ + 303.62145464574394, + 336.05569457646544 + ], + "pace":[ + 380.55927782266116, + 397.60789726832775 + ], + "heartRate":[ + 121.52696452049059, + 127.31525441110122 + ], + "distanceFromStart":0.75 + }, + { + "elevation":[ + 319.90393365162629, + 346.26966025518789 + ], + "pace":[ + 357.94116421258531, + 398.0750288648062 + ], + "heartRate":[ + 123.75908585923588, + 132.77069404486801 + ], + "distanceFromStart":1.125 + }, + { + "elevation":[ + 354.17104439267905, + 403.57031216972939 + ], + "pace":[ + 335.07385149392701, + 397.82674381875808 + ], + "heartRate":[ + 130.8235194572915, + 140.55700591418218 + ], + "distanceFromStart":1.5 + }, + { + "elevation":[ + 357.42992871175124, + 385.92155620623635 + ], + "pace":[ + 395.16168913839374, + 404.60294066527558 + ], + "heartRate":[ + 131.5456052446734, + 134.65984504627627 + ], + "distanceFromStart":1.875 + }, + { + "elevation":[ + 345.47736721935661, + 363.18776661379422 + ], + "pace":[ + 340.82303041339082, + 404.71689228682374 + ], + "heartRate":[ + 125.1949698433959, + 131.31354363122026 + ], + "distanceFromStart":2.25 + }, + { + "elevation":[ + 346.23343025200535, + 497.23376445462401 + ], + "pace":[ + 261.27629148816021, + 331.68516208719467 + ], + "heartRate":[ + 131.67810544238606, + 154.26779645311458 + ], + "distanceFromStart":2.625 + }, + { + "elevation":[ + 491.57378483134391, + 547.49535224251053 + ], + "pace":[ + 296.05298644112088, + 401.14092967732398 + ], + "heartRate":[ + 151.36398089694217, + 166.20454793289232 + ], + "distanceFromStart":3 + }, + { + "elevation":[ + 472.06803233416338, + 531.92570520228401 + ], + "pace":[ + 395.50830663514012, + 401.67837917543591 + ], + "heartRate":[ + 134.41798110234078, + 151.90886697564241 + ], + "distanceFromStart":3.375 + }, + { + "elevation":[ + 339.81419476005283, + 461.03832527824829 + ], + "pace":[ + 395.31160487975183, + 404.49550455974907 + ], + "heartRate":[ + 129.97753472415462, + 138.13531094848992 + ], + "distanceFromStart":3.75 + }, + { + "elevation":[ + 303.1495508565697, + 342.3532820173541 + ], + "pace":[ + 395.02844559698116, + 402.65878340653796 + ], + "heartRate":[ + 127.72304232462609, + 133.26322270764186 + ], + "distanceFromStart":4.125 + } + ] + }, + { + "name":"Lonesome Ridge Trail", + "id":1008, + "distance":4.5, + "difficulty":3, + "observations":[ + { + "elevation":[ + 291.65263635636268, + 309.26016677925196 + ], + "pace":[ + 396.08716481908732, + 403.68937873525232 + ], + "heartRate":[ + 117.16351898665887, + 121.95815455919609 + ], + "distanceFromStart":0 + }, + { + "elevation":[ + 299.24001936628116, + 317.44584350790012 + ], + "pace":[ + 380.19020240756623, + 395.3978319010256 + ], + "heartRate":[ + 117.6410892152911, + 124.82185220506081 + ], + "distanceFromStart":0.375 + }, + { + "elevation":[ + 303.62145464574394, + 336.05569457646544 + ], + "pace":[ + 380.55927782266116, + 397.60789726832775 + ], + "heartRate":[ + 121.52696452049059, + 127.31525441110122 + ], + "distanceFromStart":0.75 + }, + { + "elevation":[ + 319.90393365162629, + 346.26966025518789 + ], + "pace":[ + 357.94116421258531, + 398.0750288648062 + ], + "heartRate":[ + 123.75908585923588, + 132.77069404486801 + ], + "distanceFromStart":1.125 + }, + { + "elevation":[ + 354.17104439267905, + 403.57031216972939 + ], + "pace":[ + 335.07385149392701, + 397.82674381875808 + ], + "heartRate":[ + 130.8235194572915, + 140.55700591418218 + ], + "distanceFromStart":1.5 + }, + { + "elevation":[ + 357.42992871175124, + 385.92155620623635 + ], + "pace":[ + 395.16168913839374, + 404.60294066527558 + ], + "heartRate":[ + 131.5456052446734, + 134.65984504627627 + ], + "distanceFromStart":1.875 + }, + { + "elevation":[ + 345.47736721935661, + 363.18776661379422 + ], + "pace":[ + 340.82303041339082, + 404.71689228682374 + ], + "heartRate":[ + 125.1949698433959, + 131.31354363122026 + ], + "distanceFromStart":2.25 + }, + { + "elevation":[ + 346.23343025200535, + 497.23376445462401 + ], + "pace":[ + 261.27629148816021, + 331.68516208719467 + ], + "heartRate":[ + 131.67810544238606, + 154.26779645311458 + ], + "distanceFromStart":2.625 + }, + { + "elevation":[ + 491.57378483134391, + 547.49535224251053 + ], + "pace":[ + 296.05298644112088, + 401.14092967732398 + ], + "heartRate":[ + 151.36398089694217, + 166.20454793289232 + ], + "distanceFromStart":3 + }, + { + "elevation":[ + 472.06803233416338, + 531.92570520228401 + ], + "pace":[ + 395.50830663514012, + 401.67837917543591 + ], + "heartRate":[ + 134.41798110234078, + 151.90886697564241 + ], + "distanceFromStart":3.375 + }, + { + "elevation":[ + 339.81419476005283, + 461.03832527824829 + ], + "pace":[ + 395.31160487975183, + 404.49550455974907 + ], + "heartRate":[ + 129.97753472415462, + 138.13531094848992 + ], + "distanceFromStart":3.75 + }, + { + "elevation":[ + 303.1495508565697, + 342.3532820173541 + ], + "pace":[ + 395.02844559698116, + 402.65878340653796 + ], + "heartRate":[ + 127.72304232462609, + 133.26322270764186 + ], + "distanceFromStart":4.125 + } + ] + }, + { + "name":"Lonesome Ridge Trail", + "id":1009, + "distance":4.5, + "difficulty":3, + "observations":[ + { + "elevation":[ + 291.65263635636268, + 309.26016677925196 + ], + "pace":[ + 396.08716481908732, + 403.68937873525232 + ], + "heartRate":[ + 117.16351898665887, + 121.95815455919609 + ], + "distanceFromStart":0 + }, + { + "elevation":[ + 299.24001936628116, + 317.44584350790012 + ], + "pace":[ + 380.19020240756623, + 395.3978319010256 + ], + "heartRate":[ + 117.6410892152911, + 124.82185220506081 + ], + "distanceFromStart":0.375 + }, + { + "elevation":[ + 303.62145464574394, + 336.05569457646544 + ], + "pace":[ + 380.55927782266116, + 397.60789726832775 + ], + "heartRate":[ + 121.52696452049059, + 127.31525441110122 + ], + "distanceFromStart":0.75 + }, + { + "elevation":[ + 319.90393365162629, + 346.26966025518789 + ], + "pace":[ + 357.94116421258531, + 398.0750288648062 + ], + "heartRate":[ + 123.75908585923588, + 132.77069404486801 + ], + "distanceFromStart":1.125 + }, + { + "elevation":[ + 354.17104439267905, + 403.57031216972939 + ], + "pace":[ + 335.07385149392701, + 397.82674381875808 + ], + "heartRate":[ + 130.8235194572915, + 140.55700591418218 + ], + "distanceFromStart":1.5 + }, + { + "elevation":[ + 357.42992871175124, + 385.92155620623635 + ], + "pace":[ + 395.16168913839374, + 404.60294066527558 + ], + "heartRate":[ + 131.5456052446734, + 134.65984504627627 + ], + "distanceFromStart":1.875 + }, + { + "elevation":[ + 345.47736721935661, + 363.18776661379422 + ], + "pace":[ + 340.82303041339082, + 404.71689228682374 + ], + "heartRate":[ + 125.1949698433959, + 131.31354363122026 + ], + "distanceFromStart":2.25 + }, + { + "elevation":[ + 346.23343025200535, + 497.23376445462401 + ], + "pace":[ + 261.27629148816021, + 331.68516208719467 + ], + "heartRate":[ + 131.67810544238606, + 154.26779645311458 + ], + "distanceFromStart":2.625 + }, + { + "elevation":[ + 491.57378483134391, + 547.49535224251053 + ], + "pace":[ + 296.05298644112088, + 401.14092967732398 + ], + "heartRate":[ + 151.36398089694217, + 166.20454793289232 + ], + "distanceFromStart":3 + }, + { + "elevation":[ + 472.06803233416338, + 531.92570520228401 + ], + "pace":[ + 395.50830663514012, + 401.67837917543591 + ], + "heartRate":[ + 134.41798110234078, + 151.90886697564241 + ], + "distanceFromStart":3.375 + }, + { + "elevation":[ + 339.81419476005283, + 461.03832527824829 + ], + "pace":[ + 395.31160487975183, + 404.49550455974907 + ], + "heartRate":[ + 129.97753472415462, + 138.13531094848992 + ], + "distanceFromStart":3.75 + }, + { + "elevation":[ + 303.1495508565697, + 342.3532820173541 + ], + "pace":[ + 395.02844559698116, + 402.65878340653796 + ], + "heartRate":[ + 127.72304232462609, + 133.26322270764186 + ], + "distanceFromStart":4.125 + } + ] + }, + { + "name":"Lonesome Ridge Trail", + "id":1010, + "distance":4.5, + "difficulty":3, + "observations":[ + { + "elevation":[ + 291.65263635636268, + 309.26016677925196 + ], + "pace":[ + 396.08716481908732, + 403.68937873525232 + ], + "heartRate":[ + 117.16351898665887, + 121.95815455919609 + ], + "distanceFromStart":0 + }, + { + "elevation":[ + 299.24001936628116, + 317.44584350790012 + ], + "pace":[ + 380.19020240756623, + 395.3978319010256 + ], + "heartRate":[ + 117.6410892152911, + 124.82185220506081 + ], + "distanceFromStart":0.375 + }, + { + "elevation":[ + 303.62145464574394, + 336.05569457646544 + ], + "pace":[ + 380.55927782266116, + 397.60789726832775 + ], + "heartRate":[ + 121.52696452049059, + 127.31525441110122 + ], + "distanceFromStart":0.75 + }, + { + "elevation":[ + 319.90393365162629, + 346.26966025518789 + ], + "pace":[ + 357.94116421258531, + 398.0750288648062 + ], + "heartRate":[ + 123.75908585923588, + 132.77069404486801 + ], + "distanceFromStart":1.125 + }, + { + "elevation":[ + 354.17104439267905, + 403.57031216972939 + ], + "pace":[ + 335.07385149392701, + 397.82674381875808 + ], + "heartRate":[ + 130.8235194572915, + 140.55700591418218 + ], + "distanceFromStart":1.5 + }, + { + "elevation":[ + 357.42992871175124, + 385.92155620623635 + ], + "pace":[ + 395.16168913839374, + 404.60294066527558 + ], + "heartRate":[ + 131.5456052446734, + 134.65984504627627 + ], + "distanceFromStart":1.875 + }, + { + "elevation":[ + 345.47736721935661, + 363.18776661379422 + ], + "pace":[ + 340.82303041339082, + 404.71689228682374 + ], + "heartRate":[ + 125.1949698433959, + 131.31354363122026 + ], + "distanceFromStart":2.25 + }, + { + "elevation":[ + 346.23343025200535, + 497.23376445462401 + ], + "pace":[ + 261.27629148816021, + 331.68516208719467 + ], + "heartRate":[ + 131.67810544238606, + 154.26779645311458 + ], + "distanceFromStart":2.625 + }, + { + "elevation":[ + 491.57378483134391, + 547.49535224251053 + ], + "pace":[ + 296.05298644112088, + 401.14092967732398 + ], + "heartRate":[ + 151.36398089694217, + 166.20454793289232 + ], + "distanceFromStart":3 + }, + { + "elevation":[ + 472.06803233416338, + 531.92570520228401 + ], + "pace":[ + 395.50830663514012, + 401.67837917543591 + ], + "heartRate":[ + 134.41798110234078, + 151.90886697564241 + ], + "distanceFromStart":3.375 + }, + { + "elevation":[ + 339.81419476005283, + 461.03832527824829 + ], + "pace":[ + 395.31160487975183, + 404.49550455974907 + ], + "heartRate":[ + 129.97753472415462, + 138.13531094848992 + ], + "distanceFromStart":3.75 + }, + { + "elevation":[ + 303.1495508565697, + 342.3532820173541 + ], + "pace":[ + 395.02844559698116, + 402.65878340653796 + ], + "heartRate":[ + 127.72304232462609, + 133.26322270764186 + ], + "distanceFromStart":4.125 + } + ] + } +] diff --git a/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Resources/icybay.jpg b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Resources/icybay.jpg new file mode 100644 index 0000000..feb1764 Binary files /dev/null and b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Resources/icybay.jpg differ diff --git a/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Resources/lakemcdonald.jpg b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Resources/lakemcdonald.jpg new file mode 100644 index 0000000..bd9d6b9 Binary files /dev/null and b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Resources/lakemcdonald.jpg differ diff --git a/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Resources/landmarkData.json b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Resources/landmarkData.json new file mode 100644 index 0000000..a25b4e4 --- /dev/null +++ b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Resources/landmarkData.json @@ -0,0 +1,182 @@ +[ + { + "name": "Turtle Rock", + "category": "Rivers", + "city": "Twentynine Palms", + "state": "California", + "id": 1001, + "isFeatured": true, + "isFavorite": true, + "park": "Joshua Tree National Park", + "coordinates": { + "longitude": -116.166868, + "latitude": 34.011286 + }, + "imageName": "turtlerock" + }, + { + "name": "Silver Salmon Creek", + "category": "Lakes", + "city": "Port Alsworth", + "state": "Alaska", + "id": 1002, + "isFeatured": false, + "isFavorite": false, + "park": "Lake Clark National Park and Preserve", + "coordinates": { + "longitude": -152.665167, + "latitude": 59.980167 + }, + "imageName": "silversalmoncreek" + }, + { + "name": "Chilkoot Trail", + "category": "Mountains", + "city": "Skagway", + "state": "Alaska", + "id": 1003, + "isFeatured": false, + "isFavorite": true, + "park": "Klondike Gold Rush National Historical Park", + "coordinates": { + "longitude": -135.334571, + "latitude": 59.560551 + }, + "imageName": "chilkoottrail" + }, + { + "name": "St. Mary Lake", + "category": "Lakes", + "city": "Browning", + "state": "Montana", + "id": 1004, + "isFeatured": true, + "isFavorite": true, + "park": "Glacier National Park", + "coordinates": { + "longitude": -113.536248, + "latitude": 48.69423 + }, + "imageName": "stmarylake" + }, + { + "name": "Twin Lake", + "category": "Lakes", + "city": "Twin Lakes", + "state": "Alaska", + "id": 1005, + "isFeatured": false, + "isFavorite": false, + "park": "Lake Clark National Park and Preserve", + "coordinates": { + "longitude": -153.849883, + "latitude": 60.641684 + }, + "imageName": "twinlake" + }, + { + "name": "Lake McDonald", + "category": "Mountains", + "city": "West Glacier", + "state": "Montana", + "id": 1006, + "isFeatured": false, + "isFavorite": false, + "park": "Glacier National Park", + "coordinates": { + "longitude": -113.934831, + "latitude": 48.56002 + }, + "imageName": "lakemcdonald" + }, + { + "name": "Charley Rivers", + "category": "Rivers", + "city": "Eaking", + "state": "Alaska", + "id": 1007, + "isFeatured": true, + "isFavorite": false, + "park": "Charley Rivers National Preserve", + "coordinates": { + "longitude": -143.122586, + "latitude": 65.350021 + }, + "imageName": "charleyrivers", + }, + { + "name": "Icy Bay", + "category": "Mountains", + "city": "Icy Bay", + "state": "Alaska", + "id": 1008, + "isFeatured": false, + "isFavorite": false, + "park": "Wrangell-St. Elias National Park and Preserve", + "coordinates": { + "longitude": -141.518167, + "latitude": 60.089917 + }, + "imageName": "icybay" + }, + { + "name": "Rainbow Lake", + "category": "Lakes", + "city": "Willow", + "state": "Alaska", + "id": 1009, + "isFeatured": false, + "isFavorite": false, + "park": "State Recreation Area", + "coordinates": { + "longitude": -150.086103, + "latitude": 61.694334 + }, + "imageName": "rainbowlake" + }, + { + "name": "Hidden Lake", + "category": "Lakes", + "city": "Newhalem", + "state": "Washington", + "id": 1010, + "isFeatured": false, + "isFavorite": false, + "park": "North Cascades National Park", + "coordinates": { + "longitude": -121.17799, + "latitude": 48.495442 + }, + "imageName": "hiddenlake" + }, + { + "name": "Chincoteague", + "category": "Rivers", + "city": "Chincoteague", + "state": "Virginia", + "id": 1011, + "isFeatured": false, + "isFavorite": false, + "park": "Chincoteague National Wildlife Refuge", + "coordinates": { + "longitude": -75.383212, + "latitude": 37.91531 + }, + "imageName": "chincoteague" + }, + { + "name": "Lake Umbagog", + "category": "Lakes", + "city": "Errol", + "state": "New Hampshire", + "id": 1012, + "isFeatured": false, + "isFavorite": false, + "park": "Umbagog National Wildlife Refuge", + "coordinates": { + "longitude": -71.056816, + "latitude": 44.747408 + }, + "imageName": "umbagog" + } +] diff --git a/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Resources/rainbowlake.jpg b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Resources/rainbowlake.jpg new file mode 100644 index 0000000..6da43dd Binary files /dev/null and b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Resources/rainbowlake.jpg differ diff --git a/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Resources/silversalmoncreek.jpg b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Resources/silversalmoncreek.jpg new file mode 100644 index 0000000..f657532 Binary files /dev/null and b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Resources/silversalmoncreek.jpg differ diff --git a/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Resources/stmarylake.jpg b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Resources/stmarylake.jpg new file mode 100644 index 0000000..1c71de4 Binary files /dev/null and b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Resources/stmarylake.jpg differ diff --git a/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Resources/stmarylake_feature.jpg b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Resources/stmarylake_feature.jpg new file mode 100644 index 0000000..5eb97b1 Binary files /dev/null and b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Resources/stmarylake_feature.jpg differ diff --git a/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Resources/turtlerock.jpg b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Resources/turtlerock.jpg new file mode 100644 index 0000000..f7a6e6d Binary files /dev/null and b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Resources/turtlerock.jpg differ diff --git a/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Resources/turtlerock_feature.jpg b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Resources/turtlerock_feature.jpg new file mode 100644 index 0000000..448c70f Binary files /dev/null and b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Resources/turtlerock_feature.jpg differ diff --git a/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Resources/twinlake.jpg b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Resources/twinlake.jpg new file mode 100644 index 0000000..3e7a57c Binary files /dev/null and b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Resources/twinlake.jpg differ diff --git a/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Resources/umbagog.jpg b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Resources/umbagog.jpg new file mode 100644 index 0000000..56291c6 Binary files /dev/null and b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Resources/umbagog.jpg differ diff --git a/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/SceneDelegate.swift b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/SceneDelegate.swift new file mode 100644 index 0000000..0f5f17e --- /dev/null +++ b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/SceneDelegate.swift @@ -0,0 +1,56 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +The scene delegate. +*/ + +import UIKit +import SwiftUI + +class SceneDelegate: UIResponder, UIWindowSceneDelegate { + + var window: UIWindow? + + func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { + // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`. + // If using a storyboard, the `window` property will automatically be initialized and attached to the scene. + // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead). + + // Use a UIHostingController as window root view controller + let window = UIWindow(frame: UIScreen.main.bounds) + window.rootViewController = UIHostingController(rootView: CategoryHome().environmentObject(UserData())) + self.window = window + window.makeKeyAndVisible() + } + + func sceneDidDisconnect(_ scene: UIScene) { + // Called as the scene is being released by the system. + // This occurs shortly after the scene enters the background, or when its session is discarded. + // Release any resources associated with this scene that can be re-created the next time the scene connects. + // The scene may re-connect later, as its session was not neccessarily discarded (see `application:didDiscardSceneSessions` instead). + } + + func sceneDidBecomeActive(_ scene: UIScene) { + // Called when the scene has moved from an inactive state to an active state. + // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive. + } + + func sceneWillResignActive(_ scene: UIScene) { + // Called when the scene will move from an active state to an inactive state. + // This may occur due to temporary interruptions (ex. an incoming phone call). + } + + func sceneWillEnterForeground(_ scene: UIScene) { + // Called as the scene transitions from the background to the foreground. + // Use this method to undo the changes made on entering the background. + } + + func sceneDidEnterBackground(_ scene: UIScene) { + // Called as the scene transitions from the foreground to the background. + // Use this method to save data, release shared resources, and store enough scene-specific state information + // to restore the scene back to its current state. + } + +} + diff --git a/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Supporting Views/Badge.swift b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Supporting Views/Badge.swift new file mode 100644 index 0000000..59f03b2 --- /dev/null +++ b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Supporting Views/Badge.swift @@ -0,0 +1,41 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A view that displays a badge. +*/ + +import SwiftUI + +struct Badge: View { + static let rotationCount = 8 + + var badgeSymbols: some View { + ForEach(0.. + var overallRange: Range + + var heightRatio: Length { + max(Length(magnitude(of: range) / magnitude(of: overallRange)), 0.15) + } + + var offsetRatio: Length { + Length((range.lowerBound - overallRange.lowerBound) / magnitude(of: overallRange)) + } + + var animation: Animation { + Animation.spring(initialVelocity: 5) + .speed(2) + .delay(0.03 * Double(index)) + } + + var body: some View { + Capsule() + .fill(Color.white) + .frame(height: height * heightRatio, alignment: .bottom) + .offset(x: 0, y: height * -offsetRatio) + .animation(animation) + } +} + +#if DEBUG +struct GraphCapsule_Previews: PreviewProvider { + static var previews: some View { + GraphCapsule(index: 0, height: 150, range: 10..<50, overallRange: 0..<100) + } +} +#endif diff --git a/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Supporting Views/HikeGraph.swift b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Supporting Views/HikeGraph.swift new file mode 100644 index 0000000..7df5194 --- /dev/null +++ b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Supporting Views/HikeGraph.swift @@ -0,0 +1,74 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +The elevation, heart rate, and pace of a hike plotted on a graph. +*/ + +import SwiftUI + +func rangeOfRanges(_ ranges: C) -> Range + where C.Element == Range { + guard !ranges.isEmpty else { return 0..<0 } + let low = ranges.lazy.map { $0.lowerBound }.min()! + let high = ranges.lazy.map { $0.upperBound }.max()! + return low..) -> Double { + return range.upperBound - range.lowerBound +} + +struct HikeGraph: View { + var hike: Hike + var path: KeyPath> + + var color: Color { + switch path { + case \.elevation: + return .gray + case \.heartRate: + return Color(hue: 0, saturation: 0.5, brightness: 0.7) + case \.pace: + return Color(hue: 0.7, saturation: 0.4, brightness: 0.7) + default: + return .black + } + } + + var body: some View { + let data = hike.observations + let overallRange = rangeOfRanges(data.lazy.map { $0[keyPath: self.path] }) + let maxMagnitude = data.map { magnitude(of: $0[keyPath: path]) }.max()! + let heightRatio = 1 - Length(maxMagnitude / magnitude(of: overallRange)) + + return GeometryReader { proxy in + HStack(alignment: .bottom, spacing: proxy.size.width / 120) { + ForEach(data.indices) { index in + GraphCapsule( + index: index, + height: proxy.size.height, + range: data[index][keyPath: self.path], + overallRange: overallRange) + .colorMultiply(self.color) + } + .offset(x: 0, y: proxy.size.height * heightRatio) + } + } + } +} + +#if DEBUG +struct HikeGraph_Previews: PreviewProvider { + static var previews: some View { + Group { + HikeGraph(hike: hikeData[0], path: \.elevation) + .frame(height: 200) + HikeGraph(hike: hikeData[0], path: \.heartRate) + .frame(height: 200) + HikeGraph(hike: hikeData[0], path: \.pace) + .frame(height: 200) + } + } +} +#endif diff --git a/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Supporting Views/LandmarkRow.swift b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Supporting Views/LandmarkRow.swift new file mode 100644 index 0000000..2f8110c --- /dev/null +++ b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Supporting Views/LandmarkRow.swift @@ -0,0 +1,38 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A single row to be displayed in a list of landmarks. +*/ + +import SwiftUI + +struct LandmarkRow: View { + var landmark: Landmark + + var body: some View { + HStack { + landmark.image(forSize: 50) + Text(verbatim: landmark.name) + Spacer() + + if landmark.isFavorite { + Image(systemName: "star.fill") + .imageScale(.medium) + .foregroundColor(.yellow) + } + } + } +} + +#if DEBUG +struct LandmarkRow_Previews: PreviewProvider { + static var previews: some View { + Group { + LandmarkRow(landmark: landmarkData[0]) + LandmarkRow(landmark: landmarkData[1]) + } + .previewLayout(.fixed(width: 300, height: 70)) + } +} +#endif diff --git a/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Supporting Views/MapView.swift b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Supporting Views/MapView.swift new file mode 100644 index 0000000..5a8c64b --- /dev/null +++ b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Supporting Views/MapView.swift @@ -0,0 +1,31 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A view that hosts an `MKMapView`. +*/ + +import SwiftUI +import MapKit + +struct MapView: UIViewRepresentable { + var coordinate: CLLocationCoordinate2D + + func makeUIView(context: Context) -> MKMapView { + MKMapView(frame: .zero) + } + + func updateUIView(_ view: MKMapView, context: Context) { + let span = MKCoordinateSpan(latitudeDelta: 0.02, longitudeDelta: 0.02) + let region = MKCoordinateRegion(center: coordinate, span: span) + view.setRegion(region, animated: true) + } +} + +#if DEBUG +struct MapView_Previews: PreviewProvider { + static var previews: some View { + MapView(coordinate: landmarkData[0].locationCoordinate) + } +} +#endif diff --git a/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Supporting Views/RotatedBadgeSymbol.swift b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Supporting Views/RotatedBadgeSymbol.swift new file mode 100644 index 0000000..a7e4b53 --- /dev/null +++ b/Other Projects/Interfacing With UIKit/StartingPoint/Landmarks/Landmarks/Supporting Views/RotatedBadgeSymbol.swift @@ -0,0 +1,26 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A view that displays a rotated version of a badge symbol. +*/ + +import SwiftUI + +struct RotatedBadgeSymbol: View { + let angle: Angle + + var body: some View { + BadgeSymbol() + .padding(-60) + .rotationEffect(angle, anchor: .bottom) + } +} + +#if DEBUG +struct RotatedBadgeSymbol_Previews: PreviewProvider { + static var previews: some View { + RotatedBadgeSymbol(angle: .init(degrees: 5)) + } +} +#endif diff --git a/Other Projects/Interfacing With UIKit/StartingPoint/README.md b/Other Projects/Interfacing With UIKit/StartingPoint/README.md new file mode 100644 index 0000000..4a86ad6 --- /dev/null +++ b/Other Projects/Interfacing With UIKit/StartingPoint/README.md @@ -0,0 +1,3 @@ +# Interfacing with UIKit + +Use this project to code along with the [Interfacing with UIKit](https://developer.apple.com/tutorials/swiftui/interfacing-with-uikit) tutorial. \ No newline at end of file diff --git a/Other Projects/Jike/SwiftUI_Jike.xcodeproj/project.pbxproj b/Other Projects/Jike/SwiftUI_Jike.xcodeproj/project.pbxproj new file mode 100644 index 0000000..0f13bf9 --- /dev/null +++ b/Other Projects/Jike/SwiftUI_Jike.xcodeproj/project.pbxproj @@ -0,0 +1,507 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 50; + objects = { + +/* Begin PBXBuildFile section */ + 08284DAC22A6FB0B008C5D73 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 08284DAB22A6FB0B008C5D73 /* AppDelegate.swift */; }; + 08284DAE22A6FB0B008C5D73 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 08284DAD22A6FB0B008C5D73 /* SceneDelegate.swift */; }; + 08284DB022A6FB0B008C5D73 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 08284DAF22A6FB0B008C5D73 /* ContentView.swift */; }; + 08284DB222A6FB10008C5D73 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 08284DB122A6FB10008C5D73 /* Assets.xcassets */; }; + 08284DB522A6FB10008C5D73 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 08284DB422A6FB10008C5D73 /* Preview Assets.xcassets */; }; + 08284DB822A6FB10008C5D73 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 08284DB622A6FB10008C5D73 /* LaunchScreen.storyboard */; }; + 08284DC222A75613008C5D73 /* SettingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 08284DC122A75613008C5D73 /* SettingView.swift */; }; + 08284DC422A75BEE008C5D73 /* HomeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 08284DC322A75BEE008C5D73 /* HomeView.swift */; }; + 08284DC622A75C4A008C5D73 /* ActivityView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 08284DC522A75C4A008C5D73 /* ActivityView.swift */; }; + 08284DC822A75C5F008C5D73 /* ChatView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 08284DC722A75C5F008C5D73 /* ChatView.swift */; }; + 086A477922A76F2900DDF3ED /* TabIconInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 086A477822A76F2900DDF3ED /* TabIconInfo.swift */; }; + 086A477B22A7705500DDF3ED /* Datas.swift in Sources */ = {isa = PBXBuildFile; fileRef = 086A477A22A7705500DDF3ED /* Datas.swift */; }; + 088DA23922A78B82006103D5 /* CircleImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 088DA23822A78B81006103D5 /* CircleImage.swift */; }; + 088DA23B22A78C3B006103D5 /* UITool.swift in Sources */ = {isa = PBXBuildFile; fileRef = 088DA23A22A78C3B006103D5 /* UITool.swift */; }; + 088DA23D22A7AF11006103D5 /* SettingCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 088DA23C22A7AF11006103D5 /* SettingCell.swift */; }; + 088DA24022A7D182006103D5 /* ChatCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 088DA23F22A7D181006103D5 /* ChatCell.swift */; }; + 088DA24222A7DDBB006103D5 /* ActivityCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 088DA24122A7DDBB006103D5 /* ActivityCell.swift */; }; + 088DA24422A7FBEF006103D5 /* ZoneCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 088DA24322A7FBEF006103D5 /* ZoneCell.swift */; }; + 088DA24622A81A15006103D5 /* CategoryRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 088DA24522A81A15006103D5 /* CategoryRow.swift */; }; + 08C52A8A22A81AB900CDFA3D /* ZoneModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 08C52A8922A81AB900CDFA3D /* ZoneModel.swift */; }; + 08C52A8D22A81BE500CDFA3D /* zoneData.json in Resources */ = {isa = PBXBuildFile; fileRef = 08C52A8C22A81BE500CDFA3D /* zoneData.json */; }; + 08C52A8F22A81F1E00CDFA3D /* test.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 08C52A8E22A81F1E00CDFA3D /* test.jpg */; }; + 08C52A9122A8242700CDFA3D /* test1.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 08C52A9022A8242700CDFA3D /* test1.jpg */; }; + 08C52A9322A8509C00CDFA3D /* SegmentViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 08C52A9222A8509C00CDFA3D /* SegmentViewController.swift */; }; + 08FAC5FA22A8CC0300BC476C /* GYSegmentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 08FAC5F922A8CC0300BC476C /* GYSegmentView.swift */; }; + 08FAC64922A8D92A00BC476C /* HomeCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 08FAC64822A8D92A00BC476C /* HomeCell.swift */; }; + 08FAC64B22A8DC4900BC476C /* kcc.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 08FAC64A22A8DC4900BC476C /* kcc.jpg */; }; + 08FAC64D22A8DCB300BC476C /* 30_Fotor.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 08FAC64C22A8DCB300BC476C /* 30_Fotor.jpg */; }; + 08FAC65B22A8F37500BC476C /* faxian.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 08FAC65A22A8F37400BC476C /* faxian.jpg */; }; + 08FAC66222A8F46A00BC476C /* keji.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 08FAC65C22A8F46A00BC476C /* keji.jpg */; }; + 08FAC66322A8F46A00BC476C /* jianzhu.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 08FAC65D22A8F46A00BC476C /* jianzhu.jpg */; }; + 08FAC66422A8F46A00BC476C /* aihao.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 08FAC65E22A8F46A00BC476C /* aihao.jpg */; }; + 08FAC66522A8F46A00BC476C /* miao.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 08FAC65F22A8F46A00BC476C /* miao.jpg */; }; + 08FAC66622A8F46A00BC476C /* shadiao.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 08FAC66022A8F46A00BC476C /* shadiao.jpg */; }; + 08FAC66722A8F46A00BC476C /* sheying.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 08FAC66122A8F46A00BC476C /* sheying.jpg */; }; + 08FAC67022A90DB900BC476C /* GYTabBarViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 08FAC66E22A90DB900BC476C /* GYTabBarViewController.swift */; }; + 08FAC67122A90DB900BC476C /* GYTabView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 08FAC66F22A90DB900BC476C /* GYTabView.swift */; }; + 08FAC67322A9125900BC476C /* TabBarItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 08FAC67222A9125900BC476C /* TabBarItem.swift */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 08284DA822A6FB0B008C5D73 /* SwiftUI_Jike.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SwiftUI_Jike.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 08284DAB22A6FB0B008C5D73 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 08284DAD22A6FB0B008C5D73 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; + 08284DAF22A6FB0B008C5D73 /* ContentView.swift */ = {isa = PBXFileReference; indentWidth = 4; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; tabWidth = 4; usesTabs = 1; }; + 08284DB122A6FB10008C5D73 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 08284DB422A6FB10008C5D73 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; + 08284DB722A6FB10008C5D73 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 08284DB922A6FB10008C5D73 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 08284DC122A75613008C5D73 /* SettingView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingView.swift; sourceTree = ""; usesTabs = 0; }; + 08284DC322A75BEE008C5D73 /* HomeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeView.swift; sourceTree = ""; }; + 08284DC522A75C4A008C5D73 /* ActivityView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActivityView.swift; sourceTree = ""; }; + 08284DC722A75C5F008C5D73 /* ChatView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatView.swift; sourceTree = ""; }; + 086A477822A76F2900DDF3ED /* TabIconInfo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabIconInfo.swift; sourceTree = ""; }; + 086A477A22A7705500DDF3ED /* Datas.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Datas.swift; sourceTree = ""; }; + 088DA23822A78B81006103D5 /* CircleImage.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CircleImage.swift; sourceTree = ""; }; + 088DA23A22A78C3B006103D5 /* UITool.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UITool.swift; sourceTree = ""; }; + 088DA23C22A7AF11006103D5 /* SettingCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingCell.swift; sourceTree = ""; }; + 088DA23F22A7D181006103D5 /* ChatCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatCell.swift; sourceTree = ""; }; + 088DA24122A7DDBB006103D5 /* ActivityCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActivityCell.swift; sourceTree = ""; }; + 088DA24322A7FBEF006103D5 /* ZoneCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ZoneCell.swift; sourceTree = ""; }; + 088DA24522A81A15006103D5 /* CategoryRow.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CategoryRow.swift; sourceTree = ""; }; + 08C52A8922A81AB900CDFA3D /* ZoneModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ZoneModel.swift; sourceTree = ""; }; + 08C52A8C22A81BE500CDFA3D /* zoneData.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = zoneData.json; sourceTree = ""; }; + 08C52A8E22A81F1E00CDFA3D /* test.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = test.jpg; sourceTree = ""; }; + 08C52A9022A8242700CDFA3D /* test1.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = test1.jpg; sourceTree = ""; }; + 08C52A9222A8509C00CDFA3D /* SegmentViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SegmentViewController.swift; sourceTree = ""; }; + 08FAC5F922A8CC0300BC476C /* GYSegmentView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GYSegmentView.swift; sourceTree = ""; }; + 08FAC64822A8D92A00BC476C /* HomeCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeCell.swift; sourceTree = ""; }; + 08FAC64A22A8DC4900BC476C /* kcc.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = kcc.jpg; sourceTree = ""; }; + 08FAC64C22A8DCB300BC476C /* 30_Fotor.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = 30_Fotor.jpg; sourceTree = ""; }; + 08FAC65A22A8F37400BC476C /* faxian.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = faxian.jpg; sourceTree = ""; }; + 08FAC65C22A8F46A00BC476C /* keji.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = keji.jpg; sourceTree = ""; }; + 08FAC65D22A8F46A00BC476C /* jianzhu.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = jianzhu.jpg; sourceTree = ""; }; + 08FAC65E22A8F46A00BC476C /* aihao.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = aihao.jpg; sourceTree = ""; }; + 08FAC65F22A8F46A00BC476C /* miao.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = miao.jpg; sourceTree = ""; }; + 08FAC66022A8F46A00BC476C /* shadiao.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = shadiao.jpg; sourceTree = ""; }; + 08FAC66122A8F46A00BC476C /* sheying.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = sheying.jpg; sourceTree = ""; }; + 08FAC66E22A90DB900BC476C /* GYTabBarViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GYTabBarViewController.swift; sourceTree = ""; }; + 08FAC66F22A90DB900BC476C /* GYTabView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GYTabView.swift; sourceTree = ""; }; + 08FAC67222A9125900BC476C /* TabBarItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabBarItem.swift; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 08284DA522A6FB0B008C5D73 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 08284D9F22A6FB0B008C5D73 = { + isa = PBXGroup; + children = ( + 08284DAA22A6FB0B008C5D73 /* SwiftUI_Jike */, + 08284DA922A6FB0B008C5D73 /* Products */, + ); + sourceTree = ""; + }; + 08284DA922A6FB0B008C5D73 /* Products */ = { + isa = PBXGroup; + children = ( + 08284DA822A6FB0B008C5D73 /* SwiftUI_Jike.app */, + ); + name = Products; + sourceTree = ""; + }; + 08284DAA22A6FB0B008C5D73 /* SwiftUI_Jike */ = { + isa = PBXGroup; + children = ( + 08FAC5FB22A8CEC500BC476C /* Tools */, + 088DA24722A81A6C006103D5 /* Models */, + 088DA23E22A7D16C006103D5 /* Cell */, + 08284DAB22A6FB0B008C5D73 /* AppDelegate.swift */, + 08284DAD22A6FB0B008C5D73 /* SceneDelegate.swift */, + 08284DAF22A6FB0B008C5D73 /* ContentView.swift */, + 08284DC322A75BEE008C5D73 /* HomeView.swift */, + 08284DC522A75C4A008C5D73 /* ActivityView.swift */, + 08284DC722A75C5F008C5D73 /* ChatView.swift */, + 08284DC122A75613008C5D73 /* SettingView.swift */, + 08C52A9222A8509C00CDFA3D /* SegmentViewController.swift */, + 08FAC66F22A90DB900BC476C /* GYTabView.swift */, + 08FAC66E22A90DB900BC476C /* GYTabBarViewController.swift */, + 08C52A8B22A81BAC00CDFA3D /* Res */, + 08284DB122A6FB10008C5D73 /* Assets.xcassets */, + 08284DB622A6FB10008C5D73 /* LaunchScreen.storyboard */, + 08284DB922A6FB10008C5D73 /* Info.plist */, + 08284DB322A6FB10008C5D73 /* Preview Content */, + ); + path = SwiftUI_Jike; + sourceTree = ""; + }; + 08284DB322A6FB10008C5D73 /* Preview Content */ = { + isa = PBXGroup; + children = ( + 08284DB422A6FB10008C5D73 /* Preview Assets.xcassets */, + ); + path = "Preview Content"; + sourceTree = ""; + }; + 088DA23E22A7D16C006103D5 /* Cell */ = { + isa = PBXGroup; + children = ( + 088DA23822A78B81006103D5 /* CircleImage.swift */, + 088DA23C22A7AF11006103D5 /* SettingCell.swift */, + 08FAC5F922A8CC0300BC476C /* GYSegmentView.swift */, + 088DA24522A81A15006103D5 /* CategoryRow.swift */, + 088DA23F22A7D181006103D5 /* ChatCell.swift */, + 088DA24122A7DDBB006103D5 /* ActivityCell.swift */, + 088DA24322A7FBEF006103D5 /* ZoneCell.swift */, + 08FAC64822A8D92A00BC476C /* HomeCell.swift */, + ); + path = Cell; + sourceTree = ""; + }; + 088DA24722A81A6C006103D5 /* Models */ = { + isa = PBXGroup; + children = ( + 086A477822A76F2900DDF3ED /* TabIconInfo.swift */, + 08C52A8922A81AB900CDFA3D /* ZoneModel.swift */, + 08FAC67222A9125900BC476C /* TabBarItem.swift */, + 086A477A22A7705500DDF3ED /* Datas.swift */, + ); + path = Models; + sourceTree = ""; + }; + 08C52A8B22A81BAC00CDFA3D /* Res */ = { + isa = PBXGroup; + children = ( + 08FAC65E22A8F46A00BC476C /* aihao.jpg */, + 08FAC65D22A8F46A00BC476C /* jianzhu.jpg */, + 08FAC65C22A8F46A00BC476C /* keji.jpg */, + 08FAC65F22A8F46A00BC476C /* miao.jpg */, + 08FAC66022A8F46A00BC476C /* shadiao.jpg */, + 08FAC66122A8F46A00BC476C /* sheying.jpg */, + 08FAC65A22A8F37400BC476C /* faxian.jpg */, + 08FAC64C22A8DCB300BC476C /* 30_Fotor.jpg */, + 08FAC64A22A8DC4900BC476C /* kcc.jpg */, + 08C52A9022A8242700CDFA3D /* test1.jpg */, + 08C52A8E22A81F1E00CDFA3D /* test.jpg */, + 08C52A8C22A81BE500CDFA3D /* zoneData.json */, + ); + path = Res; + sourceTree = ""; + }; + 08FAC5FB22A8CEC500BC476C /* Tools */ = { + isa = PBXGroup; + children = ( + 088DA23A22A78C3B006103D5 /* UITool.swift */, + ); + path = Tools; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 08284DA722A6FB0B008C5D73 /* SwiftUI_Jike */ = { + isa = PBXNativeTarget; + buildConfigurationList = 08284DBC22A6FB10008C5D73 /* Build configuration list for PBXNativeTarget "SwiftUI_Jike" */; + buildPhases = ( + 08284DA422A6FB0B008C5D73 /* Sources */, + 08284DA522A6FB0B008C5D73 /* Frameworks */, + 08284DA622A6FB0B008C5D73 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = SwiftUI_Jike; + productName = SwiftUI_Jike; + productReference = 08284DA822A6FB0B008C5D73 /* SwiftUI_Jike.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 08284DA022A6FB0B008C5D73 /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 1100; + LastUpgradeCheck = 1100; + ORGANIZATIONNAME = alexyang; + TargetAttributes = { + 08284DA722A6FB0B008C5D73 = { + CreatedOnToolsVersion = 11.0; + }; + }; + }; + buildConfigurationList = 08284DA322A6FB0B008C5D73 /* Build configuration list for PBXProject "SwiftUI_Jike" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 08284D9F22A6FB0B008C5D73; + productRefGroup = 08284DA922A6FB0B008C5D73 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 08284DA722A6FB0B008C5D73 /* SwiftUI_Jike */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 08284DA622A6FB0B008C5D73 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 08284DB822A6FB10008C5D73 /* LaunchScreen.storyboard in Resources */, + 08FAC66622A8F46A00BC476C /* shadiao.jpg in Resources */, + 08FAC64B22A8DC4900BC476C /* kcc.jpg in Resources */, + 08FAC66422A8F46A00BC476C /* aihao.jpg in Resources */, + 08C52A8F22A81F1E00CDFA3D /* test.jpg in Resources */, + 08284DB522A6FB10008C5D73 /* Preview Assets.xcassets in Resources */, + 08FAC65B22A8F37500BC476C /* faxian.jpg in Resources */, + 08284DB222A6FB10008C5D73 /* Assets.xcassets in Resources */, + 08FAC66322A8F46A00BC476C /* jianzhu.jpg in Resources */, + 08FAC66522A8F46A00BC476C /* miao.jpg in Resources */, + 08FAC66222A8F46A00BC476C /* keji.jpg in Resources */, + 08C52A8D22A81BE500CDFA3D /* zoneData.json in Resources */, + 08C52A9122A8242700CDFA3D /* test1.jpg in Resources */, + 08FAC64D22A8DCB300BC476C /* 30_Fotor.jpg in Resources */, + 08FAC66722A8F46A00BC476C /* sheying.jpg in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 08284DA422A6FB0B008C5D73 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 08284DAC22A6FB0B008C5D73 /* AppDelegate.swift in Sources */, + 08FAC64922A8D92A00BC476C /* HomeCell.swift in Sources */, + 08FAC67022A90DB900BC476C /* GYTabBarViewController.swift in Sources */, + 08284DC222A75613008C5D73 /* SettingView.swift in Sources */, + 08C52A9322A8509C00CDFA3D /* SegmentViewController.swift in Sources */, + 08284DAE22A6FB0B008C5D73 /* SceneDelegate.swift in Sources */, + 08284DC422A75BEE008C5D73 /* HomeView.swift in Sources */, + 08284DC822A75C5F008C5D73 /* ChatView.swift in Sources */, + 08FAC67122A90DB900BC476C /* GYTabView.swift in Sources */, + 08FAC67322A9125900BC476C /* TabBarItem.swift in Sources */, + 08C52A8A22A81AB900CDFA3D /* ZoneModel.swift in Sources */, + 088DA24422A7FBEF006103D5 /* ZoneCell.swift in Sources */, + 08284DC622A75C4A008C5D73 /* ActivityView.swift in Sources */, + 088DA24622A81A15006103D5 /* CategoryRow.swift in Sources */, + 088DA24222A7DDBB006103D5 /* ActivityCell.swift in Sources */, + 088DA23D22A7AF11006103D5 /* SettingCell.swift in Sources */, + 086A477B22A7705500DDF3ED /* Datas.swift in Sources */, + 088DA23922A78B82006103D5 /* CircleImage.swift in Sources */, + 086A477922A76F2900DDF3ED /* TabIconInfo.swift in Sources */, + 08FAC5FA22A8CC0300BC476C /* GYSegmentView.swift in Sources */, + 088DA24022A7D182006103D5 /* ChatCell.swift in Sources */, + 08284DB022A6FB0B008C5D73 /* ContentView.swift in Sources */, + 088DA23B22A78C3B006103D5 /* UITool.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 08284DB622A6FB10008C5D73 /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 08284DB722A6FB10008C5D73 /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 08284DBA22A6FB10008C5D73 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + 08284DBB22A6FB10008C5D73 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 08284DBD22A6FB10008C5D73 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_ASSET_PATHS = "SwiftUI_Jike/Preview\\ Content"; + DEVELOPMENT_TEAM = PD973WK396; + ENABLE_PREVIEWS = YES; + INFOPLIST_FILE = SwiftUI_Jike/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = "com.shigy.SwiftUI-Jike"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 08284DBE22A6FB10008C5D73 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_ASSET_PATHS = "SwiftUI_Jike/Preview\\ Content"; + DEVELOPMENT_TEAM = PD973WK396; + ENABLE_PREVIEWS = YES; + INFOPLIST_FILE = SwiftUI_Jike/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = "com.shigy.SwiftUI-Jike"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 08284DA322A6FB0B008C5D73 /* Build configuration list for PBXProject "SwiftUI_Jike" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 08284DBA22A6FB10008C5D73 /* Debug */, + 08284DBB22A6FB10008C5D73 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 08284DBC22A6FB10008C5D73 /* Build configuration list for PBXNativeTarget "SwiftUI_Jike" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 08284DBD22A6FB10008C5D73 /* Debug */, + 08284DBE22A6FB10008C5D73 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 08284DA022A6FB0B008C5D73 /* Project object */; +} diff --git a/Other Projects/Jike/SwiftUI_Jike.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/Other Projects/Jike/SwiftUI_Jike.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..5923d6a --- /dev/null +++ b/Other Projects/Jike/SwiftUI_Jike.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/Other Projects/Jike/SwiftUI_Jike.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/Other Projects/Jike/SwiftUI_Jike.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/Other Projects/Jike/SwiftUI_Jike.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/Other Projects/Jike/SwiftUI_Jike/ActivityView.swift b/Other Projects/Jike/SwiftUI_Jike/ActivityView.swift new file mode 100644 index 0000000..5392d2d --- /dev/null +++ b/Other Projects/Jike/SwiftUI_Jike/ActivityView.swift @@ -0,0 +1,65 @@ +// +// ActivityView.swift +// SwiftUI_Jike +// +// Created by alexyang on 2019/6/5. +// Copyright © 2019 alexyang. All rights reserved. +// + +import SwiftUI + +struct ActivityView : View { + var body: some View { + VStack{ + VStack{ + HStack{ + Image("addPer") + .padding(.horizontal, 10) + Spacer() + Text("动态").bold() + .padding(.trailing, 44) + Spacer() + + } + } + HStack{ + Color(red: 240.0/255.0, green: 243.0/255.0, blue: 245.0/255) + } + .padding(.top, 0) + .frame(height: 10.0) + HStack(alignment: .center){ + CircleImage(imgName: "subIcon") + .padding(.leading, 10) + Text("发布动态...") + .foregroundColor(Color.gray) + Spacer() + } + HStack{ + Color(red: 240.0/255.0, green: 243.0/255.0, blue: 245.0/255) + } + .padding(.top, 0) + .frame(height: 10.0) + + List{ + ActivityCell(nickName: "皮卡丘", timeStamp: "2小时前",content: "发明一种新吃法#一人食灌蛋手抓饼夹小油条泡菜香肠,挤上番茄酱甜面酱巨好吃呀😘!!灌蛋是灵魂,不能偷懒!!", imgName: "sucai" + ) + ActivityCell(nickName: "皮卡丘", timeStamp: "2小时前",content: "发明一种新吃法#一人食灌蛋手抓饼夹小油条泡菜香肠,挤上番茄酱甜面酱巨好吃呀😘!!灌蛋是灵魂,不能偷懒!!", imgName: "sucai" + ) + ActivityCell(nickName: "皮卡丘", timeStamp: "2小时前",content: "发明一种新吃法#一人食灌蛋手抓饼夹小油条泡菜香肠,挤上番茄酱甜面酱巨好吃呀😘!!灌蛋是灵魂,不能偷懒!!", imgName: "sucai" + ) + ActivityCell(nickName: "皮卡丘", timeStamp: "2小时前",content: "发明一种新吃法#一人食灌蛋手抓饼夹小油条泡菜香肠,挤上番茄酱甜面酱巨好吃呀😘!!灌蛋是灵魂,不能偷懒!!", imgName: "sucai" + ) + } + .padding(.leading, -20) + + } + } +} + +#if DEBUG +struct ActivityView_Previews : PreviewProvider { + static var previews: some View { + ActivityView() + } +} +#endif diff --git a/Other Projects/Jike/SwiftUI_Jike/AppDelegate.swift b/Other Projects/Jike/SwiftUI_Jike/AppDelegate.swift new file mode 100644 index 0000000..1c6ca42 --- /dev/null +++ b/Other Projects/Jike/SwiftUI_Jike/AppDelegate.swift @@ -0,0 +1,41 @@ +// +// AppDelegate.swift +// SwiftUI_Jike +// +// Created by alexyang on 2019/6/5. +// Copyright © 2019 alexyang. All rights reserved. +// + +import UIKit + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + + + + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { + // Override point for customization after application launch. + return true + } + + func applicationWillTerminate(_ application: UIApplication) { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. + } + + // MARK: UISceneSession Lifecycle + + func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration { + // Called when a new scene session is being created. + // Use this method to select a configuration to create the new scene with. + return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role) + } + + func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) { + // Called when the user discards a scene session. + // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions. + // Use this method to release any resources that were specific to the discarded scenes, as they will not return. + } + + +} + diff --git a/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/AppIcon.appiconset/Contents.json b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..193d0dc --- /dev/null +++ b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,158 @@ +{ + "images": [ + { + "size": "20x20", + "idiom": "iphone", + "filename": "icon-20@2x.png", + "scale": "2x" + }, + { + "size": "20x20", + "idiom": "iphone", + "filename": "icon-20@3x.png", + "scale": "3x" + }, + { + "size": "29x29", + "idiom": "iphone", + "filename": "icon-29.png", + "scale": "1x" + }, + { + "size": "29x29", + "idiom": "iphone", + "filename": "icon-29@2x.png", + "scale": "2x" + }, + { + "size": "29x29", + "idiom": "iphone", + "filename": "icon-29@3x.png", + "scale": "3x" + }, + { + "size": "40x40", + "idiom": "iphone", + "filename": "icon-40@2x.png", + "scale": "2x" + }, + { + "size": "40x40", + "idiom": "iphone", + "filename": "icon-40@3x.png", + "scale": "3x" + }, + { + "size": "57x57", + "idiom": "iphone", + "filename": "icon-57.png", + "scale": "1x" + }, + { + "size": "57x57", + "idiom": "iphone", + "filename": "icon-57@2x.png", + "scale": "2x" + }, + { + "size": "60x60", + "idiom": "iphone", + "filename": "icon-60@2x.png", + "scale": "2x" + }, + { + "size": "60x60", + "idiom": "iphone", + "filename": "icon-60@3x.png", + "scale": "3x" + }, + { + "size": "20x20", + "idiom": "ipad", + "filename": "icon-20-ipad.png", + "scale": "1x" + }, + { + "size": "20x20", + "idiom": "ipad", + "filename": "icon-20@2x-ipad.png", + "scale": "2x" + }, + { + "size": "29x29", + "idiom": "ipad", + "filename": "icon-29-ipad.png", + "scale": "1x" + }, + { + "size": "29x29", + "idiom": "ipad", + "filename": "icon-29@2x-ipad.png", + "scale": "2x" + }, + { + "size": "40x40", + "idiom": "ipad", + "filename": "icon-40.png", + "scale": "1x" + }, + { + "size": "40x40", + "idiom": "ipad", + "filename": "icon-40@2x.png", + "scale": "2x" + }, + { + "size": "50x50", + "idiom": "ipad", + "filename": "icon-50.png", + "scale": "1x" + }, + { + "size": "50x50", + "idiom": "ipad", + "filename": "icon-50@2x.png", + "scale": "2x" + }, + { + "size": "72x72", + "idiom": "ipad", + "filename": "icon-72.png", + "scale": "1x" + }, + { + "size": "72x72", + "idiom": "ipad", + "filename": "icon-72@2x.png", + "scale": "2x" + }, + { + "size": "76x76", + "idiom": "ipad", + "filename": "icon-76.png", + "scale": "1x" + }, + { + "size": "76x76", + "idiom": "ipad", + "filename": "icon-76@2x.png", + "scale": "2x" + }, + { + "size": "83.5x83.5", + "idiom": "ipad", + "filename": "icon-83.5@2x.png", + "scale": "2x" + }, + { + "size": "1024x1024", + "idiom": "ios-marketing", + "filename": "icon-1024.png", + "scale": "1x" + } + ], + "info": { + "version": 1, + "author": "icon.wuruihong.com" + } +} \ No newline at end of file diff --git a/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/AppIcon.appiconset/icon-1024.png b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/AppIcon.appiconset/icon-1024.png new file mode 100644 index 0000000..33cdb42 Binary files /dev/null and b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/AppIcon.appiconset/icon-1024.png differ diff --git a/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/AppIcon.appiconset/icon-20-ipad.png b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/AppIcon.appiconset/icon-20-ipad.png new file mode 100644 index 0000000..54302ec Binary files /dev/null and b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/AppIcon.appiconset/icon-20-ipad.png differ diff --git a/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/AppIcon.appiconset/icon-20@2x-ipad.png b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/AppIcon.appiconset/icon-20@2x-ipad.png new file mode 100644 index 0000000..79846be Binary files /dev/null and b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/AppIcon.appiconset/icon-20@2x-ipad.png differ diff --git a/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/AppIcon.appiconset/icon-20@2x.png b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/AppIcon.appiconset/icon-20@2x.png new file mode 100644 index 0000000..79846be Binary files /dev/null and b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/AppIcon.appiconset/icon-20@2x.png differ diff --git a/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/AppIcon.appiconset/icon-20@3x.png b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/AppIcon.appiconset/icon-20@3x.png new file mode 100644 index 0000000..64e1fb9 Binary files /dev/null and b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/AppIcon.appiconset/icon-20@3x.png differ diff --git a/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/AppIcon.appiconset/icon-29-ipad.png b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/AppIcon.appiconset/icon-29-ipad.png new file mode 100644 index 0000000..a3d8fc7 Binary files /dev/null and b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/AppIcon.appiconset/icon-29-ipad.png differ diff --git a/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/AppIcon.appiconset/icon-29.png b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/AppIcon.appiconset/icon-29.png new file mode 100644 index 0000000..a3d8fc7 Binary files /dev/null and b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/AppIcon.appiconset/icon-29.png differ diff --git a/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/AppIcon.appiconset/icon-29@2x-ipad.png b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/AppIcon.appiconset/icon-29@2x-ipad.png new file mode 100644 index 0000000..a5c7c71 Binary files /dev/null and b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/AppIcon.appiconset/icon-29@2x-ipad.png differ diff --git a/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/AppIcon.appiconset/icon-29@2x.png b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/AppIcon.appiconset/icon-29@2x.png new file mode 100644 index 0000000..a5c7c71 Binary files /dev/null and b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/AppIcon.appiconset/icon-29@2x.png differ diff --git a/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/AppIcon.appiconset/icon-29@3x.png b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/AppIcon.appiconset/icon-29@3x.png new file mode 100644 index 0000000..92f0457 Binary files /dev/null and b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/AppIcon.appiconset/icon-29@3x.png differ diff --git a/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/AppIcon.appiconset/icon-40.png b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/AppIcon.appiconset/icon-40.png new file mode 100644 index 0000000..79846be Binary files /dev/null and b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/AppIcon.appiconset/icon-40.png differ diff --git a/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/AppIcon.appiconset/icon-40@2x.png b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/AppIcon.appiconset/icon-40@2x.png new file mode 100644 index 0000000..d5770bf Binary files /dev/null and b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/AppIcon.appiconset/icon-40@2x.png differ diff --git a/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/AppIcon.appiconset/icon-40@3x.png b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/AppIcon.appiconset/icon-40@3x.png new file mode 100644 index 0000000..6711604 Binary files /dev/null and b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/AppIcon.appiconset/icon-40@3x.png differ diff --git a/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/AppIcon.appiconset/icon-50.png b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/AppIcon.appiconset/icon-50.png new file mode 100644 index 0000000..f972585 Binary files /dev/null and b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/AppIcon.appiconset/icon-50.png differ diff --git a/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/AppIcon.appiconset/icon-50@2x.png b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/AppIcon.appiconset/icon-50@2x.png new file mode 100644 index 0000000..2f3cc0b Binary files /dev/null and b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/AppIcon.appiconset/icon-50@2x.png differ diff --git a/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/AppIcon.appiconset/icon-57.png b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/AppIcon.appiconset/icon-57.png new file mode 100644 index 0000000..9336ede Binary files /dev/null and b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/AppIcon.appiconset/icon-57.png differ diff --git a/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/AppIcon.appiconset/icon-57@2x.png b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/AppIcon.appiconset/icon-57@2x.png new file mode 100644 index 0000000..fff81bd Binary files /dev/null and b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/AppIcon.appiconset/icon-57@2x.png differ diff --git a/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/AppIcon.appiconset/icon-60@2x.png b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/AppIcon.appiconset/icon-60@2x.png new file mode 100644 index 0000000..6711604 Binary files /dev/null and b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/AppIcon.appiconset/icon-60@2x.png differ diff --git a/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/AppIcon.appiconset/icon-60@3x.png b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/AppIcon.appiconset/icon-60@3x.png new file mode 100644 index 0000000..fd4aaa7 Binary files /dev/null and b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/AppIcon.appiconset/icon-60@3x.png differ diff --git a/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/AppIcon.appiconset/icon-72.png b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/AppIcon.appiconset/icon-72.png new file mode 100644 index 0000000..df50566 Binary files /dev/null and b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/AppIcon.appiconset/icon-72.png differ diff --git a/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/AppIcon.appiconset/icon-72@2x.png b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/AppIcon.appiconset/icon-72@2x.png new file mode 100644 index 0000000..6d766b1 Binary files /dev/null and b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/AppIcon.appiconset/icon-72@2x.png differ diff --git a/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/AppIcon.appiconset/icon-76.png b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/AppIcon.appiconset/icon-76.png new file mode 100644 index 0000000..ef95783 Binary files /dev/null and b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/AppIcon.appiconset/icon-76.png differ diff --git a/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/AppIcon.appiconset/icon-76@2x.png b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/AppIcon.appiconset/icon-76@2x.png new file mode 100644 index 0000000..98b0be9 Binary files /dev/null and b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/AppIcon.appiconset/icon-76@2x.png differ diff --git a/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/AppIcon.appiconset/icon-83.5@2x.png b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/AppIcon.appiconset/icon-83.5@2x.png new file mode 100644 index 0000000..9e45c1a Binary files /dev/null and b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/AppIcon.appiconset/icon-83.5@2x.png differ diff --git a/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/Contents.json b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/addPer.imageset/Contents.json b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/addPer.imageset/Contents.json new file mode 100644 index 0000000..36bbc3c --- /dev/null +++ b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/addPer.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "ic_navbar_add_friends_Normal@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/addPer.imageset/ic_navbar_add_friends_Normal@3x.png b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/addPer.imageset/ic_navbar_add_friends_Normal@3x.png new file mode 100644 index 0000000..144db0f Binary files /dev/null and b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/addPer.imageset/ic_navbar_add_friends_Normal@3x.png differ diff --git a/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/chat_box.imageset/Contents.json b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/chat_box.imageset/Contents.json new file mode 100644 index 0000000..0909221 --- /dev/null +++ b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/chat_box.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "ic_chat_box_Normal@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/chat_box.imageset/ic_chat_box_Normal@3x.png b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/chat_box.imageset/ic_chat_box_Normal@3x.png new file mode 100644 index 0000000..034d3cf Binary files /dev/null and b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/chat_box.imageset/ic_chat_box_Normal@3x.png differ diff --git a/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/dianzan.imageset/Contents.json b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/dianzan.imageset/Contents.json new file mode 100644 index 0000000..b5d6c47 --- /dev/null +++ b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/dianzan.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "ic_comment_like_Normal@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/dianzan.imageset/ic_comment_like_Normal@3x.png b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/dianzan.imageset/ic_comment_like_Normal@3x.png new file mode 100644 index 0000000..c039ed0 Binary files /dev/null and b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/dianzan.imageset/ic_comment_like_Normal@3x.png differ diff --git a/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/discovery_icon.imageset/Contents.json b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/discovery_icon.imageset/Contents.json new file mode 100644 index 0000000..7ab971d --- /dev/null +++ b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/discovery_icon.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "ic_navbar_discovery_Normal@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/discovery_icon.imageset/ic_navbar_discovery_Normal@3x.png b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/discovery_icon.imageset/ic_navbar_discovery_Normal@3x.png new file mode 100644 index 0000000..e8b0c5a Binary files /dev/null and b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/discovery_icon.imageset/ic_navbar_discovery_Normal@3x.png differ diff --git a/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/meIcon.imageset/Contents.json b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/meIcon.imageset/Contents.json new file mode 100644 index 0000000..e31cc96 --- /dev/null +++ b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/meIcon.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "IMG_9777_Fotor.jpg", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/meIcon.imageset/IMG_9777_Fotor.jpg b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/meIcon.imageset/IMG_9777_Fotor.jpg new file mode 100644 index 0000000..7b3223d Binary files /dev/null and b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/meIcon.imageset/IMG_9777_Fotor.jpg differ diff --git a/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/pinglun.imageset/Contents.json b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/pinglun.imageset/Contents.json new file mode 100644 index 0000000..6024481 --- /dev/null +++ b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/pinglun.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "ic_messages_comment_Normal@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/pinglun.imageset/ic_messages_comment_Normal@3x.png b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/pinglun.imageset/ic_messages_comment_Normal@3x.png new file mode 100644 index 0000000..b33db56 Binary files /dev/null and b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/pinglun.imageset/ic_messages_comment_Normal@3x.png differ diff --git a/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/pokemon.imageset/Contents.json b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/pokemon.imageset/Contents.json new file mode 100644 index 0000000..b48fcfb --- /dev/null +++ b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/pokemon.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "WechatIMG46_Fotor.jpg", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/pokemon.imageset/WechatIMG46_Fotor.jpg b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/pokemon.imageset/WechatIMG46_Fotor.jpg new file mode 100644 index 0000000..5c48cf8 Binary files /dev/null and b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/pokemon.imageset/WechatIMG46_Fotor.jpg differ diff --git a/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/righ_arrow.imageset/Contents.json b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/righ_arrow.imageset/Contents.json new file mode 100644 index 0000000..00ea621 --- /dev/null +++ b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/righ_arrow.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "ic_common_arrow_right_Normal@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/righ_arrow.imageset/ic_common_arrow_right_Normal@3x.png b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/righ_arrow.imageset/ic_common_arrow_right_Normal@3x.png new file mode 100644 index 0000000..87d16c6 Binary files /dev/null and b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/righ_arrow.imageset/ic_common_arrow_right_Normal@3x.png differ diff --git a/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/scan_icon.imageset/Contents.json b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/scan_icon.imageset/Contents.json new file mode 100644 index 0000000..39f3b85 --- /dev/null +++ b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/scan_icon.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "ic_navbar_scan_Normal@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/scan_icon.imageset/ic_navbar_scan_Normal@3x.png b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/scan_icon.imageset/ic_navbar_scan_Normal@3x.png new file mode 100644 index 0000000..9738065 Binary files /dev/null and b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/scan_icon.imageset/ic_navbar_scan_Normal@3x.png differ diff --git a/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/search_icon.imageset/Contents.json b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/search_icon.imageset/Contents.json new file mode 100644 index 0000000..1b4f0da --- /dev/null +++ b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/search_icon.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "ic_navbar_search_Normal@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/search_icon.imageset/ic_navbar_search_Normal@3x.png b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/search_icon.imageset/ic_navbar_search_Normal@3x.png new file mode 100644 index 0000000..6bac94f Binary files /dev/null and b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/search_icon.imageset/ic_navbar_search_Normal@3x.png differ diff --git a/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/setting_feedback.imageset/Contents.json b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/setting_feedback.imageset/Contents.json new file mode 100644 index 0000000..643d21f --- /dev/null +++ b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/setting_feedback.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "ic_personal_tab_support_center_Normal@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/setting_feedback.imageset/ic_personal_tab_support_center_Normal@3x.png b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/setting_feedback.imageset/ic_personal_tab_support_center_Normal@3x.png new file mode 100644 index 0000000..ea9552a Binary files /dev/null and b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/setting_feedback.imageset/ic_personal_tab_support_center_Normal@3x.png differ diff --git a/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/setting_hehuoren.imageset/Contents.json b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/setting_hehuoren.imageset/Contents.json new file mode 100644 index 0000000..28978bd --- /dev/null +++ b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/setting_hehuoren.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "ic_comment_sync_jike_selected_Normal@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/setting_hehuoren.imageset/ic_comment_sync_jike_selected_Normal@3x.png b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/setting_hehuoren.imageset/ic_comment_sync_jike_selected_Normal@3x.png new file mode 100644 index 0000000..e86ed6a Binary files /dev/null and b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/setting_hehuoren.imageset/ic_comment_sync_jike_selected_Normal@3x.png differ diff --git a/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/setting_icon.imageset/Contents.json b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/setting_icon.imageset/Contents.json new file mode 100644 index 0000000..6e91625 --- /dev/null +++ b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/setting_icon.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "ic_navbar_setting_Normal@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/setting_icon.imageset/ic_navbar_setting_Normal@3x.png b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/setting_icon.imageset/ic_navbar_setting_Normal@3x.png new file mode 100644 index 0000000..f9a9dcb Binary files /dev/null and b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/setting_icon.imageset/ic_navbar_setting_Normal@3x.png differ diff --git a/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/setting_mainliuliang.imageset/Contents.json b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/setting_mainliuliang.imageset/Contents.json new file mode 100644 index 0000000..e644bb2 --- /dev/null +++ b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/setting_mainliuliang.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "ic_personal_tab_kingcard_Normal@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/setting_mainliuliang.imageset/ic_personal_tab_kingcard_Normal@3x.png b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/setting_mainliuliang.imageset/ic_personal_tab_kingcard_Normal@3x.png new file mode 100644 index 0000000..9d5771f Binary files /dev/null and b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/setting_mainliuliang.imageset/ic_personal_tab_kingcard_Normal@3x.png differ diff --git a/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/setting_quanzi.imageset/Contents.json b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/setting_quanzi.imageset/Contents.json new file mode 100644 index 0000000..77d62ad --- /dev/null +++ b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/setting_quanzi.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "ic_personal_tab_my_topic_Normal@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/setting_quanzi.imageset/ic_personal_tab_my_topic_Normal@3x.png b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/setting_quanzi.imageset/ic_personal_tab_my_topic_Normal@3x.png new file mode 100644 index 0000000..c679021 Binary files /dev/null and b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/setting_quanzi.imageset/ic_personal_tab_my_topic_Normal@3x.png differ diff --git a/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/setting_shoucang.imageset/Contents.json b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/setting_shoucang.imageset/Contents.json new file mode 100644 index 0000000..6923575 --- /dev/null +++ b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/setting_shoucang.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "ic_personal_tab_collection_Normal@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/setting_shoucang.imageset/ic_personal_tab_collection_Normal@3x.png b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/setting_shoucang.imageset/ic_personal_tab_collection_Normal@3x.png new file mode 100644 index 0000000..b058df1 Binary files /dev/null and b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/setting_shoucang.imageset/ic_personal_tab_collection_Normal@3x.png differ diff --git a/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/setting_tongzhi.imageset/Contents.json b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/setting_tongzhi.imageset/Contents.json new file mode 100644 index 0000000..e7429b9 --- /dev/null +++ b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/setting_tongzhi.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "ic_personal_tab_activity_notification_new_messages_4_Normal@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/setting_tongzhi.imageset/ic_personal_tab_activity_notification_new_messages_4_Normal@3x.png b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/setting_tongzhi.imageset/ic_personal_tab_activity_notification_new_messages_4_Normal@3x.png new file mode 100644 index 0000000..19b624d Binary files /dev/null and b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/setting_tongzhi.imageset/ic_personal_tab_activity_notification_new_messages_4_Normal@3x.png differ diff --git a/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/share.imageset/Contents.json b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/share.imageset/Contents.json new file mode 100644 index 0000000..9ab41ed --- /dev/null +++ b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/share.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "ic_messages_share_Normal@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/share.imageset/ic_messages_share_Normal@3x.png b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/share.imageset/ic_messages_share_Normal@3x.png new file mode 100644 index 0000000..74c34ce Binary files /dev/null and b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/share.imageset/ic_messages_share_Normal@3x.png differ diff --git a/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/shenglue.imageset/Contents.json b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/shenglue.imageset/Contents.json new file mode 100644 index 0000000..e03d259 --- /dev/null +++ b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/shenglue.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "ic_messages_more_Normal@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/shenglue.imageset/ic_messages_more_Normal@3x.png b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/shenglue.imageset/ic_messages_more_Normal@3x.png new file mode 100644 index 0000000..14a608a Binary files /dev/null and b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/shenglue.imageset/ic_messages_more_Normal@3x.png differ diff --git a/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/subIcon.imageset/Contents.json b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/subIcon.imageset/Contents.json new file mode 100644 index 0000000..4bb721b --- /dev/null +++ b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/subIcon.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "IMG_9776_Fotor.jpg", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/subIcon.imageset/IMG_9776_Fotor.jpg b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/subIcon.imageset/IMG_9776_Fotor.jpg new file mode 100644 index 0000000..9eb6e78 Binary files /dev/null and b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/subIcon.imageset/IMG_9776_Fotor.jpg differ diff --git a/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/sucai.imageset/Contents.json b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/sucai.imageset/Contents.json new file mode 100644 index 0000000..b62312e --- /dev/null +++ b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/sucai.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "IMG_9778_Fotor.jpg", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/sucai.imageset/IMG_9778_Fotor.jpg b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/sucai.imageset/IMG_9778_Fotor.jpg new file mode 100644 index 0000000..38a915e Binary files /dev/null and b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/sucai.imageset/IMG_9778_Fotor.jpg differ diff --git a/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/tab_chat_normal.imageset/Contents.json b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/tab_chat_normal.imageset/Contents.json new file mode 100644 index 0000000..f03e786 --- /dev/null +++ b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/tab_chat_normal.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "ic_navbar_chat_Normal@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/tab_chat_normal.imageset/ic_navbar_chat_Normal@3x.png b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/tab_chat_normal.imageset/ic_navbar_chat_Normal@3x.png new file mode 100644 index 0000000..8cd613b Binary files /dev/null and b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/tab_chat_normal.imageset/ic_navbar_chat_Normal@3x.png differ diff --git a/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/tab_chat_select.imageset/Contents.json b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/tab_chat_select.imageset/Contents.json new file mode 100644 index 0000000..1da09d6 --- /dev/null +++ b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/tab_chat_select.imageset/Contents.json @@ -0,0 +1,24 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "ic_tabbar_chat_selected_Normal@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + }, + "properties" : { + "template-rendering-intent" : "original" + } +} \ No newline at end of file diff --git a/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/tab_chat_select.imageset/ic_tabbar_chat_selected_Normal@3x.png b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/tab_chat_select.imageset/ic_tabbar_chat_selected_Normal@3x.png new file mode 100644 index 0000000..7b3104b Binary files /dev/null and b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/tab_chat_select.imageset/ic_tabbar_chat_selected_Normal@3x.png differ diff --git a/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/tab_home_normal.imageset/Contents.json b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/tab_home_normal.imageset/Contents.json new file mode 100644 index 0000000..1bff2b7 --- /dev/null +++ b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/tab_home_normal.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "ic_tabbar_home_unselected_Normal@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/tab_home_normal.imageset/ic_tabbar_home_unselected_Normal@3x.png b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/tab_home_normal.imageset/ic_tabbar_home_unselected_Normal@3x.png new file mode 100644 index 0000000..687f8f6 Binary files /dev/null and b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/tab_home_normal.imageset/ic_tabbar_home_unselected_Normal@3x.png differ diff --git a/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/tab_home_select.imageset/Contents.json b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/tab_home_select.imageset/Contents.json new file mode 100644 index 0000000..a04abf4 --- /dev/null +++ b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/tab_home_select.imageset/Contents.json @@ -0,0 +1,24 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "ic_tabbar_home_selected_Normal@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + }, + "properties" : { + "template-rendering-intent" : "original" + } +} \ No newline at end of file diff --git a/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/tab_home_select.imageset/ic_tabbar_home_selected_Normal@3x.png b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/tab_home_select.imageset/ic_tabbar_home_selected_Normal@3x.png new file mode 100644 index 0000000..e225c5c Binary files /dev/null and b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/tab_home_select.imageset/ic_tabbar_home_selected_Normal@3x.png differ diff --git a/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/tab_me_normal.imageset/Contents.json b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/tab_me_normal.imageset/Contents.json new file mode 100644 index 0000000..2fd3d12 --- /dev/null +++ b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/tab_me_normal.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "ic_tabbar_personal_unselected_Normal@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/tab_me_normal.imageset/ic_tabbar_personal_unselected_Normal@3x.png b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/tab_me_normal.imageset/ic_tabbar_personal_unselected_Normal@3x.png new file mode 100644 index 0000000..f02a1a4 Binary files /dev/null and b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/tab_me_normal.imageset/ic_tabbar_personal_unselected_Normal@3x.png differ diff --git a/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/tab_me_select.imageset/Contents.json b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/tab_me_select.imageset/Contents.json new file mode 100644 index 0000000..d5ad1f0 --- /dev/null +++ b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/tab_me_select.imageset/Contents.json @@ -0,0 +1,24 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "ic_tabbar_personal_selected_Normal@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + }, + "properties" : { + "template-rendering-intent" : "original" + } +} \ No newline at end of file diff --git a/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/tab_me_select.imageset/ic_tabbar_personal_selected_Normal@3x.png b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/tab_me_select.imageset/ic_tabbar_personal_selected_Normal@3x.png new file mode 100644 index 0000000..19efe11 Binary files /dev/null and b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/tab_me_select.imageset/ic_tabbar_personal_selected_Normal@3x.png differ diff --git a/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/tab_status_normal.imageset/Contents.json b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/tab_status_normal.imageset/Contents.json new file mode 100644 index 0000000..6105034 --- /dev/null +++ b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/tab_status_normal.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "ic_tabbar_activity_unselected_Normal@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/tab_status_normal.imageset/ic_tabbar_activity_unselected_Normal@3x.png b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/tab_status_normal.imageset/ic_tabbar_activity_unselected_Normal@3x.png new file mode 100644 index 0000000..29d263c Binary files /dev/null and b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/tab_status_normal.imageset/ic_tabbar_activity_unselected_Normal@3x.png differ diff --git a/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/tab_status_select.imageset/Contents.json b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/tab_status_select.imageset/Contents.json new file mode 100644 index 0000000..0103165 --- /dev/null +++ b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/tab_status_select.imageset/Contents.json @@ -0,0 +1,24 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "ic_tabbar_activity_selected_Normal@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + }, + "properties" : { + "template-rendering-intent" : "original" + } +} \ No newline at end of file diff --git a/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/tab_status_select.imageset/ic_tabbar_activity_selected_Normal@3x.png b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/tab_status_select.imageset/ic_tabbar_activity_selected_Normal@3x.png new file mode 100644 index 0000000..8de64c3 Binary files /dev/null and b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/tab_status_select.imageset/ic_tabbar_activity_selected_Normal@3x.png differ diff --git a/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/touxiang.imageset/Contents.json b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/touxiang.imageset/Contents.json new file mode 100644 index 0000000..85d9eae --- /dev/null +++ b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/touxiang.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "ic_personal_tab_follower_Normal@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/touxiang.imageset/ic_personal_tab_follower_Normal@3x.png b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/touxiang.imageset/ic_personal_tab_follower_Normal@3x.png new file mode 100644 index 0000000..d3b0318 Binary files /dev/null and b/Other Projects/Jike/SwiftUI_Jike/Assets.xcassets/touxiang.imageset/ic_personal_tab_follower_Normal@3x.png differ diff --git a/Other Projects/Jike/SwiftUI_Jike/Base.lproj/LaunchScreen.storyboard b/Other Projects/Jike/SwiftUI_Jike/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000..865e932 --- /dev/null +++ b/Other Projects/Jike/SwiftUI_Jike/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Other Projects/Jike/SwiftUI_Jike/Cell/ActivityCell.swift b/Other Projects/Jike/SwiftUI_Jike/Cell/ActivityCell.swift new file mode 100644 index 0000000..d88c536 --- /dev/null +++ b/Other Projects/Jike/SwiftUI_Jike/Cell/ActivityCell.swift @@ -0,0 +1,71 @@ +// +// ActivityCell.swift +// SwiftUI_Jike +// +// Created by alexyang on 2019/6/5. +// Copyright © 2019 alexyang. All rights reserved. +// + +import SwiftUI + +struct ActivityCell : View { + var nickName:String + var timeStamp:String + var content:String + var imgName:String + var body: some View { + VStack(alignment: .leading){ + HStack(){ + VStack{ + CircleImage(imgName: "pokemon") + .padding(.leading, 20) + .padding(.top, 10) + Spacer() + } + + VStack(alignment: .leading){ + HStack{ + Text(nickName) + .padding(.top, 5) + .padding(.bottom, 2) + Spacer() + } + Text(timeStamp) + .font(Font.system(size: 12)) + .foregroundColor(Color.gray) + .padding(.bottom, 2) + + Text(content) + .frame(minHeight:50, maxHeight: 300, alignment: .top) + .font(Font.system(size: 15)) + .lineLimit(-1) + Image(imgName) + .padding(.bottom, 20) + .padding(.trailing, 10) + } + + } + HStack{ + Spacer() + Image("dianzan") + Spacer() + Image("pinglun") + Spacer() + Image("share") + Spacer() + Image("shenglue") + } + } + .lineSpacing(0) + .frame(minHeight: 300) + } +} + +#if DEBUG +struct ActivityCell_Previews : PreviewProvider { + static var previews: some View { + ActivityCell(nickName: "皮卡丘", timeStamp: "2小时前",content: "发明一种新吃法#一人食灌蛋手抓饼夹小油条泡菜香肠,挤上番茄酱甜面酱巨好吃呀😘!!灌蛋是灵魂,不能偷懒!!", imgName: "sucai" + ) + } +} +#endif diff --git a/Other Projects/Jike/SwiftUI_Jike/Cell/CategoryRow.swift b/Other Projects/Jike/SwiftUI_Jike/Cell/CategoryRow.swift new file mode 100644 index 0000000..4860dab --- /dev/null +++ b/Other Projects/Jike/SwiftUI_Jike/Cell/CategoryRow.swift @@ -0,0 +1,60 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A view showing a scrollable list of landmarks. +*/ + +import SwiftUI + +struct CategoryRow: View { + var items: [ZoneModel] + + var body: some View { + VStack(alignment: .leading) { + ScrollView(.horizontal) { + HStack(alignment: .top, spacing: 0) { + ForEach(self.items, id: \.id) { zone in + CategoryItem(zone: zone) + } + } + } + } + } +} + +struct CategoryItem: View { + var zone: ZoneModel + var body: some View { + VStack(alignment: .center) { + + VStack{ + Color.white + .frame(width:65,height:65) + .background(RoundedRectangle(cornerRadius: 15).strokeBorder(Color(red: 218.0/255.0, green: 218.0/255.0, blue: 218.0/255.0), lineWidth: 3)) + .cornerRadius(15) + zone + .image(forSize: 55) + .renderingMode(.original) + .cornerRadius(10) + .padding(.top,-68) + + } + Text(zone.name) + .frame(width: 65, height: 20, alignment: .center) + .font(Font.system(size: 12)) + .padding(.top, -8) + } + .padding(.trailing, -5) + .padding(.leading, 10) + } +} + +#if DEBUG +struct CategoryRow_Previews: PreviewProvider { + static var previews: some View { + + CategoryRow(items: zonnData) + } +} +#endif diff --git a/Other Projects/Jike/SwiftUI_Jike/Cell/ChatCell.swift b/Other Projects/Jike/SwiftUI_Jike/Cell/ChatCell.swift new file mode 100644 index 0000000..378f175 --- /dev/null +++ b/Other Projects/Jike/SwiftUI_Jike/Cell/ChatCell.swift @@ -0,0 +1,40 @@ +// +// ChatCell.swift +// SwiftUI_Jike +// +// Created by alexyang on 2019/6/5. +// Copyright © 2019 alexyang. All rights reserved. +// + +import SwiftUI + +struct ChatCell : View { + var imageName:String + var title:String + var subTitle:String + var body: some View { + HStack(alignment: .center){ + CircleImage(imgName:imageName) + VStack(alignment: .leading){ + Text(title) + .bold() + .padding(.top, 4) + Text(subTitle) + .foregroundColor(Color.gray) + .padding(.bottom, 8) + } + Spacer() + } + .padding(.horizontal, 15) + .frame(height: 60) + } + +} + +#if DEBUG +struct ChatCell_Previews : PreviewProvider { + static var previews: some View { + ChatCell(imageName: "chat_box",title: "一条虫",subTitle: "瓦恁出来挨打") + } +} +#endif diff --git a/Other Projects/Jike/SwiftUI_Jike/Cell/CircleImage.swift b/Other Projects/Jike/SwiftUI_Jike/Cell/CircleImage.swift new file mode 100644 index 0000000..078d8c7 --- /dev/null +++ b/Other Projects/Jike/SwiftUI_Jike/Cell/CircleImage.swift @@ -0,0 +1,27 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A view that clips an image to a circle and adds a stroke and shadow. +*/ + +import SwiftUI + +struct CircleImage: View { + var imgName:String + var body: some View { + Image(imgName) + .clipShape(Circle()) + .overlay( + + Circle().stroke(Color.white, lineWidth: 1)) + + .shadow(radius: 3) + } +} + +struct CircleImage_Preview: PreviewProvider { + static var previews: some View { + CircleImage(imgName:"meIcon") + } +} diff --git a/Other Projects/Jike/SwiftUI_Jike/Cell/GYSegmentView.swift b/Other Projects/Jike/SwiftUI_Jike/Cell/GYSegmentView.swift new file mode 100644 index 0000000..7769b17 --- /dev/null +++ b/Other Projects/Jike/SwiftUI_Jike/Cell/GYSegmentView.swift @@ -0,0 +1,51 @@ +// +// GYSegmentView.swift +// Landmarks +// +// Created by alexyang on 2019/6/6. +// Copyright © 2019 Apple. All rights reserved. +// +import UIKit +import SwiftUI + +struct GYSegmentView : UIViewRepresentable { + func makeCoordinator() -> GYSegmentView.Coordinator { + Coordinator(self) + } + + + var titles:[String] + @Binding var currentPage: Int + + func makeUIView(context: Context) -> UISegmentedControl + { + let segment = UISegmentedControl(items: titles) + segment.addTarget(context.coordinator, action:#selector(Coordinator.updateCurrentPage(sender:)) , for: .valueChanged) + return segment + } + + func updateUIView(_ segment: UISegmentedControl, context: Context) { + + segment.selectedSegmentIndex = currentPage + } + + class Coordinator: NSObject { + var control: GYSegmentView + + init(_ control: GYSegmentView) { + self.control = control + } + + @objc func updateCurrentPage(sender: UISegmentedControl) { + control.currentPage = sender.selectedSegmentIndex + } + } +} + +#if DEBUG +struct GYSegmentView_Previews : PreviewProvider { + static var previews: some View { + GYSegmentView(titles: ["哈哈","你好","无聊"], currentPage: .constant(0)) + } +} +#endif diff --git a/Other Projects/Jike/SwiftUI_Jike/Cell/HomeCell.swift b/Other Projects/Jike/SwiftUI_Jike/Cell/HomeCell.swift new file mode 100644 index 0000000..04d552f --- /dev/null +++ b/Other Projects/Jike/SwiftUI_Jike/Cell/HomeCell.swift @@ -0,0 +1,92 @@ +// +// HomeCell.swift +// SwiftUI_Jike +// +// Created by alexyang on 2019/6/6. +// Copyright © 2019 alexyang. All rights reserved. +// + +import SwiftUI + +struct HomeCell : View { + var zoneName:String + var zoneImgName:String + var userIcon:String + var nickName:String + var timeStamp:String + var content:String + var imgName:String + var body: some View { + VStack(alignment: .leading){ + VStack(){ + + HStack{ + ImageStore.shared.image(name: zoneImgName, size: 60) + .cornerRadius(5) + .padding(.leading, 20) + .padding(.top, 10) + .padding(.bottom, 10) + VStack(alignment: .leading, spacing: 5){ + Text(zoneName) + .font(Font.system(size: 16)) + .bold() + Text(timeStamp) + .font(Font.system(size: 12)) + .foregroundColor(Color.gray) + .padding(.top, 8) + } + Spacer() + } + .background(Color(red: 245.0/255.0, green: 245.0/255.0, blue: 245.0/255.0)) + + VStack(alignment: .leading){ + Text(content) + .font(Font.system(size: 15)) + .frame(minWidth: 320,minHeight:50, maxHeight: 300, alignment: .leading) + .lineLimit(-1) + ImageStore.shared.image(name: imgName, size: 200) + .padding(.bottom, 10) + } + .padding(.leading, -20) + + HStack(alignment: .center){ + CircleImage(imgName: userIcon) + .padding(.leading, 20) + Text(nickName) + .font(Font.system(size: 14)) + .bold() + Text("发布") + .font(Font.system(size: 13)) + .foregroundColor(Color.gray) + Spacer() + } + + } + Divider() + .padding(.horizontal,20) + HStack{ + Image("dianzan") + Spacer() + Image("pinglun") + Spacer() + Image("share") + Spacer() + Image("shenglue") + } + .padding(.leading, 20) + .padding(.trailing, 20) + Color(red: 240.0/255.0, green: 243.0/255.0, blue: 245.0/255.0) + .frame(height: CGFloat(1.0)) + } + .frame(height:450) + } +} + +#if DEBUG +struct HomeCell_Previews : PreviewProvider { + static var previews: some View { + HomeCell(zoneName: "人人都爱宝可梦", zoneImgName: "30_Fotor", userIcon: "pokemon", nickName: "皮卡丘", timeStamp: "2小时前",content: "蒜头丘!\n皮卡皮卡₍₍ (̨̡ ‾᷄ᗣ‾᷅ )̧̢ ₎₎", imgName: "kcc" + ) + } +} +#endif diff --git a/Other Projects/Jike/SwiftUI_Jike/Cell/SettingCell.swift b/Other Projects/Jike/SwiftUI_Jike/Cell/SettingCell.swift new file mode 100644 index 0000000..20f73c5 --- /dev/null +++ b/Other Projects/Jike/SwiftUI_Jike/Cell/SettingCell.swift @@ -0,0 +1,38 @@ +// +// SettingCell.swift +// SwiftUI_Jike +// +// Created by alexyang on 2019/6/5. +// Copyright © 2019 alexyang. All rights reserved. +// + +import SwiftUI + +struct SettingCell : View { + var imageName:String + var title:String + var body: some View { + VStack{ + HStack(){ + Image(imageName) + Text(title) + Spacer() + } + .padding(.top, 5) + .frame(height: 44) + .padding(.horizontal, 15) + Spacer() + Color(red: 240.0/255.0, green: 243.0/255.0, blue: 245.0/255.0) + .frame(height: 1) + } + .frame(height: 50) + } +} + +#if DEBUG +struct SettingCell_Previews : PreviewProvider { + static var previews: some View { + SettingCell(imageName: "setting_quanzi", title: "我的圈子") + } +} +#endif diff --git a/Other Projects/Jike/SwiftUI_Jike/Cell/ZoneCell.swift b/Other Projects/Jike/SwiftUI_Jike/Cell/ZoneCell.swift new file mode 100644 index 0000000..9db68a3 --- /dev/null +++ b/Other Projects/Jike/SwiftUI_Jike/Cell/ZoneCell.swift @@ -0,0 +1,32 @@ +// +// ZoneCell.swift +// SwiftUI_Jike +// +// Created by alexyang on 2019/6/5. +// Copyright © 2019 alexyang. All rights reserved. +// + +import SwiftUI + +struct ZoneCell : View { + var imgName:String + var title:String + var body: some View { + VStack{ + Image(imgName) + Text(title) + .font(Font.system(size: 10)) + .foregroundColor(Color.gray) + .frame(alignment: .center) + } + + } +} + +#if DEBUG +struct ZoneCell_Previews : PreviewProvider { + static var previews: some View { + ZoneCell(imgName: "pokemon", title: "苹果产品爱好者") + } +} +#endif diff --git a/Other Projects/Jike/SwiftUI_Jike/ChatView.swift b/Other Projects/Jike/SwiftUI_Jike/ChatView.swift new file mode 100644 index 0000000..7e9102e --- /dev/null +++ b/Other Projects/Jike/SwiftUI_Jike/ChatView.swift @@ -0,0 +1,52 @@ +// +// ChatView.swift +// SwiftUI_Jike +// +// Created by alexyang on 2019/6/5. +// Copyright © 2019 alexyang. All rights reserved. +// + +import SwiftUI + +struct ChatView : View { + var body: some View { + VStack{ + VStack{ + HStack{ + Spacer() + Text("聊天").bold() + .padding(.leading, 44) + Spacer() + Image("discovery_icon") + .padding(.horizontal, 10) + } + Color(red: 240.0/255.0, green: 243.0/255.0, blue: 245.0/255) + .frame(height: 1) + } + Group() { + ChatCell(imageName: "chat_box", title: "招呼",subTitle: "和XX等人的9999个招呼") + HStack{ + Color(red: 240.0/255.0, green: 243.0/255.0, blue: 245.0/255) + .frame(height: 10.0) + } + + ChatCell(imageName: "subIcon", title: "墨小埋",subTitle: "[有事找你]") + Divider() + ChatCell(imageName: "subIcon", title: "墨小埋",subTitle: "[有事找你]") + Divider() + ChatCell(imageName: "subIcon", title: "墨小埋",subTitle: "[有事找你]") + Divider() + } + Spacer() + + } + } +} + +#if DEBUG +struct ChatView_Previews : PreviewProvider { + static var previews: some View { + ChatView() + } +} +#endif diff --git a/Other Projects/Jike/SwiftUI_Jike/ContentView.swift b/Other Projects/Jike/SwiftUI_Jike/ContentView.swift new file mode 100644 index 0000000..b7421d1 --- /dev/null +++ b/Other Projects/Jike/SwiftUI_Jike/ContentView.swift @@ -0,0 +1,40 @@ +// +// ContentView.swift +// SwiftUI_Jike +// +// Created by alexyang on 2019/6/5. +// Copyright © 2019 alexyang. All rights reserved. +// + +import SwiftUI + +struct ContentView : View { + + var body: some View { + + GYTabView([Text("233")], titles: ["首页","动态","聊天","我的"], + images: ["tab_home_normal", + "tab_status_normal", + "tab_chat_normal", + "tab_me_normal"], + imageSels: ["tab_home_select", + "tab_status_select", + "tab_chat_select", + "tab_me_select"]) + .edgesIgnoringSafeArea(.top) + } + + func getIndex(item: TabBarItem) -> Int { + return 0 + } + +} + +#if DEBUG +struct ContentView_Previews : PreviewProvider { + static var previews: some View { + ContentView() + + } +} +#endif diff --git a/Other Projects/Jike/SwiftUI_Jike/GYTabBarViewController.swift b/Other Projects/Jike/SwiftUI_Jike/GYTabBarViewController.swift new file mode 100644 index 0000000..08f7007 --- /dev/null +++ b/Other Projects/Jike/SwiftUI_Jike/GYTabBarViewController.swift @@ -0,0 +1,60 @@ +// +// GYTabBarViewController.swift +// SegmentDemo +// +// Created by alexyang on 2019/6/6. +// Copyright © 2019 alexyang. All rights reserved. +// + +import SwiftUI + +struct GYTabBarViewController : UIViewControllerRepresentable { + + func makeCoordinator() -> GYTabBarViewController.Coordinator { + Coordinator(self) + } + + var titles:[String] + var imgs:[String] + var imgSels:[String] + var controllers:[UIViewController] + + func makeUIViewController(context: Context) -> UITabBarController { + + let tabBar = UITabBarController() + var index:Int = 0 + let attributes = [NSAttributedString.Key.foregroundColor: UIColor.black] + for vc in controllers { + let title = titles[index] + let image = UIImage(named: imgs[index]) + let imgSel = UIImage(named: imgSels[index]) + let tabBarItem = UITabBarItem(title: title, image: image, selectedImage: imgSel) + tabBarItem.setTitleTextAttributes(attributes, for: .selected) + vc.tabBarItem = tabBarItem + index += 1 + } + tabBar.viewControllers = controllers + tabBar.delegate = context.coordinator + return tabBar + } + + func updateUIViewController(_ tabBarVC: UITabBarController, context: Context) { + tabBarVC.setViewControllers(controllers, animated: true) + } + + class Coordinator: NSObject, UITabBarControllerDelegate { + var parent: GYTabBarViewController + + init(_ tabBarVC: GYTabBarViewController) { + self.parent = tabBarVC + } + + func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController) { + + } + + func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool { + return true + } + } +} diff --git a/Other Projects/Jike/SwiftUI_Jike/GYTabView.swift b/Other Projects/Jike/SwiftUI_Jike/GYTabView.swift new file mode 100644 index 0000000..4a92d5a --- /dev/null +++ b/Other Projects/Jike/SwiftUI_Jike/GYTabView.swift @@ -0,0 +1,45 @@ +// +// GYTabView.swift +// SegmentDemo +// +// Created by alexyang on 2019/6/6. +// Copyright © 2019 alexyang. All rights reserved. +// + +import SwiftUI + +struct GYTabView: View { + var titles:[String] + var imgs:[String] + var imgSels:[String] + var viewControllers: [UIHostingController] + + init(_ views: [Page], titles: [String], images:[String], imageSels:[String]) { + + let vc0 = UIHostingController(rootView: HomeView()) + let vc1 = UIHostingController(rootView: ActivityView()) + let vc2 = UIHostingController(rootView: ChatView()) + let vc3 = UIHostingController(rootView: SettingView()) + self.viewControllers = [vc0,vc1,vc2,vc3] as! [UIHostingController] + self.titles = titles + self.imgs = images + self.imgSels = imageSels + } + + + var body: some View { + + GYTabBarViewController(titles: titles, imgs: imgs, imgSels: imgSels, controllers: viewControllers) + } +} + +#if DEBUG +struct GYTabView_Previews : PreviewProvider { + static var previews: some View { + GYTabView([Text("haha"),Text("hah1"),Text("haa")], + titles: ["tab1","tab2","tab3"], + images: ["tab_home_normal","tab_chat_normal","tab_me_normal"], + imageSels: ["tab_home_select","tab_chat_select","tab_me_select"]) + } +} +#endif diff --git a/Other Projects/Jike/SwiftUI_Jike/HomeView.swift b/Other Projects/Jike/SwiftUI_Jike/HomeView.swift new file mode 100644 index 0000000..0b16d25 --- /dev/null +++ b/Other Projects/Jike/SwiftUI_Jike/HomeView.swift @@ -0,0 +1,92 @@ +// +// HomeView.swift +// SwiftUI_Jike +// +// Created by alexyang on 2019/6/5. +// Copyright © 2019 alexyang. All rights reserved. +// + +import SwiftUI + +struct HomeView : View { + let itemId = "关注" + let segItems: [String] = ["关注", "推荐", "附近", "即刻合伙人"] + var body: some View { + VStack{ + VStack{ + VStack{ + Color(red: 1.0, green: 228.0/255.0, blue: 20.0/255) + } + .frame(height: 40) + .edgesIgnoringSafeArea(.top) + HStack{ + HStack{ + Image("search_icon") + .padding(EdgeInsets(top: 5, leading: 5, bottom: 5, trailing: 5)) + Text("优衣库KAWS遭疯抢") + .font(Font.system(size: 14)) + .foregroundColor(Color.gray) + Spacer() + } + .background( + Color.white + .cornerRadius(5) + ) + .frame(height: 50) + Image("scan_icon") + .padding(.leading, 20) + .padding(.trailing, 10) + } + .padding(.leading, 20) + .background(Color(red: 1.0, green: 228.0/255.0, blue: 20.0/255)) + .padding(.top, -52) + } + + VStack{ + HStack{ + Text("我的圈子") + .font(Font.system(size: 16)) + .bold() + .padding(.leading, 15) + Spacer() + Image("righ_arrow") + .frame(width: 21, height: 36, alignment: .center) + .scaledToFill() + } + .frame(height:36) + CategoryRow(items: zonnData) + } + .padding(.top, -10) + .frame(height: 135) + HStack{ + Color(red: 240.0/255.0, green: 243.0/255.0, blue: 245.0/255) + .frame(height: 10.0) + } + .padding(.top, -5) + HStack{ + GYSegmentView(titles: segItems, currentPage: .constant(0)) + .frame(width: 160, alignment: .leading) + Spacer() + } + .padding(.leading, 10) + + List{ + HomeCell(zoneName: "人人都爱宝可梦", zoneImgName: "30_Fotor", userIcon: "pokemon", nickName: "皮卡丘", timeStamp: "2小时前",content: "蒜头丘!\n皮卡皮卡₍₍ (̨̡ ‾᷄ᗣ‾᷅ )̧̢ ₎₎", imgName: "kcc" + ) + HomeCell(zoneName: "人人都爱宝可梦", zoneImgName: "30_Fotor", userIcon: "pokemon", nickName: "皮卡丘", timeStamp: "2小时前",content: "蒜头丘!\n皮卡皮卡₍₍ (̨̡ ‾᷄ᗣ‾᷅ )̧̢ ₎₎", imgName: "kcc" + ) + HomeCell(zoneName: "人人都爱宝可梦", zoneImgName: "30_Fotor", userIcon: "pokemon", nickName: "皮卡丘", timeStamp: "2小时前",content: "蒜头丘!\n皮卡皮卡₍₍ (̨̡ ‾᷄ᗣ‾᷅ )̧̢ ₎₎", imgName: "kcc" + ) + } + .padding(EdgeInsets(top: 0, leading: -20, bottom: 0, trailing: -20)) + } + } +} + +#if DEBUG +struct HomeView_Previews : PreviewProvider { + static var previews: some View { + HomeView() + } +} +#endif diff --git a/Other Projects/Jike/SwiftUI_Jike/Info.plist b/Other Projects/Jike/SwiftUI_Jike/Info.plist new file mode 100644 index 0000000..1b81c10 --- /dev/null +++ b/Other Projects/Jike/SwiftUI_Jike/Info.plist @@ -0,0 +1,64 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleDisplayName + 即刻 + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + $(PRODUCT_BUNDLE_PACKAGE_TYPE) + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UIApplicationSceneManifest + + UIApplicationSupportsMultipleScenes + + UISceneConfigurations + + UIWindowSceneSessionRoleApplication + + + UILaunchStoryboardName + LaunchScreen + UISceneConfigurationName + Default Configuration + UISceneDelegateClassName + $(PRODUCT_MODULE_NAME).SceneDelegate + + + + + UILaunchStoryboardName + LaunchScreen + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/Other Projects/Jike/SwiftUI_Jike/Models/Datas.swift b/Other Projects/Jike/SwiftUI_Jike/Models/Datas.swift new file mode 100644 index 0000000..6b9722b --- /dev/null +++ b/Other Projects/Jike/SwiftUI_Jike/Models/Datas.swift @@ -0,0 +1,26 @@ +// +// Datas.swift +// SwiftUI_Jike +// +// Created by alexyang on 2019/6/5. +// Copyright © 2019 alexyang. All rights reserved. +// + +import SwiftUI + +let tabItems: [TabBarItem] = getTabItems() + +func getTabItems() -> [TabBarItem] { + + var items = [TabBarItem]() + let item0 = TabBarItem(id: 0, title: "首页", image: "tab_home_normal", imageSelect: "tab_home_select") + items.append(item0) + let item1 = TabBarItem(id: 1, title: "动态", image: "tab_status_normal", imageSelect: "tab_status_select") + items.append(item1) + let item2 = TabBarItem(id: 2, title: "聊天", image: "tab_chat_normal", imageSelect: "tab_chat_select") + items.append(item2) + let item3 = TabBarItem(id: 3, title: "我的", image: "tab_me_normal", imageSelect: "tab_me_select") + items.append(item3) + + return items +} diff --git a/Other Projects/Jike/SwiftUI_Jike/Models/TabBarItem.swift b/Other Projects/Jike/SwiftUI_Jike/Models/TabBarItem.swift new file mode 100644 index 0000000..4fc7ada --- /dev/null +++ b/Other Projects/Jike/SwiftUI_Jike/Models/TabBarItem.swift @@ -0,0 +1,16 @@ +// +// TabBarModel.swift +// SwiftUI_Jike +// +// Created by alexyang on 2019/6/6. +// Copyright © 2019 alexyang. All rights reserved. +// + +import SwiftUI + +struct TabBarItem: Hashable, Codable, Identifiable { + var id: Int + var title: String + var image: String + var imageSelect: String +} diff --git a/Other Projects/Jike/SwiftUI_Jike/Models/TabIconInfo.swift b/Other Projects/Jike/SwiftUI_Jike/Models/TabIconInfo.swift new file mode 100644 index 0000000..701e153 --- /dev/null +++ b/Other Projects/Jike/SwiftUI_Jike/Models/TabIconInfo.swift @@ -0,0 +1,16 @@ +// +// TabIconInfo.swift +// SwiftUI_Jike +// +// Created by alexyang on 2019/6/5. +// Copyright © 2019 alexyang. All rights reserved. +// + +import SwiftUI + +struct TabIcon: Hashable, Codable, Identifiable { + var id: Int + var title: String + var imgName: String +} + diff --git a/Other Projects/Jike/SwiftUI_Jike/Models/ZoneModel.swift b/Other Projects/Jike/SwiftUI_Jike/Models/ZoneModel.swift new file mode 100644 index 0000000..19cd422 --- /dev/null +++ b/Other Projects/Jike/SwiftUI_Jike/Models/ZoneModel.swift @@ -0,0 +1,19 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +The model for an individual landmark. +*/ + +import SwiftUI + +struct ZoneModel: Hashable, Codable, Identifiable { + var id: Int + var name: String + var imageName: String + var category: String + + func image(forSize size: Int) -> Image { + ImageStore.shared.image(name: imageName, size: size) + } +} diff --git a/Other Projects/Jike/SwiftUI_Jike/Preview Content/Preview Assets.xcassets/Contents.json b/Other Projects/Jike/SwiftUI_Jike/Preview Content/Preview Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/Other Projects/Jike/SwiftUI_Jike/Preview Content/Preview Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/Jike/SwiftUI_Jike/Res/30_Fotor.jpg b/Other Projects/Jike/SwiftUI_Jike/Res/30_Fotor.jpg new file mode 100644 index 0000000..cacc110 Binary files /dev/null and b/Other Projects/Jike/SwiftUI_Jike/Res/30_Fotor.jpg differ diff --git a/Other Projects/Jike/SwiftUI_Jike/Res/aihao.jpg b/Other Projects/Jike/SwiftUI_Jike/Res/aihao.jpg new file mode 100644 index 0000000..115ed42 Binary files /dev/null and b/Other Projects/Jike/SwiftUI_Jike/Res/aihao.jpg differ diff --git a/Other Projects/Jike/SwiftUI_Jike/Res/faxian.jpg b/Other Projects/Jike/SwiftUI_Jike/Res/faxian.jpg new file mode 100644 index 0000000..b09417e Binary files /dev/null and b/Other Projects/Jike/SwiftUI_Jike/Res/faxian.jpg differ diff --git a/Other Projects/Jike/SwiftUI_Jike/Res/jianzhu.jpg b/Other Projects/Jike/SwiftUI_Jike/Res/jianzhu.jpg new file mode 100644 index 0000000..aa75d7f Binary files /dev/null and b/Other Projects/Jike/SwiftUI_Jike/Res/jianzhu.jpg differ diff --git a/Other Projects/Jike/SwiftUI_Jike/Res/kcc.jpg b/Other Projects/Jike/SwiftUI_Jike/Res/kcc.jpg new file mode 100644 index 0000000..22c2b48 Binary files /dev/null and b/Other Projects/Jike/SwiftUI_Jike/Res/kcc.jpg differ diff --git a/Other Projects/Jike/SwiftUI_Jike/Res/keji.jpg b/Other Projects/Jike/SwiftUI_Jike/Res/keji.jpg new file mode 100644 index 0000000..5dc24c8 Binary files /dev/null and b/Other Projects/Jike/SwiftUI_Jike/Res/keji.jpg differ diff --git a/Other Projects/Jike/SwiftUI_Jike/Res/miao.jpg b/Other Projects/Jike/SwiftUI_Jike/Res/miao.jpg new file mode 100644 index 0000000..4552e7b Binary files /dev/null and b/Other Projects/Jike/SwiftUI_Jike/Res/miao.jpg differ diff --git a/Other Projects/Jike/SwiftUI_Jike/Res/shadiao.jpg b/Other Projects/Jike/SwiftUI_Jike/Res/shadiao.jpg new file mode 100644 index 0000000..091eccc Binary files /dev/null and b/Other Projects/Jike/SwiftUI_Jike/Res/shadiao.jpg differ diff --git a/Other Projects/Jike/SwiftUI_Jike/Res/sheying.jpg b/Other Projects/Jike/SwiftUI_Jike/Res/sheying.jpg new file mode 100644 index 0000000..0a035e4 Binary files /dev/null and b/Other Projects/Jike/SwiftUI_Jike/Res/sheying.jpg differ diff --git a/Other Projects/Jike/SwiftUI_Jike/Res/test.jpg b/Other Projects/Jike/SwiftUI_Jike/Res/test.jpg new file mode 100644 index 0000000..5132503 Binary files /dev/null and b/Other Projects/Jike/SwiftUI_Jike/Res/test.jpg differ diff --git a/Other Projects/Jike/SwiftUI_Jike/Res/test1.jpg b/Other Projects/Jike/SwiftUI_Jike/Res/test1.jpg new file mode 100644 index 0000000..4e91545 Binary files /dev/null and b/Other Projects/Jike/SwiftUI_Jike/Res/test1.jpg differ diff --git a/Other Projects/Jike/SwiftUI_Jike/Res/zoneData.json b/Other Projects/Jike/SwiftUI_Jike/Res/zoneData.json new file mode 100644 index 0000000..b0448e6 --- /dev/null +++ b/Other Projects/Jike/SwiftUI_Jike/Res/zoneData.json @@ -0,0 +1,38 @@ +[ + { + "name": "发现圈子", + "category": "233", + "id": 1001, + "imgName": "test1" + }, + { + "name": "喵星人的日常", + "category": "233", + "id": 1002, + "imgName": "test1" + }, + { + "name": "沙雕动物世界", + "category": "233", + "id": 1003, + "imgName": "test1" + }, + { + "name": "科技圈大小事", + "category": "233", + "id": 1004, + "imgName": "test1" + }, + { + "name": "今日份摄影", + "category": "333", + "id": 1005, + "imgName": "test1" + }, + { + "name": "一起拍建筑", + "category": "333", + "id": 1006, + "imgName": "test1" + } +] diff --git a/Other Projects/Jike/SwiftUI_Jike/SceneDelegate.swift b/Other Projects/Jike/SwiftUI_Jike/SceneDelegate.swift new file mode 100644 index 0000000..ba17391 --- /dev/null +++ b/Other Projects/Jike/SwiftUI_Jike/SceneDelegate.swift @@ -0,0 +1,61 @@ +// +// SceneDelegate.swift +// SwiftUI_Jike +// +// Created by alexyang on 2019/6/5. +// Copyright © 2019 alexyang. All rights reserved. +// + +import UIKit +import SwiftUI + +class SceneDelegate: UIResponder, UIWindowSceneDelegate { + + var window: UIWindow? + + + func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { + // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`. + // If using a storyboard, the `window` property will automatically be initialized and attached to the scene. + // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead). + + // Use a UIHostingController as window root view controller + if let windowScene = scene as? UIWindowScene { + let window = UIWindow(windowScene: windowScene) + window.rootViewController = UIHostingController(rootView: ContentView()) + self.window = window + window.makeKeyAndVisible() + } + } + + func sceneDidDisconnect(_ scene: UIScene) { + // Called as the scene is being released by the system. + // This occurs shortly after the scene enters the background, or when its session is discarded. + // Release any resources associated with this scene that can be re-created the next time the scene connects. + // The scene may re-connect later, as its session was not neccessarily discarded (see `application:didDiscardSceneSessions` instead). + } + + func sceneDidBecomeActive(_ scene: UIScene) { + // Called when the scene has moved from an inactive state to an active state. + // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive. + } + + func sceneWillResignActive(_ scene: UIScene) { + // Called when the scene will move from an active state to an inactive state. + // This may occur due to temporary interruptions (ex. an incoming phone call). + } + + func sceneWillEnterForeground(_ scene: UIScene) { + // Called as the scene transitions from the background to the foreground. + // Use this method to undo the changes made on entering the background. + } + + func sceneDidEnterBackground(_ scene: UIScene) { + // Called as the scene transitions from the foreground to the background. + // Use this method to save data, release shared resources, and store enough scene-specific state information + // to restore the scene back to its current state. + } + + +} + diff --git a/Other Projects/Jike/SwiftUI_Jike/SegmentViewController.swift b/Other Projects/Jike/SwiftUI_Jike/SegmentViewController.swift new file mode 100644 index 0000000..9c6555e --- /dev/null +++ b/Other Projects/Jike/SwiftUI_Jike/SegmentViewController.swift @@ -0,0 +1,27 @@ +// +// SegmentViewController.swift +// SwiftUI_Jike +// +// Created by alexyang on 2019/6/6. +// Copyright © 2019 alexyang. All rights reserved. +// + +import UIKit +import SwiftUI + +struct SegmentViewController : UIViewControllerRepresentable { + var controllers: [UIViewController] + func makeUIViewController(context: Context) -> UIPageViewController { + let pageViewController = UIPageViewController( + transitionStyle: .scroll, + navigationOrientation: .horizontal) + + return pageViewController + } + + func updateUIViewController(_ pageViewController: UIPageViewController, context: Context) { + pageViewController.setViewControllers( + [controllers[0]], direction: .forward, animated: true) + } + +} diff --git a/Other Projects/Jike/SwiftUI_Jike/SettingView.swift b/Other Projects/Jike/SwiftUI_Jike/SettingView.swift new file mode 100644 index 0000000..7bd4311 --- /dev/null +++ b/Other Projects/Jike/SwiftUI_Jike/SettingView.swift @@ -0,0 +1,85 @@ +// +// SettingView.swift +// SwiftUI_Jike +// +// Created by alexyang on 2019/6/5. +// Copyright © 2019 alexyang. All rights reserved. +// + +import SwiftUI + +struct SettingView : View { + var body: some View { + VStack{ + VStack{ + Color(red: 1.0, green: 228.0/255.0, blue: 20.0/255) + } + .frame(height: 50) + .edgesIgnoringSafeArea(.top) + VStack{ + HStack{ + Spacer() + Image("setting_icon") + .padding(.horizontal, 15) + .padding(.vertical, 15) + } + Spacer() + } + .frame(height: 100) + .background(Color(red: 1.0, green: 228.0/255.0, blue: 20.0/255) + ) + .padding(.top, -70) + + VStack{ + HStack(alignment: .center){ + CircleImage(imgName:"meIcon") + .padding(.horizontal, 15) + VStack(alignment: .leading){ + Text("瓦恁") + HStack{ + Image("touxiang") + Text("99999") + } + } + .padding(.horizontal, -10) + Spacer() + } + .frame(height: 100) + .background(Color.white + .cornerRadius(10, antialiased: true)) + .shadow(radius: 5) + .padding(.horizontal, 15) + .padding(.vertical, 5) + + Group() { + SettingCell(imageName: "setting_quanzi", title: "我的圈子") + SettingCell(imageName: "setting_shoucang", title: "我的收藏") + SettingCell(imageName: "setting_tongzhi", title: "我的通知") + SettingCell(imageName: "setting_feedback", title: "帮助与反馈") + HStack{ + Color(red: 240.0/255.0, green: 243.0/255.0, blue: 245.0/255) + } + .frame(height: 3.0) + SettingCell(imageName: "setting_mainliuliang", title: "免流量") + SettingCell(imageName: "setting_hehuoren", title: "即刻合伙人") + } + .background(Color.white) + .padding(.bottom, -7) + Spacer() + } + .padding(.top, -60) + } + //.edgesIgnoringSafeArea(.top) + .background(Color(red: 240.0/255.0, green: 243.0/255.0, blue: 245.0/255)) + } + + +} + +#if DEBUG +struct SettingView_Previews : PreviewProvider { + static var previews: some View { + SettingView() + } +} +#endif diff --git a/Other Projects/Jike/SwiftUI_Jike/Tools/UITool.swift b/Other Projects/Jike/SwiftUI_Jike/Tools/UITool.swift new file mode 100644 index 0000000..4330c02 --- /dev/null +++ b/Other Projects/Jike/SwiftUI_Jike/Tools/UITool.swift @@ -0,0 +1,113 @@ +// +// UITool.swift +// SwiftUI_Jike +// +// Created by alexyang on 2019/6/5. +// Copyright © 2019 alexyang. All rights reserved. +// +import UIKit +import SwiftUI + +let zoneData: [ZoneModel] = load("zoneData.json") +let zonnData: [ZoneModel] = getZoneModel() + +func getZoneModel() -> [ZoneModel] { + + let model = ZoneModel(id: 1000, name: "发现圈子", imageName: "faxian", category: "233") + let model0 = ZoneModel(id: 1001, name: "苹果产品爱好者", imageName: "aihao", category: "233") + let model1 = ZoneModel(id: 1002, name: "喵星人的日常", imageName: "miao", category: "233") + let model2 = ZoneModel(id: 1003, name: "沙雕动物世界", imageName: "shadiao", category: "233") + let model3 = ZoneModel(id: 1004, name: "科技圈大小事", imageName: "keji", category: "233") + let model4 = ZoneModel(id: 1004, name: "今日份摄影", imageName: "sheying", category: "233") + let model5 = ZoneModel(id: 1004, name: "一起拍建筑", imageName: "jianzhu", category: "233") + var models = [ZoneModel]() + models.append(model) + models.append(model0) + models.append(model1) + models.append(model2) + models.append(model3) + models.append(model4) + models.append(model5) + + return models +} + +func load(_ filename: String, as type: T.Type = T.self) -> T { + let data: Data + + guard let file = Bundle.main.url(forResource: filename, withExtension: nil) + else { + fatalError("Couldn't find \(filename) in main bundle.") + } + + do { + data = try Data(contentsOf: file) + } catch { + fatalError("Couldn't load \(filename) from main bundle:\n\(error)") + } + + do { + let decoder = JSONDecoder() + return try decoder.decode(T.self, from: data) + } catch { + fatalError("Couldn't parse \(filename) as \(T.self):\n\(error)") + } +} + +final class ImageStore { + fileprivate typealias _ImageDictionary = [String: [Int: CGImage]] + fileprivate var images: _ImageDictionary = [:] + + fileprivate static var originalSize = 250 + fileprivate static var scale = 2 + + static var shared = ImageStore() + + func image(name: String, size: Int) -> Image { + let index = _guaranteeInitialImage(name: name) + + let sizedImage = images.values[index][size] + ?? _sizeImage(images.values[index][ImageStore.originalSize]!, to: size * ImageStore.scale) + images.values[index][size] = sizedImage + + return Image(sizedImage, scale: CGFloat(ImageStore.scale), label: Text(verbatim: name)) + } + + fileprivate func _guaranteeInitialImage(name: String) -> _ImageDictionary.Index { + if let index = images.index(forKey: name) { return index } + + guard + let url = Bundle.main.url(forResource: name, withExtension: "jpg"), + let imageSource = CGImageSourceCreateWithURL(url as NSURL, nil), + let image = CGImageSourceCreateImageAtIndex(imageSource, 0, nil) + else { + fatalError("Couldn't load image \(name).jpg from main bundle.") + } + + images[name] = [ImageStore.originalSize: image] + return images.index(forKey: name)! + } + + fileprivate func _sizeImage(_ image: CGImage, to size: Int) -> CGImage { + guard + let colorSpace = image.colorSpace, + let context = CGContext( + data: nil, + width: size, height: size, + bitsPerComponent: image.bitsPerComponent, + bytesPerRow: image.bytesPerRow, + space: colorSpace, + bitmapInfo: image.bitmapInfo.rawValue) + else { + fatalError("Couldn't create graphics context.") + } + context.interpolationQuality = .high + context.draw(image, in: CGRect(x: 0, y: 0, width: size, height: size)) + + if let sizedImage = context.makeImage() { + return sizedImage + } else { + fatalError("Couldn't resize image.") + } + } +} diff --git a/Other Projects/Movie/MovieSwift/MovieSwift.xcodeproj/project.pbxproj b/Other Projects/Movie/MovieSwift/MovieSwift.xcodeproj/project.pbxproj new file mode 100644 index 0000000..bec96c4 --- /dev/null +++ b/Other Projects/Movie/MovieSwift/MovieSwift.xcodeproj/project.pbxproj @@ -0,0 +1,451 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 50; + objects = { + +/* Begin PBXBuildFile section */ + 69FFAF8022A99F1100801F3C /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 69FFAF7F22A99F1100801F3C /* AppDelegate.swift */; }; + 69FFAF8222A99F1100801F3C /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 69FFAF8122A99F1100801F3C /* SceneDelegate.swift */; }; + 69FFAF8422A99F1100801F3C /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 69FFAF8322A99F1100801F3C /* ContentView.swift */; }; + 69FFAF8622A99F1200801F3C /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 69FFAF8522A99F1200801F3C /* Assets.xcassets */; }; + 69FFAF8922A99F1200801F3C /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 69FFAF8822A99F1200801F3C /* Preview Assets.xcassets */; }; + 69FFAF8C22A99F1200801F3C /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 69FFAF8A22A99F1200801F3C /* LaunchScreen.storyboard */; }; + 69FFAF9822A9A12800801F3C /* APIService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 69FFAF9722A9A12800801F3C /* APIService.swift */; }; + 69FFAF9B22A9A66200801F3C /* Movie.swift in Sources */ = {isa = PBXBuildFile; fileRef = 69FFAF9A22A9A66200801F3C /* Movie.swift */; }; + 69FFAF9D22A9A6D500801F3C /* PaginatedResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = 69FFAF9C22A9A6D500801F3C /* PaginatedResponse.swift */; }; + 69FFAFA122A9A9F600801F3C /* Reducer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 69FFAFA022A9A9F600801F3C /* Reducer.swift */; }; + 69FFAFA422A9AA2600801F3C /* Action.swift in Sources */ = {isa = PBXBuildFile; fileRef = 69FFAFA322A9AA2600801F3C /* Action.swift */; }; + 69FFAFA622A9AA3500801F3C /* FluxState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 69FFAFA522A9AA3500801F3C /* FluxState.swift */; }; + 69FFAFA822A9AA4900801F3C /* AppState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 69FFAFA722A9AA4900801F3C /* AppState.swift */; }; + 69FFAFAA22A9AA6500801F3C /* MoviesState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 69FFAFA922A9AA6500801F3C /* MoviesState.swift */; }; + 69FFAFAC22A9AABB00801F3C /* MoviesStateReducer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 69FFAFAB22A9AABB00801F3C /* MoviesStateReducer.swift */; }; + 69FFAFAE22A9AB1D00801F3C /* MoviesAction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 69FFAFAD22A9AB1D00801F3C /* MoviesAction.swift */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 69FFAF7C22A99F1100801F3C /* MovieSwift.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MovieSwift.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 69FFAF7F22A99F1100801F3C /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 69FFAF8122A99F1100801F3C /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; + 69FFAF8322A99F1100801F3C /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; }; + 69FFAF8522A99F1200801F3C /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 69FFAF8822A99F1200801F3C /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; + 69FFAF8B22A99F1200801F3C /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 69FFAF8D22A99F1200801F3C /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 69FFAF9722A9A12800801F3C /* APIService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = APIService.swift; sourceTree = ""; }; + 69FFAF9A22A9A66200801F3C /* Movie.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Movie.swift; sourceTree = ""; }; + 69FFAF9C22A9A6D500801F3C /* PaginatedResponse.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PaginatedResponse.swift; sourceTree = ""; }; + 69FFAFA022A9A9F600801F3C /* Reducer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Reducer.swift; sourceTree = ""; }; + 69FFAFA322A9AA2600801F3C /* Action.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Action.swift; sourceTree = ""; }; + 69FFAFA522A9AA3500801F3C /* FluxState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FluxState.swift; sourceTree = ""; }; + 69FFAFA722A9AA4900801F3C /* AppState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppState.swift; sourceTree = ""; }; + 69FFAFA922A9AA6500801F3C /* MoviesState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MoviesState.swift; sourceTree = ""; }; + 69FFAFAB22A9AABB00801F3C /* MoviesStateReducer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MoviesStateReducer.swift; sourceTree = ""; }; + 69FFAFAD22A9AB1D00801F3C /* MoviesAction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MoviesAction.swift; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 69FFAF7922A99F1100801F3C /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 69FFAF7322A99F1100801F3C = { + isa = PBXGroup; + children = ( + 69FFAF7E22A99F1100801F3C /* MovieSwift */, + 69FFAF7D22A99F1100801F3C /* Products */, + ); + sourceTree = ""; + }; + 69FFAF7D22A99F1100801F3C /* Products */ = { + isa = PBXGroup; + children = ( + 69FFAF7C22A99F1100801F3C /* MovieSwift.app */, + ); + name = Products; + sourceTree = ""; + }; + 69FFAF7E22A99F1100801F3C /* MovieSwift */ = { + isa = PBXGroup; + children = ( + 69FFAF9322A9A0D800801F3C /* launch */, + 69FFAF9522A9A0E300801F3C /* flux */, + 69FFAF9622A9A11A00801F3C /* services */, + 69FFAF9422A9A0DF00801F3C /* views */, + 69FFAF8522A99F1200801F3C /* Assets.xcassets */, + 69FFAF8A22A99F1200801F3C /* LaunchScreen.storyboard */, + 69FFAF8D22A99F1200801F3C /* Info.plist */, + 69FFAF8722A99F1200801F3C /* Preview Content */, + ); + path = MovieSwift; + sourceTree = ""; + }; + 69FFAF8722A99F1200801F3C /* Preview Content */ = { + isa = PBXGroup; + children = ( + 69FFAF8822A99F1200801F3C /* Preview Assets.xcassets */, + ); + path = "Preview Content"; + sourceTree = ""; + }; + 69FFAF9322A9A0D800801F3C /* launch */ = { + isa = PBXGroup; + children = ( + 69FFAF7F22A99F1100801F3C /* AppDelegate.swift */, + 69FFAF8122A99F1100801F3C /* SceneDelegate.swift */, + ); + path = launch; + sourceTree = ""; + }; + 69FFAF9422A9A0DF00801F3C /* views */ = { + isa = PBXGroup; + children = ( + 69FFAF8322A99F1100801F3C /* ContentView.swift */, + ); + path = views; + sourceTree = ""; + }; + 69FFAF9522A9A0E300801F3C /* flux */ = { + isa = PBXGroup; + children = ( + 69FFAFA222A9AA1E00801F3C /* actions */, + 69FFAF9F22A9A9E600801F3C /* reducers */, + 69FFAF9E22A9A9D400801F3C /* state */, + 69FFAF9922A9A1AE00801F3C /* models */, + ); + path = flux; + sourceTree = ""; + }; + 69FFAF9622A9A11A00801F3C /* services */ = { + isa = PBXGroup; + children = ( + 69FFAF9722A9A12800801F3C /* APIService.swift */, + ); + path = services; + sourceTree = ""; + }; + 69FFAF9922A9A1AE00801F3C /* models */ = { + isa = PBXGroup; + children = ( + 69FFAF9A22A9A66200801F3C /* Movie.swift */, + 69FFAF9C22A9A6D500801F3C /* PaginatedResponse.swift */, + ); + path = models; + sourceTree = ""; + }; + 69FFAF9E22A9A9D400801F3C /* state */ = { + isa = PBXGroup; + children = ( + 69FFAFA522A9AA3500801F3C /* FluxState.swift */, + 69FFAFA722A9AA4900801F3C /* AppState.swift */, + 69FFAFA922A9AA6500801F3C /* MoviesState.swift */, + ); + path = state; + sourceTree = ""; + }; + 69FFAF9F22A9A9E600801F3C /* reducers */ = { + isa = PBXGroup; + children = ( + 69FFAFA022A9A9F600801F3C /* Reducer.swift */, + 69FFAFAB22A9AABB00801F3C /* MoviesStateReducer.swift */, + ); + path = reducers; + sourceTree = ""; + }; + 69FFAFA222A9AA1E00801F3C /* actions */ = { + isa = PBXGroup; + children = ( + 69FFAFA322A9AA2600801F3C /* Action.swift */, + 69FFAFAD22A9AB1D00801F3C /* MoviesAction.swift */, + ); + path = actions; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 69FFAF7B22A99F1100801F3C /* MovieSwift */ = { + isa = PBXNativeTarget; + buildConfigurationList = 69FFAF9022A99F1200801F3C /* Build configuration list for PBXNativeTarget "MovieSwift" */; + buildPhases = ( + 69FFAF7822A99F1100801F3C /* Sources */, + 69FFAF7922A99F1100801F3C /* Frameworks */, + 69FFAF7A22A99F1100801F3C /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = MovieSwift; + productName = MovieSwift; + productReference = 69FFAF7C22A99F1100801F3C /* MovieSwift.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 69FFAF7422A99F1100801F3C /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 1100; + LastUpgradeCheck = 1100; + ORGANIZATIONNAME = "Thomas Ricouard"; + TargetAttributes = { + 69FFAF7B22A99F1100801F3C = { + CreatedOnToolsVersion = 11.0; + }; + }; + }; + buildConfigurationList = 69FFAF7722A99F1100801F3C /* Build configuration list for PBXProject "MovieSwift" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 69FFAF7322A99F1100801F3C; + productRefGroup = 69FFAF7D22A99F1100801F3C /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 69FFAF7B22A99F1100801F3C /* MovieSwift */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 69FFAF7A22A99F1100801F3C /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 69FFAF8C22A99F1200801F3C /* LaunchScreen.storyboard in Resources */, + 69FFAF8922A99F1200801F3C /* Preview Assets.xcassets in Resources */, + 69FFAF8622A99F1200801F3C /* Assets.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 69FFAF7822A99F1100801F3C /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 69FFAF8022A99F1100801F3C /* AppDelegate.swift in Sources */, + 69FFAFA822A9AA4900801F3C /* AppState.swift in Sources */, + 69FFAF8222A99F1100801F3C /* SceneDelegate.swift in Sources */, + 69FFAF9D22A9A6D500801F3C /* PaginatedResponse.swift in Sources */, + 69FFAF9822A9A12800801F3C /* APIService.swift in Sources */, + 69FFAFA122A9A9F600801F3C /* Reducer.swift in Sources */, + 69FFAFA422A9AA2600801F3C /* Action.swift in Sources */, + 69FFAF8422A99F1100801F3C /* ContentView.swift in Sources */, + 69FFAFA622A9AA3500801F3C /* FluxState.swift in Sources */, + 69FFAFAC22A9AABB00801F3C /* MoviesStateReducer.swift in Sources */, + 69FFAFAA22A9AA6500801F3C /* MoviesState.swift in Sources */, + 69FFAF9B22A9A66200801F3C /* Movie.swift in Sources */, + 69FFAFAE22A9AB1D00801F3C /* MoviesAction.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 69FFAF8A22A99F1200801F3C /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 69FFAF8B22A99F1200801F3C /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 69FFAF8E22A99F1200801F3C /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + 69FFAF8F22A99F1200801F3C /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 69FFAF9122A99F1200801F3C /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_ASSET_PATHS = "MovieSwift/Preview\\ Content"; + DEVELOPMENT_TEAM = Z6P74P6T99; + ENABLE_PREVIEWS = YES; + INFOPLIST_FILE = MovieSwift/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.thomasricouard.MovieSwift; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 69FFAF9222A99F1200801F3C /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_ASSET_PATHS = "MovieSwift/Preview\\ Content"; + DEVELOPMENT_TEAM = Z6P74P6T99; + ENABLE_PREVIEWS = YES; + INFOPLIST_FILE = MovieSwift/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.thomasricouard.MovieSwift; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 69FFAF7722A99F1100801F3C /* Build configuration list for PBXProject "MovieSwift" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 69FFAF8E22A99F1200801F3C /* Debug */, + 69FFAF8F22A99F1200801F3C /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 69FFAF9022A99F1200801F3C /* Build configuration list for PBXNativeTarget "MovieSwift" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 69FFAF9122A99F1200801F3C /* Debug */, + 69FFAF9222A99F1200801F3C /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 69FFAF7422A99F1100801F3C /* Project object */; +} diff --git a/Other Projects/Movie/MovieSwift/MovieSwift.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/Other Projects/Movie/MovieSwift/MovieSwift.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..d9c7017 --- /dev/null +++ b/Other Projects/Movie/MovieSwift/MovieSwift.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/Other Projects/Movie/MovieSwift/MovieSwift.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/Other Projects/Movie/MovieSwift/MovieSwift.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/Other Projects/Movie/MovieSwift/MovieSwift.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/Other Projects/Movie/MovieSwift/MovieSwift/Assets.xcassets/AppIcon.appiconset/Contents.json b/Other Projects/Movie/MovieSwift/MovieSwift/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..d8db8d6 --- /dev/null +++ b/Other Projects/Movie/MovieSwift/MovieSwift/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,98 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "83.5x83.5", + "scale" : "2x" + }, + { + "idiom" : "ios-marketing", + "size" : "1024x1024", + "scale" : "1x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/Movie/MovieSwift/MovieSwift/Assets.xcassets/Contents.json b/Other Projects/Movie/MovieSwift/MovieSwift/Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/Other Projects/Movie/MovieSwift/MovieSwift/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/Movie/MovieSwift/MovieSwift/Base.lproj/LaunchScreen.storyboard b/Other Projects/Movie/MovieSwift/MovieSwift/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000..865e932 --- /dev/null +++ b/Other Projects/Movie/MovieSwift/MovieSwift/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Other Projects/Movie/MovieSwift/MovieSwift/Info.plist b/Other Projects/Movie/MovieSwift/MovieSwift/Info.plist new file mode 100644 index 0000000..e8bb4c6 --- /dev/null +++ b/Other Projects/Movie/MovieSwift/MovieSwift/Info.plist @@ -0,0 +1,62 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + $(PRODUCT_BUNDLE_PACKAGE_TYPE) + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UIApplicationSceneManifest + + UIApplicationSupportsMultipleScenes + + UISceneConfigurations + + UIWindowSceneSessionRoleApplication + + + UILaunchStoryboardName + LaunchScreen + UISceneConfigurationName + Default Configuration + UISceneDelegateClassName + $(PRODUCT_MODULE_NAME).SceneDelegate + + + + + UILaunchStoryboardName + LaunchScreen + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/Other Projects/Movie/MovieSwift/MovieSwift/Preview Content/Preview Assets.xcassets/Contents.json b/Other Projects/Movie/MovieSwift/MovieSwift/Preview Content/Preview Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/Other Projects/Movie/MovieSwift/MovieSwift/Preview Content/Preview Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/Movie/MovieSwift/MovieSwift/flux/actions/Action.swift b/Other Projects/Movie/MovieSwift/MovieSwift/flux/actions/Action.swift new file mode 100644 index 0000000..85d8c53 --- /dev/null +++ b/Other Projects/Movie/MovieSwift/MovieSwift/flux/actions/Action.swift @@ -0,0 +1,13 @@ +// +// Action.swift +// MovieSwift +// +// Created by Thomas Ricouard on 06/06/2019. +// Copyright © 2019 Thomas Ricouard. All rights reserved. +// + +import Foundation + +protocol Action { + +} diff --git a/Other Projects/Movie/MovieSwift/MovieSwift/flux/actions/MoviesAction.swift b/Other Projects/Movie/MovieSwift/MovieSwift/flux/actions/MoviesAction.swift new file mode 100644 index 0000000..c831f1b --- /dev/null +++ b/Other Projects/Movie/MovieSwift/MovieSwift/flux/actions/MoviesAction.swift @@ -0,0 +1,29 @@ +// +// MoviesAction.swift +// MovieSwift +// +// Created by Thomas Ricouard on 06/06/2019. +// Copyright © 2019 Thomas Ricouard. All rights reserved. +// + +import Foundation + +struct MoviesActions { + struct FetchPopular: Action { + init() { + APIService.shared.GET(endpoint: .popular, params: nil) { + (result: Result, APIService.APIError>) in + switch result { + case let .success(response): + store.dispatch(action: SetPopular(response: response)) + case .failure(_): + break + } + } + } + } + + struct SetPopular: Action { + let response: PaginatedResponse + } +} diff --git a/Other Projects/Movie/MovieSwift/MovieSwift/flux/models/Movie.swift b/Other Projects/Movie/MovieSwift/MovieSwift/flux/models/Movie.swift new file mode 100644 index 0000000..2ced65c --- /dev/null +++ b/Other Projects/Movie/MovieSwift/MovieSwift/flux/models/Movie.swift @@ -0,0 +1,14 @@ +// +// Movie.swift +// MovieSwift +// +// Created by Thomas Ricouard on 06/06/2019. +// Copyright © 2019 Thomas Ricouard. All rights reserved. +// + +import Foundation + +struct Movie: Codable { + let id: Int + let original_title: String +} diff --git a/Other Projects/Movie/MovieSwift/MovieSwift/flux/models/PaginatedResponse.swift b/Other Projects/Movie/MovieSwift/MovieSwift/flux/models/PaginatedResponse.swift new file mode 100644 index 0000000..1908815 --- /dev/null +++ b/Other Projects/Movie/MovieSwift/MovieSwift/flux/models/PaginatedResponse.swift @@ -0,0 +1,16 @@ +// +// PaginatedResponse.swift +// MovieSwift +// +// Created by Thomas Ricouard on 06/06/2019. +// Copyright © 2019 Thomas Ricouard. All rights reserved. +// + +import Foundation + +struct PaginatedResponse: Codable { + let page: Int + let total_results: Int + let total_pages: Int + let results: [T] +} diff --git a/Other Projects/Movie/MovieSwift/MovieSwift/flux/reducers/MoviesStateReducer.swift b/Other Projects/Movie/MovieSwift/MovieSwift/flux/reducers/MoviesStateReducer.swift new file mode 100644 index 0000000..0eef827 --- /dev/null +++ b/Other Projects/Movie/MovieSwift/MovieSwift/flux/reducers/MoviesStateReducer.swift @@ -0,0 +1,22 @@ +// +// MoviesStateReducer.swift +// MovieSwift +// +// Created by Thomas Ricouard on 06/06/2019. +// Copyright © 2019 Thomas Ricouard. All rights reserved. +// + +import Foundation + +struct MoviesStateReducer: Reducer { + func reduce(state: MoviesState, action: Action) -> MoviesState { + var state = state + if let action = action as? MoviesActions.SetPopular { + state.popular = action.response.results.map{ $0.id } + for (_, value) in action.response.results.enumerated() { + state.movies[value.id] = value + } + } + return state + } +} diff --git a/Other Projects/Movie/MovieSwift/MovieSwift/flux/reducers/Reducer.swift b/Other Projects/Movie/MovieSwift/MovieSwift/flux/reducers/Reducer.swift new file mode 100644 index 0000000..cdf6ca1 --- /dev/null +++ b/Other Projects/Movie/MovieSwift/MovieSwift/flux/reducers/Reducer.swift @@ -0,0 +1,14 @@ +// +// Reducer.swift +// MovieSwift +// +// Created by Thomas Ricouard on 06/06/2019. +// Copyright © 2019 Thomas Ricouard. All rights reserved. +// + +import Foundation + +protocol Reducer { + associatedtype StateType: FluxState + func reduce(state: StateType, action: Action) -> StateType +} diff --git a/Other Projects/Movie/MovieSwift/MovieSwift/flux/state/AppState.swift b/Other Projects/Movie/MovieSwift/MovieSwift/flux/state/AppState.swift new file mode 100644 index 0000000..9322ffa --- /dev/null +++ b/Other Projects/Movie/MovieSwift/MovieSwift/flux/state/AppState.swift @@ -0,0 +1,30 @@ +// +// AppState.swift +// MovieSwift +// +// Created by Thomas Ricouard on 06/06/2019. +// Copyright © 2019 Thomas Ricouard. All rights reserved. +// + +import Foundation +import SwiftUI +import Combine + +final class AppState: ObservableObject { + var objectWillChange = PassthroughSubject() + + var moviesState: MoviesState + + init(moviesState: MoviesState = MoviesState()) { + self.moviesState = moviesState + } + + func dispatch(action: Action) { + moviesState = MoviesStateReducer().reduce(state: moviesState, action: action) + DispatchQueue.main.async { + self.objectWillChange.send(self) + } + } +} + +let store = AppState() diff --git a/Other Projects/Movie/MovieSwift/MovieSwift/flux/state/FluxState.swift b/Other Projects/Movie/MovieSwift/MovieSwift/flux/state/FluxState.swift new file mode 100644 index 0000000..08d1d6b --- /dev/null +++ b/Other Projects/Movie/MovieSwift/MovieSwift/flux/state/FluxState.swift @@ -0,0 +1,13 @@ +// +// FluxState.swift +// MovieSwift +// +// Created by Thomas Ricouard on 06/06/2019. +// Copyright © 2019 Thomas Ricouard. All rights reserved. +// + +import Foundation + +protocol FluxState { + +} diff --git a/Other Projects/Movie/MovieSwift/MovieSwift/flux/state/MoviesState.swift b/Other Projects/Movie/MovieSwift/MovieSwift/flux/state/MoviesState.swift new file mode 100644 index 0000000..8cbbdb9 --- /dev/null +++ b/Other Projects/Movie/MovieSwift/MovieSwift/flux/state/MoviesState.swift @@ -0,0 +1,14 @@ +// +// MoviesState.swift +// MovieSwift +// +// Created by Thomas Ricouard on 06/06/2019. +// Copyright © 2019 Thomas Ricouard. All rights reserved. +// + +import Foundation + +struct MoviesState: FluxState { + var movies: [Int: Movie] = [:] + var popular: [Int] = [] +} diff --git a/Other Projects/Movie/MovieSwift/MovieSwift/launch/AppDelegate.swift b/Other Projects/Movie/MovieSwift/MovieSwift/launch/AppDelegate.swift new file mode 100644 index 0000000..ff8abd8 --- /dev/null +++ b/Other Projects/Movie/MovieSwift/MovieSwift/launch/AppDelegate.swift @@ -0,0 +1,41 @@ +// +// AppDelegate.swift +// MovieSwift +// +// Created by Thomas Ricouard on 06/06/2019. +// Copyright © 2019 Thomas Ricouard. All rights reserved. +// + +import UIKit + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + + + + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { + // Override point for customization after application launch. + return true + } + + func applicationWillTerminate(_ application: UIApplication) { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. + } + + // MARK: UISceneSession Lifecycle + + func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration { + // Called when a new scene session is being created. + // Use this method to select a configuration to create the new scene with. + return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role) + } + + func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) { + // Called when the user discards a scene session. + // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions. + // Use this method to release any resources that were specific to the discarded scenes, as they will not return. + } + + +} + diff --git a/Other Projects/Movie/MovieSwift/MovieSwift/launch/SceneDelegate.swift b/Other Projects/Movie/MovieSwift/MovieSwift/launch/SceneDelegate.swift new file mode 100644 index 0000000..a4442c3 --- /dev/null +++ b/Other Projects/Movie/MovieSwift/MovieSwift/launch/SceneDelegate.swift @@ -0,0 +1,61 @@ +// +// SceneDelegate.swift +// MovieSwift +// +// Created by Thomas Ricouard on 06/06/2019. +// Copyright © 2019 Thomas Ricouard. All rights reserved. +// + +import UIKit +import SwiftUI + +class SceneDelegate: UIResponder, UIWindowSceneDelegate { + + var window: UIWindow? + + + func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { + // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`. + // If using a storyboard, the `window` property will automatically be initialized and attached to the scene. + // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead). + + // Use a UIHostingController as window root view controller + if let windowScene = scene as? UIWindowScene { + let window = UIWindow(windowScene: windowScene) + window.rootViewController = UIHostingController(rootView: ContentView().environmentObject(store)) + self.window = window + window.makeKeyAndVisible() + } + } + + func sceneDidDisconnect(_ scene: UIScene) { + // Called as the scene is being released by the system. + // This occurs shortly after the scene enters the background, or when its session is discarded. + // Release any resources associated with this scene that can be re-created the next time the scene connects. + // The scene may re-connect later, as its session was not neccessarily discarded (see `application:didDiscardSceneSessions` instead). + } + + func sceneDidBecomeActive(_ scene: UIScene) { + // Called when the scene has moved from an inactive state to an active state. + // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive. + } + + func sceneWillResignActive(_ scene: UIScene) { + // Called when the scene will move from an active state to an inactive state. + // This may occur due to temporary interruptions (ex. an incoming phone call). + } + + func sceneWillEnterForeground(_ scene: UIScene) { + // Called as the scene transitions from the background to the foreground. + // Use this method to undo the changes made on entering the background. + } + + func sceneDidEnterBackground(_ scene: UIScene) { + // Called as the scene transitions from the foreground to the background. + // Use this method to save data, release shared resources, and store enough scene-specific state information + // to restore the scene back to its current state. + } + + +} + diff --git a/Other Projects/Movie/MovieSwift/MovieSwift/services/APIService.swift b/Other Projects/Movie/MovieSwift/MovieSwift/services/APIService.swift new file mode 100644 index 0000000..1a4d142 --- /dev/null +++ b/Other Projects/Movie/MovieSwift/MovieSwift/services/APIService.swift @@ -0,0 +1,68 @@ +// +// APIService.swift +// MovieSwift +// +// Created by Thomas Ricouard on 06/06/2019. +// Copyright © 2019 Thomas Ricouard. All rights reserved. +// + +import Foundation + +struct APIService { + let baseURL = URL(string: "https://api.themoviedb.org/3")! + let apiKey = "1d9b898a212ea52e283351e521e17871" + static let shared = APIService() + let decoder = JSONDecoder() + + enum APIError: Error { + case noResponse + case jsonDecodingError(error: Error) + case networkError(error: Error) + } + + enum Endpoint { + case popular + + func path() -> String { + switch self { + case .popular: + return "movie/popular" + } + } + } + + func GET(endpoint: Endpoint, + params: [String: String]?, + completionHandler: @escaping (Result) -> Void) { + let queryURL = baseURL.appendingPathComponent(endpoint.path()) + var components = URLComponents(url: queryURL, resolvingAgainstBaseURL: true)! + components.queryItems = [ + URLQueryItem(name: "api_key", value: apiKey) + ] + if let params = params { + for (_, value) in params.enumerated() { + components.queryItems?.append(URLQueryItem(name: value.key, value: value.value)) + } + } + var request = URLRequest(url: components.url!) + request.httpMethod = "GET" + let task = URLSession.shared.dataTask(with: request) { (data, response, error) in + guard let data = data else { + completionHandler(.failure(.noResponse)) + return + } + guard error == nil else { + completionHandler(.failure(.networkError(error: error!))) + return + } + do { + let object = try self.decoder.decode(T.self, from: data) + completionHandler(.success(object)) + } catch let error { + completionHandler(.failure(.jsonDecodingError(error: error))) + } + } + task.resume() + } +} + diff --git a/Other Projects/Movie/MovieSwift/MovieSwift/views/ContentView.swift b/Other Projects/Movie/MovieSwift/MovieSwift/views/ContentView.swift new file mode 100644 index 0000000..30af701 --- /dev/null +++ b/Other Projects/Movie/MovieSwift/MovieSwift/views/ContentView.swift @@ -0,0 +1,33 @@ +// +// ContentView.swift +// MovieSwift +// +// Created by Thomas Ricouard on 06/06/2019. +// Copyright © 2019 Thomas Ricouard. All rights reserved. +// + +import SwiftUI + +struct ContentView : View { + @EnvironmentObject var state: AppState + + init() { + store.dispatch(action: MoviesActions.FetchPopular()) + } + + var body: some View { + List { + ForEach(state.moviesState.popular, id: \.self) { id in + Text(self.state.moviesState.movies[id]?.original_title ?? "No title") + } + } + } +} + +#if DEBUG +struct ContentView_Previews : PreviewProvider { + static var previews: some View { + ContentView() + } +} +#endif diff --git a/Other Projects/PureGenius/PureGenius.playground/Contents.swift b/Other Projects/PureGenius/PureGenius.playground/Contents.swift new file mode 100644 index 0000000..d64a5eb --- /dev/null +++ b/Other Projects/PureGenius/PureGenius.playground/Contents.swift @@ -0,0 +1,81 @@ +import PlaygroundSupport +import SwiftUI + +struct PureGeniusView: View { + var body: some View { + ZStack { + Rectangle() + .fill() + .foregroundColor(.init(hue: 0.57, saturation: 0.25, brightness: 1)) + Circle() + .frame(width: 320, height: 320) + .foregroundColor(.init(hue: 0.8, saturation: 0.25, brightness: 0.75)) + VStack { + PGWordView(word: ["P", "U", "R", "E"]).offset(x: 0, y: 20) + PGWordView(word: ["G", "E", "N", "I", "U", "S"]).offset(x: 0, y: -20) + } + } + } +} + +struct PGWordView: View { + var word: [String] + var body: some View { + HStack { + ForEach(word.identified(by: \.self)) { letter in + PGLetterView(text: letter) + } + } + } +} + +struct PGLetterView: View { + var text: String + var body: some View { + ZStack { + MovingLetterView(text: text, color: .init(hue: 0.14, saturation: 0.56, brightness: 0.98)) + MovingLetterView(text: text, color: .init(hue: 0.37, saturation: 0.52, brightness: 0.7)) + } + } +} + +struct MovingLetterView: View { + var text: String + var color: Color + + @State var position: CGPoint = .zero + @State var activeTimer: Timer = nil + + private let animationDuration: Double = 2 + private let maxOffset: CGFloat = 10 + private var timer: Timer { + return Timer.scheduledTimer(withTimeInterval: self.animationDuration * 0.25, repeats: true) {_ in + let x = CGFloat(arc4random_uniform(UInt32(self.maxOffset))) - (self.maxOffset / 2) + let y = CGFloat(arc4random_uniform(UInt32(self.maxOffset))) - (self.maxOffset / 2) + self.position = CGPoint.init(x: x, y: y) + } + } + + var body: some View { + Text(text) + .color(self.color) + .font(Font.custom("Baskerville-Bold", size: 40)) + .bold() + .offset(by: self.position) + .animation(.basic(duration: self.animationDuration, curve: .easeInOut)) + .onAppear { + self.activeTimer = self.timer + } + .onDisappear { + self.activeTimer = nil + } + } +} + +extension View { + public func offset(by offset: CGPoint) -> Self.Modified<_OffsetEffect> { + self.offset(x: offset.x, y: offset.y) + } +} + +PlaygroundPage.current.liveView = UIHostingController(rootView: PureGeniusView()) diff --git a/Other Projects/PureGenius/PureGenius.playground/contents.xcplayground b/Other Projects/PureGenius/PureGenius.playground/contents.xcplayground new file mode 100644 index 0000000..5da2641 --- /dev/null +++ b/Other Projects/PureGenius/PureGenius.playground/contents.xcplayground @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/Other Projects/React Meets SwiftUI/.gitignore b/Other Projects/React Meets SwiftUI/.gitignore new file mode 100644 index 0000000..e86fe25 --- /dev/null +++ b/Other Projects/React Meets SwiftUI/.gitignore @@ -0,0 +1,69 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Bower dependency directory (https://bower.io/) +bower_components + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (http://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules/ +jspm_packages/ + +# Typescript v1 declaration files +typings/ + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# dotenv environment variables file +.env + +# gatsby files +.cache/ +public + +# Mac files +.DS_Store + +# Yarn +yarn-error.log +.pnp/ +.pnp.js +# Yarn Integrity file +.yarn-integrity diff --git a/Other Projects/React Meets SwiftUI/Children.md b/Other Projects/React Meets SwiftUI/Children.md new file mode 100644 index 0000000..d0e474b --- /dev/null +++ b/Other Projects/React Meets SwiftUI/Children.md @@ -0,0 +1,55 @@ +## Children + +I'm still trying to really nail this one down, but it seems possible to pass children to child views in SwiftUI. This example shows a common `Layout`, `Content` composition pattern which I commonly use in React, and is the key to developing reusable, flexible components. + +### React + +```jsx +import React from "react"; + +function Page() { + return ( + + This is the page content + + ); +} + +function Layout({ children }) { + return ( +
+ This is the layout + {children} +
+ ); +} +``` + +### SwiftUI + +The SwiftUI version seems harder to type. Currently, the below example only accepts a `Text` child. Does anyone know how to make this accept any view type? + +```swift +import SwiftUI + +struct Page : View { + var body: some View { + Layout() { + Text("This is the page content") + } + } +} + +struct Layout : View { + + var content: () -> Text + + var body: some View { + VStack { + Text("This is the layout") + content() + } + } +} + +``` diff --git a/Other Projects/React Meets SwiftUI/CloneElement.md b/Other Projects/React Meets SwiftUI/CloneElement.md new file mode 100644 index 0000000..af7bba0 --- /dev/null +++ b/Other Projects/React Meets SwiftUI/CloneElement.md @@ -0,0 +1,61 @@ +## cloneElement + +You'll sometimes use React's `cloneElement` to provide additonal attributes to a child component - i.e, to add an event handler, className, etc. You can achieve similar behaviour in SwiftUI. + +### React + +```jsx +import React from "react"; + +export function PageElement() { + return ( +
+ + This is the page content + +
+ ); +} + +export function LayoutElement({ children }) { + return ( +
+ This is the layout + {React.cloneElement(children, { + style: { + fontWeight: "bold", + fontSize: "2rem" + } + })} +
+ ); +} +``` + +### Swift + +```swift +import SwiftUI + +struct PageElement : View { + var body: some View { + LayoutElement() { + Text("This is the page content") + } + } +} + +struct LayoutElement : View { + + var content: () -> Text + + var body: some View { + VStack { + Text("This is the layout") + content() + .bold() + .font(.largeTitle) + } + } +} +``` diff --git a/Other Projects/React Meets SwiftUI/ComponentDidMount.md b/Other Projects/React Meets SwiftUI/ComponentDidMount.md new file mode 100644 index 0000000..23d676d --- /dev/null +++ b/Other Projects/React Meets SwiftUI/ComponentDidMount.md @@ -0,0 +1,125 @@ +## ComponentDidMount + +With React it's common to perform one-time operations (such as async fetches to a server) in the `componentDidMount` function or the `useEffect` hook. You can replicate this behaviour using the `onAppear` and `onDisappear` callbacks on any View. This means that you can actually have multiple `onAppear` callbacks attached to multiple views contained within your `body` function. Your parent view can also attach these callbacks to custom child views. + +The below example mounts and unmounts the counter readout when it reaches a certain value. We log when the mount/unmount happens. + +### React + +```jsx +import React from "react"; + +export function Counter() { + const [count, setCount] = React.useState(0); + + function increment() { + setCount(count + 1); + } + + return ( +
+ + {(count < 10 || count > 12) && } +
+ ); +} + +export function ChildCounter({ count }) { + React.useEffect(() => { + console.log("mounted"); + + return () => { + console.log("unmounting"); + }; + }, []); + + return
{count}
; +} +``` + +### Swift + +Note that this only approximates the React behaviour. I'm not sure what the `appear` / `mount` distinction implies, but it seems to provide similar utility. + +```swift +import SwiftUI + +struct Counter : View { + @State var count = 0 + + func increment () { + count += 1 + } + + var body: some View { + + VStack { + Button(action: increment) { + Text("Increment") + } + if count < 10 || count > 12 { + ChildCounter(count: count) + } + } + + } +} + +struct ChildCounter : View { + var count: Int + + func onMount () { + print("on mount") + } + + func onUnmount () { + print("on unmount") + } + + var body: some View { + Text("\(count)") + .onAppear(perform: onMount) + .onDisappear(perform: onUnmount) + } +} + +``` + +You can attach multiple `onAppear` and `onDisappear` callbacks in your `body` function: + +```swift +struct Counter : View { + @State var count = 0 + + func increment () { + count += 1 + } + + func mount () { + print("Child mount") + } + + func unmount () { + print("Child unmount") + } + + func parentMount () { + print("parent mount") + } + + + var body: some View { + VStack { + Button(action: increment) { + Text("Increment") + } + if count < 10 || count > 12 { + ChildCounter(count: count) + .onAppear(perform: mount) + .onDisappear(perform: unmount) + } + } + .onAppear(perform: parentMount) + } +} +``` diff --git a/Other Projects/React Meets SwiftUI/Context.md b/Other Projects/React Meets SwiftUI/Context.md new file mode 100644 index 0000000..b699938 --- /dev/null +++ b/Other Projects/React Meets SwiftUI/Context.md @@ -0,0 +1,70 @@ +## Context + +You can replicate the context functionality found in React by using a combination of `BindableObject`, `Combine` and defining an `environmentObject` for a View. You create a class that adheres to the `BindableObject` and provide that as an argument to `environmentObject` when initiating your parent view. Any child of that parent view can then access the class using `@EnvironmentObject`. + +### React + +```jsx +import React, { useContext } from "react"; + +const Session = React.createContext({ name: "" }); + +export function ContextProvider() { + return ( + + + + ); +} + +export function Parent() { + return ; +} + +export function Child() { + const session = useContext(Session); + + return Hello {session.name}; +} +``` + +### SwiftUI + +```swift +import SwiftUI +import Combine + +final class Session: BindableObject { + let didChange = PassthroughSubject() + + var name: String { + didSet { didChange.send(self) } + } + + init(name: String) { + self.name = name + } +} + + +struct ContextProvider : View { + var body: some View { + Parent().environmentObject(Session(name: "Bento")) + } +} + +struct Parent : View { + var body: some View { + Child() + } +} + +struct Child : View { + + @EnvironmentObject var session: Session + + var body: some View { + Text("Hello \(session.name)") + } +} +``` diff --git a/Other Projects/React Meets SwiftUI/README.md b/Other Projects/React Meets SwiftUI/README.md new file mode 100644 index 0000000..1e57d59 --- /dev/null +++ b/Other Projects/React Meets SwiftUI/README.md @@ -0,0 +1,13 @@ +# React Meets SwiftUI + +I'm looking to learn SwiftUI over the coming weeks and will be using this repository to record various common React design patterns implemented in SwiftUI. + +Please note: I'm a total newbie when it comes to Swift, so please contribute where you can to fix my inevitable errors. + +### Examples + +- [Managing State](State.md) +- [Using Context](Context.md) +- [Using Children](Children.md) +- [Mounting and Unmounting Callbacks](ComponentDidMount.md) +- [Emulating CloneElement](CloneElement.md) diff --git a/Other Projects/React Meets SwiftUI/State.md b/Other Projects/React Meets SwiftUI/State.md new file mode 100644 index 0000000..0bb5f1a --- /dev/null +++ b/Other Projects/React Meets SwiftUI/State.md @@ -0,0 +1,112 @@ +## Managing State + +With SwiftUI you can create state in views and pass that state to child views, much as you would in React. You can also pass functions as props which allow child views to control state in parent components. + +The example below creates a simple counter. The `ContentView` manages the `count` state, while the child view renders that count and asks the parent to increment. + +### React + +```jsx +import React from "react"; + +export function ContentView() { + const [count, setCount] = useState(0); + + function increment() { + setCount(count + 1); + } + + return ( +
+
Press the button below
+ +
+ ); +} + +export function ChildView({ count, increment }) { + return ( +
+
{coun t}
+ +
+ ); +} +``` + +### SwiftUI + +```swift +import SwiftUI + +struct ContentView : View { + @State var count = 0 + + var body: some View { + VStack(spacing: 1.0) { + Text("Press the button below") + ChildView( + counter: count, + increment: increment + ) + } + } + + func increment() { + count += 1 + } +} + + +struct ChildView : View { + var counter: Int + var increment: () -> Void + + var body: some View { + VStack { + Text("\(counter)") + Button(action: increment) { + Text("Increment") + } + } + } +} + +``` + +With SwiftUI you can use `@Binding` to enable child views to alter state provided by parent views. Notice that we prepend the `$` to our count value to pass its binding value. Our child can then alter the `count` state itself without supplying a callback to the parent. + +```swift +import SwiftUI + +struct ContentView : View { + @State var count = 0 + + var body: some View { + VStack(spacing: 1.0) { + Text("Press the button below") + ChildView( + counter: $count + ) + } + } +} + + +struct ChildView : View { + @Binding var counter: Int + + func increment () { + counter += 1 + } + + var body: some View { + VStack { + Text("\(counter)") + Button(action: increment) { + Text("Increment") + } + } + } +} +``` diff --git a/Other Projects/SFSymbols/.gitignore b/Other Projects/SFSymbols/.gitignore new file mode 100644 index 0000000..312d1f6 --- /dev/null +++ b/Other Projects/SFSymbols/.gitignore @@ -0,0 +1,68 @@ +# Xcode +# +# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore + +## Build generated +build/ +DerivedData/ + +## Various settings +*.pbxuser +!default.pbxuser +*.mode1v3 +!default.mode1v3 +*.mode2v3 +!default.mode2v3 +*.perspectivev3 +!default.perspectivev3 +xcuserdata/ + +## Other +*.moved-aside +*.xccheckout +*.xcscmblueprint + +## Obj-C/Swift specific +*.hmap +*.ipa +*.dSYM.zip +*.dSYM + +## Playgrounds +timeline.xctimeline +playground.xcworkspace + +# Swift Package Manager +# +# Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. +# Packages/ +# Package.pins +# Package.resolved +.build/ + +# CocoaPods +# +# We recommend against adding the Pods directory to your .gitignore. However +# you should judge for yourself, the pros and cons are mentioned at: +# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control +# +# Pods/ + +# Carthage +# +# Add this line if you want to avoid checking in source code from Carthage dependencies. +# Carthage/Checkouts + +Carthage/Build + +# fastlane +# +# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the +# screenshots whenever they are needed. +# For more information about the recommended setup visit: +# https://docs.fastlane.tools/best-practices/source-control/#source-control + +fastlane/report.xml +fastlane/Preview.html +fastlane/screenshots/**/*.png +fastlane/test_output diff --git a/Other Projects/SFSymbols/README.md b/Other Projects/SFSymbols/README.md new file mode 100644 index 0000000..a92033f --- /dev/null +++ b/Other Projects/SFSymbols/README.md @@ -0,0 +1,7 @@ +# SFSymbols-Playground +A playground listing all the SFSymbols in SwiftUI + +![Demo GIF](https://github.com/jstart/SFSymbols-Playground/blob/master/demo.gif) + +You can download the SF Symbols.app beta for Mac here: https://developer.apple.com/design/downloads/SF-Symbols.dmg +A Swift Package has already been developed to make SF Symbols an enum instead of strings: https://twitter.com/simjp/status/1135936933916336128 diff --git a/Other Projects/SFSymbols/SFSymbols.playground/Contents.swift b/Other Projects/SFSymbols/SFSymbols.playground/Contents.swift new file mode 100644 index 0000000..2f25612 --- /dev/null +++ b/Other Projects/SFSymbols/SFSymbols.playground/Contents.swift @@ -0,0 +1,60 @@ +import UIKit +import PlaygroundSupport +import SwiftUI + +var colors: [Color] = [.red, .blue, .black, .gray, .green, .yellow, .orange, .pink, .purple] + +struct SymbolRow: View { + var symbol: String + + var body: some View { + HStack { + Image(systemName: symbol).foregroundColor(colors.randomElement()) + Divider() + Text(symbol) + } + } +} + +struct SymbolDetail: View { + var symbol: String + + var body: some View { + VStack { + Image(systemName: symbol) + .foregroundColor(colors.randomElement()) + .imageScale(.large) + .scaleEffect(3.0) + .padding(.bottom, 100) + Divider() +// .animation(Animation.basic().delay(0.25)) + Text(symbol).font(.headline) + } + } +} + +struct ContentView: View { + + var body: some View { + let list = (0.. + + + \ No newline at end of file diff --git a/Other Projects/SFSymbols/demo.gif b/Other Projects/SFSymbols/demo.gif new file mode 100644 index 0000000..9606053 Binary files /dev/null and b/Other Projects/SFSymbols/demo.gif differ diff --git a/Other Projects/SplitView/.gitignore b/Other Projects/SplitView/.gitignore new file mode 100644 index 0000000..312d1f6 --- /dev/null +++ b/Other Projects/SplitView/.gitignore @@ -0,0 +1,68 @@ +# Xcode +# +# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore + +## Build generated +build/ +DerivedData/ + +## Various settings +*.pbxuser +!default.pbxuser +*.mode1v3 +!default.mode1v3 +*.mode2v3 +!default.mode2v3 +*.perspectivev3 +!default.perspectivev3 +xcuserdata/ + +## Other +*.moved-aside +*.xccheckout +*.xcscmblueprint + +## Obj-C/Swift specific +*.hmap +*.ipa +*.dSYM.zip +*.dSYM + +## Playgrounds +timeline.xctimeline +playground.xcworkspace + +# Swift Package Manager +# +# Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. +# Packages/ +# Package.pins +# Package.resolved +.build/ + +# CocoaPods +# +# We recommend against adding the Pods directory to your .gitignore. However +# you should judge for yourself, the pros and cons are mentioned at: +# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control +# +# Pods/ + +# Carthage +# +# Add this line if you want to avoid checking in source code from Carthage dependencies. +# Carthage/Checkouts + +Carthage/Build + +# fastlane +# +# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the +# screenshots whenever they are needed. +# For more information about the recommended setup visit: +# https://docs.fastlane.tools/best-practices/source-control/#source-control + +fastlane/report.xml +fastlane/Preview.html +fastlane/screenshots/**/*.png +fastlane/test_output diff --git a/Other Projects/SplitView/LICENSE b/Other Projects/SplitView/LICENSE new file mode 100644 index 0000000..713ace4 --- /dev/null +++ b/Other Projects/SplitView/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2019 Alexsander Akers + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/Other Projects/SplitView/Package.swift b/Other Projects/SplitView/Package.swift new file mode 100644 index 0000000..132d1ec --- /dev/null +++ b/Other Projects/SplitView/Package.swift @@ -0,0 +1,32 @@ +// swift-tools-version:5.1 +// The swift-tools-version declares the minimum version of Swift required to build this package. + +import PackageDescription + +let package = Package( + name: "SplitView", + platforms: [ + .iOS(.v13), + .tvOS(.v13) + ], + products: [ + // Products define the executables and libraries produced by a package, and make them visible to other packages. + .library( + name: "SplitView", + targets: ["SplitView"]), + ], + 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 which this package depends on. + .target( + name: "SplitView", + dependencies: []), + .testTarget( + name: "SplitViewTests", + dependencies: ["SplitView"]), + ] +) diff --git a/Other Projects/SplitView/README.md b/Other Projects/SplitView/README.md new file mode 100644 index 0000000..9c557dc --- /dev/null +++ b/Other Projects/SplitView/README.md @@ -0,0 +1,3 @@ +# SplitView + +A SwiftUI view that manages a UISplitViewController. diff --git a/Other Projects/SplitView/Sources/SplitView/SplitView.swift b/Other Projects/SplitView/Sources/SplitView/SplitView.swift new file mode 100644 index 0000000..7e0f958 --- /dev/null +++ b/Other Projects/SplitView/Sources/SplitView/SplitView.swift @@ -0,0 +1,22 @@ +import SwiftUI + +public struct SplitView: View { + public var master: Master + public var detail: Detail + @State public var preferredDisplayMode: UISplitViewController.DisplayMode + + public var body: some View { + let controllers = [UIHostingController(rootView: master), UIHostingController(rootView: detail)] + return SplitViewController(controllers: controllers, preferredDisplayMode: $preferredDisplayMode) + } +} + +public extension SplitView { + init(master: Master, detail: Detail) { + self.init(master: master, detail: detail, preferredDisplayMode: .automatic) + } + + func preferredDisplayMode(_ preferredDisplayMode: UISplitViewController.DisplayMode) -> Self { + return SplitView(master: master, detail: detail, preferredDisplayMode: preferredDisplayMode) + } +} diff --git a/Other Projects/SplitView/Sources/SplitView/SplitViewController.swift b/Other Projects/SplitView/Sources/SplitView/SplitViewController.swift new file mode 100644 index 0000000..8910ab7 --- /dev/null +++ b/Other Projects/SplitView/Sources/SplitView/SplitViewController.swift @@ -0,0 +1,18 @@ +import SwiftUI + +public struct SplitViewController: UIViewControllerRepresentable { + public var controllers: [UIViewController] + @Binding public var preferredDisplayMode: UISplitViewController.DisplayMode + + public func makeUIViewController(context: UIViewControllerRepresentableContext) -> UISplitViewController { + let splitViewController = UISplitViewController() + splitViewController.preferredDisplayMode = preferredDisplayMode + splitViewController.viewControllers = controllers + return splitViewController + } + + public func updateUIViewController(_ uiViewController: UISplitViewController, context: UIViewControllerRepresentableContext) { + uiViewController.preferredDisplayMode = preferredDisplayMode + uiViewController.viewControllers = controllers + } +} diff --git a/Other Projects/SplitView/Tests/LinuxMain.swift b/Other Projects/SplitView/Tests/LinuxMain.swift new file mode 100644 index 0000000..ed76b32 --- /dev/null +++ b/Other Projects/SplitView/Tests/LinuxMain.swift @@ -0,0 +1,7 @@ +import XCTest + +import SplitViewTests + +var tests = [XCTestCaseEntry]() +tests += SplitViewTests.allTests() +XCTMain(tests) diff --git a/Other Projects/SplitView/Tests/SplitViewTests/SplitViewTests.swift b/Other Projects/SplitView/Tests/SplitViewTests/SplitViewTests.swift new file mode 100644 index 0000000..0491d33 --- /dev/null +++ b/Other Projects/SplitView/Tests/SplitViewTests/SplitViewTests.swift @@ -0,0 +1,14 @@ +import XCTest +@testable import SplitView + +final class SplitViewTests: XCTestCase { + func testExample() { + // This is an example of a functional test case. + // Use XCTAssert and related functions to verify your tests produce the correct + // results. + } + + static var allTests = [ + ("testExample", testExample), + ] +} diff --git a/Other Projects/SplitView/Tests/SplitViewTests/XCTestManifests.swift b/Other Projects/SplitView/Tests/SplitViewTests/XCTestManifests.swift new file mode 100644 index 0000000..7c6256c --- /dev/null +++ b/Other Projects/SplitView/Tests/SplitViewTests/XCTestManifests.swift @@ -0,0 +1,9 @@ +import XCTest + +#if !canImport(ObjectiveC) +public func allTests() -> [XCTestCaseEntry] { + return [ + testCase(SplitViewTests.allTests), + ] +} +#endif diff --git a/Other Projects/SwiftUI + Redux/SwiftUIDemo.xcodeproj/project.pbxproj b/Other Projects/SwiftUI + Redux/SwiftUIDemo.xcodeproj/project.pbxproj new file mode 100644 index 0000000..72acd98 --- /dev/null +++ b/Other Projects/SwiftUI + Redux/SwiftUIDemo.xcodeproj/project.pbxproj @@ -0,0 +1,495 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 50; + objects = { + +/* Begin PBXBuildFile section */ + 6905595122A82C0400639314 /* AppState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6905595022A82C0400639314 /* AppState.swift */; }; + 69250A8B22A97BE300332EF0 /* Badge.swift in Sources */ = {isa = PBXBuildFile; fileRef = 69250A8A22A97BE300332EF0 /* Badge.swift */; }; + 69516A5D22A8743500E62A5E /* Reducer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 69516A5C22A8743500E62A5E /* Reducer.swift */; }; + 69516A5F22A8745800E62A5E /* FluxState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 69516A5E22A8745800E62A5E /* FluxState.swift */; }; + 69516A6122A8747600E62A5E /* Action.swift in Sources */ = {isa = PBXBuildFile; fileRef = 69516A6022A8747600E62A5E /* Action.swift */; }; + 69516A6322A874CE00E62A5E /* UsersStateReducer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 69516A6222A874CE00E62A5E /* UsersStateReducer.swift */; }; + 69516A6522A874F900E62A5E /* UsersAction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 69516A6422A874F900E62A5E /* UsersAction.swift */; }; + 6994C88022A81130006C5F62 /* UserEditForm.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6994C87F22A81130006C5F62 /* UserEditForm.swift */; }; + 69C1521A22A8CB3600149392 /* TabbarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 69C1521922A8CB3600149392 /* TabbarView.swift */; }; + 69C1522222A8CF4600149392 /* MapView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 69C1522122A8CF4600149392 /* MapView.swift */; }; + 69C1522522A8D01300149392 /* MapKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 69C1522422A8D01300149392 /* MapKit.framework */; }; + 69E06C2D22A6FD6B0081D614 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 69E06C2C22A6FD6B0081D614 /* AppDelegate.swift */; }; + 69E06C2F22A6FD6B0081D614 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 69E06C2E22A6FD6B0081D614 /* SceneDelegate.swift */; }; + 69E06C3122A6FD6B0081D614 /* UsersListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 69E06C3022A6FD6B0081D614 /* UsersListView.swift */; }; + 69E06C3322A6FD6D0081D614 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 69E06C3222A6FD6D0081D614 /* Assets.xcassets */; }; + 69E06C3622A6FD6D0081D614 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 69E06C3522A6FD6D0081D614 /* Preview Assets.xcassets */; }; + 69E06C3922A6FD6D0081D614 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 69E06C3722A6FD6D0081D614 /* LaunchScreen.storyboard */; }; + 69E06C4422A6FE940081D614 /* User.swift in Sources */ = {isa = PBXBuildFile; fileRef = 69E06C4322A6FE940081D614 /* User.swift */; }; + 69E06C4622A6FF3C0081D614 /* UsersState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 69E06C4522A6FF3C0081D614 /* UsersState.swift */; }; + 69E06C4922A7016B0081D614 /* UserRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 69E06C4822A7016B0081D614 /* UserRow.swift */; }; + 69E06C4C22A706450081D614 /* UserDetailView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 69E06C4B22A706450081D614 /* UserDetailView.swift */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 6905595022A82C0400639314 /* AppState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppState.swift; sourceTree = ""; }; + 69250A8A22A97BE300332EF0 /* Badge.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Badge.swift; sourceTree = ""; }; + 69516A5C22A8743500E62A5E /* Reducer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Reducer.swift; sourceTree = ""; }; + 69516A5E22A8745800E62A5E /* FluxState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FluxState.swift; sourceTree = ""; }; + 69516A6022A8747600E62A5E /* Action.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Action.swift; sourceTree = ""; }; + 69516A6222A874CE00E62A5E /* UsersStateReducer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UsersStateReducer.swift; sourceTree = ""; }; + 69516A6422A874F900E62A5E /* UsersAction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UsersAction.swift; sourceTree = ""; }; + 6994C87F22A81130006C5F62 /* UserEditForm.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserEditForm.swift; sourceTree = ""; }; + 69C1521922A8CB3600149392 /* TabbarView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabbarView.swift; sourceTree = ""; }; + 69C1522122A8CF4600149392 /* MapView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapView.swift; sourceTree = ""; }; + 69C1522422A8D01300149392 /* MapKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MapKit.framework; path = System/Library/Frameworks/MapKit.framework; sourceTree = SDKROOT; }; + 69E06C2922A6FD6B0081D614 /* SwiftUIDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SwiftUIDemo.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 69E06C2C22A6FD6B0081D614 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 69E06C2E22A6FD6B0081D614 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; + 69E06C3022A6FD6B0081D614 /* UsersListView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UsersListView.swift; sourceTree = ""; }; + 69E06C3222A6FD6D0081D614 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 69E06C3522A6FD6D0081D614 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; + 69E06C3822A6FD6D0081D614 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 69E06C3A22A6FD6D0081D614 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 69E06C4322A6FE940081D614 /* User.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = User.swift; sourceTree = ""; }; + 69E06C4522A6FF3C0081D614 /* UsersState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UsersState.swift; sourceTree = ""; }; + 69E06C4822A7016B0081D614 /* UserRow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserRow.swift; sourceTree = ""; }; + 69E06C4B22A706450081D614 /* UserDetailView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserDetailView.swift; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 69E06C2622A6FD6B0081D614 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 69C1522522A8D01300149392 /* MapKit.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 69250A8922A97BD500332EF0 /* component */ = { + isa = PBXGroup; + children = ( + 69250A8A22A97BE300332EF0 /* Badge.swift */, + ); + path = component; + sourceTree = ""; + }; + 69516A5822A873C900E62A5E /* states */ = { + isa = PBXGroup; + children = ( + 69516A5E22A8745800E62A5E /* FluxState.swift */, + 6905595022A82C0400639314 /* AppState.swift */, + 69E06C4522A6FF3C0081D614 /* UsersState.swift */, + ); + path = states; + sourceTree = ""; + }; + 69516A5922A873D100E62A5E /* actions */ = { + isa = PBXGroup; + children = ( + 69516A6022A8747600E62A5E /* Action.swift */, + 69516A6422A874F900E62A5E /* UsersAction.swift */, + ); + path = actions; + sourceTree = ""; + }; + 69516A5A22A873D700E62A5E /* reducers */ = { + isa = PBXGroup; + children = ( + 69516A5C22A8743500E62A5E /* Reducer.swift */, + 69516A6222A874CE00E62A5E /* UsersStateReducer.swift */, + ); + path = reducers; + sourceTree = ""; + }; + 69C1521F22A8CF2A00149392 /* users */ = { + isa = PBXGroup; + children = ( + 69250A8922A97BD500332EF0 /* component */, + 69E06C4722A7015F0081D614 /* rows */, + 69E06C3022A6FD6B0081D614 /* UsersListView.swift */, + 69E06C4B22A706450081D614 /* UserDetailView.swift */, + 6994C87F22A81130006C5F62 /* UserEditForm.swift */, + ); + path = users; + sourceTree = ""; + }; + 69C1522022A8CF3800149392 /* map */ = { + isa = PBXGroup; + children = ( + 69C1522122A8CF4600149392 /* MapView.swift */, + ); + path = map; + sourceTree = ""; + }; + 69C1522322A8D01300149392 /* Frameworks */ = { + isa = PBXGroup; + children = ( + 69C1522422A8D01300149392 /* MapKit.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + 69E06C2022A6FD6B0081D614 = { + isa = PBXGroup; + children = ( + 69E06C2B22A6FD6B0081D614 /* SwiftUIDemo */, + 69E06C2A22A6FD6B0081D614 /* Products */, + 69C1522322A8D01300149392 /* Frameworks */, + ); + sourceTree = ""; + }; + 69E06C2A22A6FD6B0081D614 /* Products */ = { + isa = PBXGroup; + children = ( + 69E06C2922A6FD6B0081D614 /* SwiftUIDemo.app */, + ); + name = Products; + sourceTree = ""; + }; + 69E06C2B22A6FD6B0081D614 /* SwiftUIDemo */ = { + isa = PBXGroup; + children = ( + 69F83D4822A85D8E00268B3F /* flux */, + 69E06C4A22A7061E0081D614 /* views */, + 69E06C2C22A6FD6B0081D614 /* AppDelegate.swift */, + 69E06C2E22A6FD6B0081D614 /* SceneDelegate.swift */, + 69E06C3222A6FD6D0081D614 /* Assets.xcassets */, + 69E06C3722A6FD6D0081D614 /* LaunchScreen.storyboard */, + 69E06C3A22A6FD6D0081D614 /* Info.plist */, + 69E06C3422A6FD6D0081D614 /* Preview Content */, + ); + path = SwiftUIDemo; + sourceTree = ""; + }; + 69E06C3422A6FD6D0081D614 /* Preview Content */ = { + isa = PBXGroup; + children = ( + 69E06C3522A6FD6D0081D614 /* Preview Assets.xcassets */, + ); + path = "Preview Content"; + sourceTree = ""; + }; + 69E06C4022A6FD730081D614 /* models */ = { + isa = PBXGroup; + children = ( + 69E06C4322A6FE940081D614 /* User.swift */, + ); + path = models; + sourceTree = ""; + }; + 69E06C4722A7015F0081D614 /* rows */ = { + isa = PBXGroup; + children = ( + 69E06C4822A7016B0081D614 /* UserRow.swift */, + ); + path = rows; + sourceTree = ""; + }; + 69E06C4A22A7061E0081D614 /* views */ = { + isa = PBXGroup; + children = ( + 69C1522022A8CF3800149392 /* map */, + 69C1521F22A8CF2A00149392 /* users */, + 69C1521922A8CB3600149392 /* TabbarView.swift */, + ); + path = views; + sourceTree = ""; + }; + 69F83D4822A85D8E00268B3F /* flux */ = { + isa = PBXGroup; + children = ( + 69516A5A22A873D700E62A5E /* reducers */, + 69516A5922A873D100E62A5E /* actions */, + 69516A5822A873C900E62A5E /* states */, + 69E06C4022A6FD730081D614 /* models */, + ); + path = flux; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 69E06C2822A6FD6B0081D614 /* SwiftUIDemo */ = { + isa = PBXNativeTarget; + buildConfigurationList = 69E06C3D22A6FD6D0081D614 /* Build configuration list for PBXNativeTarget "SwiftUIDemo" */; + buildPhases = ( + 69E06C2522A6FD6B0081D614 /* Sources */, + 69E06C2622A6FD6B0081D614 /* Frameworks */, + 69E06C2722A6FD6B0081D614 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = SwiftUIDemo; + productName = SwiftUIDemo; + productReference = 69E06C2922A6FD6B0081D614 /* SwiftUIDemo.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 69E06C2122A6FD6B0081D614 /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 1100; + LastUpgradeCheck = 1100; + ORGANIZATIONNAME = "Thomas Ricouarf"; + TargetAttributes = { + 69E06C2822A6FD6B0081D614 = { + CreatedOnToolsVersion = 11.0; + }; + }; + }; + buildConfigurationList = 69E06C2422A6FD6B0081D614 /* Build configuration list for PBXProject "SwiftUIDemo" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 69E06C2022A6FD6B0081D614; + productRefGroup = 69E06C2A22A6FD6B0081D614 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 69E06C2822A6FD6B0081D614 /* SwiftUIDemo */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 69E06C2722A6FD6B0081D614 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 69E06C3922A6FD6D0081D614 /* LaunchScreen.storyboard in Resources */, + 69E06C3622A6FD6D0081D614 /* Preview Assets.xcassets in Resources */, + 69E06C3322A6FD6D0081D614 /* Assets.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 69E06C2522A6FD6B0081D614 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 69E06C4622A6FF3C0081D614 /* UsersState.swift in Sources */, + 69516A6522A874F900E62A5E /* UsersAction.swift in Sources */, + 69516A6122A8747600E62A5E /* Action.swift in Sources */, + 69E06C4422A6FE940081D614 /* User.swift in Sources */, + 69516A6322A874CE00E62A5E /* UsersStateReducer.swift in Sources */, + 69E06C2D22A6FD6B0081D614 /* AppDelegate.swift in Sources */, + 69516A5D22A8743500E62A5E /* Reducer.swift in Sources */, + 69E06C2F22A6FD6B0081D614 /* SceneDelegate.swift in Sources */, + 69E06C4C22A706450081D614 /* UserDetailView.swift in Sources */, + 69250A8B22A97BE300332EF0 /* Badge.swift in Sources */, + 69C1522222A8CF4600149392 /* MapView.swift in Sources */, + 69E06C3122A6FD6B0081D614 /* UsersListView.swift in Sources */, + 6905595122A82C0400639314 /* AppState.swift in Sources */, + 6994C88022A81130006C5F62 /* UserEditForm.swift in Sources */, + 69516A5F22A8745800E62A5E /* FluxState.swift in Sources */, + 69C1521A22A8CB3600149392 /* TabbarView.swift in Sources */, + 69E06C4922A7016B0081D614 /* UserRow.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 69E06C3722A6FD6D0081D614 /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 69E06C3822A6FD6D0081D614 /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 69E06C3B22A6FD6D0081D614 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + 69E06C3C22A6FD6D0081D614 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 69E06C3E22A6FD6D0081D614 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_ASSET_PATHS = "SwiftUIDemo/Preview\\ Content"; + DEVELOPMENT_TEAM = Z6P74P6T99; + ENABLE_PREVIEWS = YES; + INFOPLIST_FILE = SwiftUIDemo/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.thomasricouard.SwiftUIDemo; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 69E06C3F22A6FD6D0081D614 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_ASSET_PATHS = "SwiftUIDemo/Preview\\ Content"; + DEVELOPMENT_TEAM = Z6P74P6T99; + ENABLE_PREVIEWS = YES; + INFOPLIST_FILE = SwiftUIDemo/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.thomasricouard.SwiftUIDemo; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 69E06C2422A6FD6B0081D614 /* Build configuration list for PBXProject "SwiftUIDemo" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 69E06C3B22A6FD6D0081D614 /* Debug */, + 69E06C3C22A6FD6D0081D614 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 69E06C3D22A6FD6D0081D614 /* Build configuration list for PBXNativeTarget "SwiftUIDemo" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 69E06C3E22A6FD6D0081D614 /* Debug */, + 69E06C3F22A6FD6D0081D614 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 69E06C2122A6FD6B0081D614 /* Project object */; +} diff --git a/Other Projects/SwiftUI + Redux/SwiftUIDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/Other Projects/SwiftUI + Redux/SwiftUIDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..e5954d1 --- /dev/null +++ b/Other Projects/SwiftUI + Redux/SwiftUIDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/Other Projects/SwiftUI + Redux/SwiftUIDemo.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/Other Projects/SwiftUI + Redux/SwiftUIDemo.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/Other Projects/SwiftUI + Redux/SwiftUIDemo.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/Other Projects/SwiftUI + Redux/SwiftUIDemo/AppDelegate.swift b/Other Projects/SwiftUI + Redux/SwiftUIDemo/AppDelegate.swift new file mode 100644 index 0000000..1a0e145 --- /dev/null +++ b/Other Projects/SwiftUI + Redux/SwiftUIDemo/AppDelegate.swift @@ -0,0 +1,41 @@ +// +// AppDelegate.swift +// SwiftUIDemo +// +// Created by Thomas Ricouard on 04/06/2019. +// Copyright © 2019 Thomas Ricouarf. All rights reserved. +// + +import UIKit + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + + + + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { + // Override point for customization after application launch. + return true + } + + func applicationWillTerminate(_ application: UIApplication) { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. + } + + // MARK: UISceneSession Lifecycle + + func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration { + // Called when a new scene session is being created. + // Use this method to select a configuration to create the new scene with. + return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role) + } + + func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) { + // Called when the user discards a scene session. + // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions. + // Use this method to release any resources that were specific to the discarded scenes, as they will not return. + } + + +} + diff --git a/Other Projects/SwiftUI + Redux/SwiftUIDemo/Assets.xcassets/AppIcon.appiconset/Contents.json b/Other Projects/SwiftUI + Redux/SwiftUIDemo/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..d8db8d6 --- /dev/null +++ b/Other Projects/SwiftUI + Redux/SwiftUIDemo/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,98 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "83.5x83.5", + "scale" : "2x" + }, + { + "idiom" : "ios-marketing", + "size" : "1024x1024", + "scale" : "1x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/SwiftUI + Redux/SwiftUIDemo/Assets.xcassets/Contents.json b/Other Projects/SwiftUI + Redux/SwiftUIDemo/Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/Other Projects/SwiftUI + Redux/SwiftUIDemo/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/SwiftUI + Redux/SwiftUIDemo/Assets.xcassets/user-image.imageset/Contents.json b/Other Projects/SwiftUI + Redux/SwiftUIDemo/Assets.xcassets/user-image.imageset/Contents.json new file mode 100644 index 0000000..7fef6bd --- /dev/null +++ b/Other Projects/SwiftUI + Redux/SwiftUIDemo/Assets.xcassets/user-image.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "user-image.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "user-image@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/SwiftUI + Redux/SwiftUIDemo/Assets.xcassets/user-image.imageset/user-image.png b/Other Projects/SwiftUI + Redux/SwiftUIDemo/Assets.xcassets/user-image.imageset/user-image.png new file mode 100644 index 0000000..f78dc24 Binary files /dev/null and b/Other Projects/SwiftUI + Redux/SwiftUIDemo/Assets.xcassets/user-image.imageset/user-image.png differ diff --git a/Other Projects/SwiftUI + Redux/SwiftUIDemo/Assets.xcassets/user-image.imageset/user-image@2x.png b/Other Projects/SwiftUI + Redux/SwiftUIDemo/Assets.xcassets/user-image.imageset/user-image@2x.png new file mode 100644 index 0000000..a674d48 Binary files /dev/null and b/Other Projects/SwiftUI + Redux/SwiftUIDemo/Assets.xcassets/user-image.imageset/user-image@2x.png differ diff --git a/Other Projects/SwiftUI + Redux/SwiftUIDemo/Base.lproj/LaunchScreen.storyboard b/Other Projects/SwiftUI + Redux/SwiftUIDemo/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000..865e932 --- /dev/null +++ b/Other Projects/SwiftUI + Redux/SwiftUIDemo/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Other Projects/SwiftUI + Redux/SwiftUIDemo/Info.plist b/Other Projects/SwiftUI + Redux/SwiftUIDemo/Info.plist new file mode 100644 index 0000000..e8bb4c6 --- /dev/null +++ b/Other Projects/SwiftUI + Redux/SwiftUIDemo/Info.plist @@ -0,0 +1,62 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + $(PRODUCT_BUNDLE_PACKAGE_TYPE) + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UIApplicationSceneManifest + + UIApplicationSupportsMultipleScenes + + UISceneConfigurations + + UIWindowSceneSessionRoleApplication + + + UILaunchStoryboardName + LaunchScreen + UISceneConfigurationName + Default Configuration + UISceneDelegateClassName + $(PRODUCT_MODULE_NAME).SceneDelegate + + + + + UILaunchStoryboardName + LaunchScreen + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/Other Projects/SwiftUI + Redux/SwiftUIDemo/Preview Content/Preview Assets.xcassets/Contents.json b/Other Projects/SwiftUI + Redux/SwiftUIDemo/Preview Content/Preview Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/Other Projects/SwiftUI + Redux/SwiftUIDemo/Preview Content/Preview Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/SwiftUI + Redux/SwiftUIDemo/SceneDelegate.swift b/Other Projects/SwiftUI + Redux/SwiftUIDemo/SceneDelegate.swift new file mode 100644 index 0000000..5c0bea8 --- /dev/null +++ b/Other Projects/SwiftUI + Redux/SwiftUIDemo/SceneDelegate.swift @@ -0,0 +1,26 @@ +// +// SceneDelegate.swift +// SwiftUIDemo +// +// Created by Thomas Ricouard on 04/06/2019. +// Copyright © 2019 Thomas Ricouarf. All rights reserved. +// + +import UIKit +import SwiftUI + +class SceneDelegate: UIResponder, UIWindowSceneDelegate { + + var window: UIWindow? + + func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { + + if let windowScene = scene as? UIWindowScene { + let window = UIWindow(windowScene: windowScene) + window.rootViewController = UIHostingController(rootView: TabbarView().environmentObject(store)) + self.window = window + window.makeKeyAndVisible() + } + } +} + diff --git a/Other Projects/SwiftUI + Redux/SwiftUIDemo/flux/actions/Action.swift b/Other Projects/SwiftUI + Redux/SwiftUIDemo/flux/actions/Action.swift new file mode 100644 index 0000000..0de6f62 --- /dev/null +++ b/Other Projects/SwiftUI + Redux/SwiftUIDemo/flux/actions/Action.swift @@ -0,0 +1,13 @@ +// +// Action.swift +// SwiftUIDemo +// +// Created by Thomas Ricouard on 05/06/2019. +// Copyright © 2019 Thomas Ricouarf. All rights reserved. +// + +import Foundation + +protocol Action { + +} diff --git a/Other Projects/SwiftUI + Redux/SwiftUIDemo/flux/actions/UsersAction.swift b/Other Projects/SwiftUI + Redux/SwiftUIDemo/flux/actions/UsersAction.swift new file mode 100644 index 0000000..88631a8 --- /dev/null +++ b/Other Projects/SwiftUI + Redux/SwiftUIDemo/flux/actions/UsersAction.swift @@ -0,0 +1,19 @@ +// +// UsersAction.swift +// SwiftUIDemo +// +// Created by Thomas Ricouard on 05/06/2019. +// Copyright © 2019 Thomas Ricouarf. All rights reserved. +// + +import Foundation + +enum UserActions: Action { + case addUser + case deleteUser(index: Int) + case move(from: Int, to: Int) + case editUser(id: Int, name: String, username: String) + case testEditFirstUser + case startEditUser + case stopEditUser +} diff --git a/Other Projects/SwiftUI + Redux/SwiftUIDemo/flux/models/User.swift b/Other Projects/SwiftUI + Redux/SwiftUIDemo/flux/models/User.swift new file mode 100644 index 0000000..616ee06 --- /dev/null +++ b/Other Projects/SwiftUI + Redux/SwiftUIDemo/flux/models/User.swift @@ -0,0 +1,20 @@ +// +// User.swift +// SwiftUIDemo +// +// Created by Thomas Ricouard on 04/06/2019. +// Copyright © 2019 Thomas Ricouarf. All rights reserved. +// + +import Foundation +import SwiftUI + +struct User: Identifiable { + let id: Int + var name: String + var username: String + let imageName = "person" +} + +let sampleData = [User(id: 0, name: "user 1", username: "@user1"), + User(id: 1, name: "user 2", username: "@user2")] diff --git a/Other Projects/SwiftUI + Redux/SwiftUIDemo/flux/reducers/Reducer.swift b/Other Projects/SwiftUI + Redux/SwiftUIDemo/flux/reducers/Reducer.swift new file mode 100644 index 0000000..d89a916 --- /dev/null +++ b/Other Projects/SwiftUI + Redux/SwiftUIDemo/flux/reducers/Reducer.swift @@ -0,0 +1,14 @@ +// +// Reducer.swift +// SwiftUIDemo +// +// Created by Thomas Ricouard on 05/06/2019. +// Copyright © 2019 Thomas Ricouarf. All rights reserved. +// + +import Foundation + +protocol Reducer { + associatedtype StateType: FluxState + func reduce(state: StateType, action: Action) -> StateType +} diff --git a/Other Projects/SwiftUI + Redux/SwiftUIDemo/flux/reducers/UsersStateReducer.swift b/Other Projects/SwiftUI + Redux/SwiftUIDemo/flux/reducers/UsersStateReducer.swift new file mode 100644 index 0000000..b2d492e --- /dev/null +++ b/Other Projects/SwiftUI + Redux/SwiftUIDemo/flux/reducers/UsersStateReducer.swift @@ -0,0 +1,42 @@ +// +// UsersStateReducer.swift +// SwiftUIDemo +// +// Created by Thomas Ricouard on 05/06/2019. +// Copyright © 2019 Thomas Ricouarf. All rights reserved. +// + +import Foundation + +struct UserStateReducer: Reducer { + func reduce(state: UsersState, action: Action) -> UsersState { + var state = state + switch action { + case UserActions.addUser: + state.users.append(User(id: state.users.count, + name: "New user \(state.users.count + 1)", + username: "@newuser\(state.users.count + 1)")) + case let UserActions.deleteUser(index): + state.users.remove(at: index) + case let UserActions.move(from, to): + let user = state.users.remove(at: from) + state.users.insert(user, at: to) + case let UserActions.editUser(id, name, username): + var user = state.users[id] + user.name = name + user.username = username + state.users[id] = user + case UserActions.testEditFirstUser: + if !state.users.isEmpty { + state.users[0] = User(id: 0, name: "user1", username: "u\ns\ne\nr\nn\na\nm\ne") + } + case UserActions.startEditUser: + state.isEditingUser = true + case UserActions.stopEditUser: + state.isEditingUser = false + default: + break + } + return state + } +} diff --git a/Other Projects/SwiftUI + Redux/SwiftUIDemo/flux/states/AppState.swift b/Other Projects/SwiftUI + Redux/SwiftUIDemo/flux/states/AppState.swift new file mode 100644 index 0000000..067ccce --- /dev/null +++ b/Other Projects/SwiftUI + Redux/SwiftUIDemo/flux/states/AppState.swift @@ -0,0 +1,34 @@ +// +// AppStore.swift +// SwiftUIDemo +// +// Created by Thomas Ricouard on 05/06/2019. +// Copyright © 2019 Thomas Ricouarf. All rights reserved. +// + +import Foundation +import SwiftUI +import Combine + +final class AppState: ObservableObject { + var objectWillChange = PassthroughSubject() + + var usersState: UsersState + + init(usersState: UsersState = UsersState()) { + self.usersState = usersState + } + + func dispatch(action: Action) { + usersState = UserStateReducer().reduce(state: usersState, action: action) + objectWillChange.send(self) + } +} + +let store = AppState() + +#if DEBUG +let sampleStore = AppState(usersState: UsersState(users: sampleData)) +#endif + + diff --git a/Other Projects/SwiftUI + Redux/SwiftUIDemo/flux/states/FluxState.swift b/Other Projects/SwiftUI + Redux/SwiftUIDemo/flux/states/FluxState.swift new file mode 100644 index 0000000..4c6243a --- /dev/null +++ b/Other Projects/SwiftUI + Redux/SwiftUIDemo/flux/states/FluxState.swift @@ -0,0 +1,11 @@ +// +// FluxState.swift +// SwiftUIDemo +// +// Created by Thomas Ricouard on 05/06/2019. +// Copyright © 2019 Thomas Ricouarf. All rights reserved. +// + +import Foundation + +protocol FluxState { } diff --git a/Other Projects/SwiftUI + Redux/SwiftUIDemo/flux/states/UsersState.swift b/Other Projects/SwiftUI + Redux/SwiftUIDemo/flux/states/UsersState.swift new file mode 100644 index 0000000..6f96bd9 --- /dev/null +++ b/Other Projects/SwiftUI + Redux/SwiftUIDemo/flux/states/UsersState.swift @@ -0,0 +1,20 @@ +// +// UsersStore.swift +// SwiftUIDemo +// +// Created by Thomas Ricouard on 04/06/2019. +// Copyright © 2019 Thomas Ricouarf. All rights reserved. +// + +import Foundation +import SwiftUI +import Combine + +struct UsersState: FluxState { + var users: [User] + var isEditingUser = false + + init(users: [User] = []) { + self.users = users + } +} diff --git a/Other Projects/SwiftUI + Redux/SwiftUIDemo/views/TabbarView.swift b/Other Projects/SwiftUI + Redux/SwiftUIDemo/views/TabbarView.swift new file mode 100644 index 0000000..8e2c1f8 --- /dev/null +++ b/Other Projects/SwiftUI + Redux/SwiftUIDemo/views/TabbarView.swift @@ -0,0 +1,32 @@ +// +// MainView.swift +// SwiftUIDemo +// +// Created by Thomas Ricouard on 05/06/2019. +// Copyright © 2019 Thomas Ricouarf. All rights reserved. +// + +import SwiftUI + +struct TabbarView : View { + @EnvironmentObject var state: AppState + @State var selectedIndex: Int = 0 + + var body: some View { + TabView(selection: $selectedIndex) { + UsersListView() + .tabItem({ Text("Users") }) + MapView() + .tabItem({ Text("Map") }) + } + } +} + +#if DEBUG +struct MainView_Previews : PreviewProvider { + static var previews: some View { + TabbarView(selectedIndex: 0).environmentObject(sampleStore) + } +} +#endif + diff --git a/Other Projects/SwiftUI + Redux/SwiftUIDemo/views/map/MapView.swift b/Other Projects/SwiftUI + Redux/SwiftUIDemo/views/map/MapView.swift new file mode 100644 index 0000000..72a5010 --- /dev/null +++ b/Other Projects/SwiftUI + Redux/SwiftUIDemo/views/map/MapView.swift @@ -0,0 +1,36 @@ + +// +// MapVie.swift +// SwiftUIDemo +// +// Created by Thomas Ricouard on 05/06/2019. +// Copyright © 2019 Thomas Ricouarf. All rights reserved. +// + +import SwiftUI +import UIKit +import MapKit + +struct MapViewRepresentable: UIViewRepresentable { + func makeUIView(context: Context) -> MKMapView { + return MKMapView() + } + + func updateUIView(_ uiView: MKMapView, context: Context) { + + } +} + +struct MapView : View { + var body: some View { + MapViewRepresentable() + } +} + +#if DEBUG +struct MapVie_Previews : PreviewProvider { + static var previews: some View { + MapView() + } +} +#endif diff --git a/Other Projects/SwiftUI + Redux/SwiftUIDemo/views/users/UserDetailView.swift b/Other Projects/SwiftUI + Redux/SwiftUIDemo/views/users/UserDetailView.swift new file mode 100644 index 0000000..b623d01 --- /dev/null +++ b/Other Projects/SwiftUI + Redux/SwiftUIDemo/views/users/UserDetailView.swift @@ -0,0 +1,48 @@ +// +// UserDetailView.swift +// SwiftUIDemo +// +// Created by Thomas Ricouard on 04/06/2019. +// Copyright © 2019 Thomas Ricouarf. All rights reserved. +// + +import SwiftUI +import Combine + +struct UserDetailView : View { + @EnvironmentObject var state: AppState + let userId: Int + + var body: some View { + let user = state.usersState.users[userId] + return VStack { + Image(systemName: user.imageName) + Text(user.name) + Text(user.username).lineLimit(0) + } + .navigationBarTitle(Text(user.name), displayMode: .inline) + .navigationBarItems(trailing: + Button(action: { + self.state.dispatch(action: UserActions.startEditUser) + }) { + Text("Edit user") + } + .sheet(isPresented: $state.usersState.isEditingUser) { + UserEditForm(userId: user.id, saveHandler: { saved in + self.state.dispatch(action: UserActions.stopEditUser) + }) + }) + } +} + +#if DEBUG +struct UserDetailView_Previews : PreviewProvider { + static var previews: some View { + NavigationView { + UserDetailView(userId: 0).environmentObject(sampleStore) + } + } +} +#endif + + diff --git a/Other Projects/SwiftUI + Redux/SwiftUIDemo/views/users/UserEditForm.swift b/Other Projects/SwiftUI + Redux/SwiftUIDemo/views/users/UserEditForm.swift new file mode 100644 index 0000000..5283b22 --- /dev/null +++ b/Other Projects/SwiftUI + Redux/SwiftUIDemo/views/users/UserEditForm.swift @@ -0,0 +1,88 @@ + // + // UserEditForm.swift + // SwiftUIDemo + // + // Created by Thomas Ricouard on 05/06/2019. + // Copyright © 2019 Thomas Ricouarf. All rights reserved. + // + + import SwiftUI + + struct UserEditForm : View { + @EnvironmentObject var state: AppState + + let userId: Int + let saveHandler: ((Bool) -> Swift.Void)? + + @State var newUserName = "" + @State var newUserUsername = "" + @State var showSaved = false + @State var showError = false + + var body: some View { + let user = state.usersState.users[userId] + return NavigationView { + VStack(alignment: .leading, spacing: 10) { + Text("User name") + TextField("New name", text: $newUserName) + .textFieldStyle(RoundedBorderTextFieldStyle()) + Divider() + Text("Username") + TextField("New username", text: $newUserUsername) + .textFieldStyle(RoundedBorderTextFieldStyle()) + }.padding(16) + Button(action: save) { + Text("Save") + .padding(8) + .foregroundColor(.white) + .background(Color.green) + .cornerRadius(8) + } + .navigationBarItems(trailing: Button(action: close) { + Text("Close") + }) + .navigationBarTitle(Text("Edit \(user.name)"), displayMode: .inline) + + Badge(text: "Saved successfully", color: .green, show: $showSaved) + Badge(text: "Missing username or name", color: .red, show: $showError) + } + } + + func save() { + guard !newUserName.isEmpty && !newUserUsername.isEmpty else { + withAnimation{ + showError = true + } + DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) { + self.showError = false + } + return + } + + withAnimation { + showSaved = true + } + + DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) { + self.showSaved = false + } + + state.dispatch(action: UserActions.editUser(id: userId, name: newUserName, username: newUserUsername)) + saveHandler?(true) + } + + func close() { + saveHandler?(false) + } + } + + #if DEBUG + struct UserEditForm_Previews : PreviewProvider { + static var previews: some View { + UserEditForm(userId: 0, saveHandler: nil).environmentObject(sampleStore) + } + } + #endif + + + diff --git a/Other Projects/SwiftUI + Redux/SwiftUIDemo/views/users/UsersListView.swift b/Other Projects/SwiftUI + Redux/SwiftUIDemo/views/users/UsersListView.swift new file mode 100644 index 0000000..460afe8 --- /dev/null +++ b/Other Projects/SwiftUI + Redux/SwiftUIDemo/views/users/UsersListView.swift @@ -0,0 +1,67 @@ +// +// ContentView.swift +// SwiftUIDemo +// +// Created by Thomas Ricouard on 04/06/2019. +// Copyright © 2019 Thomas Ricouarf. All rights reserved. +// + +import SwiftUI + +struct UsersListView : View { + @EnvironmentObject var state: AppState + + var body: some View { + NavigationView { + List { + Section { + Button(action: addUser) { + Text("Add user") + } + Button(action: targetUpdate) { + Text("Update first") + } + } + Section { + ForEach(state.usersState.users) {user in + NavigationLink(destination: UserDetailView(userId: user.id) + .environmentObject(self.state)) { + UserRow(user: user) + } + } + .onDelete(perform: delete) + .onMove(perform: move) + } + } + .listStyle(GroupedListStyle()) + .navigationBarTitle(Text("Users (\(state.usersState.users.count))")) + .navigationBarItems(trailing: EditButton()) + } + + } + + func addUser() { + state.dispatch(action: UserActions.addUser) + + } + + func targetUpdate() { + state.dispatch(action: UserActions.testEditFirstUser) + } + + func delete(at offset: IndexSet) { + state.dispatch(action: UserActions.deleteUser(index: offset.first!)) + } + + func move(from: IndexSet, to: Int) { + state.dispatch(action: UserActions.move(from: from.first!, to: to)) + } +} + +#if DEBUG +struct ContentView_Previews : PreviewProvider { + static var previews: some View { + UsersListView().environmentObject(sampleStore) + } +} +#endif diff --git a/Other Projects/SwiftUI + Redux/SwiftUIDemo/views/users/component/Badge.swift b/Other Projects/SwiftUI + Redux/SwiftUIDemo/views/users/component/Badge.swift new file mode 100644 index 0000000..15e71bf --- /dev/null +++ b/Other Projects/SwiftUI + Redux/SwiftUIDemo/views/users/component/Badge.swift @@ -0,0 +1,32 @@ +// +// GreenBadge.swift +// SwiftUIDemo +// +// Created by Thomas Ricouard on 06/06/2019. +// Copyright © 2019 Thomas Ricouarf. All rights reserved. +// + +import SwiftUI + +struct Badge : View { + let text: String + let color: Color + @Binding var show: Bool + + var animation: Animation { + Animation + .spring() + .speed(2) + } + + var body: some View { + Text(text) + .foregroundColor(.white) + .padding() + .background(color) + .cornerRadius(8) + .scaleEffect(show ? 1: 0.5) + .opacity(show ? 1 : 0) + .animation(animation) + } +} diff --git a/Other Projects/SwiftUI + Redux/SwiftUIDemo/views/users/rows/UserRow.swift b/Other Projects/SwiftUI + Redux/SwiftUIDemo/views/users/rows/UserRow.swift new file mode 100644 index 0000000..62d8c81 --- /dev/null +++ b/Other Projects/SwiftUI + Redux/SwiftUIDemo/views/users/rows/UserRow.swift @@ -0,0 +1,36 @@ +// +// UserRw.swift +// SwiftUIDemo +// +// Created by Thomas Ricouard on 04/06/2019. +// Copyright © 2019 Thomas Ricouarf. All rights reserved. +// + +import SwiftUI + +struct UserRow : View { + let user: User + + var body: some View { + VStack { + HStack { + Image(systemName: user.imageName) + + VStack { + Text(user.name) + Text(user.username) + .foregroundColor(.secondary) + .lineLimit(0) + } + } + } + } +} + +#if DEBUG +struct UserRw_Previews : PreviewProvider { + static var previews: some View { + UserRow(user: sampleData[0]) + } +} +#endif diff --git a/Other Projects/Tempus RomanumIl/TempusRomanum.xcodeproj/project.pbxproj b/Other Projects/Tempus RomanumIl/TempusRomanum.xcodeproj/project.pbxproj new file mode 100644 index 0000000..635ea0c --- /dev/null +++ b/Other Projects/Tempus RomanumIl/TempusRomanum.xcodeproj/project.pbxproj @@ -0,0 +1,351 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 50; + objects = { + +/* Begin PBXBuildFile section */ + 96A09A3F22AA0F3A00FE6BC6 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96A09A3E22AA0F3A00FE6BC6 /* AppDelegate.swift */; }; + 96A09A4122AA0F3A00FE6BC6 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96A09A4022AA0F3A00FE6BC6 /* SceneDelegate.swift */; }; + 96A09A4522AA0F3D00FE6BC6 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 96A09A4422AA0F3D00FE6BC6 /* Assets.xcassets */; }; + 96A09A4822AA0F3D00FE6BC6 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 96A09A4722AA0F3D00FE6BC6 /* Preview Assets.xcassets */; }; + 96A09A4B22AA0F3D00FE6BC6 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 96A09A4922AA0F3D00FE6BC6 /* LaunchScreen.storyboard */; }; + 96A09A6F22AA110600FE6BC6 /* Home.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96A09A6E22AA110600FE6BC6 /* Home.swift */; }; + 96A09A7122AA11D600FE6BC6 /* ClockView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96A09A7022AA11D600FE6BC6 /* ClockView.swift */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 96A09A3B22AA0F3A00FE6BC6 /* TempusRomanum.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = TempusRomanum.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 96A09A3E22AA0F3A00FE6BC6 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 96A09A4022AA0F3A00FE6BC6 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; + 96A09A4422AA0F3D00FE6BC6 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 96A09A4722AA0F3D00FE6BC6 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; + 96A09A4A22AA0F3D00FE6BC6 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 96A09A4C22AA0F3D00FE6BC6 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 96A09A6E22AA110600FE6BC6 /* Home.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Home.swift; sourceTree = ""; }; + 96A09A7022AA11D600FE6BC6 /* ClockView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ClockView.swift; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 96A09A3822AA0F3A00FE6BC6 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 96A09A3222AA0F3A00FE6BC6 = { + isa = PBXGroup; + children = ( + 96A09A3D22AA0F3A00FE6BC6 /* TempusRomanum */, + 96A09A3C22AA0F3A00FE6BC6 /* Products */, + ); + sourceTree = ""; + }; + 96A09A3C22AA0F3A00FE6BC6 /* Products */ = { + isa = PBXGroup; + children = ( + 96A09A3B22AA0F3A00FE6BC6 /* TempusRomanum.app */, + ); + name = Products; + sourceTree = ""; + }; + 96A09A3D22AA0F3A00FE6BC6 /* TempusRomanum */ = { + isa = PBXGroup; + children = ( + 96A09A3E22AA0F3A00FE6BC6 /* AppDelegate.swift */, + 96A09A4422AA0F3D00FE6BC6 /* Assets.xcassets */, + 96A09A7022AA11D600FE6BC6 /* ClockView.swift */, + 96A09A6E22AA110600FE6BC6 /* Home.swift */, + 96A09A4C22AA0F3D00FE6BC6 /* Info.plist */, + 96A09A4922AA0F3D00FE6BC6 /* LaunchScreen.storyboard */, + 96A09A4622AA0F3D00FE6BC6 /* Preview Content */, + 96A09A4022AA0F3A00FE6BC6 /* SceneDelegate.swift */, + ); + path = TempusRomanum; + sourceTree = ""; + }; + 96A09A4622AA0F3D00FE6BC6 /* Preview Content */ = { + isa = PBXGroup; + children = ( + 96A09A4722AA0F3D00FE6BC6 /* Preview Assets.xcassets */, + ); + path = "Preview Content"; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 96A09A3A22AA0F3A00FE6BC6 /* TempusRomanum */ = { + isa = PBXNativeTarget; + buildConfigurationList = 96A09A6522AA0F3E00FE6BC6 /* Build configuration list for PBXNativeTarget "TempusRomanum" */; + buildPhases = ( + 96A09A3722AA0F3A00FE6BC6 /* Sources */, + 96A09A3822AA0F3A00FE6BC6 /* Frameworks */, + 96A09A3922AA0F3A00FE6BC6 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = TempusRomanum; + productName = TempusRomanum; + productReference = 96A09A3B22AA0F3A00FE6BC6 /* TempusRomanum.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 96A09A3322AA0F3A00FE6BC6 /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 1100; + LastUpgradeCheck = 1100; + ORGANIZATIONNAME = "Poikile Creations"; + TargetAttributes = { + 96A09A3A22AA0F3A00FE6BC6 = { + CreatedOnToolsVersion = 11.0; + }; + }; + }; + buildConfigurationList = 96A09A3622AA0F3A00FE6BC6 /* Build configuration list for PBXProject "TempusRomanum" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 96A09A3222AA0F3A00FE6BC6; + productRefGroup = 96A09A3C22AA0F3A00FE6BC6 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 96A09A3A22AA0F3A00FE6BC6 /* TempusRomanum */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 96A09A3922AA0F3A00FE6BC6 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 96A09A4B22AA0F3D00FE6BC6 /* LaunchScreen.storyboard in Resources */, + 96A09A4822AA0F3D00FE6BC6 /* Preview Assets.xcassets in Resources */, + 96A09A4522AA0F3D00FE6BC6 /* Assets.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 96A09A3722AA0F3A00FE6BC6 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 96A09A3F22AA0F3A00FE6BC6 /* AppDelegate.swift in Sources */, + 96A09A6F22AA110600FE6BC6 /* Home.swift in Sources */, + 96A09A7122AA11D600FE6BC6 /* ClockView.swift in Sources */, + 96A09A4122AA0F3A00FE6BC6 /* SceneDelegate.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 96A09A4922AA0F3D00FE6BC6 /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 96A09A4A22AA0F3D00FE6BC6 /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 96A09A6322AA0F3E00FE6BC6 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + 96A09A6422AA0F3E00FE6BC6 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 96A09A6622AA0F3E00FE6BC6 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_ASSET_PATHS = "TempusRomanum/Preview\\ Content"; + DEVELOPMENT_TEAM = 3MY7LL9G36; + ENABLE_PREVIEWS = YES; + INFOPLIST_FILE = TempusRomanum/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = org.poikile.TempusRomanum; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 96A09A6722AA0F3E00FE6BC6 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_ASSET_PATHS = "TempusRomanum/Preview\\ Content"; + DEVELOPMENT_TEAM = 3MY7LL9G36; + ENABLE_PREVIEWS = YES; + INFOPLIST_FILE = TempusRomanum/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = org.poikile.TempusRomanum; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 96A09A3622AA0F3A00FE6BC6 /* Build configuration list for PBXProject "TempusRomanum" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 96A09A6322AA0F3E00FE6BC6 /* Debug */, + 96A09A6422AA0F3E00FE6BC6 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 96A09A6522AA0F3E00FE6BC6 /* Build configuration list for PBXNativeTarget "TempusRomanum" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 96A09A6622AA0F3E00FE6BC6 /* Debug */, + 96A09A6722AA0F3E00FE6BC6 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 96A09A3322AA0F3A00FE6BC6 /* Project object */; +} diff --git a/Other Projects/Tempus RomanumIl/TempusRomanum.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/Other Projects/Tempus RomanumIl/TempusRomanum.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..d4d9ae6 --- /dev/null +++ b/Other Projects/Tempus RomanumIl/TempusRomanum.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/Other Projects/Tempus RomanumIl/TempusRomanum.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/Other Projects/Tempus RomanumIl/TempusRomanum.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/Other Projects/Tempus RomanumIl/TempusRomanum.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/Other Projects/Tempus RomanumIl/TempusRomanum/AppDelegate.swift b/Other Projects/Tempus RomanumIl/TempusRomanum/AppDelegate.swift new file mode 100644 index 0000000..12622aa --- /dev/null +++ b/Other Projects/Tempus RomanumIl/TempusRomanum/AppDelegate.swift @@ -0,0 +1,35 @@ +// Copyright © 2019 Poikile Creations. All rights reserved. + +import UIKit + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + + + + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { + // Override point for customization after application launch. + return true + } + + func applicationWillTerminate(_ application: UIApplication) { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. + } + + // MARK: UISceneSession Lifecycle + + func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration { + // Called when a new scene session is being created. + // Use this method to select a configuration to create the new scene with. + return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role) + } + + func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) { + // Called when the user discards a scene session. + // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions. + // Use this method to release any resources that were specific to the discarded scenes, as they will not return. + } + + +} + diff --git a/Other Projects/Tempus RomanumIl/TempusRomanum/Assets.xcassets/AppIcon.appiconset/Contents.json b/Other Projects/Tempus RomanumIl/TempusRomanum/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..d8db8d6 --- /dev/null +++ b/Other Projects/Tempus RomanumIl/TempusRomanum/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,98 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "83.5x83.5", + "scale" : "2x" + }, + { + "idiom" : "ios-marketing", + "size" : "1024x1024", + "scale" : "1x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/Tempus RomanumIl/TempusRomanum/Assets.xcassets/Contents.json b/Other Projects/Tempus RomanumIl/TempusRomanum/Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/Other Projects/Tempus RomanumIl/TempusRomanum/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/Tempus RomanumIl/TempusRomanum/Base.lproj/LaunchScreen.storyboard b/Other Projects/Tempus RomanumIl/TempusRomanum/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000..865e932 --- /dev/null +++ b/Other Projects/Tempus RomanumIl/TempusRomanum/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Other Projects/Tempus RomanumIl/TempusRomanum/ClockView.swift b/Other Projects/Tempus RomanumIl/TempusRomanum/ClockView.swift new file mode 100644 index 0000000..feab451 --- /dev/null +++ b/Other Projects/Tempus RomanumIl/TempusRomanum/ClockView.swift @@ -0,0 +1,55 @@ +// Copyright © 2019 Poikile Creations. All rights reserved. + +import SwiftUI + +struct ClockView : View { + + @State var showMilitaryTime = false + + private var dateFormatter: DateFormatter = { + let formatter = DateFormatter() + formatter.timeStyle = .short + + return formatter + }() + + private var militaryDateFormatter: DateFormatter = { + let formatter = DateFormatter() + formatter.dateFormat = "HH:MM" + + return formatter + }() + + private var timeString: String { + if showMilitaryTime { + return militaryDateFormatter.string(from: Date()) + } else { + return dateFormatter.string(from: Date()) + } + } + + var body: some View { + VStack { + Button(action: { + self.showMilitaryTime.toggle() + }) { + Text(self.timeString) + .font(.headline) + } +// +// Text("quinta hora noctis") +// .font(.subheadline) +// .italic() +// .padding(.top, 10) + } + } + +} + +#if DEBUG +struct Clock_Previews : PreviewProvider { + static var previews: some View { + ClockView() + } +} +#endif diff --git a/Other Projects/Tempus RomanumIl/TempusRomanum/Home.swift b/Other Projects/Tempus RomanumIl/TempusRomanum/Home.swift new file mode 100644 index 0000000..ec44aa1 --- /dev/null +++ b/Other Projects/Tempus RomanumIl/TempusRomanum/Home.swift @@ -0,0 +1,20 @@ +// Copyright © 2019 Poikile Creations. All rights reserved. + +import SwiftUI + +struct Home : View { + var body: some View { + VStack { + Text("Hello World") + ClockView() + } + } +} + +#if DEBUG +struct Home_Previews : PreviewProvider { + static var previews: some View { + Home() + } +} +#endif diff --git a/Other Projects/Tempus RomanumIl/TempusRomanum/Info.plist b/Other Projects/Tempus RomanumIl/TempusRomanum/Info.plist new file mode 100644 index 0000000..e8bb4c6 --- /dev/null +++ b/Other Projects/Tempus RomanumIl/TempusRomanum/Info.plist @@ -0,0 +1,62 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + $(PRODUCT_BUNDLE_PACKAGE_TYPE) + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UIApplicationSceneManifest + + UIApplicationSupportsMultipleScenes + + UISceneConfigurations + + UIWindowSceneSessionRoleApplication + + + UILaunchStoryboardName + LaunchScreen + UISceneConfigurationName + Default Configuration + UISceneDelegateClassName + $(PRODUCT_MODULE_NAME).SceneDelegate + + + + + UILaunchStoryboardName + LaunchScreen + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/Other Projects/Tempus RomanumIl/TempusRomanum/Preview Content/Preview Assets.xcassets/Contents.json b/Other Projects/Tempus RomanumIl/TempusRomanum/Preview Content/Preview Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/Other Projects/Tempus RomanumIl/TempusRomanum/Preview Content/Preview Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/Tempus RomanumIl/TempusRomanum/SceneDelegate.swift b/Other Projects/Tempus RomanumIl/TempusRomanum/SceneDelegate.swift new file mode 100644 index 0000000..537a5f5 --- /dev/null +++ b/Other Projects/Tempus RomanumIl/TempusRomanum/SceneDelegate.swift @@ -0,0 +1,55 @@ +// Copyright © 2019 Poikile Creations. All rights reserved. + +import UIKit +import SwiftUI + +class SceneDelegate: UIResponder, UIWindowSceneDelegate { + + var window: UIWindow? + + + func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { + // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`. + // If using a storyboard, the `window` property will automatically be initialized and attached to the scene. + // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead). + + // Use a UIHostingController as window root view controller + if let windowScene = scene as? UIWindowScene { + let window = UIWindow(windowScene: windowScene) + window.rootViewController = UIHostingController(rootView: Home()) + self.window = window + window.makeKeyAndVisible() + } + } + + func sceneDidDisconnect(_ scene: UIScene) { + // Called as the scene is being released by the system. + // This occurs shortly after the scene enters the background, or when its session is discarded. + // Release any resources associated with this scene that can be re-created the next time the scene connects. + // The scene may re-connect later, as its session was not neccessarily discarded (see `application:didDiscardSceneSessions` instead). + } + + func sceneDidBecomeActive(_ scene: UIScene) { + // Called when the scene has moved from an inactive state to an active state. + // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive. + } + + func sceneWillResignActive(_ scene: UIScene) { + // Called when the scene will move from an active state to an inactive state. + // This may occur due to temporary interruptions (ex. an incoming phone call). + } + + func sceneWillEnterForeground(_ scene: UIScene) { + // Called as the scene transitions from the background to the foreground. + // Use this method to undo the changes made on entering the background. + } + + func sceneDidEnterBackground(_ scene: UIScene) { + // Called as the scene transitions from the foreground to the background. + // Use this method to save data, release shared resources, and store enough scene-specific state information + // to restore the scene back to its current state. + } + + +} + diff --git a/Other Projects/Time Travel/SwiftUITimeTravel.xcodeproj/project.pbxproj b/Other Projects/Time Travel/SwiftUITimeTravel.xcodeproj/project.pbxproj new file mode 100644 index 0000000..c7872f5 --- /dev/null +++ b/Other Projects/Time Travel/SwiftUITimeTravel.xcodeproj/project.pbxproj @@ -0,0 +1,421 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 50; + objects = { + +/* Begin PBXBuildFile section */ + 22316DC622A7B255004124F2 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 22316DC522A7B255004124F2 /* AppDelegate.swift */; }; + 22316DC822A7B255004124F2 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 22316DC722A7B255004124F2 /* SceneDelegate.swift */; }; + 22316DCA22A7B255004124F2 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 22316DC922A7B255004124F2 /* ContentView.swift */; }; + 22316DCC22A7B255004124F2 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 22316DCB22A7B255004124F2 /* Assets.xcassets */; }; + 22316DCF22A7B255004124F2 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 22316DCE22A7B255004124F2 /* Preview Assets.xcassets */; }; + 22316DD222A7B255004124F2 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 22316DD022A7B255004124F2 /* LaunchScreen.storyboard */; }; + 22316DE722A7B287004124F2 /* TodoListItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 22316DE022A7B263004124F2 /* TodoListItemView.swift */; }; + 22316DE822A7B287004124F2 /* ModalDimmingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 22316DE122A7B263004124F2 /* ModalDimmingView.swift */; }; + 22316DE922A7B287004124F2 /* AddItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 22316DE222A7B263004124F2 /* AddItemView.swift */; }; + 22316DEA22A7B28B004124F2 /* TodoItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 22316DE422A7B263004124F2 /* TodoItem.swift */; }; + 22316DEB22A7B28B004124F2 /* TodoState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 22316DE522A7B263004124F2 /* TodoState.swift */; }; + 22316DEC22A7B28D004124F2 /* TodoListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 22316DE622A7B263004124F2 /* TodoListView.swift */; }; + 22316DED22A7B291004124F2 /* StateMachine.swift in Sources */ = {isa = PBXBuildFile; fileRef = 22316DDA22A7B263004124F2 /* StateMachine.swift */; }; + 22316DEE22A7B291004124F2 /* TimeTravelView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 22316DDB22A7B263004124F2 /* TimeTravelView.swift */; }; + 22316DEF22A7B291004124F2 /* Store.swift in Sources */ = {isa = PBXBuildFile; fileRef = 22316DDC22A7B263004124F2 /* Store.swift */; }; + 22316DF022A7B291004124F2 /* TimeTravelBarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 22316DDD22A7B263004124F2 /* TimeTravelBarView.swift */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 22316DC222A7B255004124F2 /* SwiftUITimeTravel.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SwiftUITimeTravel.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 22316DC522A7B255004124F2 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 22316DC722A7B255004124F2 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; + 22316DC922A7B255004124F2 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; }; + 22316DCB22A7B255004124F2 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 22316DCE22A7B255004124F2 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; + 22316DD122A7B255004124F2 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 22316DD322A7B255004124F2 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 22316DDA22A7B263004124F2 /* StateMachine.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StateMachine.swift; sourceTree = ""; }; + 22316DDB22A7B263004124F2 /* TimeTravelView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimeTravelView.swift; sourceTree = ""; }; + 22316DDC22A7B263004124F2 /* Store.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Store.swift; sourceTree = ""; }; + 22316DDD22A7B263004124F2 /* TimeTravelBarView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimeTravelBarView.swift; sourceTree = ""; }; + 22316DE022A7B263004124F2 /* TodoListItemView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TodoListItemView.swift; sourceTree = ""; }; + 22316DE122A7B263004124F2 /* ModalDimmingView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ModalDimmingView.swift; sourceTree = ""; }; + 22316DE222A7B263004124F2 /* AddItemView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddItemView.swift; sourceTree = ""; }; + 22316DE422A7B263004124F2 /* TodoItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TodoItem.swift; sourceTree = ""; }; + 22316DE522A7B263004124F2 /* TodoState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TodoState.swift; sourceTree = ""; }; + 22316DE622A7B263004124F2 /* TodoListView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TodoListView.swift; sourceTree = ""; }; + 22316DF122A7B3FB004124F2 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 22316DBF22A7B255004124F2 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 22316DB922A7B255004124F2 = { + isa = PBXGroup; + children = ( + 22316DF122A7B3FB004124F2 /* README.md */, + 22316DC422A7B255004124F2 /* SwiftUITimeTravel */, + 22316DC322A7B255004124F2 /* Products */, + ); + sourceTree = ""; + }; + 22316DC322A7B255004124F2 /* Products */ = { + isa = PBXGroup; + children = ( + 22316DC222A7B255004124F2 /* SwiftUITimeTravel.app */, + ); + name = Products; + sourceTree = ""; + }; + 22316DC422A7B255004124F2 /* SwiftUITimeTravel */ = { + isa = PBXGroup; + children = ( + 22316DD922A7B263004124F2 /* TimeTravelView */, + 22316DDE22A7B263004124F2 /* TodoList */, + 22316DC522A7B255004124F2 /* AppDelegate.swift */, + 22316DC722A7B255004124F2 /* SceneDelegate.swift */, + 22316DC922A7B255004124F2 /* ContentView.swift */, + 22316DCB22A7B255004124F2 /* Assets.xcassets */, + 22316DD022A7B255004124F2 /* LaunchScreen.storyboard */, + 22316DD322A7B255004124F2 /* Info.plist */, + 22316DCD22A7B255004124F2 /* Preview Content */, + ); + path = SwiftUITimeTravel; + sourceTree = ""; + }; + 22316DCD22A7B255004124F2 /* Preview Content */ = { + isa = PBXGroup; + children = ( + 22316DCE22A7B255004124F2 /* Preview Assets.xcassets */, + ); + path = "Preview Content"; + sourceTree = ""; + }; + 22316DD922A7B263004124F2 /* TimeTravelView */ = { + isa = PBXGroup; + children = ( + 22316DDA22A7B263004124F2 /* StateMachine.swift */, + 22316DDB22A7B263004124F2 /* TimeTravelView.swift */, + 22316DDC22A7B263004124F2 /* Store.swift */, + 22316DDD22A7B263004124F2 /* TimeTravelBarView.swift */, + ); + path = TimeTravelView; + sourceTree = ""; + }; + 22316DDE22A7B263004124F2 /* TodoList */ = { + isa = PBXGroup; + children = ( + 22316DDF22A7B263004124F2 /* Internal Views */, + 22316DE322A7B263004124F2 /* Model */, + 22316DE622A7B263004124F2 /* TodoListView.swift */, + ); + path = TodoList; + sourceTree = ""; + }; + 22316DDF22A7B263004124F2 /* Internal Views */ = { + isa = PBXGroup; + children = ( + 22316DE022A7B263004124F2 /* TodoListItemView.swift */, + 22316DE122A7B263004124F2 /* ModalDimmingView.swift */, + 22316DE222A7B263004124F2 /* AddItemView.swift */, + ); + path = "Internal Views"; + sourceTree = ""; + }; + 22316DE322A7B263004124F2 /* Model */ = { + isa = PBXGroup; + children = ( + 22316DE422A7B263004124F2 /* TodoItem.swift */, + 22316DE522A7B263004124F2 /* TodoState.swift */, + ); + path = Model; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 22316DC122A7B255004124F2 /* SwiftUITimeTravel */ = { + isa = PBXNativeTarget; + buildConfigurationList = 22316DD622A7B255004124F2 /* Build configuration list for PBXNativeTarget "SwiftUITimeTravel" */; + buildPhases = ( + 22316DBE22A7B255004124F2 /* Sources */, + 22316DBF22A7B255004124F2 /* Frameworks */, + 22316DC022A7B255004124F2 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = SwiftUITimeTravel; + productName = SwiftUITimeTravel; + productReference = 22316DC222A7B255004124F2 /* SwiftUITimeTravel.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 22316DBA22A7B255004124F2 /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 1100; + LastUpgradeCheck = 1100; + ORGANIZATIONNAME = "Tim Donnelly"; + TargetAttributes = { + 22316DC122A7B255004124F2 = { + CreatedOnToolsVersion = 11.0; + }; + }; + }; + buildConfigurationList = 22316DBD22A7B255004124F2 /* Build configuration list for PBXProject "SwiftUITimeTravel" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 22316DB922A7B255004124F2; + productRefGroup = 22316DC322A7B255004124F2 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 22316DC122A7B255004124F2 /* SwiftUITimeTravel */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 22316DC022A7B255004124F2 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 22316DD222A7B255004124F2 /* LaunchScreen.storyboard in Resources */, + 22316DCF22A7B255004124F2 /* Preview Assets.xcassets in Resources */, + 22316DCC22A7B255004124F2 /* Assets.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 22316DBE22A7B255004124F2 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 22316DEA22A7B28B004124F2 /* TodoItem.swift in Sources */, + 22316DEE22A7B291004124F2 /* TimeTravelView.swift in Sources */, + 22316DEB22A7B28B004124F2 /* TodoState.swift in Sources */, + 22316DEF22A7B291004124F2 /* Store.swift in Sources */, + 22316DC622A7B255004124F2 /* AppDelegate.swift in Sources */, + 22316DED22A7B291004124F2 /* StateMachine.swift in Sources */, + 22316DE922A7B287004124F2 /* AddItemView.swift in Sources */, + 22316DF022A7B291004124F2 /* TimeTravelBarView.swift in Sources */, + 22316DE722A7B287004124F2 /* TodoListItemView.swift in Sources */, + 22316DEC22A7B28D004124F2 /* TodoListView.swift in Sources */, + 22316DE822A7B287004124F2 /* ModalDimmingView.swift in Sources */, + 22316DC822A7B255004124F2 /* SceneDelegate.swift in Sources */, + 22316DCA22A7B255004124F2 /* ContentView.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 22316DD022A7B255004124F2 /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 22316DD122A7B255004124F2 /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 22316DD422A7B255004124F2 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + 22316DD522A7B255004124F2 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 22316DD722A7B255004124F2 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_ASSET_PATHS = "SwiftUITimeTravel/Preview\\ Content"; + DEVELOPMENT_TEAM = MM763NMPEA; + ENABLE_PREVIEWS = YES; + INFOPLIST_FILE = SwiftUITimeTravel/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.tdonnelly.SwiftUITimeTravel; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 22316DD822A7B255004124F2 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_ASSET_PATHS = "SwiftUITimeTravel/Preview\\ Content"; + DEVELOPMENT_TEAM = MM763NMPEA; + ENABLE_PREVIEWS = YES; + INFOPLIST_FILE = SwiftUITimeTravel/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.tdonnelly.SwiftUITimeTravel; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 22316DBD22A7B255004124F2 /* Build configuration list for PBXProject "SwiftUITimeTravel" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 22316DD422A7B255004124F2 /* Debug */, + 22316DD522A7B255004124F2 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 22316DD622A7B255004124F2 /* Build configuration list for PBXNativeTarget "SwiftUITimeTravel" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 22316DD722A7B255004124F2 /* Debug */, + 22316DD822A7B255004124F2 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 22316DBA22A7B255004124F2 /* Project object */; +} diff --git a/Other Projects/Time Travel/SwiftUITimeTravel.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/Other Projects/Time Travel/SwiftUITimeTravel.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..27c23bb --- /dev/null +++ b/Other Projects/Time Travel/SwiftUITimeTravel.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/Other Projects/Time Travel/SwiftUITimeTravel.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/Other Projects/Time Travel/SwiftUITimeTravel.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/Other Projects/Time Travel/SwiftUITimeTravel.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/Other Projects/Time Travel/SwiftUITimeTravel/AppDelegate.swift b/Other Projects/Time Travel/SwiftUITimeTravel/AppDelegate.swift new file mode 100644 index 0000000..aeabacd --- /dev/null +++ b/Other Projects/Time Travel/SwiftUITimeTravel/AppDelegate.swift @@ -0,0 +1,33 @@ +import UIKit + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + + + + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { + // Override point for customization after application launch. + return true + } + + func applicationWillTerminate(_ application: UIApplication) { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. + } + + // MARK: UISceneSession Lifecycle + + func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration { + // Called when a new scene session is being created. + // Use this method to select a configuration to create the new scene with. + return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role) + } + + func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) { + // Called when the user discards a scene session. + // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions. + // Use this method to release any resources that were specific to the discarded scenes, as they will not return. + } + + +} + diff --git a/Other Projects/Time Travel/SwiftUITimeTravel/Assets.xcassets/AppIcon.appiconset/Contents.json b/Other Projects/Time Travel/SwiftUITimeTravel/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..d8db8d6 --- /dev/null +++ b/Other Projects/Time Travel/SwiftUITimeTravel/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,98 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "83.5x83.5", + "scale" : "2x" + }, + { + "idiom" : "ios-marketing", + "size" : "1024x1024", + "scale" : "1x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/Time Travel/SwiftUITimeTravel/Assets.xcassets/Contents.json b/Other Projects/Time Travel/SwiftUITimeTravel/Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/Other Projects/Time Travel/SwiftUITimeTravel/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/Time Travel/SwiftUITimeTravel/Base.lproj/LaunchScreen.storyboard b/Other Projects/Time Travel/SwiftUITimeTravel/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000..865e932 --- /dev/null +++ b/Other Projects/Time Travel/SwiftUITimeTravel/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Other Projects/Time Travel/SwiftUITimeTravel/ContentView.swift b/Other Projects/Time Travel/SwiftUITimeTravel/ContentView.swift new file mode 100644 index 0000000..577b7e6 --- /dev/null +++ b/Other Projects/Time Travel/SwiftUITimeTravel/ContentView.swift @@ -0,0 +1,17 @@ +import SwiftUI + +struct ContentView : View { + var body: some View { + TimeTravelView(initialState: TodoState()) { + TodoListView() + } + } +} + +#if DEBUG +struct ContentView_Previews : PreviewProvider { + static var previews: some View { + ContentView() + } +} +#endif diff --git a/Other Projects/Time Travel/SwiftUITimeTravel/Info.plist b/Other Projects/Time Travel/SwiftUITimeTravel/Info.plist new file mode 100644 index 0000000..e8bb4c6 --- /dev/null +++ b/Other Projects/Time Travel/SwiftUITimeTravel/Info.plist @@ -0,0 +1,62 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + $(PRODUCT_BUNDLE_PACKAGE_TYPE) + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UIApplicationSceneManifest + + UIApplicationSupportsMultipleScenes + + UISceneConfigurations + + UIWindowSceneSessionRoleApplication + + + UILaunchStoryboardName + LaunchScreen + UISceneConfigurationName + Default Configuration + UISceneDelegateClassName + $(PRODUCT_MODULE_NAME).SceneDelegate + + + + + UILaunchStoryboardName + LaunchScreen + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/Other Projects/Time Travel/SwiftUITimeTravel/Preview Content/Preview Assets.xcassets/Contents.json b/Other Projects/Time Travel/SwiftUITimeTravel/Preview Content/Preview Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/Other Projects/Time Travel/SwiftUITimeTravel/Preview Content/Preview Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/Time Travel/SwiftUITimeTravel/SceneDelegate.swift b/Other Projects/Time Travel/SwiftUITimeTravel/SceneDelegate.swift new file mode 100644 index 0000000..24e499e --- /dev/null +++ b/Other Projects/Time Travel/SwiftUITimeTravel/SceneDelegate.swift @@ -0,0 +1,53 @@ +import UIKit +import SwiftUI + +class SceneDelegate: UIResponder, UIWindowSceneDelegate { + + var window: UIWindow? + + + func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { + // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`. + // If using a storyboard, the `window` property will automatically be initialized and attached to the scene. + // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead). + + // Use a UIHostingController as window root view controller + if let windowScene = scene as? UIWindowScene { + let window = UIWindow(windowScene: windowScene) + window.rootViewController = UIHostingController(rootView: ContentView()) + self.window = window + window.makeKeyAndVisible() + } + } + + func sceneDidDisconnect(_ scene: UIScene) { + // Called as the scene is being released by the system. + // This occurs shortly after the scene enters the background, or when its session is discarded. + // Release any resources associated with this scene that can be re-created the next time the scene connects. + // The scene may re-connect later, as its session was not neccessarily discarded (see `application:didDiscardSceneSessions` instead). + } + + func sceneDidBecomeActive(_ scene: UIScene) { + // Called when the scene has moved from an inactive state to an active state. + // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive. + } + + func sceneWillResignActive(_ scene: UIScene) { + // Called when the scene will move from an active state to an inactive state. + // This may occur due to temporary interruptions (ex. an incoming phone call). + } + + func sceneWillEnterForeground(_ scene: UIScene) { + // Called as the scene transitions from the background to the foreground. + // Use this method to undo the changes made on entering the background. + } + + func sceneDidEnterBackground(_ scene: UIScene) { + // Called as the scene transitions from the foreground to the background. + // Use this method to save data, release shared resources, and store enough scene-specific state information + // to restore the scene back to its current state. + } + + +} + diff --git a/Other Projects/Time Travel/SwiftUITimeTravel/TimeTravelView/StateMachine.swift b/Other Projects/Time Travel/SwiftUITimeTravel/TimeTravelView/StateMachine.swift new file mode 100644 index 0000000..a05cf86 --- /dev/null +++ b/Other Projects/Time Travel/SwiftUITimeTravel/TimeTravelView/StateMachine.swift @@ -0,0 +1,11 @@ +/// Conforming types serve as the state of a time travelable application +public protocol StateMachine { + + /// Events define things that can happen within your application that change its state. + /// + /// This might include things like text editing, button taps, or network responses. + associatedtype Event + + /// Applies an event to the current state. + mutating func update(with event: Event) +} diff --git a/Other Projects/Time Travel/SwiftUITimeTravel/TimeTravelView/Store.swift b/Other Projects/Time Travel/SwiftUITimeTravel/TimeTravelView/Store.swift new file mode 100644 index 0000000..d549942 --- /dev/null +++ b/Other Projects/Time Travel/SwiftUITimeTravel/TimeTravelView/Store.swift @@ -0,0 +1,44 @@ +import SwiftUI +import Combine + +public final class Store: ObservableObject where StateType: StateMachine { + + private let initialState: StateType + private var subsequentStates: [StateType] = [] + + public let objectWillChange = PassthroughSubject() + + public init(state: StateType) { + initialState = state + } + + var allStates: [StateType] { + [[initialState], subsequentStates].flatMap({ $0 }) + } + + var stateCount: Int { + 1 + subsequentStates.count + } + + var currentStateIndex: Int = 0 { + didSet { + withAnimation { + objectWillChange.send(()) + } + } + } + + /// The current state of the store. This will update as time traveling occurs. + public var state: StateType { + allStates[currentStateIndex] + } + + /// Dispatches an event to be applied to the current state. + public func dispatch(event: StateType.Event) { + var newState = state + newState.update(with: event) + subsequentStates.append(newState) + currentStateIndex = stateCount - 1 + } + +} diff --git a/Other Projects/Time Travel/SwiftUITimeTravel/TimeTravelView/TimeTravelBarView.swift b/Other Projects/Time Travel/SwiftUITimeTravel/TimeTravelView/TimeTravelBarView.swift new file mode 100644 index 0000000..fb568c8 --- /dev/null +++ b/Other Projects/Time Travel/SwiftUITimeTravel/TimeTravelView/TimeTravelBarView.swift @@ -0,0 +1,25 @@ +import SwiftUI + +struct TimeTravelBarView : View { + + @EnvironmentObject var store: Store + + var body: some View { + let indexBinding = Binding( + get: { Double(self.store.currentStateIndex) }, + set: { self.store.currentStateIndex = Int($0) }) + + return Slider(value: indexBinding, in: 0...Double(store.stateCount-1)) + .background(Color.white) + .frame(height: 44.0, alignment: .bottom) + .padding() + } +} + +#if DEBUG +struct TimeTravelBarView_Previews : PreviewProvider { + static var previews: some View { + TimeTravelBarView() + } +} +#endif diff --git a/Other Projects/Time Travel/SwiftUITimeTravel/TimeTravelView/TimeTravelView.swift b/Other Projects/Time Travel/SwiftUITimeTravel/TimeTravelView/TimeTravelView.swift new file mode 100644 index 0000000..50a6867 --- /dev/null +++ b/Other Projects/Time Travel/SwiftUITimeTravel/TimeTravelView/TimeTravelView.swift @@ -0,0 +1,39 @@ +import SwiftUI + +public struct TimeTravelView: View where StateType: StateMachine, Content: View { + + let initialState: StateType + + private let content: Content + + @State var store: Store? = nil + + public init(initialState: StateType, content: () -> Content) { + self.initialState = initialState + self.content = content() + } + + public var body: some View { + + let store = self.store ?? Store(state: initialState) + if (self.store == nil) { + self.store = store + } + + return VStack { + content + TimeTravelBarView() + } + .environmentObject(store) + } +} + +#if DEBUG +struct TimeTravelView_Previews : PreviewProvider { + static var previews: some View { + TimeTravelView(initialState: TodoState()) { + TodoListView() + } + } +} +#endif diff --git a/Other Projects/Time Travel/SwiftUITimeTravel/TodoList/Internal Views/AddItemView.swift b/Other Projects/Time Travel/SwiftUITimeTravel/TodoList/Internal Views/AddItemView.swift new file mode 100644 index 0000000..f9dfe2f --- /dev/null +++ b/Other Projects/Time Travel/SwiftUITimeTravel/TodoList/Internal Views/AddItemView.swift @@ -0,0 +1,40 @@ +import SwiftUI + +struct AddItemView: View { + + @EnvironmentObject var store: Store + + var body: some View { + + let textBinding = Binding( + get: { self.store.state.partialItemName }, + set: { self.store.dispatch(event: .changePartialItemName($0)) }) + + return VStack(spacing: 16) { + TextField("Title", text: textBinding) + Button(action: { + self.store.dispatch(event: .addItem) + }) { + HStack { + Spacer() + Text("Add").padding([.top, .bottom], 8.0) + Spacer() + } + + } +// .relativeWidth(1.0) + .background(Color.accentColor) + .disabled(store.state.partialItemName.isEmpty) + .foregroundColor(.white) + .cornerRadius(8.0) + } + .padding() + } +} +#if DEBUG +struct AddItemView_Previews : PreviewProvider { + static var previews: some View { + AddItemView() + } +} +#endif diff --git a/Other Projects/Time Travel/SwiftUITimeTravel/TodoList/Internal Views/ModalDimmingView.swift b/Other Projects/Time Travel/SwiftUITimeTravel/TodoList/Internal Views/ModalDimmingView.swift new file mode 100644 index 0000000..5c165f4 --- /dev/null +++ b/Other Projects/Time Travel/SwiftUITimeTravel/TodoList/Internal Views/ModalDimmingView.swift @@ -0,0 +1,27 @@ +import SwiftUI + +struct ModalDimmingView : View { + + @EnvironmentObject var store: Store + + var body: some View { + Color + .black +// .relativeWidth(1.0) +// .relativeHeight(1.0) + .opacity(0.3) + .edgesIgnoringSafeArea([.bottom, .top]) + .transition(.opacity) + .onTapGesture { + self.store.dispatch(event: .cancelCreatingItem) + } + } +} + +#if DEBUG +struct ModalDimmingView_Previews : PreviewProvider { + static var previews: some View { + ModalDimmingView() + } +} +#endif diff --git a/Other Projects/Time Travel/SwiftUITimeTravel/TodoList/Internal Views/TodoListItemView.swift b/Other Projects/Time Travel/SwiftUITimeTravel/TodoList/Internal Views/TodoListItemView.swift new file mode 100644 index 0000000..b315a27 --- /dev/null +++ b/Other Projects/Time Travel/SwiftUITimeTravel/TodoList/Internal Views/TodoListItemView.swift @@ -0,0 +1,26 @@ +import SwiftUI + +struct TodoListItemView : View { + + @EnvironmentObject var store: Store + + let item: TodoItem + + var body: some View { + let binding = Binding( + get: { self.item.isFinished }, + set: { self.store.dispatch(event: .setItemDone(identifier: self.item.id, isDone: $0)) }) + + return Toggle(isOn: binding) { + Text(item.title) + } + } +} + +#if DEBUG +struct TodoListItemView_Previews : PreviewProvider { + static var previews: some View { + TodoListItemView(item: TodoItem(id: UUID(), title: "Test", isFinished: false)) + } +} +#endif diff --git a/Other Projects/Time Travel/SwiftUITimeTravel/TodoList/Model/TodoItem.swift b/Other Projects/Time Travel/SwiftUITimeTravel/TodoList/Model/TodoItem.swift new file mode 100644 index 0000000..74a1205 --- /dev/null +++ b/Other Projects/Time Travel/SwiftUITimeTravel/TodoList/Model/TodoItem.swift @@ -0,0 +1,7 @@ +import SwiftUI + +struct TodoItem: Identifiable { + var id: UUID + var title: String + var isFinished: Bool +} diff --git a/Other Projects/Time Travel/SwiftUITimeTravel/TodoList/Model/TodoState.swift b/Other Projects/Time Travel/SwiftUITimeTravel/TodoList/Model/TodoState.swift new file mode 100644 index 0000000..41818f9 --- /dev/null +++ b/Other Projects/Time Travel/SwiftUITimeTravel/TodoList/Model/TodoState.swift @@ -0,0 +1,39 @@ +import SwiftUI + +struct TodoState { + var isCreatingItem: Bool = false + var partialItemName: String = "" + var todoItems: [TodoItem] = [] +} + +extension TodoState: StateMachine { + + enum Event { + case startCreatingItem + case cancelCreatingItem + case changePartialItemName(String) + case addItem + case setItemDone(identifier: UUID, isDone: Bool) + } + + mutating func update(with event: TodoState.Event) { + switch event { + case .addItem: + todoItems.append(TodoItem(id: UUID(), title: partialItemName, isFinished: false)) + partialItemName = "" + isCreatingItem = false + case .changePartialItemName(let name): + partialItemName = name + case .cancelCreatingItem: + isCreatingItem = false + case .startCreatingItem: + isCreatingItem = true + partialItemName = "" + case .setItemDone(let identifier, let isDone): + if let index = todoItems.firstIndex(where: { $0.id == identifier }) { + todoItems[index].isFinished = isDone + } + } + } + +} diff --git a/Other Projects/Time Travel/SwiftUITimeTravel/TodoList/TodoListView.swift b/Other Projects/Time Travel/SwiftUITimeTravel/TodoList/TodoListView.swift new file mode 100644 index 0000000..4d20d7d --- /dev/null +++ b/Other Projects/Time Travel/SwiftUITimeTravel/TodoList/TodoListView.swift @@ -0,0 +1,43 @@ +import SwiftUI + +struct TodoListView : View { + + @EnvironmentObject var store: Store + + var body: some View { + ZStack { + NavigationView { + List(store.state.todoItems) { item in TodoListItemView(item: item) } + .navigationBarTitle(Text("Todo List")) + .navigationBarItems(trailing: Button(action: { + withAnimation { + self.store.dispatch(event: .startCreatingItem) + } + }, label: { Image(systemName: "plus.circle") })) } + + if store.state.isCreatingItem { + + ModalDimmingView() + + VStack { + Spacer() + AddItemView() +// .relativeWidth(1.0) + .background(Color.white) + .cornerRadius(12.0) + .shadow(radius: 16.0) + .padding() + Spacer() + } + .transition(.move(edge: .bottom)) + } + } + } +} +#if DEBUG +struct TodoListView_Previews : PreviewProvider { + static var previews: some View { + TodoListView() + } +} +#endif diff --git a/Other Projects/Transition and Blur/Basic Animation/SwiftUI-BasicAnimation.xcodeproj/project.pbxproj b/Other Projects/Transition and Blur/Basic Animation/SwiftUI-BasicAnimation.xcodeproj/project.pbxproj new file mode 100644 index 0000000..02cc546 --- /dev/null +++ b/Other Projects/Transition and Blur/Basic Animation/SwiftUI-BasicAnimation.xcodeproj/project.pbxproj @@ -0,0 +1,347 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 50; + objects = { + +/* Begin PBXBuildFile section */ + 962AEB8A22A920A4007F789B /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 962AEB8922A920A4007F789B /* AppDelegate.swift */; }; + 962AEB8C22A920A4007F789B /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 962AEB8B22A920A4007F789B /* SceneDelegate.swift */; }; + 962AEB8E22A920A4007F789B /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 962AEB8D22A920A4007F789B /* ContentView.swift */; }; + 962AEB9022A920A5007F789B /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 962AEB8F22A920A5007F789B /* Assets.xcassets */; }; + 962AEB9322A920A5007F789B /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 962AEB9222A920A5007F789B /* Preview Assets.xcassets */; }; + 962AEB9622A920A5007F789B /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 962AEB9422A920A5007F789B /* LaunchScreen.storyboard */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 962AEB8622A920A4007F789B /* SwiftUI-BasicAnimation.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "SwiftUI-BasicAnimation.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + 962AEB8922A920A4007F789B /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 962AEB8B22A920A4007F789B /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; + 962AEB8D22A920A4007F789B /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; }; + 962AEB8F22A920A5007F789B /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 962AEB9222A920A5007F789B /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; + 962AEB9522A920A5007F789B /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 962AEB9722A920A5007F789B /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 962AEB8322A920A4007F789B /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 962AEB7D22A920A4007F789B = { + isa = PBXGroup; + children = ( + 962AEB8822A920A4007F789B /* SwiftUI-BasicAnimation */, + 962AEB8722A920A4007F789B /* Products */, + ); + sourceTree = ""; + }; + 962AEB8722A920A4007F789B /* Products */ = { + isa = PBXGroup; + children = ( + 962AEB8622A920A4007F789B /* SwiftUI-BasicAnimation.app */, + ); + name = Products; + sourceTree = ""; + }; + 962AEB8822A920A4007F789B /* SwiftUI-BasicAnimation */ = { + isa = PBXGroup; + children = ( + 962AEB8922A920A4007F789B /* AppDelegate.swift */, + 962AEB8B22A920A4007F789B /* SceneDelegate.swift */, + 962AEB8D22A920A4007F789B /* ContentView.swift */, + 962AEB8F22A920A5007F789B /* Assets.xcassets */, + 962AEB9422A920A5007F789B /* LaunchScreen.storyboard */, + 962AEB9722A920A5007F789B /* Info.plist */, + 962AEB9122A920A5007F789B /* Preview Content */, + ); + path = "SwiftUI-BasicAnimation"; + sourceTree = ""; + }; + 962AEB9122A920A5007F789B /* Preview Content */ = { + isa = PBXGroup; + children = ( + 962AEB9222A920A5007F789B /* Preview Assets.xcassets */, + ); + path = "Preview Content"; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 962AEB8522A920A4007F789B /* SwiftUI-BasicAnimation */ = { + isa = PBXNativeTarget; + buildConfigurationList = 962AEB9A22A920A5007F789B /* Build configuration list for PBXNativeTarget "SwiftUI-BasicAnimation" */; + buildPhases = ( + 962AEB8222A920A4007F789B /* Sources */, + 962AEB8322A920A4007F789B /* Frameworks */, + 962AEB8422A920A4007F789B /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "SwiftUI-BasicAnimation"; + productName = "SwiftUI-BasicAnimation"; + productReference = 962AEB8622A920A4007F789B /* SwiftUI-BasicAnimation.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 962AEB7E22A920A4007F789B /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 1100; + LastUpgradeCheck = 1100; + ORGANIZATIONNAME = "Meng To"; + TargetAttributes = { + 962AEB8522A920A4007F789B = { + CreatedOnToolsVersion = 11.0; + }; + }; + }; + buildConfigurationList = 962AEB8122A920A4007F789B /* Build configuration list for PBXProject "SwiftUI-BasicAnimation" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 962AEB7D22A920A4007F789B; + productRefGroup = 962AEB8722A920A4007F789B /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 962AEB8522A920A4007F789B /* SwiftUI-BasicAnimation */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 962AEB8422A920A4007F789B /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 962AEB9622A920A5007F789B /* LaunchScreen.storyboard in Resources */, + 962AEB9322A920A5007F789B /* Preview Assets.xcassets in Resources */, + 962AEB9022A920A5007F789B /* Assets.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 962AEB8222A920A4007F789B /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 962AEB8A22A920A4007F789B /* AppDelegate.swift in Sources */, + 962AEB8C22A920A4007F789B /* SceneDelegate.swift in Sources */, + 962AEB8E22A920A4007F789B /* ContentView.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 962AEB9422A920A5007F789B /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 962AEB9522A920A5007F789B /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 962AEB9822A920A5007F789B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + 962AEB9922A920A5007F789B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 962AEB9B22A920A5007F789B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_ASSET_PATHS = "SwiftUI-BasicAnimation/Preview\\ Content"; + DEVELOPMENT_TEAM = 68WS2M23VC; + ENABLE_PREVIEWS = YES; + INFOPLIST_FILE = "SwiftUI-BasicAnimation/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = "io.designcode.SwiftUI-BasicAnimation"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 962AEB9C22A920A5007F789B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_ASSET_PATHS = "SwiftUI-BasicAnimation/Preview\\ Content"; + DEVELOPMENT_TEAM = 68WS2M23VC; + ENABLE_PREVIEWS = YES; + INFOPLIST_FILE = "SwiftUI-BasicAnimation/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = "io.designcode.SwiftUI-BasicAnimation"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 962AEB8122A920A4007F789B /* Build configuration list for PBXProject "SwiftUI-BasicAnimation" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 962AEB9822A920A5007F789B /* Debug */, + 962AEB9922A920A5007F789B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 962AEB9A22A920A5007F789B /* Build configuration list for PBXNativeTarget "SwiftUI-BasicAnimation" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 962AEB9B22A920A5007F789B /* Debug */, + 962AEB9C22A920A5007F789B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 962AEB7E22A920A4007F789B /* Project object */; +} diff --git a/Other Projects/Transition and Blur/Basic Animation/SwiftUI-BasicAnimation.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/Other Projects/Transition and Blur/Basic Animation/SwiftUI-BasicAnimation.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..56f9f32 --- /dev/null +++ b/Other Projects/Transition and Blur/Basic Animation/SwiftUI-BasicAnimation.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/Other Projects/Transition and Blur/Basic Animation/SwiftUI-BasicAnimation.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/Other Projects/Transition and Blur/Basic Animation/SwiftUI-BasicAnimation.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/Other Projects/Transition and Blur/Basic Animation/SwiftUI-BasicAnimation.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/Other Projects/Transition and Blur/Basic Animation/SwiftUI-BasicAnimation/AppDelegate.swift b/Other Projects/Transition and Blur/Basic Animation/SwiftUI-BasicAnimation/AppDelegate.swift new file mode 100644 index 0000000..ae09a35 --- /dev/null +++ b/Other Projects/Transition and Blur/Basic Animation/SwiftUI-BasicAnimation/AppDelegate.swift @@ -0,0 +1,41 @@ +// +// AppDelegate.swift +// SwiftUI-BasicAnimation +// +// Created by Meng To on 2019-06-06. +// Copyright © 2019 Meng To. All rights reserved. +// + +import UIKit + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + + + + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { + // Override point for customization after application launch. + return true + } + + func applicationWillTerminate(_ application: UIApplication) { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. + } + + // MARK: UISceneSession Lifecycle + + func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration { + // Called when a new scene session is being created. + // Use this method to select a configuration to create the new scene with. + return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role) + } + + func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) { + // Called when the user discards a scene session. + // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions. + // Use this method to release any resources that were specific to the discarded scenes, as they will not return. + } + + +} + diff --git a/Other Projects/Transition and Blur/Basic Animation/SwiftUI-BasicAnimation/Assets.xcassets/AppIcon.appiconset/Contents.json b/Other Projects/Transition and Blur/Basic Animation/SwiftUI-BasicAnimation/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..d8db8d6 --- /dev/null +++ b/Other Projects/Transition and Blur/Basic Animation/SwiftUI-BasicAnimation/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,98 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "83.5x83.5", + "scale" : "2x" + }, + { + "idiom" : "ios-marketing", + "size" : "1024x1024", + "scale" : "1x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/Transition and Blur/Basic Animation/SwiftUI-BasicAnimation/Assets.xcassets/Contents.json b/Other Projects/Transition and Blur/Basic Animation/SwiftUI-BasicAnimation/Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/Other Projects/Transition and Blur/Basic Animation/SwiftUI-BasicAnimation/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/Transition and Blur/Basic Animation/SwiftUI-BasicAnimation/Assets.xcassets/ui.imageset/Contents.json b/Other Projects/Transition and Blur/Basic Animation/SwiftUI-BasicAnimation/Assets.xcassets/ui.imageset/Contents.json new file mode 100644 index 0000000..a5f039a --- /dev/null +++ b/Other Projects/Transition and Blur/Basic Animation/SwiftUI-BasicAnimation/Assets.xcassets/ui.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "dribbble3_4x-2.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/Transition and Blur/Basic Animation/SwiftUI-BasicAnimation/Assets.xcassets/ui.imageset/dribbble3_4x-2.png b/Other Projects/Transition and Blur/Basic Animation/SwiftUI-BasicAnimation/Assets.xcassets/ui.imageset/dribbble3_4x-2.png new file mode 100644 index 0000000..595b696 Binary files /dev/null and b/Other Projects/Transition and Blur/Basic Animation/SwiftUI-BasicAnimation/Assets.xcassets/ui.imageset/dribbble3_4x-2.png differ diff --git a/Other Projects/Transition and Blur/Basic Animation/SwiftUI-BasicAnimation/Base.lproj/LaunchScreen.storyboard b/Other Projects/Transition and Blur/Basic Animation/SwiftUI-BasicAnimation/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000..865e932 --- /dev/null +++ b/Other Projects/Transition and Blur/Basic Animation/SwiftUI-BasicAnimation/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Other Projects/Transition and Blur/Basic Animation/SwiftUI-BasicAnimation/ContentView.swift b/Other Projects/Transition and Blur/Basic Animation/SwiftUI-BasicAnimation/ContentView.swift new file mode 100644 index 0000000..e788fc5 --- /dev/null +++ b/Other Projects/Transition and Blur/Basic Animation/SwiftUI-BasicAnimation/ContentView.swift @@ -0,0 +1,58 @@ +// +// ContentView.swift +// SwiftUI-BasicAnimation +// +// Created by Meng To on 2019-06-06. +// Copyright © 2019 Meng To. All rights reserved. +// + +import SwiftUI + +struct ContentView: View { + @State var show = false + + var body: some View { + + VStack { + Text("Learning SwiftUI") + .font(.largeTitle) + .fontWeight(.semibold) + .foregroundColor(.black) + .padding(4) +// .animation(.basic(duration: 0.3, curve: .easeOut)) + + Image("ui") + .frame(width: show ? 414 : 300, height: show ? 600 : 300) + .clipped() + .cornerRadius(show ? 0 : 30) + .shadow(radius: 30) + .blur(radius: show ? 0 : 30) + .animation(.spring()) + .aspectRatio(contentMode: .fill) + + Text("A course focused on UI") + .font(.subheadline) + .fontWeight(.regular) + .foregroundColor(.gray) + .padding(4) +// .animation(.basic(duration: 0.4, curve: .easeIn)) + + Button(action: { + withAnimation { + self.show.toggle() + } + }) { + Text("Animate") + } + } + } +} + +#if DEBUG +struct ContentView_Previews: PreviewProvider { + static var previews: some View { + ContentView() + .colorScheme(.dark) + } +} +#endif diff --git a/Other Projects/Transition and Blur/Basic Animation/SwiftUI-BasicAnimation/Info.plist b/Other Projects/Transition and Blur/Basic Animation/SwiftUI-BasicAnimation/Info.plist new file mode 100644 index 0000000..e8bb4c6 --- /dev/null +++ b/Other Projects/Transition and Blur/Basic Animation/SwiftUI-BasicAnimation/Info.plist @@ -0,0 +1,62 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + $(PRODUCT_BUNDLE_PACKAGE_TYPE) + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UIApplicationSceneManifest + + UIApplicationSupportsMultipleScenes + + UISceneConfigurations + + UIWindowSceneSessionRoleApplication + + + UILaunchStoryboardName + LaunchScreen + UISceneConfigurationName + Default Configuration + UISceneDelegateClassName + $(PRODUCT_MODULE_NAME).SceneDelegate + + + + + UILaunchStoryboardName + LaunchScreen + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/Other Projects/Transition and Blur/Basic Animation/SwiftUI-BasicAnimation/Preview Content/Preview Assets.xcassets/Contents.json b/Other Projects/Transition and Blur/Basic Animation/SwiftUI-BasicAnimation/Preview Content/Preview Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/Other Projects/Transition and Blur/Basic Animation/SwiftUI-BasicAnimation/Preview Content/Preview Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/Transition and Blur/Basic Animation/SwiftUI-BasicAnimation/SceneDelegate.swift b/Other Projects/Transition and Blur/Basic Animation/SwiftUI-BasicAnimation/SceneDelegate.swift new file mode 100644 index 0000000..9ce0628 --- /dev/null +++ b/Other Projects/Transition and Blur/Basic Animation/SwiftUI-BasicAnimation/SceneDelegate.swift @@ -0,0 +1,61 @@ +// +// SceneDelegate.swift +// SwiftUI-BasicAnimation +// +// Created by Meng To on 2019-06-06. +// Copyright © 2019 Meng To. All rights reserved. +// + +import UIKit +import SwiftUI + +class SceneDelegate: UIResponder, UIWindowSceneDelegate { + + var window: UIWindow? + + + func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { + // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`. + // If using a storyboard, the `window` property will automatically be initialized and attached to the scene. + // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead). + + // Use a UIHostingController as window root view controller + if let windowScene = scene as? UIWindowScene { + let window = UIWindow(windowScene: windowScene) + window.rootViewController = UIHostingController(rootView: ContentView()) + self.window = window + window.makeKeyAndVisible() + } + } + + func sceneDidDisconnect(_ scene: UIScene) { + // Called as the scene is being released by the system. + // This occurs shortly after the scene enters the background, or when its session is discarded. + // Release any resources associated with this scene that can be re-created the next time the scene connects. + // The scene may re-connect later, as its session was not neccessarily discarded (see `application:didDiscardSceneSessions` instead). + } + + func sceneDidBecomeActive(_ scene: UIScene) { + // Called when the scene has moved from an inactive state to an active state. + // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive. + } + + func sceneWillResignActive(_ scene: UIScene) { + // Called when the scene will move from an active state to an inactive state. + // This may occur due to temporary interruptions (ex. an incoming phone call). + } + + func sceneWillEnterForeground(_ scene: UIScene) { + // Called as the scene transitions from the background to the foreground. + // Use this method to undo the changes made on entering the background. + } + + func sceneDidEnterBackground(_ scene: UIScene) { + // Called as the scene transitions from the foreground to the background. + // Use this method to save data, release shared resources, and store enough scene-specific state information + // to restore the scene back to its current state. + } + + +} + diff --git a/Other Projects/Transition and Blur/Card Animation/SwiftUI-CardAnimation.xcodeproj/project.pbxproj b/Other Projects/Transition and Blur/Card Animation/SwiftUI-CardAnimation.xcodeproj/project.pbxproj new file mode 100644 index 0000000..a38673a --- /dev/null +++ b/Other Projects/Transition and Blur/Card Animation/SwiftUI-CardAnimation.xcodeproj/project.pbxproj @@ -0,0 +1,347 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 50; + objects = { + +/* Begin PBXBuildFile section */ + 962AEBAA22A93169007F789B /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 962AEBA922A93169007F789B /* AppDelegate.swift */; }; + 962AEBAC22A93169007F789B /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 962AEBAB22A93169007F789B /* SceneDelegate.swift */; }; + 962AEBAE22A93169007F789B /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 962AEBAD22A93169007F789B /* ContentView.swift */; }; + 962AEBB022A9316A007F789B /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 962AEBAF22A9316A007F789B /* Assets.xcassets */; }; + 962AEBB322A9316A007F789B /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 962AEBB222A9316A007F789B /* Preview Assets.xcassets */; }; + 962AEBB622A9316A007F789B /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 962AEBB422A9316A007F789B /* LaunchScreen.storyboard */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 962AEBA622A93169007F789B /* SwiftUI-CardAnimation.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "SwiftUI-CardAnimation.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + 962AEBA922A93169007F789B /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 962AEBAB22A93169007F789B /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; + 962AEBAD22A93169007F789B /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; }; + 962AEBAF22A9316A007F789B /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 962AEBB222A9316A007F789B /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; + 962AEBB522A9316A007F789B /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 962AEBB722A9316A007F789B /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 962AEBA322A93169007F789B /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 962AEB9D22A93169007F789B = { + isa = PBXGroup; + children = ( + 962AEBA822A93169007F789B /* SwiftUI-CardAnimation */, + 962AEBA722A93169007F789B /* Products */, + ); + sourceTree = ""; + }; + 962AEBA722A93169007F789B /* Products */ = { + isa = PBXGroup; + children = ( + 962AEBA622A93169007F789B /* SwiftUI-CardAnimation.app */, + ); + name = Products; + sourceTree = ""; + }; + 962AEBA822A93169007F789B /* SwiftUI-CardAnimation */ = { + isa = PBXGroup; + children = ( + 962AEBA922A93169007F789B /* AppDelegate.swift */, + 962AEBAB22A93169007F789B /* SceneDelegate.swift */, + 962AEBAD22A93169007F789B /* ContentView.swift */, + 962AEBAF22A9316A007F789B /* Assets.xcassets */, + 962AEBB422A9316A007F789B /* LaunchScreen.storyboard */, + 962AEBB722A9316A007F789B /* Info.plist */, + 962AEBB122A9316A007F789B /* Preview Content */, + ); + path = "SwiftUI-CardAnimation"; + sourceTree = ""; + }; + 962AEBB122A9316A007F789B /* Preview Content */ = { + isa = PBXGroup; + children = ( + 962AEBB222A9316A007F789B /* Preview Assets.xcassets */, + ); + path = "Preview Content"; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 962AEBA522A93169007F789B /* SwiftUI-CardAnimation */ = { + isa = PBXNativeTarget; + buildConfigurationList = 962AEBBA22A9316A007F789B /* Build configuration list for PBXNativeTarget "SwiftUI-CardAnimation" */; + buildPhases = ( + 962AEBA222A93169007F789B /* Sources */, + 962AEBA322A93169007F789B /* Frameworks */, + 962AEBA422A93169007F789B /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "SwiftUI-CardAnimation"; + productName = "SwiftUI-CardAnimation"; + productReference = 962AEBA622A93169007F789B /* SwiftUI-CardAnimation.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 962AEB9E22A93169007F789B /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 1100; + LastUpgradeCheck = 1100; + ORGANIZATIONNAME = "Meng To"; + TargetAttributes = { + 962AEBA522A93169007F789B = { + CreatedOnToolsVersion = 11.0; + }; + }; + }; + buildConfigurationList = 962AEBA122A93169007F789B /* Build configuration list for PBXProject "SwiftUI-CardAnimation" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 962AEB9D22A93169007F789B; + productRefGroup = 962AEBA722A93169007F789B /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 962AEBA522A93169007F789B /* SwiftUI-CardAnimation */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 962AEBA422A93169007F789B /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 962AEBB622A9316A007F789B /* LaunchScreen.storyboard in Resources */, + 962AEBB322A9316A007F789B /* Preview Assets.xcassets in Resources */, + 962AEBB022A9316A007F789B /* Assets.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 962AEBA222A93169007F789B /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 962AEBAA22A93169007F789B /* AppDelegate.swift in Sources */, + 962AEBAC22A93169007F789B /* SceneDelegate.swift in Sources */, + 962AEBAE22A93169007F789B /* ContentView.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 962AEBB422A9316A007F789B /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 962AEBB522A9316A007F789B /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 962AEBB822A9316A007F789B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + 962AEBB922A9316A007F789B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 962AEBBB22A9316A007F789B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_ASSET_PATHS = "SwiftUI-CardAnimation/Preview\\ Content"; + DEVELOPMENT_TEAM = 68WS2M23VC; + ENABLE_PREVIEWS = YES; + INFOPLIST_FILE = "SwiftUI-CardAnimation/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = "io.designcode.SwiftUI-CardAnimation"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 962AEBBC22A9316A007F789B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_ASSET_PATHS = "SwiftUI-CardAnimation/Preview\\ Content"; + DEVELOPMENT_TEAM = 68WS2M23VC; + ENABLE_PREVIEWS = YES; + INFOPLIST_FILE = "SwiftUI-CardAnimation/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = "io.designcode.SwiftUI-CardAnimation"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 962AEBA122A93169007F789B /* Build configuration list for PBXProject "SwiftUI-CardAnimation" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 962AEBB822A9316A007F789B /* Debug */, + 962AEBB922A9316A007F789B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 962AEBBA22A9316A007F789B /* Build configuration list for PBXNativeTarget "SwiftUI-CardAnimation" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 962AEBBB22A9316A007F789B /* Debug */, + 962AEBBC22A9316A007F789B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 962AEB9E22A93169007F789B /* Project object */; +} diff --git a/Other Projects/Transition and Blur/Card Animation/SwiftUI-CardAnimation.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/Other Projects/Transition and Blur/Card Animation/SwiftUI-CardAnimation.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..1a68b2e --- /dev/null +++ b/Other Projects/Transition and Blur/Card Animation/SwiftUI-CardAnimation.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/Other Projects/Transition and Blur/Card Animation/SwiftUI-CardAnimation.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/Other Projects/Transition and Blur/Card Animation/SwiftUI-CardAnimation.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/Other Projects/Transition and Blur/Card Animation/SwiftUI-CardAnimation.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/Other Projects/Transition and Blur/Card Animation/SwiftUI-CardAnimation/AppDelegate.swift b/Other Projects/Transition and Blur/Card Animation/SwiftUI-CardAnimation/AppDelegate.swift new file mode 100644 index 0000000..afe1e5c --- /dev/null +++ b/Other Projects/Transition and Blur/Card Animation/SwiftUI-CardAnimation/AppDelegate.swift @@ -0,0 +1,41 @@ +// +// AppDelegate.swift +// SwiftUI-CardAnimation +// +// Created by Meng To on 2019-06-06. +// Copyright © 2019 Meng To. All rights reserved. +// + +import UIKit + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + + + + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { + // Override point for customization after application launch. + return true + } + + func applicationWillTerminate(_ application: UIApplication) { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. + } + + // MARK: UISceneSession Lifecycle + + func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration { + // Called when a new scene session is being created. + // Use this method to select a configuration to create the new scene with. + return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role) + } + + func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) { + // Called when the user discards a scene session. + // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions. + // Use this method to release any resources that were specific to the discarded scenes, as they will not return. + } + + +} + diff --git a/Other Projects/Transition and Blur/Card Animation/SwiftUI-CardAnimation/Assets.xcassets/AppIcon.appiconset/Contents.json b/Other Projects/Transition and Blur/Card Animation/SwiftUI-CardAnimation/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..d8db8d6 --- /dev/null +++ b/Other Projects/Transition and Blur/Card Animation/SwiftUI-CardAnimation/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,98 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "83.5x83.5", + "scale" : "2x" + }, + { + "idiom" : "ios-marketing", + "size" : "1024x1024", + "scale" : "1x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/Transition and Blur/Card Animation/SwiftUI-CardAnimation/Assets.xcassets/Contents.json b/Other Projects/Transition and Blur/Card Animation/SwiftUI-CardAnimation/Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/Other Projects/Transition and Blur/Card Animation/SwiftUI-CardAnimation/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/Transition and Blur/Card Animation/SwiftUI-CardAnimation/Assets.xcassets/ui.imageset/Contents.json b/Other Projects/Transition and Blur/Card Animation/SwiftUI-CardAnimation/Assets.xcassets/ui.imageset/Contents.json new file mode 100644 index 0000000..a5f039a --- /dev/null +++ b/Other Projects/Transition and Blur/Card Animation/SwiftUI-CardAnimation/Assets.xcassets/ui.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "dribbble3_4x-2.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/Transition and Blur/Card Animation/SwiftUI-CardAnimation/Assets.xcassets/ui.imageset/dribbble3_4x-2.png b/Other Projects/Transition and Blur/Card Animation/SwiftUI-CardAnimation/Assets.xcassets/ui.imageset/dribbble3_4x-2.png new file mode 100644 index 0000000..595b696 Binary files /dev/null and b/Other Projects/Transition and Blur/Card Animation/SwiftUI-CardAnimation/Assets.xcassets/ui.imageset/dribbble3_4x-2.png differ diff --git a/Other Projects/Transition and Blur/Card Animation/SwiftUI-CardAnimation/Base.lproj/LaunchScreen.storyboard b/Other Projects/Transition and Blur/Card Animation/SwiftUI-CardAnimation/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000..865e932 --- /dev/null +++ b/Other Projects/Transition and Blur/Card Animation/SwiftUI-CardAnimation/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Other Projects/Transition and Blur/Card Animation/SwiftUI-CardAnimation/ContentView.swift b/Other Projects/Transition and Blur/Card Animation/SwiftUI-CardAnimation/ContentView.swift new file mode 100644 index 0000000..7cbbbb4 --- /dev/null +++ b/Other Projects/Transition and Blur/Card Animation/SwiftUI-CardAnimation/ContentView.swift @@ -0,0 +1,55 @@ +// +// ContentView.swift +// SwiftUI-CardAnimation +// +// Created by Meng To on 2019-06-06. +// Copyright © 2019 Meng To. All rights reserved. +// + +import SwiftUI + +struct ContentView : View { + @State var show = false + + var body: some View { + Button(action: { + withAnimation { + self.show.toggle() + } + }) { + VStack() { + Text("Learn SwiftUI") + .foregroundColor(.white) + .fontWeight(.bold) + .font(.largeTitle) + .padding(.top, show ? 100 : 20) + + Text("A course on UI and animations") + .foregroundColor(Color(hue: 0.567, saturation: 0.158, brightness: 0.943)) + .lineLimit(-1) + + Spacer() + + Text("Card Animation") + .foregroundColor(Color(hue: 0.498, saturation: 0.609, brightness: 1.0)) + .fontWeight(.bold) + .font(.title) + .padding(.bottom, show ? 100 : 20) + } + .padding() + .frame(width: show ? 414 : 300, height: show ? 950 : 300) + .background(Color.blue) + } + .cornerRadius(30) + .animation(.spring()) + .shadow(radius: 30) + } +} + +#if DEBUG +struct ContentView_Previews : PreviewProvider { + static var previews: some View { + ContentView() + } +} +#endif diff --git a/Other Projects/Transition and Blur/Card Animation/SwiftUI-CardAnimation/Info.plist b/Other Projects/Transition and Blur/Card Animation/SwiftUI-CardAnimation/Info.plist new file mode 100644 index 0000000..e8bb4c6 --- /dev/null +++ b/Other Projects/Transition and Blur/Card Animation/SwiftUI-CardAnimation/Info.plist @@ -0,0 +1,62 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + $(PRODUCT_BUNDLE_PACKAGE_TYPE) + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UIApplicationSceneManifest + + UIApplicationSupportsMultipleScenes + + UISceneConfigurations + + UIWindowSceneSessionRoleApplication + + + UILaunchStoryboardName + LaunchScreen + UISceneConfigurationName + Default Configuration + UISceneDelegateClassName + $(PRODUCT_MODULE_NAME).SceneDelegate + + + + + UILaunchStoryboardName + LaunchScreen + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/Other Projects/Transition and Blur/Card Animation/SwiftUI-CardAnimation/Preview Content/Preview Assets.xcassets/Contents.json b/Other Projects/Transition and Blur/Card Animation/SwiftUI-CardAnimation/Preview Content/Preview Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/Other Projects/Transition and Blur/Card Animation/SwiftUI-CardAnimation/Preview Content/Preview Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/Transition and Blur/Card Animation/SwiftUI-CardAnimation/SceneDelegate.swift b/Other Projects/Transition and Blur/Card Animation/SwiftUI-CardAnimation/SceneDelegate.swift new file mode 100644 index 0000000..0cb85e8 --- /dev/null +++ b/Other Projects/Transition and Blur/Card Animation/SwiftUI-CardAnimation/SceneDelegate.swift @@ -0,0 +1,61 @@ +// +// SceneDelegate.swift +// SwiftUI-CardAnimation +// +// Created by Meng To on 2019-06-06. +// Copyright © 2019 Meng To. All rights reserved. +// + +import UIKit +import SwiftUI + +class SceneDelegate: UIResponder, UIWindowSceneDelegate { + + var window: UIWindow? + + + func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { + // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`. + // If using a storyboard, the `window` property will automatically be initialized and attached to the scene. + // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead). + + // Use a UIHostingController as window root view controller + if let windowScene = scene as? UIWindowScene { + let window = UIWindow(windowScene: windowScene) + window.rootViewController = UIHostingController(rootView: ContentView()) + self.window = window + window.makeKeyAndVisible() + } + } + + func sceneDidDisconnect(_ scene: UIScene) { + // Called as the scene is being released by the system. + // This occurs shortly after the scene enters the background, or when its session is discarded. + // Release any resources associated with this scene that can be re-created the next time the scene connects. + // The scene may re-connect later, as its session was not neccessarily discarded (see `application:didDiscardSceneSessions` instead). + } + + func sceneDidBecomeActive(_ scene: UIScene) { + // Called when the scene has moved from an inactive state to an active state. + // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive. + } + + func sceneWillResignActive(_ scene: UIScene) { + // Called when the scene will move from an active state to an inactive state. + // This may occur due to temporary interruptions (ex. an incoming phone call). + } + + func sceneWillEnterForeground(_ scene: UIScene) { + // Called as the scene transitions from the background to the foreground. + // Use this method to undo the changes made on entering the background. + } + + func sceneDidEnterBackground(_ scene: UIScene) { + // Called as the scene transitions from the foreground to the background. + // Use this method to save data, release shared resources, and store enough scene-specific state information + // to restore the scene back to its current state. + } + + +} + diff --git a/Other Projects/UINote/SwiftUINote.xcodeproj/project.pbxproj b/Other Projects/UINote/SwiftUINote.xcodeproj/project.pbxproj new file mode 100644 index 0000000..b166dbd --- /dev/null +++ b/Other Projects/UINote/SwiftUINote.xcodeproj/project.pbxproj @@ -0,0 +1,508 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 50; + objects = { + +/* Begin PBXBuildFile section */ + 51197A6922A6B23600E78FC6 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51197A6822A6B23600E78FC6 /* AppDelegate.swift */; }; + 51197A6B22A6B23600E78FC6 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51197A6A22A6B23600E78FC6 /* SceneDelegate.swift */; }; + 51197A6F22A6B23800E78FC6 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 51197A6E22A6B23800E78FC6 /* Assets.xcassets */; }; + 51197A7222A6B23800E78FC6 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 51197A7122A6B23800E78FC6 /* Preview Assets.xcassets */; }; + 51197A7522A6B23800E78FC6 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 51197A7322A6B23800E78FC6 /* LaunchScreen.storyboard */; }; + 51197A8022A6B23800E78FC6 /* SwiftUINoteTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51197A7F22A6B23800E78FC6 /* SwiftUINoteTests.swift */; }; + 51197A9022A6E01500E78FC6 /* Note.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51197A8F22A6E01500E78FC6 /* Note.swift */; }; + 51197A9322A6E1D500E78FC6 /* NoteRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51197A9222A6E1D500E78FC6 /* NoteRow.swift */; }; + 51197A9522A7011500E78FC6 /* NoteList.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51197A9422A7011500E78FC6 /* NoteList.swift */; }; + 51197A9722A70E0400E78FC6 /* NoteData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51197A9622A70E0400E78FC6 /* NoteData.swift */; }; + 51197A9922A77E0400E78FC6 /* NoteDetail.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51197A9822A77E0400E78FC6 /* NoteDetail.swift */; }; + 51197A9B22A7852C00E78FC6 /* UserData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51197A9A22A7852C00E78FC6 /* UserData.swift */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 51197A7C22A6B23800E78FC6 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 51197A5D22A6B23600E78FC6 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 51197A6422A6B23600E78FC6; + remoteInfo = SwiftUINote; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + 51197A6522A6B23600E78FC6 /* SwiftUINote.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SwiftUINote.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 51197A6822A6B23600E78FC6 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 51197A6A22A6B23600E78FC6 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; + 51197A6E22A6B23800E78FC6 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 51197A7122A6B23800E78FC6 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; + 51197A7422A6B23800E78FC6 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 51197A7622A6B23800E78FC6 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 51197A7B22A6B23800E78FC6 /* SwiftUINoteTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SwiftUINoteTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 51197A7F22A6B23800E78FC6 /* SwiftUINoteTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SwiftUINoteTests.swift; sourceTree = ""; }; + 51197A8122A6B23800E78FC6 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 51197A8F22A6E01500E78FC6 /* Note.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Note.swift; sourceTree = ""; }; + 51197A9222A6E1D500E78FC6 /* NoteRow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NoteRow.swift; sourceTree = ""; }; + 51197A9422A7011500E78FC6 /* NoteList.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NoteList.swift; sourceTree = ""; }; + 51197A9622A70E0400E78FC6 /* NoteData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NoteData.swift; sourceTree = ""; }; + 51197A9822A77E0400E78FC6 /* NoteDetail.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NoteDetail.swift; sourceTree = ""; }; + 51197A9A22A7852C00E78FC6 /* UserData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserData.swift; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 51197A6222A6B23600E78FC6 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 51197A7822A6B23800E78FC6 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 51197A5C22A6B23600E78FC6 = { + isa = PBXGroup; + children = ( + 51197A6722A6B23600E78FC6 /* SwiftUINote */, + 51197A7E22A6B23800E78FC6 /* SwiftUINoteTests */, + 51197A6622A6B23600E78FC6 /* Products */, + ); + sourceTree = ""; + }; + 51197A6622A6B23600E78FC6 /* Products */ = { + isa = PBXGroup; + children = ( + 51197A6522A6B23600E78FC6 /* SwiftUINote.app */, + 51197A7B22A6B23800E78FC6 /* SwiftUINoteTests.xctest */, + ); + name = Products; + sourceTree = ""; + }; + 51197A6722A6B23600E78FC6 /* SwiftUINote */ = { + isa = PBXGroup; + children = ( + 51197A8E22A6DFC700E78FC6 /* Models */, + 51197A9122A6E1B600E78FC6 /* Views */, + 51197A6822A6B23600E78FC6 /* AppDelegate.swift */, + 51197A6A22A6B23600E78FC6 /* SceneDelegate.swift */, + 51197A6E22A6B23800E78FC6 /* Assets.xcassets */, + 51197A7322A6B23800E78FC6 /* LaunchScreen.storyboard */, + 51197A7622A6B23800E78FC6 /* Info.plist */, + 51197A7022A6B23800E78FC6 /* Preview Content */, + ); + path = SwiftUINote; + sourceTree = ""; + }; + 51197A7022A6B23800E78FC6 /* Preview Content */ = { + isa = PBXGroup; + children = ( + 51197A7122A6B23800E78FC6 /* Preview Assets.xcassets */, + ); + path = "Preview Content"; + sourceTree = ""; + }; + 51197A7E22A6B23800E78FC6 /* SwiftUINoteTests */ = { + isa = PBXGroup; + children = ( + 51197A7F22A6B23800E78FC6 /* SwiftUINoteTests.swift */, + 51197A8122A6B23800E78FC6 /* Info.plist */, + ); + path = SwiftUINoteTests; + sourceTree = ""; + }; + 51197A8E22A6DFC700E78FC6 /* Models */ = { + isa = PBXGroup; + children = ( + 51197A8F22A6E01500E78FC6 /* Note.swift */, + 51197A9622A70E0400E78FC6 /* NoteData.swift */, + 51197A9A22A7852C00E78FC6 /* UserData.swift */, + ); + path = Models; + sourceTree = ""; + }; + 51197A9122A6E1B600E78FC6 /* Views */ = { + isa = PBXGroup; + children = ( + 51197A9222A6E1D500E78FC6 /* NoteRow.swift */, + 51197A9422A7011500E78FC6 /* NoteList.swift */, + 51197A9822A77E0400E78FC6 /* NoteDetail.swift */, + ); + path = Views; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 51197A6422A6B23600E78FC6 /* SwiftUINote */ = { + isa = PBXNativeTarget; + buildConfigurationList = 51197A8422A6B23800E78FC6 /* Build configuration list for PBXNativeTarget "SwiftUINote" */; + buildPhases = ( + 51197A6122A6B23600E78FC6 /* Sources */, + 51197A6222A6B23600E78FC6 /* Frameworks */, + 51197A6322A6B23600E78FC6 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = SwiftUINote; + productName = SwiftUINote; + productReference = 51197A6522A6B23600E78FC6 /* SwiftUINote.app */; + productType = "com.apple.product-type.application"; + }; + 51197A7A22A6B23800E78FC6 /* SwiftUINoteTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 51197A8722A6B23800E78FC6 /* Build configuration list for PBXNativeTarget "SwiftUINoteTests" */; + buildPhases = ( + 51197A7722A6B23800E78FC6 /* Sources */, + 51197A7822A6B23800E78FC6 /* Frameworks */, + 51197A7922A6B23800E78FC6 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 51197A7D22A6B23800E78FC6 /* PBXTargetDependency */, + ); + name = SwiftUINoteTests; + productName = SwiftUINoteTests; + productReference = 51197A7B22A6B23800E78FC6 /* SwiftUINoteTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 51197A5D22A6B23600E78FC6 /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 1100; + LastUpgradeCheck = 1100; + ORGANIZATIONNAME = "we'd"; + TargetAttributes = { + 51197A6422A6B23600E78FC6 = { + CreatedOnToolsVersion = 11.0; + }; + 51197A7A22A6B23800E78FC6 = { + CreatedOnToolsVersion = 11.0; + TestTargetID = 51197A6422A6B23600E78FC6; + }; + }; + }; + buildConfigurationList = 51197A6022A6B23600E78FC6 /* Build configuration list for PBXProject "SwiftUINote" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 51197A5C22A6B23600E78FC6; + productRefGroup = 51197A6622A6B23600E78FC6 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 51197A6422A6B23600E78FC6 /* SwiftUINote */, + 51197A7A22A6B23800E78FC6 /* SwiftUINoteTests */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 51197A6322A6B23600E78FC6 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 51197A7522A6B23800E78FC6 /* LaunchScreen.storyboard in Resources */, + 51197A7222A6B23800E78FC6 /* Preview Assets.xcassets in Resources */, + 51197A6F22A6B23800E78FC6 /* Assets.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 51197A7922A6B23800E78FC6 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 51197A6122A6B23600E78FC6 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 51197A9322A6E1D500E78FC6 /* NoteRow.swift in Sources */, + 51197A9722A70E0400E78FC6 /* NoteData.swift in Sources */, + 51197A6922A6B23600E78FC6 /* AppDelegate.swift in Sources */, + 51197A9B22A7852C00E78FC6 /* UserData.swift in Sources */, + 51197A6B22A6B23600E78FC6 /* SceneDelegate.swift in Sources */, + 51197A9922A77E0400E78FC6 /* NoteDetail.swift in Sources */, + 51197A9022A6E01500E78FC6 /* Note.swift in Sources */, + 51197A9522A7011500E78FC6 /* NoteList.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 51197A7722A6B23800E78FC6 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 51197A8022A6B23800E78FC6 /* SwiftUINoteTests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 51197A7D22A6B23800E78FC6 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 51197A6422A6B23600E78FC6 /* SwiftUINote */; + targetProxy = 51197A7C22A6B23800E78FC6 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin PBXVariantGroup section */ + 51197A7322A6B23800E78FC6 /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 51197A7422A6B23800E78FC6 /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 51197A8222A6B23800E78FC6 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + 51197A8322A6B23800E78FC6 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 51197A8522A6B23800E78FC6 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_ASSET_PATHS = "SwiftUINote/Preview\\ Content"; + ENABLE_PREVIEWS = YES; + INFOPLIST_FILE = SwiftUINote/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = io.github.agiletalk.SwiftUINote; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 51197A8622A6B23800E78FC6 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_ASSET_PATHS = "SwiftUINote/Preview\\ Content"; + ENABLE_PREVIEWS = YES; + INFOPLIST_FILE = SwiftUINote/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = io.github.agiletalk.SwiftUINote; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; + 51197A8822A6B23800E78FC6 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + INFOPLIST_FILE = SwiftUINoteTests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = io.github.agiletalk.SwiftUINoteTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/SwiftUINote.app/SwiftUINote"; + }; + name = Debug; + }; + 51197A8922A6B23800E78FC6 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + INFOPLIST_FILE = SwiftUINoteTests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = io.github.agiletalk.SwiftUINoteTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/SwiftUINote.app/SwiftUINote"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 51197A6022A6B23600E78FC6 /* Build configuration list for PBXProject "SwiftUINote" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 51197A8222A6B23800E78FC6 /* Debug */, + 51197A8322A6B23800E78FC6 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 51197A8422A6B23800E78FC6 /* Build configuration list for PBXNativeTarget "SwiftUINote" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 51197A8522A6B23800E78FC6 /* Debug */, + 51197A8622A6B23800E78FC6 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 51197A8722A6B23800E78FC6 /* Build configuration list for PBXNativeTarget "SwiftUINoteTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 51197A8822A6B23800E78FC6 /* Debug */, + 51197A8922A6B23800E78FC6 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 51197A5D22A6B23600E78FC6 /* Project object */; +} diff --git a/Other Projects/UINote/SwiftUINote.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/Other Projects/UINote/SwiftUINote.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..d83239a --- /dev/null +++ b/Other Projects/UINote/SwiftUINote.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/Other Projects/UINote/SwiftUINote.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/Other Projects/UINote/SwiftUINote.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/Other Projects/UINote/SwiftUINote.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/Other Projects/UINote/SwiftUINote/AppDelegate.swift b/Other Projects/UINote/SwiftUINote/AppDelegate.swift new file mode 100644 index 0000000..142c1e0 --- /dev/null +++ b/Other Projects/UINote/SwiftUINote/AppDelegate.swift @@ -0,0 +1,42 @@ +// +// AppDelegate.swift +// SwiftUINote +// +// Created by chanju Jeon on 04/06/2019. +// Copyright © 2019 we'd. All rights reserved. +// + +import UIKit + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + + + + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { + // Override point for customization after application launch. + return true + } + + func applicationWillTerminate(_ application: UIApplication) { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. + NoteData.shared.save() + } + + // MARK: UISceneSession Lifecycle + + func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration { + // Called when a new scene session is being created. + // Use this method to select a configuration to create the new scene with. + return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role) + } + + func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) { + // Called when the user discards a scene session. + // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions. + // Use this method to release any resources that were specific to the discarded scenes, as they will not return. + } + + +} + diff --git a/Other Projects/UINote/SwiftUINote/Assets.xcassets/AppIcon.appiconset/Contents.json b/Other Projects/UINote/SwiftUINote/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..d8db8d6 --- /dev/null +++ b/Other Projects/UINote/SwiftUINote/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,98 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "83.5x83.5", + "scale" : "2x" + }, + { + "idiom" : "ios-marketing", + "size" : "1024x1024", + "scale" : "1x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/UINote/SwiftUINote/Assets.xcassets/Contents.json b/Other Projects/UINote/SwiftUINote/Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/Other Projects/UINote/SwiftUINote/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/UINote/SwiftUINote/Assets.xcassets/nomad.imageset/Contents.json b/Other Projects/UINote/SwiftUINote/Assets.xcassets/nomad.imageset/Contents.json new file mode 100644 index 0000000..25fe112 --- /dev/null +++ b/Other Projects/UINote/SwiftUINote/Assets.xcassets/nomad.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "nomad.jpg", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/UINote/SwiftUINote/Assets.xcassets/nomad.imageset/nomad.jpg b/Other Projects/UINote/SwiftUINote/Assets.xcassets/nomad.imageset/nomad.jpg new file mode 100644 index 0000000..6606b32 Binary files /dev/null and b/Other Projects/UINote/SwiftUINote/Assets.xcassets/nomad.imageset/nomad.jpg differ diff --git a/Other Projects/UINote/SwiftUINote/Base.lproj/LaunchScreen.storyboard b/Other Projects/UINote/SwiftUINote/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000..865e932 --- /dev/null +++ b/Other Projects/UINote/SwiftUINote/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Other Projects/UINote/SwiftUINote/Info.plist b/Other Projects/UINote/SwiftUINote/Info.plist new file mode 100644 index 0000000..e8bb4c6 --- /dev/null +++ b/Other Projects/UINote/SwiftUINote/Info.plist @@ -0,0 +1,62 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + $(PRODUCT_BUNDLE_PACKAGE_TYPE) + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UIApplicationSceneManifest + + UIApplicationSupportsMultipleScenes + + UISceneConfigurations + + UIWindowSceneSessionRoleApplication + + + UILaunchStoryboardName + LaunchScreen + UISceneConfigurationName + Default Configuration + UISceneDelegateClassName + $(PRODUCT_MODULE_NAME).SceneDelegate + + + + + UILaunchStoryboardName + LaunchScreen + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/Other Projects/UINote/SwiftUINote/Models/Note.swift b/Other Projects/UINote/SwiftUINote/Models/Note.swift new file mode 100644 index 0000000..fc22147 --- /dev/null +++ b/Other Projects/UINote/SwiftUINote/Models/Note.swift @@ -0,0 +1,15 @@ +// +// Note.swift +// SwiftUINote +// +// Created by chanju Jeon on 05/06/2019. +// Copyright © 2019 we'd. All rights reserved. +// + +import SwiftUI + +struct Note: Hashable, Codable, Identifiable { + let id = UUID() + var text: String + var date = Date() +} diff --git a/Other Projects/UINote/SwiftUINote/Models/NoteData.swift b/Other Projects/UINote/SwiftUINote/Models/NoteData.swift new file mode 100644 index 0000000..d5eec13 --- /dev/null +++ b/Other Projects/UINote/SwiftUINote/Models/NoteData.swift @@ -0,0 +1,38 @@ +// +// NoteData.swift +// SwiftUINote +// +// Created by chanju Jeon on 05/06/2019. +// Copyright © 2019 we'd. All rights reserved. +// + +import SwiftUI + +class NoteData { + + static let shared = NoteData() + + var notes: [Note] = [ + Note(text: "New Note"), + Note(text: "Another Note") + ] + + private init() { load() } + + static func dateToString(date: Date) -> String { + let formatter = DateFormatter() + formatter.dateStyle = .medium + return formatter.string(from: date) + } + + func save() { + UserDefaults.standard.set(try? PropertyListEncoder().encode(notes), forKey: "notes") + debugPrint("save called") + } + + func load() { + if let data = UserDefaults.standard.object(forKey: "notes") as? Data { + self.notes = try! PropertyListDecoder().decode([Note].self, from: data) + } + } +} diff --git a/Other Projects/UINote/SwiftUINote/Models/UserData.swift b/Other Projects/UINote/SwiftUINote/Models/UserData.swift new file mode 100644 index 0000000..963481d --- /dev/null +++ b/Other Projects/UINote/SwiftUINote/Models/UserData.swift @@ -0,0 +1,21 @@ +// +// UserData.swift +// SwiftUINote +// +// Created by chanju Jeon on 05/06/2019. +// Copyright © 2019 we'd. All rights reserved. +// + +import SwiftUI +import Combine + +final class UserData: ObservableObject { + let objectWillChange = PassthroughSubject() + + var notes = NoteData.shared.notes { + didSet { + objectWillChange.send(self) + NoteData.shared.notes = notes + } + } +} diff --git a/Other Projects/UINote/SwiftUINote/Preview Content/Preview Assets.xcassets/Contents.json b/Other Projects/UINote/SwiftUINote/Preview Content/Preview Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/Other Projects/UINote/SwiftUINote/Preview Content/Preview Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/UINote/SwiftUINote/SceneDelegate.swift b/Other Projects/UINote/SwiftUINote/SceneDelegate.swift new file mode 100644 index 0000000..eeb7334 --- /dev/null +++ b/Other Projects/UINote/SwiftUINote/SceneDelegate.swift @@ -0,0 +1,62 @@ +// +// SceneDelegate.swift +// SwiftUINote +// +// Created by chanju Jeon on 04/06/2019. +// Copyright © 2019 we'd. All rights reserved. +// + +import UIKit +import SwiftUI + +class SceneDelegate: UIResponder, UIWindowSceneDelegate { + + var window: UIWindow? + + + func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { + // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`. + // If using a storyboard, the `window` property will automatically be initialized and attached to the scene. + // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead). + + // Use a UIHostingController as window root view controller + if let windowScene = scene as? UIWindowScene { + let window = UIWindow(windowScene: windowScene) + window.rootViewController = UIHostingController(rootView: NoteList() + .environmentObject(UserData())) + self.window = window + window.makeKeyAndVisible() + } + } + + func sceneDidDisconnect(_ scene: UIScene) { + // Called as the scene is being released by the system. + // This occurs shortly after the scene enters the background, or when its session is discarded. + // Release any resources associated with this scene that can be re-created the next time the scene connects. + // The scene may re-connect later, as its session was not neccessarily discarded (see `application:didDiscardSceneSessions` instead). + } + + func sceneDidBecomeActive(_ scene: UIScene) { + // Called when the scene has moved from an inactive state to an active state. + // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive. + } + + func sceneWillResignActive(_ scene: UIScene) { + // Called when the scene will move from an active state to an inactive state. + // This may occur due to temporary interruptions (ex. an incoming phone call). + } + + func sceneWillEnterForeground(_ scene: UIScene) { + // Called as the scene transitions from the background to the foreground. + // Use this method to undo the changes made on entering the background. + } + + func sceneDidEnterBackground(_ scene: UIScene) { + // Called as the scene transitions from the foreground to the background. + // Use this method to save data, release shared resources, and store enough scene-specific state information + // to restore the scene back to its current state. + } + + +} + diff --git a/Other Projects/UINote/SwiftUINote/Views/NoteDetail.swift b/Other Projects/UINote/SwiftUINote/Views/NoteDetail.swift new file mode 100644 index 0000000..b3dca9b --- /dev/null +++ b/Other Projects/UINote/SwiftUINote/Views/NoteDetail.swift @@ -0,0 +1,49 @@ +// +// NoteDetail.swift +// SwiftUINote +// +// Created by chanju Jeon on 05/06/2019. +// Copyright © 2019 we'd. All rights reserved. +// + +import SwiftUI + +struct NoteDetail : View { + @EnvironmentObject var userData: UserData + var note: Note + private var text: State + + init(note: Note) { + self.note = note + self.text = .init(initialValue: note.text) + } + + var noteIndex: Int { + userData.notes.firstIndex(where: { $0.id == note.id })! + } + + var body: some View { + VStack { + TextField("", text: self.text.projectedValue, + onEditingChanged: { _ in self.updateNote()}, + onCommit: {}) + Spacer() + } + .padding() + .navigationBarTitle( + Text(NoteData.dateToString(date: note.date)), displayMode: .inline) + } + + private func updateNote() { + self.userData.notes[noteIndex].text = self.text.wrappedValue + } +} + +#if DEBUG +struct NoteDetail_Previews : PreviewProvider { + static var previews: some View { + NoteDetail(note: NoteData.shared.notes[0]) + .environmentObject(UserData()) + } +} +#endif diff --git a/Other Projects/UINote/SwiftUINote/Views/NoteList.swift b/Other Projects/UINote/SwiftUINote/Views/NoteList.swift new file mode 100644 index 0000000..9a6beb3 --- /dev/null +++ b/Other Projects/UINote/SwiftUINote/Views/NoteList.swift @@ -0,0 +1,44 @@ +// +// NoteList.swift +// SwiftUINote +// +// Created by chanju Jeon on 05/06/2019. +// Copyright © 2019 we'd. All rights reserved. +// + +import SwiftUI + +struct NoteList : View { + @EnvironmentObject var userData: UserData + + var body: some View { + NavigationView { + List(userData.notes) { note in + NavigationLink(destination: NoteDetail(note: note) + .environmentObject(self.userData)) { + NoteRow(note: note) + } + } + .navigationBarTitle(Text("Notes"), displayMode: .large) + .navigationBarItems(trailing: Button(action: self.createNote, label: { Text("New") })) + } + } + + private func createNote() { + let newNote = Note(text: "") + self.userData.notes.insert(newNote, at: 0) + } +} + +#if DEBUG +struct NoteList_Previews : PreviewProvider { + static var previews: some View { + ForEach(["iPhone SE", "iPhone XS Max"], id: \.self) { deviceName in + NoteList() + .environmentObject(UserData()) + .previewDevice(PreviewDevice(rawValue: deviceName)) + .previewDisplayName(deviceName) + } + } +} +#endif diff --git a/Other Projects/UINote/SwiftUINote/Views/NoteRow.swift b/Other Projects/UINote/SwiftUINote/Views/NoteRow.swift new file mode 100644 index 0000000..8cbf791 --- /dev/null +++ b/Other Projects/UINote/SwiftUINote/Views/NoteRow.swift @@ -0,0 +1,31 @@ +// +// NoteRow.swift +// SwiftUINote +// +// Created by chanju Jeon on 05/06/2019. +// Copyright © 2019 we'd. All rights reserved. +// + +import SwiftUI + +struct NoteRow : View { + var note: Note + + var body: some View { + HStack { + Text(note.text) + } + } +} + +#if DEBUG +struct NoteRow_Previews : PreviewProvider { + static var previews: some View { + Group { + NoteRow(note: Note(text: "New Note")) + NoteRow(note: Note(text: "Another Note")) + } + .previewLayout(.fixed(width: 300, height: 50)) + } +} +#endif diff --git a/Other Projects/UINote/SwiftUINoteTests/Info.plist b/Other Projects/UINote/SwiftUINoteTests/Info.plist new file mode 100644 index 0000000..64d65ca --- /dev/null +++ b/Other Projects/UINote/SwiftUINoteTests/Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + $(PRODUCT_BUNDLE_PACKAGE_TYPE) + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + + diff --git a/Other Projects/UINote/SwiftUINoteTests/SwiftUINoteTests.swift b/Other Projects/UINote/SwiftUINoteTests/SwiftUINoteTests.swift new file mode 100644 index 0000000..bef1feb --- /dev/null +++ b/Other Projects/UINote/SwiftUINoteTests/SwiftUINoteTests.swift @@ -0,0 +1,34 @@ +// +// SwiftUINoteTests.swift +// SwiftUINoteTests +// +// Created by chanju Jeon on 04/06/2019. +// Copyright © 2019 we'd. All rights reserved. +// + +import XCTest +@testable import SwiftUINote + +class SwiftUINoteTests: XCTestCase { + + override func setUp() { + // Put setup code here. This method is called before the invocation of each test method in the class. + } + + override func tearDown() { + // Put teardown code here. This method is called after the invocation of each test method in the class. + } + + func testExample() { + // This is an example of a functional test case. + // Use XCTAssert and related functions to verify your tests produce the correct results. + } + + func testPerformanceExample() { + // This is an example of a performance test case. + self.measure { + // Put the code you want to measure the time of here. + } + } + +} diff --git a/Other Projects/WWDCPlayer/WWDCPlayer.xcodeproj/project.pbxproj b/Other Projects/WWDCPlayer/WWDCPlayer.xcodeproj/project.pbxproj new file mode 100644 index 0000000..e331c16 --- /dev/null +++ b/Other Projects/WWDCPlayer/WWDCPlayer.xcodeproj/project.pbxproj @@ -0,0 +1,538 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 50; + objects = { + +/* Begin PBXBuildFile section */ + 8D49A1F722A8839D002D1C10 /* VideoRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8D49A1F622A8839D002D1C10 /* VideoRow.swift */; }; + 8DC3392C22A89A7D00EDE8CF /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 8DC3392A22A89A7D00EDE8CF /* Assets.xcassets */; }; + 8DC3393122A8A14800EDE8CF /* UserData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8DC3393022A8A14800EDE8CF /* UserData.swift */; }; + B83D3F7B22A8529B000A9E72 /* PlayerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B83D3F7A22A8529B000A9E72 /* PlayerViewController.swift */; }; + B83D3F7D22A855C8000A9E72 /* Video.swift in Sources */ = {isa = PBXBuildFile; fileRef = B83D3F7C22A855C8000A9E72 /* Video.swift */; }; + B8C3352422A83894003AD9B4 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8C3352322A83894003AD9B4 /* AppDelegate.swift */; }; + B8C3352622A83894003AD9B4 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8C3352522A83894003AD9B4 /* SceneDelegate.swift */; }; + B8C3352822A83894003AD9B4 /* MainView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8C3352722A83894003AD9B4 /* MainView.swift */; }; + B8C3352D22A83897003AD9B4 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B8C3352C22A83897003AD9B4 /* Preview Assets.xcassets */; }; + B8C3353022A83897003AD9B4 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B8C3352E22A83897003AD9B4 /* LaunchScreen.storyboard */; }; + B8C3353B22A83898003AD9B4 /* WWDCPlayerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8C3353A22A83898003AD9B4 /* WWDCPlayerTests.swift */; }; + B8E926AD22A8E22A009D3FF1 /* WeekDay.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8E926AC22A8E22A009D3FF1 /* WeekDay.swift */; }; + B8E926AF22A8E242009D3FF1 /* Platform.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8E926AE22A8E242009D3FF1 /* Platform.swift */; }; + B8E926B422A9CD69009D3FF1 /* WWDCPlayerTests.xctest in Resources */ = {isa = PBXBuildFile; fileRef = B8C3353622A83897003AD9B4 /* WWDCPlayerTests.xctest */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + B8C3353722A83897003AD9B4 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = B8C3351822A83894003AD9B4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = B8C3351F22A83894003AD9B4; + remoteInfo = SwiftUISample; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + 8D49A1F622A8839D002D1C10 /* VideoRow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = VideoRow.swift; path = WWDCPlayer/VideoRow.swift; sourceTree = SOURCE_ROOT; }; + 8DC3392A22A89A7D00EDE8CF /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 8DC3392B22A89A7D00EDE8CF /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 8DC3393022A8A14800EDE8CF /* UserData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = UserData.swift; path = WWDCPlayer/Model/UserData.swift; sourceTree = SOURCE_ROOT; }; + B83D3F7A22A8529B000A9E72 /* PlayerViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = PlayerViewController.swift; path = WWDCPlayer/PlayerViewController.swift; sourceTree = SOURCE_ROOT; }; + B83D3F7C22A855C8000A9E72 /* Video.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Video.swift; sourceTree = ""; }; + B8C3352022A83894003AD9B4 /* WWDCPlayer.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = WWDCPlayer.app; sourceTree = BUILT_PRODUCTS_DIR; }; + B8C3352322A83894003AD9B4 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + B8C3352522A83894003AD9B4 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; + B8C3352722A83894003AD9B4 /* MainView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = MainView.swift; path = WWDCPlayer/MainView.swift; sourceTree = SOURCE_ROOT; }; + B8C3352C22A83897003AD9B4 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; + B8C3352F22A83897003AD9B4 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + B8C3353622A83897003AD9B4 /* WWDCPlayerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = WWDCPlayerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + B8C3353A22A83898003AD9B4 /* WWDCPlayerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WWDCPlayerTests.swift; sourceTree = ""; }; + B8C3353C22A83898003AD9B4 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + B8E926AC22A8E22A009D3FF1 /* WeekDay.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WeekDay.swift; sourceTree = ""; }; + B8E926AE22A8E242009D3FF1 /* Platform.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Platform.swift; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + B8C3351D22A83894003AD9B4 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + B8C3353322A83897003AD9B4 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 8D7DEE8B22A8950D005D6A10 /* Delegates */ = { + isa = PBXGroup; + children = ( + B8C3352322A83894003AD9B4 /* AppDelegate.swift */, + B8C3352522A83894003AD9B4 /* SceneDelegate.swift */, + ); + path = Delegates; + sourceTree = ""; + }; + 8DC3392922A89A7D00EDE8CF /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 8DC3392A22A89A7D00EDE8CF /* Assets.xcassets */, + 8DC3392B22A89A7D00EDE8CF /* Info.plist */, + ); + path = "Supporting Files"; + sourceTree = ""; + }; + B8C3351722A83894003AD9B4 = { + isa = PBXGroup; + children = ( + B8C3352222A83894003AD9B4 /* WWDCPlayer */, + B8C3353922A83898003AD9B4 /* WWDCPlayerTests */, + B8C3352122A83894003AD9B4 /* Products */, + ); + sourceTree = ""; + }; + B8C3352122A83894003AD9B4 /* Products */ = { + isa = PBXGroup; + children = ( + B8C3352022A83894003AD9B4 /* WWDCPlayer.app */, + B8C3353622A83897003AD9B4 /* WWDCPlayerTests.xctest */, + ); + name = Products; + sourceTree = ""; + }; + B8C3352222A83894003AD9B4 /* WWDCPlayer */ = { + isa = PBXGroup; + children = ( + B8C3352E22A83897003AD9B4 /* LaunchScreen.storyboard */, + 8D7DEE8B22A8950D005D6A10 /* Delegates */, + B8C67D6522A8D09500C0B63F /* Model */, + B8E926B322A9CCAD009D3FF1 /* View */, + B8E926B022A8E24D009D3FF1 /* Enum */, + 8DC3392922A89A7D00EDE8CF /* Supporting Files */, + B8C3352B22A83897003AD9B4 /* Preview Content */, + ); + path = WWDCPlayer; + sourceTree = ""; + }; + B8C3352B22A83897003AD9B4 /* Preview Content */ = { + isa = PBXGroup; + children = ( + B8C3352C22A83897003AD9B4 /* Preview Assets.xcassets */, + ); + path = "Preview Content"; + sourceTree = ""; + }; + B8C3353922A83898003AD9B4 /* WWDCPlayerTests */ = { + isa = PBXGroup; + children = ( + B8C3353A22A83898003AD9B4 /* WWDCPlayerTests.swift */, + B8C3353C22A83898003AD9B4 /* Info.plist */, + ); + path = WWDCPlayerTests; + sourceTree = ""; + }; + B8C67D6522A8D09500C0B63F /* Model */ = { + isa = PBXGroup; + children = ( + B83D3F7C22A855C8000A9E72 /* Video.swift */, + 8DC3393022A8A14800EDE8CF /* UserData.swift */, + ); + path = Model; + sourceTree = ""; + }; + B8E926B022A8E24D009D3FF1 /* Enum */ = { + isa = PBXGroup; + children = ( + B8E926AC22A8E22A009D3FF1 /* WeekDay.swift */, + B8E926AE22A8E242009D3FF1 /* Platform.swift */, + ); + path = Enum; + sourceTree = ""; + }; + B8E926B322A9CCAD009D3FF1 /* View */ = { + isa = PBXGroup; + children = ( + B8C3352722A83894003AD9B4 /* MainView.swift */, + 8D49A1F622A8839D002D1C10 /* VideoRow.swift */, + B83D3F7A22A8529B000A9E72 /* PlayerViewController.swift */, + ); + path = View; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + B8C3351F22A83894003AD9B4 /* WWDCPlayer */ = { + isa = PBXNativeTarget; + buildConfigurationList = B8C3353F22A83898003AD9B4 /* Build configuration list for PBXNativeTarget "WWDCPlayer" */; + buildPhases = ( + B8C3351C22A83894003AD9B4 /* Sources */, + B8C3351D22A83894003AD9B4 /* Frameworks */, + B8C3351E22A83894003AD9B4 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = WWDCPlayer; + productName = SwiftUISample; + productReference = B8C3352022A83894003AD9B4 /* WWDCPlayer.app */; + productType = "com.apple.product-type.application"; + }; + B8C3353522A83897003AD9B4 /* WWDCPlayerTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = B8C3354222A83898003AD9B4 /* Build configuration list for PBXNativeTarget "WWDCPlayerTests" */; + buildPhases = ( + B8C3353222A83897003AD9B4 /* Sources */, + B8C3353322A83897003AD9B4 /* Frameworks */, + B8C3353422A83897003AD9B4 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + B8C3353822A83897003AD9B4 /* PBXTargetDependency */, + ); + name = WWDCPlayerTests; + productName = SwiftUISampleTests; + productReference = B8C3353622A83897003AD9B4 /* WWDCPlayerTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + B8C3351822A83894003AD9B4 /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 1100; + LastUpgradeCheck = 1100; + ORGANIZATIONNAME = daybreak; + TargetAttributes = { + B8C3351F22A83894003AD9B4 = { + CreatedOnToolsVersion = 11.0; + }; + B8C3353522A83897003AD9B4 = { + CreatedOnToolsVersion = 11.0; + TestTargetID = B8C3351F22A83894003AD9B4; + }; + }; + }; + buildConfigurationList = B8C3351B22A83894003AD9B4 /* Build configuration list for PBXProject "WWDCPlayer" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = B8C3351722A83894003AD9B4; + productRefGroup = B8C3352122A83894003AD9B4 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + B8C3351F22A83894003AD9B4 /* WWDCPlayer */, + B8C3353522A83897003AD9B4 /* WWDCPlayerTests */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + B8C3351E22A83894003AD9B4 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + B8C3353022A83897003AD9B4 /* LaunchScreen.storyboard in Resources */, + 8DC3392C22A89A7D00EDE8CF /* Assets.xcassets in Resources */, + B8C3352D22A83897003AD9B4 /* Preview Assets.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + B8C3353422A83897003AD9B4 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + B8E926B422A9CD69009D3FF1 /* WWDCPlayerTests.xctest in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + B8C3351C22A83894003AD9B4 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + B8C3352422A83894003AD9B4 /* AppDelegate.swift in Sources */, + B8C3352622A83894003AD9B4 /* SceneDelegate.swift in Sources */, + B8E926AD22A8E22A009D3FF1 /* WeekDay.swift in Sources */, + B8C3352822A83894003AD9B4 /* MainView.swift in Sources */, + 8DC3393122A8A14800EDE8CF /* UserData.swift in Sources */, + B8E926AF22A8E242009D3FF1 /* Platform.swift in Sources */, + B83D3F7B22A8529B000A9E72 /* PlayerViewController.swift in Sources */, + 8D49A1F722A8839D002D1C10 /* VideoRow.swift in Sources */, + B83D3F7D22A855C8000A9E72 /* Video.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + B8C3353222A83897003AD9B4 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + B8C3353B22A83898003AD9B4 /* WWDCPlayerTests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + B8C3353822A83897003AD9B4 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = B8C3351F22A83894003AD9B4 /* WWDCPlayer */; + targetProxy = B8C3353722A83897003AD9B4 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin PBXVariantGroup section */ + B8C3352E22A83897003AD9B4 /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + B8C3352F22A83897003AD9B4 /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + B8C3353D22A83898003AD9B4 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + B8C3353E22A83898003AD9B4 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + B8C3354022A83898003AD9B4 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_ASSET_PATHS = "WWDCPlayer/Preview\\ Content"; + ENABLE_PREVIEWS = YES; + INFOPLIST_FILE = "$(SRCROOT)/WWDCPlayer/Supporting Files/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.daybreak.WWDCPlayer; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + B8C3354122A83898003AD9B4 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_ASSET_PATHS = "WWDCPlayer/Preview\\ Content"; + ENABLE_PREVIEWS = YES; + INFOPLIST_FILE = "$(SRCROOT)/WWDCPlayer/Supporting Files/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.daybreak.WWDCPlayer; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; + B8C3354322A83898003AD9B4 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + INFOPLIST_FILE = WWDCPlayerTests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.daybreak.WWDCPlayerTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/WWDCPlayer.app/WWDCPlayer"; + }; + name = Debug; + }; + B8C3354422A83898003AD9B4 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + INFOPLIST_FILE = WWDCPlayerTests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.daybreak.WWDCPlayerTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/WWDCPlayer.app/WWDCPlayer"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + B8C3351B22A83894003AD9B4 /* Build configuration list for PBXProject "WWDCPlayer" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + B8C3353D22A83898003AD9B4 /* Debug */, + B8C3353E22A83898003AD9B4 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + B8C3353F22A83898003AD9B4 /* Build configuration list for PBXNativeTarget "WWDCPlayer" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + B8C3354022A83898003AD9B4 /* Debug */, + B8C3354122A83898003AD9B4 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + B8C3354222A83898003AD9B4 /* Build configuration list for PBXNativeTarget "WWDCPlayerTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + B8C3354322A83898003AD9B4 /* Debug */, + B8C3354422A83898003AD9B4 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = B8C3351822A83894003AD9B4 /* Project object */; +} diff --git a/Other Projects/WWDCPlayer/WWDCPlayer.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/Other Projects/WWDCPlayer/WWDCPlayer.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..cdcb85f --- /dev/null +++ b/Other Projects/WWDCPlayer/WWDCPlayer.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/Other Projects/WWDCPlayer/WWDCPlayer.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/Other Projects/WWDCPlayer/WWDCPlayer.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/Other Projects/WWDCPlayer/WWDCPlayer.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/Other Projects/WWDCPlayer/WWDCPlayer.xcodeproj/xcshareddata/xcschemes/WWDCPlayer.xcscheme b/Other Projects/WWDCPlayer/WWDCPlayer.xcodeproj/xcshareddata/xcschemes/WWDCPlayer.xcscheme new file mode 100644 index 0000000..2d0a247 --- /dev/null +++ b/Other Projects/WWDCPlayer/WWDCPlayer.xcodeproj/xcshareddata/xcschemes/WWDCPlayer.xcscheme @@ -0,0 +1,88 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Other Projects/WWDCPlayer/WWDCPlayer/Base.lproj/LaunchScreen.storyboard b/Other Projects/WWDCPlayer/WWDCPlayer/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000..a1d5f74 --- /dev/null +++ b/Other Projects/WWDCPlayer/WWDCPlayer/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,202 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Other Projects/WWDCPlayer/WWDCPlayer/Delegates/AppDelegate.swift b/Other Projects/WWDCPlayer/WWDCPlayer/Delegates/AppDelegate.swift new file mode 100644 index 0000000..0acce05 --- /dev/null +++ b/Other Projects/WWDCPlayer/WWDCPlayer/Delegates/AppDelegate.swift @@ -0,0 +1,41 @@ +// +// AppDelegate.swift +// WWDCPlayer +// +// Created by ms on 2019/06/05. +// Copyright © 2019 daybreak. All rights reserved. +// + +import UIKit + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + + + + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { + // Override point for customization after application launch. + return true + } + + func applicationWillTerminate(_ application: UIApplication) { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. + } + + // MARK: UISceneSession Lifecycle + + func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration { + // Called when a new scene session is being created. + // Use this method to select a configuration to create the new scene with. + return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role) + } + + func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) { + // Called when the user discards a scene session. + // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions. + // Use this method to release any resources that were specific to the discarded scenes, as they will not return. + } + + +} + diff --git a/Other Projects/WWDCPlayer/WWDCPlayer/Delegates/SceneDelegate.swift b/Other Projects/WWDCPlayer/WWDCPlayer/Delegates/SceneDelegate.swift new file mode 100644 index 0000000..65fd6ad --- /dev/null +++ b/Other Projects/WWDCPlayer/WWDCPlayer/Delegates/SceneDelegate.swift @@ -0,0 +1,62 @@ +// +// SceneDelegate.swift +// WWDCPlayer +// +// Created by ms on 2019/06/05. +// Copyright © 2019 daybreak. All rights reserved. +// + +import UIKit +import SwiftUI + +class SceneDelegate: UIResponder, UIWindowSceneDelegate { + + var window: UIWindow? + + + func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { + // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`. + // If using a storyboard, the `window` property will automatically be initialized and attached to the scene. + // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead). + + // Use a UIHostingController as window root view controller + if let windowScene = scene as? UIWindowScene { + let window = UIWindow(windowScene: windowScene) + window.rootViewController = UIHostingController(rootView: MainView() + .environmentObject(UserData())) + self.window = window + window.makeKeyAndVisible() + } + } + + func sceneDidDisconnect(_ scene: UIScene) { + // Called as the scene is being released by the system. + // This occurs shortly after the scene enters the background, or when its session is discarded. + // Release any resources associated with this scene that can be re-created the next time the scene connects. + // The scene may re-connect later, as its session was not neccessarily discarded (see `application:didDiscardSceneSessions` instead). + } + + func sceneDidBecomeActive(_ scene: UIScene) { + // Called when the scene has moved from an inactive state to an active state. + // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive. + } + + func sceneWillResignActive(_ scene: UIScene) { + // Called when the scene will move from an active state to an inactive state. + // This may occur due to temporary interruptions (ex. an incoming phone call). + } + + func sceneWillEnterForeground(_ scene: UIScene) { + // Called as the scene transitions from the background to the foreground. + // Use this method to undo the changes made on entering the background. + } + + func sceneDidEnterBackground(_ scene: UIScene) { + // Called as the scene transitions from the foreground to the background. + // Use this method to save data, release shared resources, and store enough scene-specific state information + // to restore the scene back to its current state. + } + + +} + diff --git a/Other Projects/WWDCPlayer/WWDCPlayer/Enum/Platform.swift b/Other Projects/WWDCPlayer/WWDCPlayer/Enum/Platform.swift new file mode 100644 index 0000000..65fcdb1 --- /dev/null +++ b/Other Projects/WWDCPlayer/WWDCPlayer/Enum/Platform.swift @@ -0,0 +1,15 @@ +// +// Platform.swift +// WWDCPlayer +// +// Created by sohee on 2019/06/05. +// Copyright © 2019 daybreak. All rights reserved. +// + +import Foundation + +enum Platform: String, CaseIterable { + case iOS, macOS, tvOS, watchOS +} + +let allPlatforms = Platform.allCases diff --git a/Other Projects/WWDCPlayer/WWDCPlayer/Enum/WeekDay.swift b/Other Projects/WWDCPlayer/WWDCPlayer/Enum/WeekDay.swift new file mode 100644 index 0000000..8b2a792 --- /dev/null +++ b/Other Projects/WWDCPlayer/WWDCPlayer/Enum/WeekDay.swift @@ -0,0 +1,23 @@ +// +// WeekDay.swift +// WWDCPlayer +// +// Created by ms on 2019/06/05. +// Copyright © 2019 daybreak. All rights reserved. +// + +import Foundation +import SwiftUI + +enum WeekDay: String, CaseIterable, Identifiable { + var id: String { + return self.rawValue + } + case monday + case tuesday + case wednesday + case thursday + case friday +} + +let allWeekDays = WeekDay.allCases diff --git a/Other Projects/WWDCPlayer/WWDCPlayer/MainView.swift b/Other Projects/WWDCPlayer/WWDCPlayer/MainView.swift new file mode 100644 index 0000000..0e88484 --- /dev/null +++ b/Other Projects/WWDCPlayer/WWDCPlayer/MainView.swift @@ -0,0 +1,72 @@ +// +// MainView.swift +// WWDCPlayer +// +// Created by ms on 2019/06/05. +// Copyright © 2019 daybreak. All rights reserved. +// + +import SwiftUI +import AVFoundation + +struct MainView: View { + + @EnvironmentObject var userData: UserData + + let player = AVPlayer() + + var body: some View { + NavigationView { + VStack { + ZStack(alignment: .bottom) { + PlayerViewController(video: $userData.currentVideo) + } + + FavoriteToggleView() + VideoListView() + } + .navigationBarTitle(Text(userData.currentVideo.title)) + } + } +} + +#if DEBUG +struct MainView_Previews : PreviewProvider { + static var previews: some View { + MainView() + .environmentObject(UserData()) + } +} +#endif + +struct FavoriteToggleView: View { + + @EnvironmentObject var userData: UserData + + var body: some View { + Toggle(isOn: $userData.showFavoriteOnly) { + Text("Favorite Only") + .foregroundColor(Color.yellow) + } + .padding([.leading, .trailing], 20) + } +} + +struct VideoListView : View { + + @EnvironmentObject var userData: UserData + + var body: some View { + List { + ForEach(allWeekDays) { day in + Section(header: Text(day.rawValue.uppercased()).fontWeight(.bold)) { + ForEach(self.userData.videos.filter { $0.weekDay == day }) { video in + if !self.userData.showFavoriteOnly || video.isFavorite { + VideoRow(video: video, isFavorite: video.isFavorite) + } + } + } + } + }.listStyle(GroupedListStyle()) + } +} diff --git a/Other Projects/WWDCPlayer/WWDCPlayer/Model/UserData.swift b/Other Projects/WWDCPlayer/WWDCPlayer/Model/UserData.swift new file mode 100644 index 0000000..93ecc82 --- /dev/null +++ b/Other Projects/WWDCPlayer/WWDCPlayer/Model/UserData.swift @@ -0,0 +1,17 @@ +// +// UserData.swift +// WWDCPlayer +// +// Created by sohee on 2019/06/06. +// Copyright © 2019 daybreak. All rights reserved. +// +import SwiftUI +import Combine + +final class UserData: ObservableObject { + @Published var showFavoriteOnly = false + + @Published var videos = videoList + + @Published var currentVideo = videoList[0] +} diff --git a/Other Projects/WWDCPlayer/WWDCPlayer/Model/Video.swift b/Other Projects/WWDCPlayer/WWDCPlayer/Model/Video.swift new file mode 100644 index 0000000..5c0e0e6 --- /dev/null +++ b/Other Projects/WWDCPlayer/WWDCPlayer/Model/Video.swift @@ -0,0 +1,35 @@ +// +// Video.swift +// WWDCPlayer +// +// Created by ms on 2019/06/05. +// Copyright © 2019 daybreak. All rights reserved. +// + +import Foundation +import SwiftUI + +struct Video: Identifiable, Equatable { + var id: Int + var title: String + var url: String + var weekDay: WeekDay + var platforms: [Platform] + var isFavorite = false + + var platformString: String { + return platforms.map { $0.rawValue }.joined(separator: ", ") + } + + static func == (lhs: Video, rhs: Video) -> Bool { + return lhs.id == rhs.id + } +} + +let videoList = [ + Video(id: 101, title: "Keynote🤖", url: "https://p-events-delivery.akamaized.net/3004qzusahnbjppuwydgjzsdyzsippar/m3u8/hls_vod_mvp.m3u8", weekDay: .monday, platforms: allPlatforms), + Video(id: 103, title: "Platforms State of the Union🛠", url: "https://devstreaming-cdn.apple.com/videos/wwdc/2019/103bax22h2udxu0n/103/hls_vod_mvp.m3u8", weekDay: .monday, platforms: allPlatforms), + Video(id: 104, title: "Apple Design Awards🏆", url: "https://devstreaming-cdn.apple.com/videos/wwdc/2019/104d6zyhb21vki/104/hls_vod_mvp.m3u8", weekDay: .monday, platforms: allPlatforms), + Video(id: 204, title: "Introducing SwiftUI: Building Your First App", url: "https://devstreaming-cdn.apple.com/videos/wwdc/2019/204isgnpbqud244/204/hls_vod_mvp.m3u8", weekDay: .tuesday, platforms: allPlatforms), + Video(id: 214, title: "Implementing Dark Mode on iOS", url: "https://devstreaming-cdn.apple.com/videos/wwdc/2019/214iqtpuhih53fw2/214/hls_vod_mvp.m3u8", weekDay: .wednesday, platforms: [.iOS]) +] diff --git a/Other Projects/WWDCPlayer/WWDCPlayer/PlayerViewController.swift b/Other Projects/WWDCPlayer/WWDCPlayer/PlayerViewController.swift new file mode 100644 index 0000000..f1b687e --- /dev/null +++ b/Other Projects/WWDCPlayer/WWDCPlayer/PlayerViewController.swift @@ -0,0 +1,37 @@ +// +// PlayerViewController.swift +// WWDCPlayer +// +// Created by ms on 2019/06/05. +// Copyright © 2019 daybreak. All rights reserved. +// + +import SwiftUI +import AVKit + +struct PlayerViewController: UIViewControllerRepresentable { + + @Binding var video: Video + + private let player = AVPlayer() + + func makeUIViewController(context: Context) -> AVPlayerViewController { + let playerVC = AVPlayerViewController() + playerVC.player = self.player + return playerVC + } + + func updateUIViewController(_ uiViewController: AVPlayerViewController, context: Context) { + guard let url = URL(string: video.url) else { return } + + resetPlayer(uiViewController) + + let item = AVPlayerItem(url: url) + uiViewController.player?.replaceCurrentItem(with: item) + } + + func resetPlayer(_ vc: AVPlayerViewController) { + vc.player?.pause() + vc.player?.replaceCurrentItem(with: nil) + } +} diff --git a/Other Projects/WWDCPlayer/WWDCPlayer/Preview Content/Preview Assets.xcassets/Contents.json b/Other Projects/WWDCPlayer/WWDCPlayer/Preview Content/Preview Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/Other Projects/WWDCPlayer/WWDCPlayer/Preview Content/Preview Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/WWDCPlayer/WWDCPlayer/Supporting Files/Assets.xcassets/AppIcon.appiconset/Contents.json b/Other Projects/WWDCPlayer/WWDCPlayer/Supporting Files/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..8d8f4bb --- /dev/null +++ b/Other Projects/WWDCPlayer/WWDCPlayer/Supporting Files/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,122 @@ +{ + "images" : [ + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "Icon-App-20x20@2x.png", + "scale" : "2x" + }, + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "Icon-App-20x20@3x.png", + "scale" : "3x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@1x.png", + "scale" : "1x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@2x.png", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@3x.png", + "scale" : "3x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "Icon-App-40x40@2x.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "Icon-App-40x40@3x.png", + "scale" : "3x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "Icon-App-60x60@2x.png", + "scale" : "2x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "Icon-App-60x60@3x.png", + "scale" : "3x" + }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "Icon-App-20x20@1x.png", + "scale" : "1x" + }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "Icon-App-20x20@2x.png", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "Icon-App-29x29@1x.png", + "scale" : "1x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "Icon-App-29x29@2x.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "Icon-App-40x40@1x.png", + "scale" : "1x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "Icon-App-40x40@2x.png", + "scale" : "2x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "Icon-App-76x76@1x.png", + "scale" : "1x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "Icon-App-76x76@2x.png", + "scale" : "2x" + }, + { + "size" : "83.5x83.5", + "idiom" : "ipad", + "filename" : "Icon-App-83.5x83.5@2x.png", + "scale" : "2x" + }, + { + "size" : "1024x1024", + "idiom" : "ios-marketing", + "filename" : "ItunesArtwork@2x.png", + "scale" : "1x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/WWDCPlayer/WWDCPlayer/Supporting Files/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/Other Projects/WWDCPlayer/WWDCPlayer/Supporting Files/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png new file mode 100644 index 0000000..063da6c Binary files /dev/null and b/Other Projects/WWDCPlayer/WWDCPlayer/Supporting Files/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png differ diff --git a/Other Projects/WWDCPlayer/WWDCPlayer/Supporting Files/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/Other Projects/WWDCPlayer/WWDCPlayer/Supporting Files/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png new file mode 100644 index 0000000..80cacb2 Binary files /dev/null and b/Other Projects/WWDCPlayer/WWDCPlayer/Supporting Files/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png differ diff --git a/Other Projects/WWDCPlayer/WWDCPlayer/Supporting Files/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/Other Projects/WWDCPlayer/WWDCPlayer/Supporting Files/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png new file mode 100644 index 0000000..78d299f Binary files /dev/null and b/Other Projects/WWDCPlayer/WWDCPlayer/Supporting Files/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png differ diff --git a/Other Projects/WWDCPlayer/WWDCPlayer/Supporting Files/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/Other Projects/WWDCPlayer/WWDCPlayer/Supporting Files/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png new file mode 100644 index 0000000..4c14f3f Binary files /dev/null and b/Other Projects/WWDCPlayer/WWDCPlayer/Supporting Files/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png differ diff --git a/Other Projects/WWDCPlayer/WWDCPlayer/Supporting Files/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/Other Projects/WWDCPlayer/WWDCPlayer/Supporting Files/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png new file mode 100644 index 0000000..1d99bd9 Binary files /dev/null and b/Other Projects/WWDCPlayer/WWDCPlayer/Supporting Files/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png differ diff --git a/Other Projects/WWDCPlayer/WWDCPlayer/Supporting Files/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png b/Other Projects/WWDCPlayer/WWDCPlayer/Supporting Files/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png new file mode 100644 index 0000000..52a1a82 Binary files /dev/null and b/Other Projects/WWDCPlayer/WWDCPlayer/Supporting Files/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png differ diff --git a/Other Projects/WWDCPlayer/WWDCPlayer/Supporting Files/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png b/Other Projects/WWDCPlayer/WWDCPlayer/Supporting Files/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png new file mode 100644 index 0000000..80cacb2 Binary files /dev/null and b/Other Projects/WWDCPlayer/WWDCPlayer/Supporting Files/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png differ diff --git a/Other Projects/WWDCPlayer/WWDCPlayer/Supporting Files/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/Other Projects/WWDCPlayer/WWDCPlayer/Supporting Files/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png new file mode 100644 index 0000000..e2184d0 Binary files /dev/null and b/Other Projects/WWDCPlayer/WWDCPlayer/Supporting Files/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png differ diff --git a/Other Projects/WWDCPlayer/WWDCPlayer/Supporting Files/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/Other Projects/WWDCPlayer/WWDCPlayer/Supporting Files/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png new file mode 100644 index 0000000..ad469dc Binary files /dev/null and b/Other Projects/WWDCPlayer/WWDCPlayer/Supporting Files/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png differ diff --git a/Other Projects/WWDCPlayer/WWDCPlayer/Supporting Files/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/Other Projects/WWDCPlayer/WWDCPlayer/Supporting Files/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png new file mode 100644 index 0000000..ad469dc Binary files /dev/null and b/Other Projects/WWDCPlayer/WWDCPlayer/Supporting Files/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png differ diff --git a/Other Projects/WWDCPlayer/WWDCPlayer/Supporting Files/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/Other Projects/WWDCPlayer/WWDCPlayer/Supporting Files/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png new file mode 100644 index 0000000..2b04608 Binary files /dev/null and b/Other Projects/WWDCPlayer/WWDCPlayer/Supporting Files/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png differ diff --git a/Other Projects/WWDCPlayer/WWDCPlayer/Supporting Files/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/Other Projects/WWDCPlayer/WWDCPlayer/Supporting Files/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png new file mode 100644 index 0000000..7c1d903 Binary files /dev/null and b/Other Projects/WWDCPlayer/WWDCPlayer/Supporting Files/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png differ diff --git a/Other Projects/WWDCPlayer/WWDCPlayer/Supporting Files/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png b/Other Projects/WWDCPlayer/WWDCPlayer/Supporting Files/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png new file mode 100644 index 0000000..a0f7bfb Binary files /dev/null and b/Other Projects/WWDCPlayer/WWDCPlayer/Supporting Files/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png differ diff --git a/Other Projects/WWDCPlayer/WWDCPlayer/Supporting Files/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/Other Projects/WWDCPlayer/WWDCPlayer/Supporting Files/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png new file mode 100644 index 0000000..06c3635 Binary files /dev/null and b/Other Projects/WWDCPlayer/WWDCPlayer/Supporting Files/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png differ diff --git a/Other Projects/WWDCPlayer/WWDCPlayer/Supporting Files/Assets.xcassets/AppIcon.appiconset/ItunesArtwork@2x.png b/Other Projects/WWDCPlayer/WWDCPlayer/Supporting Files/Assets.xcassets/AppIcon.appiconset/ItunesArtwork@2x.png new file mode 100644 index 0000000..c893d33 Binary files /dev/null and b/Other Projects/WWDCPlayer/WWDCPlayer/Supporting Files/Assets.xcassets/AppIcon.appiconset/ItunesArtwork@2x.png differ diff --git a/Other Projects/WWDCPlayer/WWDCPlayer/Supporting Files/Assets.xcassets/Contents.json b/Other Projects/WWDCPlayer/WWDCPlayer/Supporting Files/Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/Other Projects/WWDCPlayer/WWDCPlayer/Supporting Files/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/WWDCPlayer/WWDCPlayer/Supporting Files/Info.plist b/Other Projects/WWDCPlayer/WWDCPlayer/Supporting Files/Info.plist new file mode 100644 index 0000000..e8bb4c6 --- /dev/null +++ b/Other Projects/WWDCPlayer/WWDCPlayer/Supporting Files/Info.plist @@ -0,0 +1,62 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + $(PRODUCT_BUNDLE_PACKAGE_TYPE) + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UIApplicationSceneManifest + + UIApplicationSupportsMultipleScenes + + UISceneConfigurations + + UIWindowSceneSessionRoleApplication + + + UILaunchStoryboardName + LaunchScreen + UISceneConfigurationName + Default Configuration + UISceneDelegateClassName + $(PRODUCT_MODULE_NAME).SceneDelegate + + + + + UILaunchStoryboardName + LaunchScreen + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/Other Projects/WWDCPlayer/WWDCPlayer/UserData.swift b/Other Projects/WWDCPlayer/WWDCPlayer/UserData.swift new file mode 100644 index 0000000..0332c9c --- /dev/null +++ b/Other Projects/WWDCPlayer/WWDCPlayer/UserData.swift @@ -0,0 +1,9 @@ +// +// UserData.swift +// SwiftUISample +// +// Created by sohee on 2019/06/06. +// Copyright © 2019 daybreak. All rights reserved. +// + +import Foundation diff --git a/Other Projects/WWDCPlayer/WWDCPlayer/VideoRow.swift b/Other Projects/WWDCPlayer/WWDCPlayer/VideoRow.swift new file mode 100644 index 0000000..bd8f9aa --- /dev/null +++ b/Other Projects/WWDCPlayer/WWDCPlayer/VideoRow.swift @@ -0,0 +1,87 @@ +// +// VideoRow.swift +// WWDCPlayer +// +// Created by sohee on 2019/06/06. +// Copyright © 2019 daybreak. All rights reserved. +// + +import SwiftUI + +struct VideoRow : View { + + @EnvironmentObject var userData: UserData + + var video: Video + var isFavorite = false + + var body: some View { + HStack { + VStack(alignment: .leading) { + TitleText(text: video.title) + HStack { + DescriptionText(text: "Session \(video.id)") + DescriptionText(text: "·") + DescriptionText(text: video.platformString) + } + } + Spacer() + HStack(spacing: 15) { + if userData.currentVideo == video { + Image(systemName: "music.mic") + } + + Image(systemName: video.isFavorite ? "star.fill" : "star") + .foregroundColor(video.isFavorite ? Color.yellow : Color.gray) + .onTapGesture { + self.setFavorite(video: self.video) + } + } + } + .padding([.top, .bottom], 10) + .onTapGesture { + self.setCurrentVideo(video: self.video) + } + } + + func setCurrentVideo(video: Video) { + guard self.userData.currentVideo != self.video else { + return + } + self.userData.currentVideo = self.video + } + + func setFavorite(video: Video) { + guard let index = userData.videos.firstIndex (where: { $0 == video }) else { + return + } + self.userData.videos[index].isFavorite.toggle() + } +} + +#if DEBUG +struct VideoRow_Previews : PreviewProvider { + static var previews: some View { + VideoRow(video: videoList[0]) + .environmentObject(UserData()) + } +} +#endif + +struct TitleText: View { + let text: String + var body: some View { + return Text(text) + .foregroundColor(.primary) + .bold() + } +} + +struct DescriptionText : View { + let text: String + var body: some View { + return Text(text) + .font(.footnote).fontWeight(.semibold) + .foregroundColor(.secondary) + } +} diff --git a/Other Projects/WWDCPlayer/WWDCPlayerTests/Info.plist b/Other Projects/WWDCPlayer/WWDCPlayerTests/Info.plist new file mode 100644 index 0000000..64d65ca --- /dev/null +++ b/Other Projects/WWDCPlayer/WWDCPlayerTests/Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + $(PRODUCT_BUNDLE_PACKAGE_TYPE) + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + + diff --git a/Other Projects/WWDCPlayer/WWDCPlayerTests/WWDCPlayerTests.swift b/Other Projects/WWDCPlayer/WWDCPlayerTests/WWDCPlayerTests.swift new file mode 100644 index 0000000..8244056 --- /dev/null +++ b/Other Projects/WWDCPlayer/WWDCPlayerTests/WWDCPlayerTests.swift @@ -0,0 +1,34 @@ +// +// WWDCPlayerTests.swift +// WWDCPlayerTests +// +// Created by ms on 2019/06/05. +// Copyright © 2019 daybreak. All rights reserved. +// + +import XCTest +@testable import WWDCPlayer + +class WWDCPlayerTests: XCTestCase { + + override func setUp() { + // Put setup code here. This method is called before the invocation of each test method in the class. + } + + override func tearDown() { + // Put teardown code here. This method is called after the invocation of each test method in the class. + } + + func testExample() { + // This is an example of a functional test case. + // Use XCTAssert and related functions to verify your tests produce the correct results. + } + + func testPerformanceExample() { + // This is an example of a performance test case. + self.measure { + // Put the code you want to measure the time of here. + } + } + +} diff --git a/Other Projects/Webview/.gitignore b/Other Projects/Webview/.gitignore new file mode 100644 index 0000000..d522f94 --- /dev/null +++ b/Other Projects/Webview/.gitignore @@ -0,0 +1,8 @@ +# CocoaPods +# +# We recommend against adding the Pods directory to your .gitignore. However +# you should judge for yourself, the pros and cons are mentioned at: +# http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control? +# +# Pods/ + diff --git a/Other Projects/Webview/LICENSE b/Other Projects/Webview/LICENSE new file mode 100644 index 0000000..d066666 --- /dev/null +++ b/Other Projects/Webview/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2014 Jholman8 + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/Other Projects/Webview/README.md b/Other Projects/Webview/README.md new file mode 100644 index 0000000..d73cbc6 --- /dev/null +++ b/Other Projects/Webview/README.md @@ -0,0 +1,4 @@ +SwiftUIWebview +============== + +Simple UIWebview Example Written in Swift diff --git a/Other Projects/Webview/SwiftTest1/AppDelegate.swift b/Other Projects/Webview/SwiftTest1/AppDelegate.swift new file mode 100644 index 0000000..f104df4 --- /dev/null +++ b/Other Projects/Webview/SwiftTest1/AppDelegate.swift @@ -0,0 +1,135 @@ +// +// AppDelegate.swift +// SwiftTest1 +// +// Created by Jacob Holman on 6/3/14. +// Copyright (c) 2014 Jacob Holman. All rights reserved. +// + +import UIKit +import CoreData + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + + var window: UIWindow? + + + func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: NSDictionary?) -> Bool { + // Override point for customization after application launch. + return true + } + + func applicationWillResignActive(application: UIApplication) { + // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. + // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. + } + + func applicationDidEnterBackground(application: UIApplication) { + // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. + // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. + } + + func applicationWillEnterForeground(application: UIApplication) { + // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. + } + + func applicationDidBecomeActive(application: UIApplication) { + // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. + } + + func applicationWillTerminate(application: UIApplication) { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. + // Saves changes in the application's managed object context before the application terminates. + self.saveContext() + } + + func saveContext () { + var error: NSError? = nil + let managedObjectContext = self.managedObjectContext + if managedObjectContext != nil { + if managedObjectContext.hasChanges && !managedObjectContext.save(&error) { + // Replace this implementation with code to handle the error appropriately. + // abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. + //println("Unresolved error \(error), \(error.userInfo)") + abort() + } + } + } + + // #pragma mark - Core Data stack + + // Returns the managed object context for the application. + // If the context doesn't already exist, it is created and bound to the persistent store coordinator for the application. + var managedObjectContext: NSManagedObjectContext { + if !_managedObjectContext { + let coordinator = self.persistentStoreCoordinator + if coordinator != nil { + _managedObjectContext = NSManagedObjectContext() + _managedObjectContext!.persistentStoreCoordinator = coordinator + } + } + return _managedObjectContext! + } + var _managedObjectContext: NSManagedObjectContext? = nil + + // Returns the managed object model for the application. + // If the model doesn't already exist, it is created from the application's model. + var managedObjectModel: NSManagedObjectModel { + if !_managedObjectModel { + let modelURL = NSBundle.mainBundle().URLForResource("SwiftTest1", withExtension: "momd") + _managedObjectModel = NSManagedObjectModel(contentsOfURL: modelURL) + } + return _managedObjectModel! + } + var _managedObjectModel: NSManagedObjectModel? = nil + + // Returns the persistent store coordinator for the application. + // If the coordinator doesn't already exist, it is created and the application's store added to it. + var persistentStoreCoordinator: NSPersistentStoreCoordinator { + if !_persistentStoreCoordinator { + let storeURL = self.applicationDocumentsDirectory.URLByAppendingPathComponent("SwiftTest1.sqlite") + var error: NSError? = nil + _persistentStoreCoordinator = NSPersistentStoreCoordinator(managedObjectModel: self.managedObjectModel) + if _persistentStoreCoordinator!.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: storeURL, options: nil, error: &error) == nil { + /* + Replace this implementation with code to handle the error appropriately. + + abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. + + Typical reasons for an error here include: + * The persistent store is not accessible; + * The schema for the persistent store is incompatible with current managed object model. + Check the error message to determine what the actual problem was. + + + If the persistent store is not accessible, there is typically something wrong with the file path. Often, a file URL is pointing into the application's resources directory instead of a writeable directory. + + If you encounter schema incompatibility errors during development, you can reduce their frequency by: + * Simply deleting the existing store: + NSFileManager.defaultManager().removeItemAtURL(storeURL, error: nil) + + * Performing automatic lightweight migration by passing the following dictionary as the options parameter: + [NSMigratePersistentStoresAutomaticallyOption: true, NSInferMappingModelAutomaticallyOption: true} + + Lightweight migration will only work for a limited set of schema changes; consult "Core Data Model Versioning and Data Migration Programming Guide" for details. + + */ + //println("Unresolved error \(error), \(error.userInfo)") + abort() + } + } + return _persistentStoreCoordinator! + } + var _persistentStoreCoordinator: NSPersistentStoreCoordinator? = nil + + // #pragma mark - Application's Documents directory + + // Returns the URL to the application's Documents directory. + var applicationDocumentsDirectory: NSURL { + let urls = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask) + return urls[urls.endIndex-1] as NSURL + } + +} + diff --git a/Other Projects/Webview/SwiftTest1/Base.lproj/Main.storyboard b/Other Projects/Webview/SwiftTest1/Base.lproj/Main.storyboard new file mode 100644 index 0000000..81e7cb1 --- /dev/null +++ b/Other Projects/Webview/SwiftTest1/Base.lproj/Main.storyboard @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Other Projects/Webview/SwiftTest1/Images.xcassets/AppIcon.appiconset/Contents.json b/Other Projects/Webview/SwiftTest1/Images.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..a396706 --- /dev/null +++ b/Other Projects/Webview/SwiftTest1/Images.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/Webview/SwiftTest1/Images.xcassets/LaunchImage.launchimage/Contents.json b/Other Projects/Webview/SwiftTest1/Images.xcassets/LaunchImage.launchimage/Contents.json new file mode 100644 index 0000000..c79ebd3 --- /dev/null +++ b/Other Projects/Webview/SwiftTest1/Images.xcassets/LaunchImage.launchimage/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "orientation" : "portrait", + "idiom" : "iphone", + "extent" : "full-screen", + "minimum-system-version" : "7.0", + "scale" : "2x" + }, + { + "orientation" : "portrait", + "idiom" : "iphone", + "subtype" : "retina4", + "extent" : "full-screen", + "minimum-system-version" : "7.0", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/Webview/SwiftTest1/Info.plist b/Other Projects/Webview/SwiftTest1/Info.plist new file mode 100644 index 0000000..47599d0 --- /dev/null +++ b/Other Projects/Webview/SwiftTest1/Info.plist @@ -0,0 +1,32 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + byui.${PRODUCT_NAME:rfc1034identifier} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + + diff --git a/Other Projects/Webview/SwiftTest1/SwiftTest1.xcdatamodeld/.xccurrentversion b/Other Projects/Webview/SwiftTest1/SwiftTest1.xcdatamodeld/.xccurrentversion new file mode 100644 index 0000000..573ca47 --- /dev/null +++ b/Other Projects/Webview/SwiftTest1/SwiftTest1.xcdatamodeld/.xccurrentversion @@ -0,0 +1,8 @@ + + + + + _XCCurrentVersionName + SwiftTest1.xcdatamodel + + diff --git a/Other Projects/Webview/SwiftTest1/SwiftTest1.xcdatamodeld/SwiftTest1.xcdatamodel/contents b/Other Projects/Webview/SwiftTest1/SwiftTest1.xcdatamodeld/SwiftTest1.xcdatamodel/contents new file mode 100644 index 0000000..193f33c --- /dev/null +++ b/Other Projects/Webview/SwiftTest1/SwiftTest1.xcdatamodeld/SwiftTest1.xcdatamodel/contents @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/Other Projects/Webview/SwiftTest1/ViewController.swift b/Other Projects/Webview/SwiftTest1/ViewController.swift new file mode 100644 index 0000000..344b5cc --- /dev/null +++ b/Other Projects/Webview/SwiftTest1/ViewController.swift @@ -0,0 +1,32 @@ +// +// ViewController.swift +// SwiftTest1 +// +// Created by Jacob Holman on 6/3/14. +// Copyright (c) 2014 Jacob Holman. All rights reserved. +// + +import UIKit + +class ViewController: UIViewController { + @IBOutlet var helloWeb : UIWebView + + override func viewDidLoad() { + super.viewDidLoad() + + } + + @IBAction func buttonTapped(AnyObject) { + + helloWeb.loadRequest(NSURLRequest(URL:NSURL(string:"https://www.google.com"))) + + } + + override func didReceiveMemoryWarning() { + super.didReceiveMemoryWarning() + // Dispose of any resources that can be recreated. + } + + +} + diff --git a/Other Projects/Webview/SwiftTest1Tests/Info.plist b/Other Projects/Webview/SwiftTest1Tests/Info.plist new file mode 100644 index 0000000..444dfab --- /dev/null +++ b/Other Projects/Webview/SwiftTest1Tests/Info.plist @@ -0,0 +1,24 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + byui.${PRODUCT_NAME:rfc1034identifier} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + + diff --git a/Other Projects/Webview/SwiftTest1Tests/SwiftTest1Tests.swift b/Other Projects/Webview/SwiftTest1Tests/SwiftTest1Tests.swift new file mode 100644 index 0000000..1b0b118 --- /dev/null +++ b/Other Projects/Webview/SwiftTest1Tests/SwiftTest1Tests.swift @@ -0,0 +1,35 @@ +// +// SwiftTest1Tests.swift +// SwiftTest1Tests +// +// Created by Jacob Holman on 6/3/14. +// Copyright (c) 2014 Jacob Holman. All rights reserved. +// + +import XCTest + +class SwiftTest1Tests: XCTestCase { + + override func setUp() { + super.setUp() + // Put setup code here. This method is called before the invocation of each test method in the class. + } + + override func tearDown() { + // Put teardown code here. This method is called after the invocation of each test method in the class. + super.tearDown() + } + + func testExample() { + // This is an example of a functional test case. + XCTAssert(true, "Pass") + } + + func testPerformanceExample() { + // This is an example of a performance test case. + self.measureBlock() { + // Put the code you want to measure the time of here. + } + } + +} diff --git a/Other Projects/Working With UIControls/Complete/.gitignore b/Other Projects/Working With UIControls/Complete/.gitignore new file mode 100644 index 0000000..9e50718 --- /dev/null +++ b/Other Projects/Working With UIControls/Complete/.gitignore @@ -0,0 +1,21 @@ +# See LICENSE folder for this sample’s licensing information. +# +# Apple sample code gitignore configuration. + +# Finder +.DS_Store + +# Xcode - User files +xcuserdata/ + +**/*.xcodeproj/project.xcworkspace/* +!**/*.xcodeproj/project.xcworkspace/xcshareddata + +**/*.xcodeproj/project.xcworkspace/xcshareddata/* +!**/*.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings + +**/*.playground/playground.xcworkspace/* +!**/*.playground/playground.xcworkspace/xcshareddata + +**/*.playground/playground.xcworkspace/xcshareddata/* +!**/*.playground/playground.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings diff --git a/Other Projects/Working With UIControls/Complete/Configuration/SampleCode.xcconfig b/Other Projects/Working With UIControls/Complete/Configuration/SampleCode.xcconfig new file mode 100644 index 0000000..db86c06 --- /dev/null +++ b/Other Projects/Working With UIControls/Complete/Configuration/SampleCode.xcconfig @@ -0,0 +1,13 @@ +// +// See LICENSE folder for this sample’s licensing information. +// +// SampleCode.xcconfig +// + +// The `SAMPLE_CODE_DISAMBIGUATOR` configuration is to make it easier to build +// and run a sample code project. Once you set your project's development team, +// you'll have a unique bundle identifier. This is because the bundle identifier +// is derived based on the 'SAMPLE_CODE_DISAMBIGUATOR' value. Do not use this +// approach in your own projects—it's only useful for sample code projects because +// they are frequently downloaded and don't have a development team set. +SAMPLE_CODE_DISAMBIGUATOR=${DEVELOPMENT_TEAM} diff --git a/Other Projects/Working With UIControls/Complete/LICENSE/LICENSE.txt b/Other Projects/Working With UIControls/Complete/LICENSE/LICENSE.txt new file mode 100644 index 0000000..94e3d54 --- /dev/null +++ b/Other Projects/Working With UIControls/Complete/LICENSE/LICENSE.txt @@ -0,0 +1,8 @@ +Copyright © 2019 Apple Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + diff --git a/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/AppDelegate.swift b/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/AppDelegate.swift new file mode 100644 index 0000000..e22943b --- /dev/null +++ b/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/AppDelegate.swift @@ -0,0 +1,36 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +The application delegate. +*/ + +import UIKit + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { + // Override point for customization after application launch. + return true + } + + func applicationWillTerminate(_ application: UIApplication) { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. + } + + // MARK: UISceneSession Lifecycle + func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration { + // Called when a new scene session is being created. + // Use this method to select a configuration to create the new scene with. + return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role) + } + + func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) { + // Called when the user discards a scene session. + // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions. + // Use this method to release any resources that were specific to the discarded scenes, as they will not return. + } + +} + diff --git a/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/Contents.json b/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..8eb9b4e --- /dev/null +++ b/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,113 @@ +{ + "images" : [ + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "landmark_app_icon_40x40.png", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "3x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "landmark_app_icon_58x58.png", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "landmark_app_icon_87x87.png", + "scale" : "3x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "landmark_app_icon_80x80.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "landmark_app_icon_120x120.png", + "scale" : "3x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "landmark_app_icon_120x120-1.png", + "scale" : "2x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "landmark_app_icon_180x180.png", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "1x" + }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "landmark_app_icon_40x40-2.png", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "landmark_app_icon_58x58-1.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "landmark_app_icon_40x40-1.png", + "scale" : "1x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "landmark_app_icon_80x80-1.png", + "scale" : "2x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "landmark_app_icon_76x76.png", + "scale" : "1x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "landmark_app_icon_152x152.png", + "scale" : "2x" + }, + { + "size" : "83.5x83.5", + "idiom" : "ipad", + "filename" : "landmark_app_icon_167x167.png", + "scale" : "2x" + }, + { + "size" : "1024x1024", + "idiom" : "ios-marketing", + "filename" : "landmark_app_icon_1024x1024.png", + "scale" : "1x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_1024x1024.png b/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_1024x1024.png new file mode 100644 index 0000000..00d81c1 Binary files /dev/null and b/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_1024x1024.png differ diff --git a/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_120x120-1.png b/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_120x120-1.png new file mode 100644 index 0000000..d382b8b Binary files /dev/null and b/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_120x120-1.png differ diff --git a/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_120x120.png b/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_120x120.png new file mode 100644 index 0000000..d382b8b Binary files /dev/null and b/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_120x120.png differ diff --git a/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_152x152.png b/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_152x152.png new file mode 100644 index 0000000..11057f8 Binary files /dev/null and b/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_152x152.png differ diff --git a/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_167x167.png b/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_167x167.png new file mode 100644 index 0000000..f73bc26 Binary files /dev/null and b/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_167x167.png differ diff --git a/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_180x180.png b/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_180x180.png new file mode 100644 index 0000000..b02738c Binary files /dev/null and b/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_180x180.png differ diff --git a/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40-1.png b/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40-1.png new file mode 100644 index 0000000..abaff0e Binary files /dev/null and b/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40-1.png differ diff --git a/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40-2.png b/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40-2.png new file mode 100644 index 0000000..abaff0e Binary files /dev/null and b/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40-2.png differ diff --git a/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40.png b/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40.png new file mode 100644 index 0000000..abaff0e Binary files /dev/null and b/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40.png differ diff --git a/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_58x58-1.png b/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_58x58-1.png new file mode 100644 index 0000000..cf7c73d Binary files /dev/null and b/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_58x58-1.png differ diff --git a/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_58x58.png b/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_58x58.png new file mode 100644 index 0000000..cf7c73d Binary files /dev/null and b/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_58x58.png differ diff --git a/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_76x76.png b/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_76x76.png new file mode 100644 index 0000000..3eff85b Binary files /dev/null and b/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_76x76.png differ diff --git a/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_80x80-1.png b/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_80x80-1.png new file mode 100644 index 0000000..6f33f66 Binary files /dev/null and b/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_80x80-1.png differ diff --git a/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_80x80.png b/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_80x80.png new file mode 100644 index 0000000..6f33f66 Binary files /dev/null and b/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_80x80.png differ diff --git a/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_87x87.png b/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_87x87.png new file mode 100644 index 0000000..9e1616c Binary files /dev/null and b/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_87x87.png differ diff --git a/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Assets.xcassets/Contents.json b/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Assets.xcassets/turtlerock.imageset/Contents.json b/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Assets.xcassets/turtlerock.imageset/Contents.json new file mode 100644 index 0000000..5bfd7bf --- /dev/null +++ b/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Assets.xcassets/turtlerock.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "turtlerock.jpg", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Assets.xcassets/turtlerock.imageset/turtlerock.jpg b/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Assets.xcassets/turtlerock.imageset/turtlerock.jpg new file mode 100644 index 0000000..68bcd3e Binary files /dev/null and b/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Assets.xcassets/turtlerock.imageset/turtlerock.jpg differ diff --git a/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Base.lproj/LaunchScreen.storyboard b/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000..865e932 --- /dev/null +++ b/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/CategoryRow.swift b/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/CategoryRow.swift new file mode 100644 index 0000000..e3d5760 --- /dev/null +++ b/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/CategoryRow.swift @@ -0,0 +1,64 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A view showing a scrollable list of landmarks. +*/ + +import SwiftUI + +struct CategoryRow: View { + var categoryName: String + var items: [Landmark] + + var body: some View { + VStack(alignment: .leading) { + Text(self.categoryName) + .font(.headline) + .padding(.leading, 15) + .padding(.top, 5) + + ScrollView(.horizontal) { + HStack(alignment: .top, spacing: 0) { + ForEach(self.items, id: \.name) { landmark in + NavigationLink( + destination: LandmarkDetail( + landmark: landmark + ) + ) { + CategoryItem(landmark: landmark) + } + } + } + } + .frame(height: 185) + } + } +} + +struct CategoryItem: View { + var landmark: Landmark + var body: some View { + VStack(alignment: .leading) { + landmark + .image(forSize: 155) + .renderingMode(.original) + .cornerRadius(5) + Text(landmark.name) + .foregroundColor(.primary) + .font(.caption) + } + .padding(.leading, 15) + } +} + +#if DEBUG +struct CategoryRow_Previews: PreviewProvider { + static var previews: some View { + CategoryRow( + categoryName: landmarkData[0].category.rawValue, + items: Array(landmarkData.prefix(4)) + ) + } +} +#endif diff --git a/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/HexagonParameters.swift b/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/HexagonParameters.swift new file mode 100644 index 0000000..8decba4 --- /dev/null +++ b/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/HexagonParameters.swift @@ -0,0 +1,57 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +Size, position, and other information used to draw a badge. +*/ + +import SwiftUI + +struct HexagonParameters { + struct Segment { + let useWidth: (CGFloat, CGFloat, CGFloat) + let xFactors: (CGFloat, CGFloat, CGFloat) + let useHeight: (CGFloat, CGFloat, CGFloat) + let yFactors: (CGFloat, CGFloat, CGFloat) + } + + static let adjustment: CGFloat = 0.085 + static let points = [ + Segment( + useWidth: (1.00, 1.00, 1.00), + xFactors: (0.60, 0.40, 0.50), + useHeight: (1.00, 1.00, 0.00), + yFactors: (0.05, 0.05, 0.00) + ), + Segment( + useWidth: (1.00, 1.00, 0.00), + xFactors: (0.05, 0.00, 0.00), + useHeight: (1.00, 1.00, 1.00), + yFactors: (0.20 + adjustment, 0.30 + adjustment, 0.25 + adjustment) + ), + Segment( + useWidth: (1.00, 1.00, 0.00), + xFactors: (0.00, 0.05, 0.00), + useHeight: (1.00, 1.00, 1.00), + yFactors: (0.70 - adjustment, 0.80 - adjustment, 0.75 - adjustment) + ), + Segment( + useWidth: (1.00, 1.00, 1.00), + xFactors: (0.40, 0.60, 0.50), + useHeight: (1.00, 1.00, 1.00), + yFactors: (0.95, 0.95, 1.00) + ), + Segment( + useWidth: (1.00, 1.00, 1.00), + xFactors: (0.95, 1.00, 1.00), + useHeight: (1.00, 1.00, 1.00), + yFactors: (0.80 - adjustment, 0.70 - adjustment, 0.75 - adjustment) + ), + Segment( + useWidth: (1.00, 1.00, 1.00), + xFactors: (1.00, 0.95, 1.00), + useHeight: (1.00, 1.00, 1.00), + yFactors: (0.30 + adjustment, 0.20 + adjustment, 0.25 + adjustment) + ) + ] +} diff --git a/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/HikeBadge.swift b/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/HikeBadge.swift new file mode 100644 index 0000000..52716cf --- /dev/null +++ b/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/HikeBadge.swift @@ -0,0 +1,31 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A view that shows a badge for hiking. +*/ + +import SwiftUI + +struct HikeBadge: View { + var name: String + var body: some View { + VStack(alignment: .center) { + Badge() + .frame(width: 300, height: 300) + .scaleEffect(1.0 / 3.0) + .frame(width: 100, height: 100) + Text(name) + .font(.caption) + .accessibility(label: Text("Badge for \(name).")) + } + } +} + +#if DEBUG +struct HikeBadge_Previews: PreviewProvider { + static var previews: some View { + HikeBadge(name: "Preview Testing") + } +} +#endif diff --git a/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/HikeDetail.swift b/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/HikeDetail.swift new file mode 100644 index 0000000..1d63904 --- /dev/null +++ b/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/HikeDetail.swift @@ -0,0 +1,49 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A view showing the details for a hike. +*/ + +import SwiftUI + +struct HikeDetail: View { + let hike: Hike + @State var dataToShow = \Hike.Observation.elevation + + var buttons = [ + ("Elevation", \Hike.Observation.elevation), + ("Heart Rate", \Hike.Observation.heartRate), + ("Pace", \Hike.Observation.pace), + ] + + var body: some View { + return VStack { + HikeGraph(hike: hike, path: dataToShow) + .frame(height: 200, alignment: .center) + + HStack(spacing: 25) { + ForEach(buttons, id: \.0) { value in + Button(action: { + self.dataToShow = value.1 + }) { + Text(verbatim: value.0) + .font(.system(size: 15)) + .foregroundColor(value.1 == self.dataToShow + ? Color.gray + : Color.accentColor) + .animation(nil) + } + } + } + } + } +} + +#if DEBUG +struct HikeDetail_Previews: PreviewProvider { + static var previews: some View { + HikeDetail(hike: hikeData[0]) + } +} +#endif diff --git a/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/HikeView.swift b/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/HikeView.swift new file mode 100644 index 0000000..b9964c7 --- /dev/null +++ b/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/HikeView.swift @@ -0,0 +1,68 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A view displaying inforamtion about a hike, including an elevation graph. +*/ + +import SwiftUI + +struct HikeView: View { + var hike: Hike + @State private var showDetail = false + + var transition: AnyTransition { + let insertion = AnyTransition.move(edge: .trailing) + .combined(with: .opacity) + let removal = AnyTransition.scale(scale: 0.0) + .combined(with: .opacity) + return .asymmetric(insertion: insertion, removal: removal) + } + + var body: some View { + VStack { + HStack { + HikeGraph(hike: hike, path: \.elevation) + .frame(width: 50, height: 30) + .animation(nil) + + VStack(alignment: .leading) { + Text(verbatim: hike.name) + .font(.headline) + Text(verbatim: hike.distanceText) + } + + Spacer() + + Button(action: { + withAnimation { + self.showDetail.toggle() + } + }) { + Image(systemName: "chevron.right.circle") + .imageScale(.large) + .rotationEffect(.degrees(showDetail ? 90 : 0)) + .scaleEffect(showDetail ? 1.5 : 1) + .padding() + } + } + + if showDetail { + HikeDetail(hike: hike) + .transition(transition) + } + } + } +} + +#if DEBUG +struct HikeView_Previews: PreviewProvider { + static var previews: some View { + VStack { + HikeView(hike: hikeData[0]) + .padding() + Spacer() + } + } +} +#endif diff --git a/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Home.swift b/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Home.swift new file mode 100644 index 0000000..9614cf6 --- /dev/null +++ b/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Home.swift @@ -0,0 +1,71 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A view showing featured landmarks above a list of all of the landmarks. +*/ + +import SwiftUI + +struct CategoryHome: View { + @State private var isProfilePresented = false + + var categories: [String: [Landmark]] { + .init( + grouping: landmarkData, + by: { $0.category.rawValue } + ) + } + + var featured: [Landmark] { + landmarkData.filter { $0.isFeatured } + } + + var body: some View { + NavigationView { + List { + FeaturedLandmarks(landmarks: featured) + .scaledToFill() + .frame(height: 200) + .clipped() + .listRowInsets(EdgeInsets()) + + ForEach(categories.keys.sorted(), id: \.self) { key in + CategoryRow(categoryName: key, items: self.categories[key]!) + } + .listRowInsets(EdgeInsets()) + + NavigationLink(destination: LandmarkList()) { + Text("See All") + } + } + .navigationBarTitle(Text("Featured")) + .navigationBarItems(trailing: + Button(action: { + self.isProfilePresented = true + }) { + Image(systemName: "person.crop.circle") + .imageScale(.large) + .accessibility(label: Text("User Profile")) + .padding() + } + ).sheet(isPresented: $isProfilePresented, + content: { ProfileHost().environmentObject(UserData()) }) + } + } +} + +struct FeaturedLandmarks: View { + var landmarks: [Landmark] + var body: some View { + landmarks[0].image(forSize: 250).resizable() + } +} + +#if DEBUG +struct CategoryHome_Previews: PreviewProvider { + static var previews: some View { + CategoryHome() + } +} +#endif diff --git a/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Info.plist b/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Info.plist new file mode 100644 index 0000000..e8bb4c6 --- /dev/null +++ b/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Info.plist @@ -0,0 +1,62 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + $(PRODUCT_BUNDLE_PACKAGE_TYPE) + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UIApplicationSceneManifest + + UIApplicationSupportsMultipleScenes + + UISceneConfigurations + + UIWindowSceneSessionRoleApplication + + + UILaunchStoryboardName + LaunchScreen + UISceneConfigurationName + Default Configuration + UISceneDelegateClassName + $(PRODUCT_MODULE_NAME).SceneDelegate + + + + + UILaunchStoryboardName + LaunchScreen + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/LandmarkDetail.swift b/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/LandmarkDetail.swift new file mode 100644 index 0000000..6c290a3 --- /dev/null +++ b/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/LandmarkDetail.swift @@ -0,0 +1,71 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A view showing the details for a landmark. +*/ + +import SwiftUI + +struct LandmarkDetail: View { + @EnvironmentObject var userData: UserData + var landmark: Landmark + + var landmarkIndex: Int { + userData.landmarks.firstIndex(where: { $0.id == landmark.id })! + } + + var body: some View { + VStack { + MapView(coordinate: landmark.locationCoordinate) + .edgesIgnoringSafeArea(.top) + .frame(height: 300) + + CircleImage(image: landmark.image(forSize: 250)) + .offset(x: 0, y: -130) + .padding(.bottom, -130) + + VStack(alignment: .leading) { + HStack { + Text(verbatim: landmark.name) + .font(.title) + + Button(action: { + self.userData.landmarks[self.landmarkIndex] + .isFavorite.toggle() + }) { + if self.userData.landmarks[self.landmarkIndex] + .isFavorite { + Image(systemName: "star.fill") + .foregroundColor(Color.yellow) + } else { + Image(systemName: "star") + .foregroundColor(Color.gray) + } + } + } + + HStack(alignment: .top) { + Text(verbatim: landmark.park) + .font(.subheadline) + Spacer() + Text(verbatim: landmark.state) + .font(.subheadline) + } + } + .padding() + + Spacer() + } + } +} + +#if DEBUG +struct LandmarkDetail_Preview: PreviewProvider { + static var previews: some View { + let userData = UserData() + return LandmarkDetail(landmark: userData.landmarks[0]) + .environmentObject(userData) + } +} +#endif diff --git a/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/LandmarkList.swift b/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/LandmarkList.swift new file mode 100644 index 0000000..665a08e --- /dev/null +++ b/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/LandmarkList.swift @@ -0,0 +1,46 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A view showing a list of landmarks. +*/ + +import SwiftUI + +struct LandmarkList: View { + @EnvironmentObject private var userData: UserData + + var body: some View { + NavigationView { + List { + Toggle(isOn: $userData.showFavoritesOnly) { + Text("Show Favorites Only") + } + + ForEach(userData.landmarks) { landmark in + if !self.userData.showFavoritesOnly || landmark.isFavorite { + NavigationLink( + destination: LandmarkDetail(landmark: landmark) + .environmentObject(self.userData)) { + LandmarkRow(landmark: landmark) + } + } + } + } + .navigationBarTitle(Text("Landmarks"), displayMode: .large) + } + } +} + +#if DEBUG +struct LandmarksList_Previews: PreviewProvider { + static var previews: some View { + ForEach(["iPhone SE", "iPhone XS Max"], id: \.self) { deviceName in + LandmarkList() + .previewDevice(PreviewDevice(rawValue: deviceName)) + .previewDisplayName(deviceName) + } + .environmentObject(UserData()) + } +} +#endif diff --git a/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Models/Data.swift b/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Models/Data.swift new file mode 100644 index 0000000..cfe5a4a --- /dev/null +++ b/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Models/Data.swift @@ -0,0 +1,95 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +Helpers for loading images and data. +*/ + +import Foundation +import CoreLocation +import UIKit +import SwiftUI + +let landmarkData: [Landmark] = load("landmarkData.json") +let hikeData: [Hike] = load("hikeData.json") + +func load(_ filename: String, as type: T.Type = T.self) -> T { + let data: Data + + guard let file = Bundle.main.url(forResource: filename, withExtension: nil) + else { + fatalError("Couldn't find \(filename) in main bundle.") + } + + do { + data = try Data(contentsOf: file) + } catch { + fatalError("Couldn't load \(filename) from main bundle:\n\(error)") + } + + do { + let decoder = JSONDecoder() + return try decoder.decode(T.self, from: data) + } catch { + fatalError("Couldn't parse \(filename) as \(T.self):\n\(error)") + } +} + +final class ImageStore { + fileprivate typealias _ImageDictionary = [String: [Int: CGImage]] + fileprivate var images: _ImageDictionary = [:] + + fileprivate static var originalSize = 250 + fileprivate static var scale = 2 + + static var shared = ImageStore() + + func image(name: String, size: Int) -> Image { + let index = _guaranteeInitialImage(name: name) + + let sizedImage = images.values[index][size] + ?? _sizeImage(images.values[index][ImageStore.originalSize]!, to: size * ImageStore.scale) + images.values[index][size] = sizedImage + + return Image(sizedImage, scale: CGFloat(ImageStore.scale), label: Text(verbatim: name)) + } + + fileprivate func _guaranteeInitialImage(name: String) -> _ImageDictionary.Index { + if let index = images.index(forKey: name) { return index } + + guard + let url = Bundle.main.url(forResource: name, withExtension: "jpg"), + let imageSource = CGImageSourceCreateWithURL(url as NSURL, nil), + let image = CGImageSourceCreateImageAtIndex(imageSource, 0, nil) + else { + fatalError("Couldn't load image \(name).jpg from main bundle.") + } + + images[name] = [ImageStore.originalSize: image] + return images.index(forKey: name)! + } + + fileprivate func _sizeImage(_ image: CGImage, to size: Int) -> CGImage { + guard + let colorSpace = image.colorSpace, + let context = CGContext( + data: nil, + width: size, height: size, + bitsPerComponent: image.bitsPerComponent, + bytesPerRow: image.bytesPerRow, + space: colorSpace, + bitmapInfo: image.bitmapInfo.rawValue) + else { + fatalError("Couldn't create graphics context.") + } + context.interpolationQuality = .high + context.draw(image, in: CGRect(x: 0, y: 0, width: size, height: size)) + + if let sizedImage = context.makeImage() { + return sizedImage + } else { + fatalError("Couldn't resize image.") + } + } +} + diff --git a/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Models/Hike.swift b/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Models/Hike.swift new file mode 100644 index 0000000..dfd2bb8 --- /dev/null +++ b/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Models/Hike.swift @@ -0,0 +1,31 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +The model for a hike. +*/ + +import SwiftUI + +struct Hike: Codable, Hashable, Identifiable { + var name: String + var id: Int + var distance: Double + var difficulty: Int + var observations: [Observation] + + static var formatter = LengthFormatter() + + var distanceText: String { + return Hike.formatter + .string(fromValue: distance, unit: .kilometer) + } + + struct Observation: Codable, Hashable { + var distanceFromStart: Double + + var elevation: Range + var pace: Range + var heartRate: Range + } +} diff --git a/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Models/Landmark.swift b/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Models/Landmark.swift new file mode 100644 index 0000000..4a7586d --- /dev/null +++ b/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Models/Landmark.swift @@ -0,0 +1,43 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +The model for an individual landmark. +*/ + +import SwiftUI +import CoreLocation + +struct Landmark: Hashable, Codable, Identifiable { + var id: Int + var name: String + fileprivate var imageName: String + fileprivate var coordinates: Coordinates + var state: String + var park: String + var category: Category + var isFavorite: Bool + var isFeatured: Bool + + var locationCoordinate: CLLocationCoordinate2D { + CLLocationCoordinate2D( + latitude: coordinates.latitude, + longitude: coordinates.longitude) + } + + func image(forSize size: Int) -> Image { + ImageStore.shared.image(name: imageName, size: size) + } + + enum Category: String, CaseIterable, Codable, Hashable { + case featured = "Featured" + case lakes = "Lakes" + case rivers = "Rivers" + case mountains = "Mountains" + } +} + +struct Coordinates: Hashable, Codable { + var latitude: Double + var longitude: Double +} diff --git a/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Models/Profile.swift b/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Models/Profile.swift new file mode 100644 index 0000000..7c30519 --- /dev/null +++ b/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Models/Profile.swift @@ -0,0 +1,30 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +An object that models a user profile. +*/ +import Foundation + +struct Profile { + var username: String + var prefersNotifications: Bool + var seasonalPhoto: Season + var goalDate: Date + + static let `default` = Self(username: "g_kumar", prefersNotifications: true, seasonalPhoto: .winter) + + init(username: String, prefersNotifications: Bool = true, seasonalPhoto: Season = .winter) { + self.username = username + self.prefersNotifications = prefersNotifications + self.seasonalPhoto = seasonalPhoto + self.goalDate = Date() + } + + enum Season: String, CaseIterable { + case spring = "🌷" + case summer = "🌞" + case autumn = "🍂" + case winter = "☃️" + } +} diff --git a/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Models/UserData.swift b/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Models/UserData.swift new file mode 100644 index 0000000..afc2cca --- /dev/null +++ b/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Models/UserData.swift @@ -0,0 +1,15 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A model object that stores app data. +*/ + +import Combine +import SwiftUI + +final class UserData: ObservableObject { + @Published var showFavoritesOnly = false + + @Published var landmarks = landmarkData +} diff --git a/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Preview Content/Preview Assets.xcassets/Contents.json b/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Preview Content/Preview Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Preview Content/Preview Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Profiles/ProfileEditor.swift b/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Profiles/ProfileEditor.swift new file mode 100644 index 0000000..57c933b --- /dev/null +++ b/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Profiles/ProfileEditor.swift @@ -0,0 +1,55 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +An editable profile view. +*/ + +import SwiftUI + +struct ProfileEditor: View { + @Binding var profile: Profile + + var body: some View { + List { + HStack { + Text("Username").bold() + Divider() + TextField("", text: $profile.username) + } + + Toggle(isOn: $profile.prefersNotifications) { + Text("Enable Notifications") + } + + VStack(alignment: .leading, spacing: 20) { + Text("Seasonal Photo").bold() + + Picker("", selection: $profile.seasonalPhoto) { + ForEach(Profile.Season.allCases, id: \.self) { season in + Text(season.rawValue).tag(season) + } + }.pickerStyle(SegmentedPickerStyle()) + } + .padding(.top) + + VStack(alignment: .leading, spacing: 20) { + Text("Goal Date").bold() + DatePicker( + "", selection: $profile.goalDate, + in: Calendar.current.date(byAdding: .year, value: -1, to: profile.goalDate)! ... Calendar.current.date(byAdding: .year, value: 1, to: profile.goalDate)!, + displayedComponents: .date + ) + } + .padding(.top) + } + } +} + +#if DEBUG +struct ProfileEditor_Previews: PreviewProvider { + static var previews: some View { + ProfileEditor(profile: .constant(.default)) + } +} +#endif diff --git a/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Profiles/ProfileHost.swift b/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Profiles/ProfileHost.swift new file mode 100644 index 0000000..8fb3e81 --- /dev/null +++ b/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Profiles/ProfileHost.swift @@ -0,0 +1,50 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A view that hosts the profile viewer and editor. +*/ + +import SwiftUI + +struct ProfileHost: View { + @Environment(\.editMode) var mode + @State var profile = Profile.default + @State var draftProfile = Profile.default + + var body: some View { + VStack(alignment: .leading, spacing: 20) { + HStack { + if self.mode?.wrappedValue == .active { + Button(action: { + self.draftProfile = self.profile + self.mode?.animation().wrappedValue = .inactive + }) { + Text("Done") + } + } + + Spacer() + + EditButton() + } + if self.mode?.wrappedValue == .inactive { + ProfileSummary(profile: profile) + } else { + ProfileEditor(profile: $draftProfile) + .onDisappear { + self.profile = self.draftProfile + } + } + } + .padding() + } +} + +#if DEBUG +struct ProfileHost_Previews: PreviewProvider { + static var previews: some View { + ProfileHost() + } +} +#endif diff --git a/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Profiles/ProfileSummary.swift b/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Profiles/ProfileSummary.swift new file mode 100644 index 0000000..c6eca8f --- /dev/null +++ b/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Profiles/ProfileSummary.swift @@ -0,0 +1,65 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A view that summarizes a profile. +*/ + +import SwiftUI + +struct ProfileSummary: View { + var profile: Profile + + static var goalFormat: DateFormatter { + let formatter = DateFormatter() + formatter.dateFormat = "MMMM d, yyyy" + return formatter + } + + var body: some View { + List { + Text(profile.username) + .bold() + .font(.title) + + Text("Notifications: \(self.profile.prefersNotifications ? "On": "Off" )") + + Text("Seasonal Photos: \(self.profile.seasonalPhoto.rawValue)") + + Text("Goal Date: \(self.profile.goalDate, formatter: Self.goalFormat)") + + VStack(alignment: .leading) { + Text("Completed Badges") + .font(.headline) + ScrollView(.horizontal) { + HStack { + HikeBadge(name: "First Hike") + + HikeBadge(name: "Earth Day") + .hueRotation(Angle(degrees: 90)) + + HikeBadge(name: "Tenth Hike") + .grayscale(0.5) + .hueRotation(Angle(degrees: 45)) + } + } + .frame(height: 140) + } + + VStack(alignment: .leading) { + Text("Recent Hikes") + .font(.headline) + + HikeView(hike: hikeData[0]) + } + } + } +} + +#if DEBUG +struct ProfileSummary_Previews: PreviewProvider { + static var previews: some View { + ProfileSummary(profile: Profile.default) + } +} +#endif diff --git a/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Resources/charleyrivers.jpg b/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Resources/charleyrivers.jpg new file mode 100644 index 0000000..17ff44b Binary files /dev/null and b/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Resources/charleyrivers.jpg differ diff --git a/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Resources/chilkoottrail.jpg b/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Resources/chilkoottrail.jpg new file mode 100644 index 0000000..e7f805e Binary files /dev/null and b/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Resources/chilkoottrail.jpg differ diff --git a/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Resources/chincoteague.jpg b/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Resources/chincoteague.jpg new file mode 100644 index 0000000..5f47986 Binary files /dev/null and b/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Resources/chincoteague.jpg differ diff --git a/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Resources/hiddenlake.jpg b/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Resources/hiddenlake.jpg new file mode 100644 index 0000000..d8e804c Binary files /dev/null and b/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Resources/hiddenlake.jpg differ diff --git a/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Resources/hikeData.json b/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Resources/hikeData.json new file mode 100644 index 0000000..3fb1e96 --- /dev/null +++ b/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Resources/hikeData.json @@ -0,0 +1,1882 @@ +[ + { + "name":"Lonesome Ridge Trail", + "id":1001, + "distance":4.5, + "difficulty":3, + "observations":[ + { + "elevation":[ + 291.65263635636268, + 309.26016677925196 + ], + "pace":[ + 396.08716481908732, + 403.68937873525232 + ], + "heartRate":[ + 117.16351898665887, + 121.95815455919609 + ], + "distanceFromStart":0 + }, + { + "elevation":[ + 299.24001936628116, + 317.44584350790012 + ], + "pace":[ + 380.19020240756623, + 395.3978319010256 + ], + "heartRate":[ + 117.6410892152911, + 124.82185220506081 + ], + "distanceFromStart":0.375 + }, + { + "elevation":[ + 303.62145464574394, + 336.05569457646544 + ], + "pace":[ + 380.55927782266116, + 397.60789726832775 + ], + "heartRate":[ + 121.52696452049059, + 127.31525441110122 + ], + "distanceFromStart":0.75 + }, + { + "elevation":[ + 319.90393365162629, + 346.26966025518789 + ], + "pace":[ + 357.94116421258531, + 398.0750288648062 + ], + "heartRate":[ + 123.75908585923588, + 132.77069404486801 + ], + "distanceFromStart":1.125 + }, + { + "elevation":[ + 354.17104439267905, + 403.57031216972939 + ], + "pace":[ + 335.07385149392701, + 397.82674381875808 + ], + "heartRate":[ + 130.8235194572915, + 140.55700591418218 + ], + "distanceFromStart":1.5 + }, + { + "elevation":[ + 357.42992871175124, + 385.92155620623635 + ], + "pace":[ + 395.16168913839374, + 404.60294066527558 + ], + "heartRate":[ + 131.5456052446734, + 134.65984504627627 + ], + "distanceFromStart":1.875 + }, + { + "elevation":[ + 345.47736721935661, + 363.18776661379422 + ], + "pace":[ + 340.82303041339082, + 404.71689228682374 + ], + "heartRate":[ + 125.1949698433959, + 131.31354363122026 + ], + "distanceFromStart":2.25 + }, + { + "elevation":[ + 346.23343025200535, + 497.23376445462401 + ], + "pace":[ + 261.27629148816021, + 331.68516208719467 + ], + "heartRate":[ + 131.67810544238606, + 154.26779645311458 + ], + "distanceFromStart":2.625 + }, + { + "elevation":[ + 491.57378483134391, + 547.49535224251053 + ], + "pace":[ + 296.05298644112088, + 401.14092967732398 + ], + "heartRate":[ + 151.36398089694217, + 166.20454793289232 + ], + "distanceFromStart":3 + }, + { + "elevation":[ + 472.06803233416338, + 531.92570520228401 + ], + "pace":[ + 395.50830663514012, + 401.67837917543591 + ], + "heartRate":[ + 134.41798110234078, + 151.90886697564241 + ], + "distanceFromStart":3.375 + }, + { + "elevation":[ + 339.81419476005283, + 461.03832527824829 + ], + "pace":[ + 395.31160487975183, + 404.49550455974907 + ], + "heartRate":[ + 129.97753472415462, + 138.13531094848992 + ], + "distanceFromStart":3.75 + }, + { + "elevation":[ + 303.1495508565697, + 342.3532820173541 + ], + "pace":[ + 395.02844559698116, + 402.65878340653796 + ], + "heartRate":[ + 127.72304232462609, + 133.26322270764186 + ], + "distanceFromStart":4.125 + } + ] + }, + { + "name":"Lonesome Ridge Trail", + "id":1002, + "distance":4.5, + "difficulty":3, + "observations":[ + { + "elevation":[ + 291.65263635636268, + 309.26016677925196 + ], + "pace":[ + 396.08716481908732, + 403.68937873525232 + ], + "heartRate":[ + 117.16351898665887, + 121.95815455919609 + ], + "distanceFromStart":0 + }, + { + "elevation":[ + 299.24001936628116, + 317.44584350790012 + ], + "pace":[ + 380.19020240756623, + 395.3978319010256 + ], + "heartRate":[ + 117.6410892152911, + 124.82185220506081 + ], + "distanceFromStart":0.375 + }, + { + "elevation":[ + 303.62145464574394, + 336.05569457646544 + ], + "pace":[ + 380.55927782266116, + 397.60789726832775 + ], + "heartRate":[ + 121.52696452049059, + 127.31525441110122 + ], + "distanceFromStart":0.75 + }, + { + "elevation":[ + 319.90393365162629, + 346.26966025518789 + ], + "pace":[ + 357.94116421258531, + 398.0750288648062 + ], + "heartRate":[ + 123.75908585923588, + 132.77069404486801 + ], + "distanceFromStart":1.125 + }, + { + "elevation":[ + 354.17104439267905, + 403.57031216972939 + ], + "pace":[ + 335.07385149392701, + 397.82674381875808 + ], + "heartRate":[ + 130.8235194572915, + 140.55700591418218 + ], + "distanceFromStart":1.5 + }, + { + "elevation":[ + 357.42992871175124, + 385.92155620623635 + ], + "pace":[ + 395.16168913839374, + 404.60294066527558 + ], + "heartRate":[ + 131.5456052446734, + 134.65984504627627 + ], + "distanceFromStart":1.875 + }, + { + "elevation":[ + 345.47736721935661, + 363.18776661379422 + ], + "pace":[ + 340.82303041339082, + 404.71689228682374 + ], + "heartRate":[ + 125.1949698433959, + 131.31354363122026 + ], + "distanceFromStart":2.25 + }, + { + "elevation":[ + 346.23343025200535, + 497.23376445462401 + ], + "pace":[ + 261.27629148816021, + 331.68516208719467 + ], + "heartRate":[ + 131.67810544238606, + 154.26779645311458 + ], + "distanceFromStart":2.625 + }, + { + "elevation":[ + 491.57378483134391, + 547.49535224251053 + ], + "pace":[ + 296.05298644112088, + 401.14092967732398 + ], + "heartRate":[ + 151.36398089694217, + 166.20454793289232 + ], + "distanceFromStart":3 + }, + { + "elevation":[ + 472.06803233416338, + 531.92570520228401 + ], + "pace":[ + 395.50830663514012, + 401.67837917543591 + ], + "heartRate":[ + 134.41798110234078, + 151.90886697564241 + ], + "distanceFromStart":3.375 + }, + { + "elevation":[ + 339.81419476005283, + 461.03832527824829 + ], + "pace":[ + 395.31160487975183, + 404.49550455974907 + ], + "heartRate":[ + 129.97753472415462, + 138.13531094848992 + ], + "distanceFromStart":3.75 + }, + { + "elevation":[ + 303.1495508565697, + 342.3532820173541 + ], + "pace":[ + 395.02844559698116, + 402.65878340653796 + ], + "heartRate":[ + 127.72304232462609, + 133.26322270764186 + ], + "distanceFromStart":4.125 + } + ] + }, + { + "name":"Lonesome Ridge Trail", + "id":1003, + "distance":4.5, + "difficulty":3, + "observations":[ + { + "elevation":[ + 291.65263635636268, + 309.26016677925196 + ], + "pace":[ + 396.08716481908732, + 403.68937873525232 + ], + "heartRate":[ + 117.16351898665887, + 121.95815455919609 + ], + "distanceFromStart":0 + }, + { + "elevation":[ + 299.24001936628116, + 317.44584350790012 + ], + "pace":[ + 380.19020240756623, + 395.3978319010256 + ], + "heartRate":[ + 117.6410892152911, + 124.82185220506081 + ], + "distanceFromStart":0.375 + }, + { + "elevation":[ + 303.62145464574394, + 336.05569457646544 + ], + "pace":[ + 380.55927782266116, + 397.60789726832775 + ], + "heartRate":[ + 121.52696452049059, + 127.31525441110122 + ], + "distanceFromStart":0.75 + }, + { + "elevation":[ + 319.90393365162629, + 346.26966025518789 + ], + "pace":[ + 357.94116421258531, + 398.0750288648062 + ], + "heartRate":[ + 123.75908585923588, + 132.77069404486801 + ], + "distanceFromStart":1.125 + }, + { + "elevation":[ + 354.17104439267905, + 403.57031216972939 + ], + "pace":[ + 335.07385149392701, + 397.82674381875808 + ], + "heartRate":[ + 130.8235194572915, + 140.55700591418218 + ], + "distanceFromStart":1.5 + }, + { + "elevation":[ + 357.42992871175124, + 385.92155620623635 + ], + "pace":[ + 395.16168913839374, + 404.60294066527558 + ], + "heartRate":[ + 131.5456052446734, + 134.65984504627627 + ], + "distanceFromStart":1.875 + }, + { + "elevation":[ + 345.47736721935661, + 363.18776661379422 + ], + "pace":[ + 340.82303041339082, + 404.71689228682374 + ], + "heartRate":[ + 125.1949698433959, + 131.31354363122026 + ], + "distanceFromStart":2.25 + }, + { + "elevation":[ + 346.23343025200535, + 497.23376445462401 + ], + "pace":[ + 261.27629148816021, + 331.68516208719467 + ], + "heartRate":[ + 131.67810544238606, + 154.26779645311458 + ], + "distanceFromStart":2.625 + }, + { + "elevation":[ + 491.57378483134391, + 547.49535224251053 + ], + "pace":[ + 296.05298644112088, + 401.14092967732398 + ], + "heartRate":[ + 151.36398089694217, + 166.20454793289232 + ], + "distanceFromStart":3 + }, + { + "elevation":[ + 472.06803233416338, + 531.92570520228401 + ], + "pace":[ + 395.50830663514012, + 401.67837917543591 + ], + "heartRate":[ + 134.41798110234078, + 151.90886697564241 + ], + "distanceFromStart":3.375 + }, + { + "elevation":[ + 339.81419476005283, + 461.03832527824829 + ], + "pace":[ + 395.31160487975183, + 404.49550455974907 + ], + "heartRate":[ + 129.97753472415462, + 138.13531094848992 + ], + "distanceFromStart":3.75 + }, + { + "elevation":[ + 303.1495508565697, + 342.3532820173541 + ], + "pace":[ + 395.02844559698116, + 402.65878340653796 + ], + "heartRate":[ + 127.72304232462609, + 133.26322270764186 + ], + "distanceFromStart":4.125 + } + ] + }, + { + "name":"Lonesome Ridge Trail", + "id":1004, + "distance":4.5, + "difficulty":3, + "observations":[ + { + "elevation":[ + 291.65263635636268, + 309.26016677925196 + ], + "pace":[ + 396.08716481908732, + 403.68937873525232 + ], + "heartRate":[ + 117.16351898665887, + 121.95815455919609 + ], + "distanceFromStart":0 + }, + { + "elevation":[ + 299.24001936628116, + 317.44584350790012 + ], + "pace":[ + 380.19020240756623, + 395.3978319010256 + ], + "heartRate":[ + 117.6410892152911, + 124.82185220506081 + ], + "distanceFromStart":0.375 + }, + { + "elevation":[ + 303.62145464574394, + 336.05569457646544 + ], + "pace":[ + 380.55927782266116, + 397.60789726832775 + ], + "heartRate":[ + 121.52696452049059, + 127.31525441110122 + ], + "distanceFromStart":0.75 + }, + { + "elevation":[ + 319.90393365162629, + 346.26966025518789 + ], + "pace":[ + 357.94116421258531, + 398.0750288648062 + ], + "heartRate":[ + 123.75908585923588, + 132.77069404486801 + ], + "distanceFromStart":1.125 + }, + { + "elevation":[ + 354.17104439267905, + 403.57031216972939 + ], + "pace":[ + 335.07385149392701, + 397.82674381875808 + ], + "heartRate":[ + 130.8235194572915, + 140.55700591418218 + ], + "distanceFromStart":1.5 + }, + { + "elevation":[ + 357.42992871175124, + 385.92155620623635 + ], + "pace":[ + 395.16168913839374, + 404.60294066527558 + ], + "heartRate":[ + 131.5456052446734, + 134.65984504627627 + ], + "distanceFromStart":1.875 + }, + { + "elevation":[ + 345.47736721935661, + 363.18776661379422 + ], + "pace":[ + 340.82303041339082, + 404.71689228682374 + ], + "heartRate":[ + 125.1949698433959, + 131.31354363122026 + ], + "distanceFromStart":2.25 + }, + { + "elevation":[ + 346.23343025200535, + 497.23376445462401 + ], + "pace":[ + 261.27629148816021, + 331.68516208719467 + ], + "heartRate":[ + 131.67810544238606, + 154.26779645311458 + ], + "distanceFromStart":2.625 + }, + { + "elevation":[ + 491.57378483134391, + 547.49535224251053 + ], + "pace":[ + 296.05298644112088, + 401.14092967732398 + ], + "heartRate":[ + 151.36398089694217, + 166.20454793289232 + ], + "distanceFromStart":3 + }, + { + "elevation":[ + 472.06803233416338, + 531.92570520228401 + ], + "pace":[ + 395.50830663514012, + 401.67837917543591 + ], + "heartRate":[ + 134.41798110234078, + 151.90886697564241 + ], + "distanceFromStart":3.375 + }, + { + "elevation":[ + 339.81419476005283, + 461.03832527824829 + ], + "pace":[ + 395.31160487975183, + 404.49550455974907 + ], + "heartRate":[ + 129.97753472415462, + 138.13531094848992 + ], + "distanceFromStart":3.75 + }, + { + "elevation":[ + 303.1495508565697, + 342.3532820173541 + ], + "pace":[ + 395.02844559698116, + 402.65878340653796 + ], + "heartRate":[ + 127.72304232462609, + 133.26322270764186 + ], + "distanceFromStart":4.125 + } + ] + }, + { + "name":"Lonesome Ridge Trail", + "id":1005, + "distance":4.5, + "difficulty":3, + "observations":[ + { + "elevation":[ + 291.65263635636268, + 309.26016677925196 + ], + "pace":[ + 396.08716481908732, + 403.68937873525232 + ], + "heartRate":[ + 117.16351898665887, + 121.95815455919609 + ], + "distanceFromStart":0 + }, + { + "elevation":[ + 299.24001936628116, + 317.44584350790012 + ], + "pace":[ + 380.19020240756623, + 395.3978319010256 + ], + "heartRate":[ + 117.6410892152911, + 124.82185220506081 + ], + "distanceFromStart":0.375 + }, + { + "elevation":[ + 303.62145464574394, + 336.05569457646544 + ], + "pace":[ + 380.55927782266116, + 397.60789726832775 + ], + "heartRate":[ + 121.52696452049059, + 127.31525441110122 + ], + "distanceFromStart":0.75 + }, + { + "elevation":[ + 319.90393365162629, + 346.26966025518789 + ], + "pace":[ + 357.94116421258531, + 398.0750288648062 + ], + "heartRate":[ + 123.75908585923588, + 132.77069404486801 + ], + "distanceFromStart":1.125 + }, + { + "elevation":[ + 354.17104439267905, + 403.57031216972939 + ], + "pace":[ + 335.07385149392701, + 397.82674381875808 + ], + "heartRate":[ + 130.8235194572915, + 140.55700591418218 + ], + "distanceFromStart":1.5 + }, + { + "elevation":[ + 357.42992871175124, + 385.92155620623635 + ], + "pace":[ + 395.16168913839374, + 404.60294066527558 + ], + "heartRate":[ + 131.5456052446734, + 134.65984504627627 + ], + "distanceFromStart":1.875 + }, + { + "elevation":[ + 345.47736721935661, + 363.18776661379422 + ], + "pace":[ + 340.82303041339082, + 404.71689228682374 + ], + "heartRate":[ + 125.1949698433959, + 131.31354363122026 + ], + "distanceFromStart":2.25 + }, + { + "elevation":[ + 346.23343025200535, + 497.23376445462401 + ], + "pace":[ + 261.27629148816021, + 331.68516208719467 + ], + "heartRate":[ + 131.67810544238606, + 154.26779645311458 + ], + "distanceFromStart":2.625 + }, + { + "elevation":[ + 491.57378483134391, + 547.49535224251053 + ], + "pace":[ + 296.05298644112088, + 401.14092967732398 + ], + "heartRate":[ + 151.36398089694217, + 166.20454793289232 + ], + "distanceFromStart":3 + }, + { + "elevation":[ + 472.06803233416338, + 531.92570520228401 + ], + "pace":[ + 395.50830663514012, + 401.67837917543591 + ], + "heartRate":[ + 134.41798110234078, + 151.90886697564241 + ], + "distanceFromStart":3.375 + }, + { + "elevation":[ + 339.81419476005283, + 461.03832527824829 + ], + "pace":[ + 395.31160487975183, + 404.49550455974907 + ], + "heartRate":[ + 129.97753472415462, + 138.13531094848992 + ], + "distanceFromStart":3.75 + }, + { + "elevation":[ + 303.1495508565697, + 342.3532820173541 + ], + "pace":[ + 395.02844559698116, + 402.65878340653796 + ], + "heartRate":[ + 127.72304232462609, + 133.26322270764186 + ], + "distanceFromStart":4.125 + } + ] + }, + { + "name":"Lonesome Ridge Trail", + "id":1006, + "distance":4.5, + "difficulty":3, + "observations":[ + { + "elevation":[ + 291.65263635636268, + 309.26016677925196 + ], + "pace":[ + 396.08716481908732, + 403.68937873525232 + ], + "heartRate":[ + 117.16351898665887, + 121.95815455919609 + ], + "distanceFromStart":0 + }, + { + "elevation":[ + 299.24001936628116, + 317.44584350790012 + ], + "pace":[ + 380.19020240756623, + 395.3978319010256 + ], + "heartRate":[ + 117.6410892152911, + 124.82185220506081 + ], + "distanceFromStart":0.375 + }, + { + "elevation":[ + 303.62145464574394, + 336.05569457646544 + ], + "pace":[ + 380.55927782266116, + 397.60789726832775 + ], + "heartRate":[ + 121.52696452049059, + 127.31525441110122 + ], + "distanceFromStart":0.75 + }, + { + "elevation":[ + 319.90393365162629, + 346.26966025518789 + ], + "pace":[ + 357.94116421258531, + 398.0750288648062 + ], + "heartRate":[ + 123.75908585923588, + 132.77069404486801 + ], + "distanceFromStart":1.125 + }, + { + "elevation":[ + 354.17104439267905, + 403.57031216972939 + ], + "pace":[ + 335.07385149392701, + 397.82674381875808 + ], + "heartRate":[ + 130.8235194572915, + 140.55700591418218 + ], + "distanceFromStart":1.5 + }, + { + "elevation":[ + 357.42992871175124, + 385.92155620623635 + ], + "pace":[ + 395.16168913839374, + 404.60294066527558 + ], + "heartRate":[ + 131.5456052446734, + 134.65984504627627 + ], + "distanceFromStart":1.875 + }, + { + "elevation":[ + 345.47736721935661, + 363.18776661379422 + ], + "pace":[ + 340.82303041339082, + 404.71689228682374 + ], + "heartRate":[ + 125.1949698433959, + 131.31354363122026 + ], + "distanceFromStart":2.25 + }, + { + "elevation":[ + 346.23343025200535, + 497.23376445462401 + ], + "pace":[ + 261.27629148816021, + 331.68516208719467 + ], + "heartRate":[ + 131.67810544238606, + 154.26779645311458 + ], + "distanceFromStart":2.625 + }, + { + "elevation":[ + 491.57378483134391, + 547.49535224251053 + ], + "pace":[ + 296.05298644112088, + 401.14092967732398 + ], + "heartRate":[ + 151.36398089694217, + 166.20454793289232 + ], + "distanceFromStart":3 + }, + { + "elevation":[ + 472.06803233416338, + 531.92570520228401 + ], + "pace":[ + 395.50830663514012, + 401.67837917543591 + ], + "heartRate":[ + 134.41798110234078, + 151.90886697564241 + ], + "distanceFromStart":3.375 + }, + { + "elevation":[ + 339.81419476005283, + 461.03832527824829 + ], + "pace":[ + 395.31160487975183, + 404.49550455974907 + ], + "heartRate":[ + 129.97753472415462, + 138.13531094848992 + ], + "distanceFromStart":3.75 + }, + { + "elevation":[ + 303.1495508565697, + 342.3532820173541 + ], + "pace":[ + 395.02844559698116, + 402.65878340653796 + ], + "heartRate":[ + 127.72304232462609, + 133.26322270764186 + ], + "distanceFromStart":4.125 + } + ] + }, + { + "name":"Lonesome Ridge Trail", + "id":1007, + "distance":4.5, + "difficulty":3, + "observations":[ + { + "elevation":[ + 291.65263635636268, + 309.26016677925196 + ], + "pace":[ + 396.08716481908732, + 403.68937873525232 + ], + "heartRate":[ + 117.16351898665887, + 121.95815455919609 + ], + "distanceFromStart":0 + }, + { + "elevation":[ + 299.24001936628116, + 317.44584350790012 + ], + "pace":[ + 380.19020240756623, + 395.3978319010256 + ], + "heartRate":[ + 117.6410892152911, + 124.82185220506081 + ], + "distanceFromStart":0.375 + }, + { + "elevation":[ + 303.62145464574394, + 336.05569457646544 + ], + "pace":[ + 380.55927782266116, + 397.60789726832775 + ], + "heartRate":[ + 121.52696452049059, + 127.31525441110122 + ], + "distanceFromStart":0.75 + }, + { + "elevation":[ + 319.90393365162629, + 346.26966025518789 + ], + "pace":[ + 357.94116421258531, + 398.0750288648062 + ], + "heartRate":[ + 123.75908585923588, + 132.77069404486801 + ], + "distanceFromStart":1.125 + }, + { + "elevation":[ + 354.17104439267905, + 403.57031216972939 + ], + "pace":[ + 335.07385149392701, + 397.82674381875808 + ], + "heartRate":[ + 130.8235194572915, + 140.55700591418218 + ], + "distanceFromStart":1.5 + }, + { + "elevation":[ + 357.42992871175124, + 385.92155620623635 + ], + "pace":[ + 395.16168913839374, + 404.60294066527558 + ], + "heartRate":[ + 131.5456052446734, + 134.65984504627627 + ], + "distanceFromStart":1.875 + }, + { + "elevation":[ + 345.47736721935661, + 363.18776661379422 + ], + "pace":[ + 340.82303041339082, + 404.71689228682374 + ], + "heartRate":[ + 125.1949698433959, + 131.31354363122026 + ], + "distanceFromStart":2.25 + }, + { + "elevation":[ + 346.23343025200535, + 497.23376445462401 + ], + "pace":[ + 261.27629148816021, + 331.68516208719467 + ], + "heartRate":[ + 131.67810544238606, + 154.26779645311458 + ], + "distanceFromStart":2.625 + }, + { + "elevation":[ + 491.57378483134391, + 547.49535224251053 + ], + "pace":[ + 296.05298644112088, + 401.14092967732398 + ], + "heartRate":[ + 151.36398089694217, + 166.20454793289232 + ], + "distanceFromStart":3 + }, + { + "elevation":[ + 472.06803233416338, + 531.92570520228401 + ], + "pace":[ + 395.50830663514012, + 401.67837917543591 + ], + "heartRate":[ + 134.41798110234078, + 151.90886697564241 + ], + "distanceFromStart":3.375 + }, + { + "elevation":[ + 339.81419476005283, + 461.03832527824829 + ], + "pace":[ + 395.31160487975183, + 404.49550455974907 + ], + "heartRate":[ + 129.97753472415462, + 138.13531094848992 + ], + "distanceFromStart":3.75 + }, + { + "elevation":[ + 303.1495508565697, + 342.3532820173541 + ], + "pace":[ + 395.02844559698116, + 402.65878340653796 + ], + "heartRate":[ + 127.72304232462609, + 133.26322270764186 + ], + "distanceFromStart":4.125 + } + ] + }, + { + "name":"Lonesome Ridge Trail", + "id":1008, + "distance":4.5, + "difficulty":3, + "observations":[ + { + "elevation":[ + 291.65263635636268, + 309.26016677925196 + ], + "pace":[ + 396.08716481908732, + 403.68937873525232 + ], + "heartRate":[ + 117.16351898665887, + 121.95815455919609 + ], + "distanceFromStart":0 + }, + { + "elevation":[ + 299.24001936628116, + 317.44584350790012 + ], + "pace":[ + 380.19020240756623, + 395.3978319010256 + ], + "heartRate":[ + 117.6410892152911, + 124.82185220506081 + ], + "distanceFromStart":0.375 + }, + { + "elevation":[ + 303.62145464574394, + 336.05569457646544 + ], + "pace":[ + 380.55927782266116, + 397.60789726832775 + ], + "heartRate":[ + 121.52696452049059, + 127.31525441110122 + ], + "distanceFromStart":0.75 + }, + { + "elevation":[ + 319.90393365162629, + 346.26966025518789 + ], + "pace":[ + 357.94116421258531, + 398.0750288648062 + ], + "heartRate":[ + 123.75908585923588, + 132.77069404486801 + ], + "distanceFromStart":1.125 + }, + { + "elevation":[ + 354.17104439267905, + 403.57031216972939 + ], + "pace":[ + 335.07385149392701, + 397.82674381875808 + ], + "heartRate":[ + 130.8235194572915, + 140.55700591418218 + ], + "distanceFromStart":1.5 + }, + { + "elevation":[ + 357.42992871175124, + 385.92155620623635 + ], + "pace":[ + 395.16168913839374, + 404.60294066527558 + ], + "heartRate":[ + 131.5456052446734, + 134.65984504627627 + ], + "distanceFromStart":1.875 + }, + { + "elevation":[ + 345.47736721935661, + 363.18776661379422 + ], + "pace":[ + 340.82303041339082, + 404.71689228682374 + ], + "heartRate":[ + 125.1949698433959, + 131.31354363122026 + ], + "distanceFromStart":2.25 + }, + { + "elevation":[ + 346.23343025200535, + 497.23376445462401 + ], + "pace":[ + 261.27629148816021, + 331.68516208719467 + ], + "heartRate":[ + 131.67810544238606, + 154.26779645311458 + ], + "distanceFromStart":2.625 + }, + { + "elevation":[ + 491.57378483134391, + 547.49535224251053 + ], + "pace":[ + 296.05298644112088, + 401.14092967732398 + ], + "heartRate":[ + 151.36398089694217, + 166.20454793289232 + ], + "distanceFromStart":3 + }, + { + "elevation":[ + 472.06803233416338, + 531.92570520228401 + ], + "pace":[ + 395.50830663514012, + 401.67837917543591 + ], + "heartRate":[ + 134.41798110234078, + 151.90886697564241 + ], + "distanceFromStart":3.375 + }, + { + "elevation":[ + 339.81419476005283, + 461.03832527824829 + ], + "pace":[ + 395.31160487975183, + 404.49550455974907 + ], + "heartRate":[ + 129.97753472415462, + 138.13531094848992 + ], + "distanceFromStart":3.75 + }, + { + "elevation":[ + 303.1495508565697, + 342.3532820173541 + ], + "pace":[ + 395.02844559698116, + 402.65878340653796 + ], + "heartRate":[ + 127.72304232462609, + 133.26322270764186 + ], + "distanceFromStart":4.125 + } + ] + }, + { + "name":"Lonesome Ridge Trail", + "id":1009, + "distance":4.5, + "difficulty":3, + "observations":[ + { + "elevation":[ + 291.65263635636268, + 309.26016677925196 + ], + "pace":[ + 396.08716481908732, + 403.68937873525232 + ], + "heartRate":[ + 117.16351898665887, + 121.95815455919609 + ], + "distanceFromStart":0 + }, + { + "elevation":[ + 299.24001936628116, + 317.44584350790012 + ], + "pace":[ + 380.19020240756623, + 395.3978319010256 + ], + "heartRate":[ + 117.6410892152911, + 124.82185220506081 + ], + "distanceFromStart":0.375 + }, + { + "elevation":[ + 303.62145464574394, + 336.05569457646544 + ], + "pace":[ + 380.55927782266116, + 397.60789726832775 + ], + "heartRate":[ + 121.52696452049059, + 127.31525441110122 + ], + "distanceFromStart":0.75 + }, + { + "elevation":[ + 319.90393365162629, + 346.26966025518789 + ], + "pace":[ + 357.94116421258531, + 398.0750288648062 + ], + "heartRate":[ + 123.75908585923588, + 132.77069404486801 + ], + "distanceFromStart":1.125 + }, + { + "elevation":[ + 354.17104439267905, + 403.57031216972939 + ], + "pace":[ + 335.07385149392701, + 397.82674381875808 + ], + "heartRate":[ + 130.8235194572915, + 140.55700591418218 + ], + "distanceFromStart":1.5 + }, + { + "elevation":[ + 357.42992871175124, + 385.92155620623635 + ], + "pace":[ + 395.16168913839374, + 404.60294066527558 + ], + "heartRate":[ + 131.5456052446734, + 134.65984504627627 + ], + "distanceFromStart":1.875 + }, + { + "elevation":[ + 345.47736721935661, + 363.18776661379422 + ], + "pace":[ + 340.82303041339082, + 404.71689228682374 + ], + "heartRate":[ + 125.1949698433959, + 131.31354363122026 + ], + "distanceFromStart":2.25 + }, + { + "elevation":[ + 346.23343025200535, + 497.23376445462401 + ], + "pace":[ + 261.27629148816021, + 331.68516208719467 + ], + "heartRate":[ + 131.67810544238606, + 154.26779645311458 + ], + "distanceFromStart":2.625 + }, + { + "elevation":[ + 491.57378483134391, + 547.49535224251053 + ], + "pace":[ + 296.05298644112088, + 401.14092967732398 + ], + "heartRate":[ + 151.36398089694217, + 166.20454793289232 + ], + "distanceFromStart":3 + }, + { + "elevation":[ + 472.06803233416338, + 531.92570520228401 + ], + "pace":[ + 395.50830663514012, + 401.67837917543591 + ], + "heartRate":[ + 134.41798110234078, + 151.90886697564241 + ], + "distanceFromStart":3.375 + }, + { + "elevation":[ + 339.81419476005283, + 461.03832527824829 + ], + "pace":[ + 395.31160487975183, + 404.49550455974907 + ], + "heartRate":[ + 129.97753472415462, + 138.13531094848992 + ], + "distanceFromStart":3.75 + }, + { + "elevation":[ + 303.1495508565697, + 342.3532820173541 + ], + "pace":[ + 395.02844559698116, + 402.65878340653796 + ], + "heartRate":[ + 127.72304232462609, + 133.26322270764186 + ], + "distanceFromStart":4.125 + } + ] + }, + { + "name":"Lonesome Ridge Trail", + "id":1010, + "distance":4.5, + "difficulty":3, + "observations":[ + { + "elevation":[ + 291.65263635636268, + 309.26016677925196 + ], + "pace":[ + 396.08716481908732, + 403.68937873525232 + ], + "heartRate":[ + 117.16351898665887, + 121.95815455919609 + ], + "distanceFromStart":0 + }, + { + "elevation":[ + 299.24001936628116, + 317.44584350790012 + ], + "pace":[ + 380.19020240756623, + 395.3978319010256 + ], + "heartRate":[ + 117.6410892152911, + 124.82185220506081 + ], + "distanceFromStart":0.375 + }, + { + "elevation":[ + 303.62145464574394, + 336.05569457646544 + ], + "pace":[ + 380.55927782266116, + 397.60789726832775 + ], + "heartRate":[ + 121.52696452049059, + 127.31525441110122 + ], + "distanceFromStart":0.75 + }, + { + "elevation":[ + 319.90393365162629, + 346.26966025518789 + ], + "pace":[ + 357.94116421258531, + 398.0750288648062 + ], + "heartRate":[ + 123.75908585923588, + 132.77069404486801 + ], + "distanceFromStart":1.125 + }, + { + "elevation":[ + 354.17104439267905, + 403.57031216972939 + ], + "pace":[ + 335.07385149392701, + 397.82674381875808 + ], + "heartRate":[ + 130.8235194572915, + 140.55700591418218 + ], + "distanceFromStart":1.5 + }, + { + "elevation":[ + 357.42992871175124, + 385.92155620623635 + ], + "pace":[ + 395.16168913839374, + 404.60294066527558 + ], + "heartRate":[ + 131.5456052446734, + 134.65984504627627 + ], + "distanceFromStart":1.875 + }, + { + "elevation":[ + 345.47736721935661, + 363.18776661379422 + ], + "pace":[ + 340.82303041339082, + 404.71689228682374 + ], + "heartRate":[ + 125.1949698433959, + 131.31354363122026 + ], + "distanceFromStart":2.25 + }, + { + "elevation":[ + 346.23343025200535, + 497.23376445462401 + ], + "pace":[ + 261.27629148816021, + 331.68516208719467 + ], + "heartRate":[ + 131.67810544238606, + 154.26779645311458 + ], + "distanceFromStart":2.625 + }, + { + "elevation":[ + 491.57378483134391, + 547.49535224251053 + ], + "pace":[ + 296.05298644112088, + 401.14092967732398 + ], + "heartRate":[ + 151.36398089694217, + 166.20454793289232 + ], + "distanceFromStart":3 + }, + { + "elevation":[ + 472.06803233416338, + 531.92570520228401 + ], + "pace":[ + 395.50830663514012, + 401.67837917543591 + ], + "heartRate":[ + 134.41798110234078, + 151.90886697564241 + ], + "distanceFromStart":3.375 + }, + { + "elevation":[ + 339.81419476005283, + 461.03832527824829 + ], + "pace":[ + 395.31160487975183, + 404.49550455974907 + ], + "heartRate":[ + 129.97753472415462, + 138.13531094848992 + ], + "distanceFromStart":3.75 + }, + { + "elevation":[ + 303.1495508565697, + 342.3532820173541 + ], + "pace":[ + 395.02844559698116, + 402.65878340653796 + ], + "heartRate":[ + 127.72304232462609, + 133.26322270764186 + ], + "distanceFromStart":4.125 + } + ] + } +] diff --git a/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Resources/icybay.jpg b/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Resources/icybay.jpg new file mode 100644 index 0000000..feb1764 Binary files /dev/null and b/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Resources/icybay.jpg differ diff --git a/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Resources/lakemcdonald.jpg b/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Resources/lakemcdonald.jpg new file mode 100644 index 0000000..bd9d6b9 Binary files /dev/null and b/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Resources/lakemcdonald.jpg differ diff --git a/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Resources/landmarkData.json b/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Resources/landmarkData.json new file mode 100644 index 0000000..e5b14fc --- /dev/null +++ b/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Resources/landmarkData.json @@ -0,0 +1,182 @@ +[ + { + "name": "Turtle Rock", + "category": "Rivers", + "city": "Twentynine Palms", + "state": "California", + "id": 1001, + "isFeatured": true, + "isFavorite": true, + "park": "Joshua Tree National Park", + "coordinates": { + "longitude": -116.166868, + "latitude": 34.011286 + }, + "imageName": "turtlerock" + }, + { + "name": "Silver Salmon Creek", + "category": "Lakes", + "city": "Port Alsworth", + "state": "Alaska", + "id": 1002, + "isFeatured": false, + "isFavorite": false, + "park": "Lake Clark National Park and Preserve", + "coordinates": { + "longitude": -152.665167, + "latitude": 59.980167 + }, + "imageName": "silversalmoncreek" + }, + { + "name": "Chilkoot Trail", + "category": "Mountains", + "city": "Skagway", + "state": "Alaska", + "id": 1003, + "isFeatured": false, + "isFavorite": true, + "park": "Klondike Gold Rush National Historical Park", + "coordinates": { + "longitude": -135.334571, + "latitude": 59.560551 + }, + "imageName": "chilkoottrail" + }, + { + "name": "St. Mary Lake", + "category": "Lakes", + "city": "Browning", + "state": "Montana", + "id": 1004, + "isFeatured": true, + "isFavorite": true, + "park": "Glacier National Park", + "coordinates": { + "longitude": -113.536248, + "latitude": 48.69423 + }, + "imageName": "stmarylake" + }, + { + "name": "Twin Lake", + "category": "Lakes", + "city": "Twin Lakes", + "state": "Alaska", + "id": 1005, + "isFeatured": false, + "isFavorite": false, + "park": "Lake Clark National Park and Preserve", + "coordinates": { + "longitude": -153.849883, + "latitude": 60.641684 + }, + "imageName": "twinlake" + }, + { + "name": "Lake McDonald", + "category": "Mountains", + "city": "West Glacier", + "state": "Montana", + "id": 1006, + "isFeatured": false, + "isFavorite": false, + "park": "Glacier National Park", + "coordinates": { + "longitude": -113.934831, + "latitude": 48.56002 + }, + "imageName": "lakemcdonald" + }, + { + "name": "Charley Rivers", + "category": "Rivers", + "city": "Eaking", + "state": "Alaska", + "id": 1007, + "isFeatured": true, + "isFavorite": false, + "park": "Charley Rivers National Preserve", + "coordinates": { + "longitude": -143.122586, + "latitude": 65.350021 + }, + "imageName": "charleyrivers", + }, + { + "name": "Icy Bay", + "category": "Mountains", + "city": "Icy Bay", + "state": "Alaska", + "id": 1008, + "isFeatured": false, + "isFavorite": false, + "park": "Wrangell-St. Elias National Park and Preserve", + "coordinates": { + "longitude": -141.518167, + "latitude": 60.089917 + }, + "imageName": "icybay" + }, + { + "name": "Rainbow Lake", + "category": "Lakes", + "city": "Willow", + "state": "Alaska", + "id": 1009, + "isFeatured": false, + "isFavorite": false, + "park": "State Recreation Area", + "coordinates": { + "longitude": -150.086103, + "latitude": 61.694334 + }, + "imageName": "rainbowlake" + }, + { + "name": "Hidden Lake", + "category": "Lakes", + "city": "Newhalem", + "state": "Washington", + "id": 1010, + "isFeatured": false, + "isFavorite": false, + "park": "North Cascades National Park", + "coordinates": { + "longitude": -121.17799, + "latitude": 48.495442 + }, + "imageName": "hiddenlake" + }, + { + "name": "Chincoteague", + "category": "Rivers", + "city": "Chincoteague", + "state": "Virginia", + "id": 1011, + "isFeatured": false, + "isFavorite": false, + "park": "Chincoteague National Wildlife Refuge", + "coordinates": { + "longitude": -75.383212, + "latitude": 37.91531 + }, + "imageName": "chincoteague" + }, + { + "name": "Lake Umbagog", + "category": "Lakes", + "city": "Errol", + "state": "New Hampshire", + "id": 1012, + "isFeatured": true, + "isFavorite": false, + "park": "Umbagog National Wildlife Refuge", + "coordinates": { + "longitude": -71.056816, + "latitude": 44.747408 + }, + "imageName": "umbagog" + } +] diff --git a/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Resources/rainbowlake.jpg b/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Resources/rainbowlake.jpg new file mode 100644 index 0000000..6da43dd Binary files /dev/null and b/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Resources/rainbowlake.jpg differ diff --git a/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Resources/silversalmoncreek.jpg b/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Resources/silversalmoncreek.jpg new file mode 100644 index 0000000..f657532 Binary files /dev/null and b/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Resources/silversalmoncreek.jpg differ diff --git a/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Resources/stmarylake.jpg b/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Resources/stmarylake.jpg new file mode 100644 index 0000000..1c71de4 Binary files /dev/null and b/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Resources/stmarylake.jpg differ diff --git a/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Resources/turtlerock.jpg b/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Resources/turtlerock.jpg new file mode 100644 index 0000000..f7a6e6d Binary files /dev/null and b/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Resources/turtlerock.jpg differ diff --git a/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Resources/twinlake.jpg b/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Resources/twinlake.jpg new file mode 100644 index 0000000..3e7a57c Binary files /dev/null and b/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Resources/twinlake.jpg differ diff --git a/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Resources/umbagog.jpg b/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Resources/umbagog.jpg new file mode 100644 index 0000000..56291c6 Binary files /dev/null and b/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Resources/umbagog.jpg differ diff --git a/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/SceneDelegate.swift b/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/SceneDelegate.swift new file mode 100644 index 0000000..51057d3 --- /dev/null +++ b/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/SceneDelegate.swift @@ -0,0 +1,58 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +The scene delegate. +*/ + +import UIKit +import SwiftUI + +class SceneDelegate: UIResponder, UIWindowSceneDelegate { + + var window: UIWindow? + + func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { + // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`. + // If using a storyboard, the `window` property will automatically be initialized and attached to the scene. + // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead). + + // Use a UIHostingController as window root view controller + if let windowScene = scene as? UIWindowScene { + let window = UIWindow(windowScene: windowScene) + window.rootViewController = UIHostingController(rootView: CategoryHome().environmentObject(UserData())) + self.window = window + window.makeKeyAndVisible() + } + } + + func sceneDidDisconnect(_ scene: UIScene) { + // Called as the scene is being released by the system. + // This occurs shortly after the scene enters the background, or when its session is discarded. + // Release any resources associated with this scene that can be re-created the next time the scene connects. + // The scene may re-connect later, as its session was not neccessarily discarded (see `application:didDiscardSceneSessions` instead). + } + + func sceneDidBecomeActive(_ scene: UIScene) { + // Called when the scene has moved from an inactive state to an active state. + // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive. + } + + func sceneWillResignActive(_ scene: UIScene) { + // Called when the scene will move from an active state to an inactive state. + // This may occur due to temporary interruptions (ex. an incoming phone call). + } + + func sceneWillEnterForeground(_ scene: UIScene) { + // Called as the scene transitions from the background to the foreground. + // Use this method to undo the changes made on entering the background. + } + + func sceneDidEnterBackground(_ scene: UIScene) { + // Called as the scene transitions from the foreground to the background. + // Use this method to save data, release shared resources, and store enough scene-specific state information + // to restore the scene back to its current state. + } + +} + diff --git a/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Supporting Views/Badge.swift b/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Supporting Views/Badge.swift new file mode 100644 index 0000000..59f03b2 --- /dev/null +++ b/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Supporting Views/Badge.swift @@ -0,0 +1,41 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A view that displays a badge. +*/ + +import SwiftUI + +struct Badge: View { + static let rotationCount = 8 + + var badgeSymbols: some View { + ForEach(0.. + var overallRange: Range + + var heightRatio: CGFloat { + max(CGFloat(magnitude(of: range) / magnitude(of: overallRange)), 0.15) + } + + var offsetRatio: CGFloat { + CGFloat((range.lowerBound - overallRange.lowerBound) / magnitude(of: overallRange)) + } + + var animation: Animation { + Animation.spring() + .speed(2) + .delay(0.03 * Double(index)) + } + + var body: some View { + Capsule() + .fill(Color.white) + .frame(height: height * heightRatio, alignment: .bottom) + .offset(x: 0, y: height * -offsetRatio) + .animation(animation) + } +} + +#if DEBUG +struct GraphCapsule_Previews: PreviewProvider { + static var previews: some View { + GraphCapsule(index: 0, height: 150, range: 10..<50, overallRange: 0..<100) + } +} +#endif diff --git a/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Supporting Views/HikeGraph.swift b/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Supporting Views/HikeGraph.swift new file mode 100644 index 0000000..2a4ff27 --- /dev/null +++ b/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Supporting Views/HikeGraph.swift @@ -0,0 +1,74 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +The elevation, heart rate, and pace of a hike plotted on a graph. +*/ + +import SwiftUI + +func rangeOfRanges(_ ranges: C) -> Range + where C.Element == Range { + guard !ranges.isEmpty else { return 0..<0 } + let low = ranges.lazy.map { $0.lowerBound }.min()! + let high = ranges.lazy.map { $0.upperBound }.max()! + return low..) -> Double { + return range.upperBound - range.lowerBound +} + +struct HikeGraph: View { + var hike: Hike + var path: KeyPath> + + var color: Color { + switch path { + case \.elevation: + return .gray + case \.heartRate: + return Color(hue: 0, saturation: 0.5, brightness: 0.7) + case \.pace: + return Color(hue: 0.7, saturation: 0.4, brightness: 0.7) + default: + return .black + } + } + + var body: some View { + let data = hike.observations + let overallRange = rangeOfRanges(data.lazy.map { $0[keyPath: self.path] }) + let maxMagnitude = data.map { magnitude(of: $0[keyPath: path]) }.max()! + let heightRatio = 1 - CGFloat(maxMagnitude / magnitude(of: overallRange)) + + return GeometryReader { proxy in + HStack(alignment: .bottom, spacing: proxy.size.width / 120) { + ForEach(data.indices) { index in + GraphCapsule( + index: index, + height: proxy.size.height, + range: data[index][keyPath: self.path], + overallRange: overallRange) + .colorMultiply(self.color) + } + .offset(x: 0, y: proxy.size.height * heightRatio) + } + } + } +} + +#if DEBUG +struct HikeGraph_Previews: PreviewProvider { + static var previews: some View { + Group { + HikeGraph(hike: hikeData[0], path: \.elevation) + .frame(height: 200) + HikeGraph(hike: hikeData[0], path: \.heartRate) + .frame(height: 200) + HikeGraph(hike: hikeData[0], path: \.pace) + .frame(height: 200) + } + } +} +#endif diff --git a/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Supporting Views/LandmarkRow.swift b/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Supporting Views/LandmarkRow.swift new file mode 100644 index 0000000..2f8110c --- /dev/null +++ b/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Supporting Views/LandmarkRow.swift @@ -0,0 +1,38 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A single row to be displayed in a list of landmarks. +*/ + +import SwiftUI + +struct LandmarkRow: View { + var landmark: Landmark + + var body: some View { + HStack { + landmark.image(forSize: 50) + Text(verbatim: landmark.name) + Spacer() + + if landmark.isFavorite { + Image(systemName: "star.fill") + .imageScale(.medium) + .foregroundColor(.yellow) + } + } + } +} + +#if DEBUG +struct LandmarkRow_Previews: PreviewProvider { + static var previews: some View { + Group { + LandmarkRow(landmark: landmarkData[0]) + LandmarkRow(landmark: landmarkData[1]) + } + .previewLayout(.fixed(width: 300, height: 70)) + } +} +#endif diff --git a/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Supporting Views/MapView.swift b/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Supporting Views/MapView.swift new file mode 100644 index 0000000..5a8c64b --- /dev/null +++ b/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Supporting Views/MapView.swift @@ -0,0 +1,31 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A view that hosts an `MKMapView`. +*/ + +import SwiftUI +import MapKit + +struct MapView: UIViewRepresentable { + var coordinate: CLLocationCoordinate2D + + func makeUIView(context: Context) -> MKMapView { + MKMapView(frame: .zero) + } + + func updateUIView(_ view: MKMapView, context: Context) { + let span = MKCoordinateSpan(latitudeDelta: 0.02, longitudeDelta: 0.02) + let region = MKCoordinateRegion(center: coordinate, span: span) + view.setRegion(region, animated: true) + } +} + +#if DEBUG +struct MapView_Previews: PreviewProvider { + static var previews: some View { + MapView(coordinate: landmarkData[0].locationCoordinate) + } +} +#endif diff --git a/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Supporting Views/RotatedBadgeSymbol.swift b/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Supporting Views/RotatedBadgeSymbol.swift new file mode 100644 index 0000000..a7e4b53 --- /dev/null +++ b/Other Projects/Working With UIControls/Complete/Landmarks/Landmarks/Supporting Views/RotatedBadgeSymbol.swift @@ -0,0 +1,26 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A view that displays a rotated version of a badge symbol. +*/ + +import SwiftUI + +struct RotatedBadgeSymbol: View { + let angle: Angle + + var body: some View { + BadgeSymbol() + .padding(-60) + .rotationEffect(angle, anchor: .bottom) + } +} + +#if DEBUG +struct RotatedBadgeSymbol_Previews: PreviewProvider { + static var previews: some View { + RotatedBadgeSymbol(angle: .init(degrees: 5)) + } +} +#endif diff --git a/Other Projects/Working With UIControls/Complete/Landmarks/WorkingWithUIControls.xcodeproj/.xcodesamplecode.plist b/Other Projects/Working With UIControls/Complete/Landmarks/WorkingWithUIControls.xcodeproj/.xcodesamplecode.plist new file mode 100644 index 0000000..5dd5da8 --- /dev/null +++ b/Other Projects/Working With UIControls/Complete/Landmarks/WorkingWithUIControls.xcodeproj/.xcodesamplecode.plist @@ -0,0 +1,5 @@ + + + + + diff --git a/Other Projects/Working With UIControls/Complete/Landmarks/WorkingWithUIControls.xcodeproj/project.pbxproj b/Other Projects/Working With UIControls/Complete/Landmarks/WorkingWithUIControls.xcodeproj/project.pbxproj new file mode 100644 index 0000000..f8ece51 --- /dev/null +++ b/Other Projects/Working With UIControls/Complete/Landmarks/WorkingWithUIControls.xcodeproj/project.pbxproj @@ -0,0 +1,561 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 50; + objects = { + +/* Begin PBXBuildFile section */ + B7310DD1229F6839001079B9 /* HexagonParameters.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7310DD0229F6839001079B9 /* HexagonParameters.swift */; }; + B7310DD3229F6CA9001079B9 /* Badge.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7310DD2229F6CA9001079B9 /* Badge.swift */; }; + B7394866229F194000C47603 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7394865229F194000C47603 /* AppDelegate.swift */; }; + B7394868229F194000C47603 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7394867229F194000C47603 /* SceneDelegate.swift */; }; + B739486A229F194000C47603 /* LandmarkDetail.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7394869229F194000C47603 /* LandmarkDetail.swift */; }; + B739486C229F194200C47603 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B739486B229F194200C47603 /* Assets.xcassets */; }; + B739486F229F194200C47603 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B739486E229F194200C47603 /* Preview Assets.xcassets */; }; + B7394872229F194200C47603 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B7394870229F194200C47603 /* LaunchScreen.storyboard */; }; + B739487A229F1B3F00C47603 /* CircleImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7394879229F1B3F00C47603 /* CircleImage.swift */; }; + B739487C229F1B6800C47603 /* MapView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B739487B229F1B6800C47603 /* MapView.swift */; }; + B7394881229F28B900C47603 /* Landmark.swift in Sources */ = {isa = PBXBuildFile; fileRef = B739487F229F28B900C47603 /* Landmark.swift */; }; + B7394882229F28B900C47603 /* Data.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7394880229F28B900C47603 /* Data.swift */; }; + B7394891229F292F00C47603 /* rainbowlake.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B7394884229F292D00C47603 /* rainbowlake.jpg */; }; + B7394893229F292F00C47603 /* icybay.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B7394886229F292E00C47603 /* icybay.jpg */; }; + B7394894229F292F00C47603 /* lakemcdonald.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B7394887229F292E00C47603 /* lakemcdonald.jpg */; }; + B7394895229F292F00C47603 /* turtlerock.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B7394888229F292E00C47603 /* turtlerock.jpg */; }; + B7394896229F292F00C47603 /* umbagog.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B7394889229F292E00C47603 /* umbagog.jpg */; }; + B7394897229F292F00C47603 /* hiddenlake.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B739488A229F292E00C47603 /* hiddenlake.jpg */; }; + B7394898229F292F00C47603 /* stmarylake.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B739488B229F292E00C47603 /* stmarylake.jpg */; }; + B7394899229F292F00C47603 /* twinlake.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B739488C229F292E00C47603 /* twinlake.jpg */; }; + B739489A229F292F00C47603 /* silversalmoncreek.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B739488D229F292E00C47603 /* silversalmoncreek.jpg */; }; + B739489B229F292F00C47603 /* landmarkData.json in Resources */ = {isa = PBXBuildFile; fileRef = B739488E229F292E00C47603 /* landmarkData.json */; }; + B739489C229F292F00C47603 /* chincoteague.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B739488F229F292F00C47603 /* chincoteague.jpg */; }; + B739489D229F292F00C47603 /* chilkoottrail.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B7394890229F292F00C47603 /* chilkoottrail.jpg */; }; + B739489F229F2D9700C47603 /* LandmarkRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = B739489E229F2D9700C47603 /* LandmarkRow.swift */; }; + B73948A1229F2E1F00C47603 /* LandmarkList.swift in Sources */ = {isa = PBXBuildFile; fileRef = B73948A0229F2E1F00C47603 /* LandmarkList.swift */; }; + B73948A3229F3E2200C47603 /* charleyrivers.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B73948A2229F3E2200C47603 /* charleyrivers.jpg */; }; + B7D2AAC5229F4D7C0061E5F5 /* UserData.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7D2AAC4229F4D7C0061E5F5 /* UserData.swift */; }; + B7D587AE229F7382006E8DCF /* BadgeBackground.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7D587AD229F7382006E8DCF /* BadgeBackground.swift */; }; + B7D587B0229F73C1006E8DCF /* BadgeSymbol.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7D587AF229F73C1006E8DCF /* BadgeSymbol.swift */; }; + B7D587B2229F7406006E8DCF /* RotatedBadgeSymbol.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7D587B1229F7406006E8DCF /* RotatedBadgeSymbol.swift */; }; + B7D587B6229F825D006E8DCF /* HikeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7D587B5229F825D006E8DCF /* HikeView.swift */; }; + B7D587B8229F826D006E8DCF /* GraphCapsule.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7D587B7229F826D006E8DCF /* GraphCapsule.swift */; }; + B7D587BA229F8288006E8DCF /* Hike.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7D587B9229F8288006E8DCF /* Hike.swift */; }; + B7D587BC229F82EB006E8DCF /* HikeDetail.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7D587BB229F82EB006E8DCF /* HikeDetail.swift */; }; + B7D587BE229F82FF006E8DCF /* HikeGraph.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7D587BD229F82FF006E8DCF /* HikeGraph.swift */; }; + B7D587C0229F830B006E8DCF /* hikeData.json in Resources */ = {isa = PBXBuildFile; fileRef = B7D587BF229F830B006E8DCF /* hikeData.json */; }; + B7D587D222A0892C006E8DCF /* Home.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7D587D122A0892C006E8DCF /* Home.swift */; }; + B7D587D422A08965006E8DCF /* CategoryRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7D587D322A08965006E8DCF /* CategoryRow.swift */; }; + B7D587D622A08C97006E8DCF /* Profile.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7D587D522A08C97006E8DCF /* Profile.swift */; }; + B7D587D922A08D33006E8DCF /* ProfileHost.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7D587D822A08D33006E8DCF /* ProfileHost.swift */; }; + B7D587DB22A08D67006E8DCF /* ProfileSummary.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7D587DA22A08D67006E8DCF /* ProfileSummary.swift */; }; + B7D587DD22A08DD6006E8DCF /* HikeBadge.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7D587DC22A08DD6006E8DCF /* HikeBadge.swift */; }; + B7D587DF22A08E1A006E8DCF /* ProfileEditor.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7D587DE22A08E1A006E8DCF /* ProfileEditor.swift */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + B7310DD0229F6839001079B9 /* HexagonParameters.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HexagonParameters.swift; sourceTree = ""; }; + B7310DD2229F6CA9001079B9 /* Badge.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Badge.swift; sourceTree = ""; }; + B7394862229F194000C47603 /* Landmarks.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Landmarks.app; sourceTree = BUILT_PRODUCTS_DIR; }; + B7394865229F194000C47603 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + B7394867229F194000C47603 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; + B7394869229F194000C47603 /* LandmarkDetail.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LandmarkDetail.swift; sourceTree = ""; }; + B739486B229F194200C47603 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + B739486E229F194200C47603 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; + B7394871229F194200C47603 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + B7394873229F194200C47603 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + B7394879229F1B3F00C47603 /* CircleImage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CircleImage.swift; sourceTree = ""; }; + B739487B229F1B6800C47603 /* MapView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapView.swift; sourceTree = ""; }; + B739487F229F28B900C47603 /* Landmark.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Landmark.swift; sourceTree = ""; }; + B7394880229F28B900C47603 /* Data.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Data.swift; sourceTree = ""; }; + B7394884229F292D00C47603 /* rainbowlake.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = rainbowlake.jpg; sourceTree = ""; }; + B7394886229F292E00C47603 /* icybay.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = icybay.jpg; sourceTree = ""; }; + B7394887229F292E00C47603 /* lakemcdonald.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = lakemcdonald.jpg; sourceTree = ""; }; + B7394888229F292E00C47603 /* turtlerock.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = turtlerock.jpg; sourceTree = ""; }; + B7394889229F292E00C47603 /* umbagog.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = umbagog.jpg; sourceTree = ""; }; + B739488A229F292E00C47603 /* hiddenlake.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = hiddenlake.jpg; sourceTree = ""; }; + B739488B229F292E00C47603 /* stmarylake.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = stmarylake.jpg; sourceTree = ""; }; + B739488C229F292E00C47603 /* twinlake.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = twinlake.jpg; sourceTree = ""; }; + B739488D229F292E00C47603 /* silversalmoncreek.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = silversalmoncreek.jpg; sourceTree = ""; }; + B739488E229F292E00C47603 /* landmarkData.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = landmarkData.json; sourceTree = ""; }; + B739488F229F292F00C47603 /* chincoteague.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = chincoteague.jpg; sourceTree = ""; }; + B7394890229F292F00C47603 /* chilkoottrail.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = chilkoottrail.jpg; sourceTree = ""; }; + B739489E229F2D9700C47603 /* LandmarkRow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = LandmarkRow.swift; path = "Supporting Views/LandmarkRow.swift"; sourceTree = ""; }; + B73948A0229F2E1F00C47603 /* LandmarkList.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LandmarkList.swift; sourceTree = ""; }; + B73948A2229F3E2200C47603 /* charleyrivers.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = charleyrivers.jpg; sourceTree = ""; }; + B7D2AAC4229F4D7C0061E5F5 /* UserData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserData.swift; sourceTree = ""; }; + B7D587AD229F7382006E8DCF /* BadgeBackground.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BadgeBackground.swift; sourceTree = ""; }; + B7D587AF229F73C1006E8DCF /* BadgeSymbol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BadgeSymbol.swift; sourceTree = ""; }; + B7D587B1229F7406006E8DCF /* RotatedBadgeSymbol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RotatedBadgeSymbol.swift; sourceTree = ""; }; + B7D587B5229F825D006E8DCF /* HikeView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HikeView.swift; sourceTree = ""; }; + B7D587B7229F826D006E8DCF /* GraphCapsule.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GraphCapsule.swift; sourceTree = ""; }; + B7D587B9229F8288006E8DCF /* Hike.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Hike.swift; sourceTree = ""; }; + B7D587BB229F82EB006E8DCF /* HikeDetail.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HikeDetail.swift; sourceTree = ""; }; + B7D587BD229F82FF006E8DCF /* HikeGraph.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HikeGraph.swift; sourceTree = ""; }; + B7D587BF229F830B006E8DCF /* hikeData.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = hikeData.json; sourceTree = ""; }; + B7D587D122A0892C006E8DCF /* Home.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Home.swift; sourceTree = ""; }; + B7D587D322A08965006E8DCF /* CategoryRow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CategoryRow.swift; sourceTree = ""; }; + B7D587D522A08C97006E8DCF /* Profile.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Profile.swift; sourceTree = ""; }; + B7D587D822A08D33006E8DCF /* ProfileHost.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileHost.swift; sourceTree = ""; }; + B7D587DA22A08D67006E8DCF /* ProfileSummary.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileSummary.swift; sourceTree = ""; }; + B7D587DC22A08DD6006E8DCF /* HikeBadge.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HikeBadge.swift; sourceTree = ""; }; + B7D587DE22A08E1A006E8DCF /* ProfileEditor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileEditor.swift; sourceTree = ""; }; + C30D96E0C30D9A6000000001 /* SampleCode.xcconfig */ = {isa = PBXFileReference; name = SampleCode.xcconfig; path = ../Configuration/SampleCode.xcconfig; sourceTree = ""; }; + C35276F0C352949000000001 /* LICENSE.txt */ = {isa = PBXFileReference; includeInIndex = 1; path = LICENSE.txt; sourceTree = ""; }; + C4E4AAA0C4E4035000000001 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; name = README.md; path = ../README.md; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + B739485F229F194000C47603 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + B7394859229F194000C47603 = { + isa = PBXGroup; + children = ( + C4E4AAA0C4E4035000000001 /* README.md */, + B7394864229F194000C47603 /* Landmarks */, + B7394863229F194000C47603 /* Products */, + C16018F0C1601FC000000001 /* Configuration */, + C3527360C3512CA000000001 /* LICENSE */, + ); + sourceTree = ""; + }; + B7394863229F194000C47603 /* Products */ = { + isa = PBXGroup; + children = ( + B7394862229F194000C47603 /* Landmarks.app */, + ); + name = Products; + sourceTree = ""; + }; + B7394864229F194000C47603 /* Landmarks */ = { + isa = PBXGroup; + children = ( + B739487E229F282200C47603 /* Models */, + B7D587D722A08D16006E8DCF /* Profiles */, + B7394865229F194000C47603 /* AppDelegate.swift */, + B7394867229F194000C47603 /* SceneDelegate.swift */, + B7D587D122A0892C006E8DCF /* Home.swift */, + B7D587D322A08965006E8DCF /* CategoryRow.swift */, + B73948A0229F2E1F00C47603 /* LandmarkList.swift */, + B739489E229F2D9700C47603 /* LandmarkRow.swift */, + B7394869229F194000C47603 /* LandmarkDetail.swift */, + B7D587B5229F825D006E8DCF /* HikeView.swift */, + B7D587BB229F82EB006E8DCF /* HikeDetail.swift */, + B7D587DC22A08DD6006E8DCF /* HikeBadge.swift */, + B7310DD0229F6839001079B9 /* HexagonParameters.swift */, + B739487D229F1C0100C47603 /* Supporting Views */, + B7394883229F291A00C47603 /* Resources */, + B739486B229F194200C47603 /* Assets.xcassets */, + B7394870229F194200C47603 /* LaunchScreen.storyboard */, + B7394873229F194200C47603 /* Info.plist */, + B739486D229F194200C47603 /* Preview Content */, + ); + path = Landmarks; + sourceTree = ""; + }; + B739486D229F194200C47603 /* Preview Content */ = { + isa = PBXGroup; + children = ( + B739486E229F194200C47603 /* Preview Assets.xcassets */, + ); + path = "Preview Content"; + sourceTree = ""; + }; + B739487D229F1C0100C47603 /* Supporting Views */ = { + isa = PBXGroup; + children = ( + B7394879229F1B3F00C47603 /* CircleImage.swift */, + B739487B229F1B6800C47603 /* MapView.swift */, + B7310DD2229F6CA9001079B9 /* Badge.swift */, + B7D587AF229F73C1006E8DCF /* BadgeSymbol.swift */, + B7D587B1229F7406006E8DCF /* RotatedBadgeSymbol.swift */, + B7D587AD229F7382006E8DCF /* BadgeBackground.swift */, + B7D587BD229F82FF006E8DCF /* HikeGraph.swift */, + B7D587B7229F826D006E8DCF /* GraphCapsule.swift */, + ); + path = "Supporting Views"; + sourceTree = ""; + }; + B739487E229F282200C47603 /* Models */ = { + isa = PBXGroup; + children = ( + B7D587D522A08C97006E8DCF /* Profile.swift */, + B7394880229F28B900C47603 /* Data.swift */, + B739487F229F28B900C47603 /* Landmark.swift */, + B7D587B9229F8288006E8DCF /* Hike.swift */, + B7D2AAC4229F4D7C0061E5F5 /* UserData.swift */, + ); + path = Models; + sourceTree = ""; + }; + B7394883229F291A00C47603 /* Resources */ = { + isa = PBXGroup; + children = ( + B739488E229F292E00C47603 /* landmarkData.json */, + B7D587BF229F830B006E8DCF /* hikeData.json */, + B7394890229F292F00C47603 /* chilkoottrail.jpg */, + B739488F229F292F00C47603 /* chincoteague.jpg */, + B739488A229F292E00C47603 /* hiddenlake.jpg */, + B7394886229F292E00C47603 /* icybay.jpg */, + B7394887229F292E00C47603 /* lakemcdonald.jpg */, + B7394884229F292D00C47603 /* rainbowlake.jpg */, + B739488D229F292E00C47603 /* silversalmoncreek.jpg */, + B739488B229F292E00C47603 /* stmarylake.jpg */, + B7394888229F292E00C47603 /* turtlerock.jpg */, + B739488C229F292E00C47603 /* twinlake.jpg */, + B7394889229F292E00C47603 /* umbagog.jpg */, + B73948A2229F3E2200C47603 /* charleyrivers.jpg */, + ); + path = Resources; + sourceTree = ""; + }; + B7D587D722A08D16006E8DCF /* Profiles */ = { + isa = PBXGroup; + children = ( + B7D587D822A08D33006E8DCF /* ProfileHost.swift */, + B7D587DA22A08D67006E8DCF /* ProfileSummary.swift */, + B7D587DE22A08E1A006E8DCF /* ProfileEditor.swift */, + ); + path = Profiles; + sourceTree = ""; + }; + C16018F0C1601FC000000001 /* Configuration */ = { + isa = PBXGroup; + children = ( + C30D96E0C30D9A6000000001 /* SampleCode.xcconfig */, + ); + name = Configuration; + sourceTree = ""; + }; + C3527360C3512CA000000001 /* LICENSE */ = { + isa = PBXGroup; + children = ( + C35276F0C352949000000001 /* LICENSE.txt */, + ); + name = LICENSE; + path = ../LICENSE; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + B7394861229F194000C47603 /* Landmarks */ = { + isa = PBXNativeTarget; + buildConfigurationList = B7394876229F194200C47603 /* Build configuration list for PBXNativeTarget "Landmarks" */; + buildPhases = ( + B739485E229F194000C47603 /* Sources */, + B739485F229F194000C47603 /* Frameworks */, + B7394860229F194000C47603 /* Resources */, + C602AC70C605937000000001, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Landmarks; + productName = Landmarks; + productReference = B7394862229F194000C47603 /* Landmarks.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + B739485A229F194000C47603 /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 1100; + LastUpgradeCheck = 1100; + ORGANIZATIONNAME = Apple; + TargetAttributes = { + B7394861229F194000C47603 = { + CreatedOnToolsVersion = 11.0; + }; + }; + }; + buildConfigurationList = B739485D229F194000C47603 /* Build configuration list for PBXProject "WorkingWithUIControls" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = B7394859229F194000C47603; + productRefGroup = B7394863229F194000C47603 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + B7394861229F194000C47603 /* Landmarks */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + B7394860229F194000C47603 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + B739489A229F292F00C47603 /* silversalmoncreek.jpg in Resources */, + B7394894229F292F00C47603 /* lakemcdonald.jpg in Resources */, + B7D587C0229F830B006E8DCF /* hikeData.json in Resources */, + B7394872229F194200C47603 /* LaunchScreen.storyboard in Resources */, + B73948A3229F3E2200C47603 /* charleyrivers.jpg in Resources */, + B7394891229F292F00C47603 /* rainbowlake.jpg in Resources */, + B739486F229F194200C47603 /* Preview Assets.xcassets in Resources */, + B7394895229F292F00C47603 /* turtlerock.jpg in Resources */, + B739486C229F194200C47603 /* Assets.xcassets in Resources */, + B7394899229F292F00C47603 /* twinlake.jpg in Resources */, + B7394896229F292F00C47603 /* umbagog.jpg in Resources */, + B739489D229F292F00C47603 /* chilkoottrail.jpg in Resources */, + B739489C229F292F00C47603 /* chincoteague.jpg in Resources */, + B739489B229F292F00C47603 /* landmarkData.json in Resources */, + B7394893229F292F00C47603 /* icybay.jpg in Resources */, + B7394897229F292F00C47603 /* hiddenlake.jpg in Resources */, + B7394898229F292F00C47603 /* stmarylake.jpg in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + B739485E229F194000C47603 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + B7394882229F28B900C47603 /* Data.swift in Sources */, + B7310DD3229F6CA9001079B9 /* Badge.swift in Sources */, + B7394866229F194000C47603 /* AppDelegate.swift in Sources */, + B7D587D922A08D33006E8DCF /* ProfileHost.swift in Sources */, + B7D587D622A08C97006E8DCF /* Profile.swift in Sources */, + B7D587B8229F826D006E8DCF /* GraphCapsule.swift in Sources */, + B7D587D422A08965006E8DCF /* CategoryRow.swift in Sources */, + B739487A229F1B3F00C47603 /* CircleImage.swift in Sources */, + B739487C229F1B6800C47603 /* MapView.swift in Sources */, + B7D587BA229F8288006E8DCF /* Hike.swift in Sources */, + B7D587BC229F82EB006E8DCF /* HikeDetail.swift in Sources */, + B7D587B6229F825D006E8DCF /* HikeView.swift in Sources */, + B7310DD1229F6839001079B9 /* HexagonParameters.swift in Sources */, + B73948A1229F2E1F00C47603 /* LandmarkList.swift in Sources */, + B7D587B0229F73C1006E8DCF /* BadgeSymbol.swift in Sources */, + B7D587B2229F7406006E8DCF /* RotatedBadgeSymbol.swift in Sources */, + B7D587DD22A08DD6006E8DCF /* HikeBadge.swift in Sources */, + B7D587D222A0892C006E8DCF /* Home.swift in Sources */, + B7D587BE229F82FF006E8DCF /* HikeGraph.swift in Sources */, + B7394868229F194000C47603 /* SceneDelegate.swift in Sources */, + B7D587AE229F7382006E8DCF /* BadgeBackground.swift in Sources */, + B739486A229F194000C47603 /* LandmarkDetail.swift in Sources */, + B739489F229F2D9700C47603 /* LandmarkRow.swift in Sources */, + B7D587DB22A08D67006E8DCF /* ProfileSummary.swift in Sources */, + B7D2AAC5229F4D7C0061E5F5 /* UserData.swift in Sources */, + B7394881229F28B900C47603 /* Landmark.swift in Sources */, + B7D587DF22A08E1A006E8DCF /* ProfileEditor.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + B7394870229F194200C47603 /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + B7394871229F194200C47603 /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + B7394874229F194200C47603 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = C30D96E0C30D9A6000000001 /* SampleCode.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + B7394875229F194200C47603 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = C30D96E0C30D9A6000000001 /* SampleCode.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + B7394877229F194200C47603 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = C30D96E0C30D9A6000000001 /* SampleCode.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_ASSET_PATHS = "Landmarks/Preview\\ Content"; + DEVELOPMENT_TEAM = ""; + ENABLE_PREVIEWS = YES; + INFOPLIST_FILE = Landmarks/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = "com.example.apple-samplecode.Landmarks${SAMPLE_CODE_DISAMBIGUATOR}"; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + B7394878229F194200C47603 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = C30D96E0C30D9A6000000001 /* SampleCode.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_ASSET_PATHS = "Landmarks/Preview\\ Content"; + DEVELOPMENT_TEAM = ""; + ENABLE_PREVIEWS = YES; + INFOPLIST_FILE = Landmarks/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = "com.example.apple-samplecode.Landmarks${SAMPLE_CODE_DISAMBIGUATOR}"; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + B739485D229F194000C47603 /* Build configuration list for PBXProject "WorkingWithUIControls" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + B7394874229F194200C47603 /* Debug */, + B7394875229F194200C47603 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + B7394876229F194200C47603 /* Build configuration list for PBXNativeTarget "Landmarks" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + B7394877229F194200C47603 /* Debug */, + B7394878229F194200C47603 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = B739485A229F194000C47603 /* Project object */; +} diff --git a/Other Projects/Working With UIControls/Complete/Landmarks/WorkingWithUIControls.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/Other Projects/Working With UIControls/Complete/Landmarks/WorkingWithUIControls.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 0000000..3ddf867 --- /dev/null +++ b/Other Projects/Working With UIControls/Complete/Landmarks/WorkingWithUIControls.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,8 @@ + + + + + BuildSystemType + Latest + + diff --git a/Other Projects/Working With UIControls/Complete/README.md b/Other Projects/Working With UIControls/Complete/README.md new file mode 100644 index 0000000..5cb1edb --- /dev/null +++ b/Other Projects/Working With UIControls/Complete/README.md @@ -0,0 +1,3 @@ +# Completed Project: Working with UI Controls + +Explore the completed project for the [Working with UI Controls](https://developer.apple.com/tutorials/swiftui/working-with-ui-controls) tutorial. \ No newline at end of file diff --git a/Other Projects/Working With UIControls/StartingPoint/.gitignore b/Other Projects/Working With UIControls/StartingPoint/.gitignore new file mode 100644 index 0000000..9e50718 --- /dev/null +++ b/Other Projects/Working With UIControls/StartingPoint/.gitignore @@ -0,0 +1,21 @@ +# See LICENSE folder for this sample’s licensing information. +# +# Apple sample code gitignore configuration. + +# Finder +.DS_Store + +# Xcode - User files +xcuserdata/ + +**/*.xcodeproj/project.xcworkspace/* +!**/*.xcodeproj/project.xcworkspace/xcshareddata + +**/*.xcodeproj/project.xcworkspace/xcshareddata/* +!**/*.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings + +**/*.playground/playground.xcworkspace/* +!**/*.playground/playground.xcworkspace/xcshareddata + +**/*.playground/playground.xcworkspace/xcshareddata/* +!**/*.playground/playground.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings diff --git a/Other Projects/Working With UIControls/StartingPoint/Configuration/SampleCode.xcconfig b/Other Projects/Working With UIControls/StartingPoint/Configuration/SampleCode.xcconfig new file mode 100644 index 0000000..db86c06 --- /dev/null +++ b/Other Projects/Working With UIControls/StartingPoint/Configuration/SampleCode.xcconfig @@ -0,0 +1,13 @@ +// +// See LICENSE folder for this sample’s licensing information. +// +// SampleCode.xcconfig +// + +// The `SAMPLE_CODE_DISAMBIGUATOR` configuration is to make it easier to build +// and run a sample code project. Once you set your project's development team, +// you'll have a unique bundle identifier. This is because the bundle identifier +// is derived based on the 'SAMPLE_CODE_DISAMBIGUATOR' value. Do not use this +// approach in your own projects—it's only useful for sample code projects because +// they are frequently downloaded and don't have a development team set. +SAMPLE_CODE_DISAMBIGUATOR=${DEVELOPMENT_TEAM} diff --git a/Other Projects/Working With UIControls/StartingPoint/LICENSE/LICENSE.txt b/Other Projects/Working With UIControls/StartingPoint/LICENSE/LICENSE.txt new file mode 100644 index 0000000..94e3d54 --- /dev/null +++ b/Other Projects/Working With UIControls/StartingPoint/LICENSE/LICENSE.txt @@ -0,0 +1,8 @@ +Copyright © 2019 Apple Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + diff --git a/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/AppDelegate.swift b/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/AppDelegate.swift new file mode 100644 index 0000000..e22943b --- /dev/null +++ b/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/AppDelegate.swift @@ -0,0 +1,36 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +The application delegate. +*/ + +import UIKit + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { + // Override point for customization after application launch. + return true + } + + func applicationWillTerminate(_ application: UIApplication) { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. + } + + // MARK: UISceneSession Lifecycle + func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration { + // Called when a new scene session is being created. + // Use this method to select a configuration to create the new scene with. + return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role) + } + + func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) { + // Called when the user discards a scene session. + // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions. + // Use this method to release any resources that were specific to the discarded scenes, as they will not return. + } + +} + diff --git a/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/Contents.json b/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..fa0d2db --- /dev/null +++ b/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,113 @@ +{ + "images" : [ + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "landmark_app_icon_40x40.png", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "3x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "landmark_app_icon_58x58.png", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "landmark_app_icon_87x87.png", + "scale" : "3x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "landmark_app_icon_80x80.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "landmark_app_icon_120x120.png", + "scale" : "3x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "landmark_app_icon_120x120-1.png", + "scale" : "2x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "landmark_app_icon_180x180.png", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "1x" + }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "landmark_app_icon_40x40-1.png", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "landmark_app_icon_58x58-1.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "landmark_app_icon_40x40-2.png", + "scale" : "1x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "landmark_app_icon_80x80-1.png", + "scale" : "2x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "landmark_app_icon_76x76.png", + "scale" : "1x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "landmark_app_icon_152x152.png", + "scale" : "2x" + }, + { + "size" : "83.5x83.5", + "idiom" : "ipad", + "filename" : "landmark_app_icon_167x167.png", + "scale" : "2x" + }, + { + "size" : "1024x1024", + "idiom" : "ios-marketing", + "filename" : "landmark_app_icon_1024x1024.png", + "scale" : "1x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_1024x1024.png b/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_1024x1024.png new file mode 100644 index 0000000..00d81c1 Binary files /dev/null and b/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_1024x1024.png differ diff --git a/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_120x120-1.png b/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_120x120-1.png new file mode 100644 index 0000000..d382b8b Binary files /dev/null and b/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_120x120-1.png differ diff --git a/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_120x120.png b/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_120x120.png new file mode 100644 index 0000000..d382b8b Binary files /dev/null and b/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_120x120.png differ diff --git a/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_152x152.png b/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_152x152.png new file mode 100644 index 0000000..11057f8 Binary files /dev/null and b/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_152x152.png differ diff --git a/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_167x167.png b/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_167x167.png new file mode 100644 index 0000000..f73bc26 Binary files /dev/null and b/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_167x167.png differ diff --git a/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_180x180.png b/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_180x180.png new file mode 100644 index 0000000..b02738c Binary files /dev/null and b/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_180x180.png differ diff --git a/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40-1.png b/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40-1.png new file mode 100644 index 0000000..abaff0e Binary files /dev/null and b/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40-1.png differ diff --git a/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40-2.png b/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40-2.png new file mode 100644 index 0000000..abaff0e Binary files /dev/null and b/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40-2.png differ diff --git a/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40.png b/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40.png new file mode 100644 index 0000000..abaff0e Binary files /dev/null and b/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_40x40.png differ diff --git a/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_58x58-1.png b/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_58x58-1.png new file mode 100644 index 0000000..cf7c73d Binary files /dev/null and b/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_58x58-1.png differ diff --git a/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_58x58.png b/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_58x58.png new file mode 100644 index 0000000..cf7c73d Binary files /dev/null and b/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_58x58.png differ diff --git a/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_76x76.png b/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_76x76.png new file mode 100644 index 0000000..3eff85b Binary files /dev/null and b/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_76x76.png differ diff --git a/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_80x80-1.png b/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_80x80-1.png new file mode 100644 index 0000000..6f33f66 Binary files /dev/null and b/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_80x80-1.png differ diff --git a/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_80x80.png b/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_80x80.png new file mode 100644 index 0000000..6f33f66 Binary files /dev/null and b/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_80x80.png differ diff --git a/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_87x87.png b/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_87x87.png new file mode 100644 index 0000000..9e1616c Binary files /dev/null and b/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Assets.xcassets/AppIcon.appiconset/landmark_app_icon_87x87.png differ diff --git a/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Assets.xcassets/Contents.json b/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Assets.xcassets/turtlerock.imageset/Contents.json b/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Assets.xcassets/turtlerock.imageset/Contents.json new file mode 100644 index 0000000..5bfd7bf --- /dev/null +++ b/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Assets.xcassets/turtlerock.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "turtlerock.jpg", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Assets.xcassets/turtlerock.imageset/turtlerock.jpg b/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Assets.xcassets/turtlerock.imageset/turtlerock.jpg new file mode 100644 index 0000000..68bcd3e Binary files /dev/null and b/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Assets.xcassets/turtlerock.imageset/turtlerock.jpg differ diff --git a/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Base.lproj/LaunchScreen.storyboard b/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000..865e932 --- /dev/null +++ b/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/CategoryRow.swift b/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/CategoryRow.swift new file mode 100644 index 0000000..1f4fbd8 --- /dev/null +++ b/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/CategoryRow.swift @@ -0,0 +1,64 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A view showing a scrollable list of landmarks. +*/ + +import SwiftUI + +struct CategoryRow: View { + var categoryName: String + var items: [Landmark] + + var body: some View { + VStack(alignment: .leading) { + Text(self.categoryName) + .font(.headline) + .padding(.leading, 15) + .padding(.top, 5) + + ScrollView(showsHorizontalIndicator: false) { + HStack(alignment: .top, spacing: 0) { + ForEach(self.items.identified(by: \.name)) { landmark in + NavigationButton( + destination: LandmarkDetail( + landmark: landmark + ) + ) { + CategoryItem(landmark: landmark) + } + } + } + } + .frame(height: 185) + } + } +} + +struct CategoryItem: View { + var landmark: Landmark + var body: some View { + VStack(alignment: .leading) { + landmark + .image(forSize: 155) + .renderingMode(.original) + .cornerRadius(5) + Text(landmark.name) + .color(.primary) + .font(.caption) + } + .padding(.leading, 15) + } +} + +#if DEBUG +struct CategoryRow_Previews: PreviewProvider { + static var previews: some View { + CategoryRow( + categoryName: landmarkData[0].category.rawValue, + items: Array(landmarkData.prefix(4)) + ) + } +} +#endif diff --git a/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/HexagonParameters.swift b/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/HexagonParameters.swift new file mode 100644 index 0000000..8decba4 --- /dev/null +++ b/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/HexagonParameters.swift @@ -0,0 +1,57 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +Size, position, and other information used to draw a badge. +*/ + +import SwiftUI + +struct HexagonParameters { + struct Segment { + let useWidth: (CGFloat, CGFloat, CGFloat) + let xFactors: (CGFloat, CGFloat, CGFloat) + let useHeight: (CGFloat, CGFloat, CGFloat) + let yFactors: (CGFloat, CGFloat, CGFloat) + } + + static let adjustment: CGFloat = 0.085 + static let points = [ + Segment( + useWidth: (1.00, 1.00, 1.00), + xFactors: (0.60, 0.40, 0.50), + useHeight: (1.00, 1.00, 0.00), + yFactors: (0.05, 0.05, 0.00) + ), + Segment( + useWidth: (1.00, 1.00, 0.00), + xFactors: (0.05, 0.00, 0.00), + useHeight: (1.00, 1.00, 1.00), + yFactors: (0.20 + adjustment, 0.30 + adjustment, 0.25 + adjustment) + ), + Segment( + useWidth: (1.00, 1.00, 0.00), + xFactors: (0.00, 0.05, 0.00), + useHeight: (1.00, 1.00, 1.00), + yFactors: (0.70 - adjustment, 0.80 - adjustment, 0.75 - adjustment) + ), + Segment( + useWidth: (1.00, 1.00, 1.00), + xFactors: (0.40, 0.60, 0.50), + useHeight: (1.00, 1.00, 1.00), + yFactors: (0.95, 0.95, 1.00) + ), + Segment( + useWidth: (1.00, 1.00, 1.00), + xFactors: (0.95, 1.00, 1.00), + useHeight: (1.00, 1.00, 1.00), + yFactors: (0.80 - adjustment, 0.70 - adjustment, 0.75 - adjustment) + ), + Segment( + useWidth: (1.00, 1.00, 1.00), + xFactors: (1.00, 0.95, 1.00), + useHeight: (1.00, 1.00, 1.00), + yFactors: (0.30 + adjustment, 0.20 + adjustment, 0.25 + adjustment) + ) + ] +} diff --git a/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/HikeDetail.swift b/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/HikeDetail.swift new file mode 100644 index 0000000..3406a6d --- /dev/null +++ b/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/HikeDetail.swift @@ -0,0 +1,49 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A view showing the details for a hike. +*/ + +import SwiftUI + +struct HikeDetail: View { + let hike: Hike + @State var dataToShow = \Hike.Observation.elevation + + var buttons = [ + ("Elevation", \Hike.Observation.elevation), + ("Heart Rate", \Hike.Observation.heartRate), + ("Pace", \Hike.Observation.pace), + ] + + var body: some View { + return VStack { + HikeGraph(hike: hike, path: dataToShow) + .frame(height: 200, alignment: .center) + + HStack(spacing: 25) { + ForEach(buttons.identified(by: \.0)) { value in + Button(action: { + self.dataToShow = value.1 + }) { + Text(verbatim: value.0) + .font(.system(size: 15)) + .color(value.1 == self.dataToShow + ? Color.gray + : Color.accentColor) + .animation(nil) + } + } + } + } + } +} + +#if DEBUG +struct HikeDetail_Previews: PreviewProvider { + static var previews: some View { + HikeDetail(hike: hikeData[0]) + } +} +#endif diff --git a/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/HikeView.swift b/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/HikeView.swift new file mode 100644 index 0000000..f4c02cc --- /dev/null +++ b/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/HikeView.swift @@ -0,0 +1,68 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A view displaying inforamtion about a hike, including an elevation graph. +*/ + +import SwiftUI + +struct HikeView: View { + var hike: Hike + @State private var showDetail = false + + var transition: AnyTransition { + let insertion = AnyTransition.move(edge: .trailing) + .combined(with: .opacity) + let removal = AnyTransition.scale() + .combined(with: .opacity) + return .asymmetric(insertion: insertion, removal: removal) + } + + var body: some View { + VStack { + HStack { + HikeGraph(hike: hike, path: \.elevation) + .frame(width: 50, height: 30) + .animation(nil) + + VStack(alignment: .leading) { + Text(verbatim: hike.name) + .font(.headline) + Text(verbatim: hike.distanceText) + } + + Spacer() + + Button(action: { + withAnimation { + self.showDetail.toggle() + } + }) { + Image(systemName: "chevron.right.circle") + .imageScale(.large) + .rotationEffect(.degrees(showDetail ? 90 : 0)) + .scaleEffect(showDetail ? 1.5 : 1) + .padding() + } + } + + if showDetail { + HikeDetail(hike: hike) + .transition(transition) + } + } + } +} + +#if DEBUG +struct HikeView_Previews: PreviewProvider { + static var previews: some View { + VStack { + HikeView(hike: hikeData[0]) + .padding() + Spacer() + } + } +} +#endif diff --git a/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Home.swift b/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Home.swift new file mode 100644 index 0000000..9e5ac93 --- /dev/null +++ b/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Home.swift @@ -0,0 +1,67 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A view showing featured landmarks above a list of all of the landmarks. +*/ + +import SwiftUI + +struct CategoryHome: View { + var categories: [String: [Landmark]] { + .init( + grouping: landmarkData, + by: { $0.category.rawValue } + ) + } + + var featured: [Landmark] { + landmarkData.filter { $0.isFeatured } + } + + var body: some View { + NavigationView { + List { + FeaturedLandmarks(landmarks: featured) + .scaledToFill() + .frame(height: 200) + .clipped() + .listRowInsets(EdgeInsets()) + + ForEach(categories.keys.sorted().identified(by: \.self)) { key in + CategoryRow(categoryName: key, items: self.categories[key]!) + } + .listRowInsets(EdgeInsets()) + + NavigationButton(destination: LandmarkList()) { + Text("See All") + } + } + .navigationBarTitle(Text("Featured")) + .navigationBarItems(trailing: + PresentationButton( + Image(systemName: "person.crop.circle") + .imageScale(.large) + .accessibility(label: Text("User Profile")) + .padding(), + destination: Text("User Profile") + ) + ) + } + } +} + +struct FeaturedLandmarks: View { + var landmarks: [Landmark] + var body: some View { + landmarks[0].image(forSize: 250).resizable() + } +} + +#if DEBUG +struct CategoryHome_Previews: PreviewProvider { + static var previews: some View { + CategoryHome() + } +} +#endif diff --git a/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Info.plist b/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Info.plist new file mode 100644 index 0000000..e8bb4c6 --- /dev/null +++ b/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Info.plist @@ -0,0 +1,62 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + $(PRODUCT_BUNDLE_PACKAGE_TYPE) + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UIApplicationSceneManifest + + UIApplicationSupportsMultipleScenes + + UISceneConfigurations + + UIWindowSceneSessionRoleApplication + + + UILaunchStoryboardName + LaunchScreen + UISceneConfigurationName + Default Configuration + UISceneDelegateClassName + $(PRODUCT_MODULE_NAME).SceneDelegate + + + + + UILaunchStoryboardName + LaunchScreen + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/LandmarkDetail.swift b/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/LandmarkDetail.swift new file mode 100644 index 0000000..6c290a3 --- /dev/null +++ b/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/LandmarkDetail.swift @@ -0,0 +1,71 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A view showing the details for a landmark. +*/ + +import SwiftUI + +struct LandmarkDetail: View { + @EnvironmentObject var userData: UserData + var landmark: Landmark + + var landmarkIndex: Int { + userData.landmarks.firstIndex(where: { $0.id == landmark.id })! + } + + var body: some View { + VStack { + MapView(coordinate: landmark.locationCoordinate) + .edgesIgnoringSafeArea(.top) + .frame(height: 300) + + CircleImage(image: landmark.image(forSize: 250)) + .offset(x: 0, y: -130) + .padding(.bottom, -130) + + VStack(alignment: .leading) { + HStack { + Text(verbatim: landmark.name) + .font(.title) + + Button(action: { + self.userData.landmarks[self.landmarkIndex] + .isFavorite.toggle() + }) { + if self.userData.landmarks[self.landmarkIndex] + .isFavorite { + Image(systemName: "star.fill") + .foregroundColor(Color.yellow) + } else { + Image(systemName: "star") + .foregroundColor(Color.gray) + } + } + } + + HStack(alignment: .top) { + Text(verbatim: landmark.park) + .font(.subheadline) + Spacer() + Text(verbatim: landmark.state) + .font(.subheadline) + } + } + .padding() + + Spacer() + } + } +} + +#if DEBUG +struct LandmarkDetail_Preview: PreviewProvider { + static var previews: some View { + let userData = UserData() + return LandmarkDetail(landmark: userData.landmarks[0]) + .environmentObject(userData) + } +} +#endif diff --git a/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/LandmarkList.swift b/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/LandmarkList.swift new file mode 100644 index 0000000..c17b5f3 --- /dev/null +++ b/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/LandmarkList.swift @@ -0,0 +1,45 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A view showing a list of landmarks. +*/ + +import SwiftUI + +struct LandmarkList: View { + @EnvironmentObject private var userData: UserData + + var body: some View { + NavigationView { + List { + Toggle(isOn: $userData.showFavoritesOnly) { + Text("Show Favorites Only") + } + + ForEach(userData.landmarks) { landmark in + if !self.userData.showFavoritesOnly || landmark.isFavorite { + NavigationButton( + destination: LandmarkDetail(landmark: landmark)) { + LandmarkRow(landmark: landmark) + } + } + } + } + .navigationBarTitle(Text("Landmarks"), displayMode: .large) + } + } +} + +#if DEBUG +struct LandmarksList_Previews: PreviewProvider { + static var previews: some View { + ForEach(["iPhone SE", "iPhone XS Max"].identified(by: \.self)) { deviceName in + LandmarkList() + .previewDevice(PreviewDevice(rawValue: deviceName)) + .previewDisplayName(deviceName) + } + .environmentObject(UserData()) + } +} +#endif diff --git a/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Models/Data.swift b/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Models/Data.swift new file mode 100644 index 0000000..248d3b2 --- /dev/null +++ b/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Models/Data.swift @@ -0,0 +1,95 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +Helpers for loading images and data. +*/ + +import Foundation +import CoreLocation +import UIKit +import SwiftUI + +let landmarkData: [Landmark] = load("landmarkData.json") +let hikeData: [Hike] = load("hikeData.json") + +func load(_ filename: String, as type: T.Type = T.self) -> T { + let data: Data + + guard let file = Bundle.main.url(forResource: filename, withExtension: nil) + else { + fatalError("Couldn't find \(filename) in main bundle.") + } + + do { + data = try Data(contentsOf: file) + } catch { + fatalError("Couldn't load \(filename) from main bundle:\n\(error)") + } + + do { + let decoder = JSONDecoder() + return try decoder.decode(T.self, from: data) + } catch { + fatalError("Couldn't parse \(filename) as \(T.self):\n\(error)") + } +} + +final class ImageStore { + fileprivate typealias _ImageDictionary = [String: [Int: CGImage]] + fileprivate var images: _ImageDictionary = [:] + + fileprivate static var originalSize = 250 + fileprivate static var scale = 2 + + static var shared = ImageStore() + + func image(name: String, size: Int) -> Image { + let index = _guaranteeInitialImage(name: name) + + let sizedImage = images.values[index][size] + ?? _sizeImage(images.values[index][ImageStore.originalSize]!, to: size * ImageStore.scale) + images.values[index][size] = sizedImage + + return Image(sizedImage, scale: Length(ImageStore.scale), label: Text(verbatim: name)) + } + + fileprivate func _guaranteeInitialImage(name: String) -> _ImageDictionary.Index { + if let index = images.index(forKey: name) { return index } + + guard + let url = Bundle.main.url(forResource: name, withExtension: "jpg"), + let imageSource = CGImageSourceCreateWithURL(url as NSURL, nil), + let image = CGImageSourceCreateImageAtIndex(imageSource, 0, nil) + else { + fatalError("Couldn't load image \(name).jpg from main bundle.") + } + + images[name] = [ImageStore.originalSize: image] + return images.index(forKey: name)! + } + + fileprivate func _sizeImage(_ image: CGImage, to size: Int) -> CGImage { + guard + let colorSpace = image.colorSpace, + let context = CGContext( + data: nil, + width: size, height: size, + bitsPerComponent: image.bitsPerComponent, + bytesPerRow: image.bytesPerRow, + space: colorSpace, + bitmapInfo: image.bitmapInfo.rawValue) + else { + fatalError("Couldn't create graphics context.") + } + context.interpolationQuality = .high + context.draw(image, in: CGRect(x: 0, y: 0, width: size, height: size)) + + if let sizedImage = context.makeImage() { + return sizedImage + } else { + fatalError("Couldn't resize image.") + } + } +} + diff --git a/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Models/Hike.swift b/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Models/Hike.swift new file mode 100644 index 0000000..dfd2bb8 --- /dev/null +++ b/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Models/Hike.swift @@ -0,0 +1,31 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +The model for a hike. +*/ + +import SwiftUI + +struct Hike: Codable, Hashable, Identifiable { + var name: String + var id: Int + var distance: Double + var difficulty: Int + var observations: [Observation] + + static var formatter = LengthFormatter() + + var distanceText: String { + return Hike.formatter + .string(fromValue: distance, unit: .kilometer) + } + + struct Observation: Codable, Hashable { + var distanceFromStart: Double + + var elevation: Range + var pace: Range + var heartRate: Range + } +} diff --git a/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Models/Landmark.swift b/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Models/Landmark.swift new file mode 100644 index 0000000..4a7586d --- /dev/null +++ b/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Models/Landmark.swift @@ -0,0 +1,43 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +The model for an individual landmark. +*/ + +import SwiftUI +import CoreLocation + +struct Landmark: Hashable, Codable, Identifiable { + var id: Int + var name: String + fileprivate var imageName: String + fileprivate var coordinates: Coordinates + var state: String + var park: String + var category: Category + var isFavorite: Bool + var isFeatured: Bool + + var locationCoordinate: CLLocationCoordinate2D { + CLLocationCoordinate2D( + latitude: coordinates.latitude, + longitude: coordinates.longitude) + } + + func image(forSize size: Int) -> Image { + ImageStore.shared.image(name: imageName, size: size) + } + + enum Category: String, CaseIterable, Codable, Hashable { + case featured = "Featured" + case lakes = "Lakes" + case rivers = "Rivers" + case mountains = "Mountains" + } +} + +struct Coordinates: Hashable, Codable { + var latitude: Double + var longitude: Double +} diff --git a/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Models/Profile.swift b/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Models/Profile.swift new file mode 100644 index 0000000..98378c8 --- /dev/null +++ b/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Models/Profile.swift @@ -0,0 +1,31 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A model object that stores user profile data. +*/ + +import Foundation + +struct Profile { + var username: String + var prefersNotifications: Bool + var seasonalPhoto: Season + var goalDate: Date + + static let `default` = Self(username: "g_kumar", prefersNotifications: true, seasonalPhoto: .winter) + + init(username: String, prefersNotifications: Bool = true, seasonalPhoto: Season = .winter) { + self.username = username + self.prefersNotifications = prefersNotifications + self.seasonalPhoto = seasonalPhoto + self.goalDate = Date() + } + + enum Season: String, CaseIterable { + case spring = "🌷" + case summer = "🌞" + case autumn = "🍂" + case winter = "☃️" + } +} diff --git a/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Models/UserData.swift b/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Models/UserData.swift new file mode 100644 index 0000000..db31fb0 --- /dev/null +++ b/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Models/UserData.swift @@ -0,0 +1,25 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A model object that stores app data. +*/ + +import Combine +import SwiftUI + +final class UserData: BindableObject { + let didChange = PassthroughSubject() + + var showFavoritesOnly = false { + didSet { + didChange.send(self) + } + } + + var landmarks = landmarkData { + didSet { + didChange.send(self) + } + } +} diff --git a/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Preview Content/Preview Assets.xcassets/Contents.json b/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Preview Content/Preview Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Preview Content/Preview Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Resources/charleyrivers.jpg b/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Resources/charleyrivers.jpg new file mode 100644 index 0000000..17ff44b Binary files /dev/null and b/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Resources/charleyrivers.jpg differ diff --git a/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Resources/chilkoottrail.jpg b/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Resources/chilkoottrail.jpg new file mode 100644 index 0000000..e7f805e Binary files /dev/null and b/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Resources/chilkoottrail.jpg differ diff --git a/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Resources/chincoteague.jpg b/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Resources/chincoteague.jpg new file mode 100644 index 0000000..5f47986 Binary files /dev/null and b/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Resources/chincoteague.jpg differ diff --git a/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Resources/hiddenlake.jpg b/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Resources/hiddenlake.jpg new file mode 100644 index 0000000..d8e804c Binary files /dev/null and b/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Resources/hiddenlake.jpg differ diff --git a/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Resources/hikeData.json b/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Resources/hikeData.json new file mode 100644 index 0000000..3fb1e96 --- /dev/null +++ b/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Resources/hikeData.json @@ -0,0 +1,1882 @@ +[ + { + "name":"Lonesome Ridge Trail", + "id":1001, + "distance":4.5, + "difficulty":3, + "observations":[ + { + "elevation":[ + 291.65263635636268, + 309.26016677925196 + ], + "pace":[ + 396.08716481908732, + 403.68937873525232 + ], + "heartRate":[ + 117.16351898665887, + 121.95815455919609 + ], + "distanceFromStart":0 + }, + { + "elevation":[ + 299.24001936628116, + 317.44584350790012 + ], + "pace":[ + 380.19020240756623, + 395.3978319010256 + ], + "heartRate":[ + 117.6410892152911, + 124.82185220506081 + ], + "distanceFromStart":0.375 + }, + { + "elevation":[ + 303.62145464574394, + 336.05569457646544 + ], + "pace":[ + 380.55927782266116, + 397.60789726832775 + ], + "heartRate":[ + 121.52696452049059, + 127.31525441110122 + ], + "distanceFromStart":0.75 + }, + { + "elevation":[ + 319.90393365162629, + 346.26966025518789 + ], + "pace":[ + 357.94116421258531, + 398.0750288648062 + ], + "heartRate":[ + 123.75908585923588, + 132.77069404486801 + ], + "distanceFromStart":1.125 + }, + { + "elevation":[ + 354.17104439267905, + 403.57031216972939 + ], + "pace":[ + 335.07385149392701, + 397.82674381875808 + ], + "heartRate":[ + 130.8235194572915, + 140.55700591418218 + ], + "distanceFromStart":1.5 + }, + { + "elevation":[ + 357.42992871175124, + 385.92155620623635 + ], + "pace":[ + 395.16168913839374, + 404.60294066527558 + ], + "heartRate":[ + 131.5456052446734, + 134.65984504627627 + ], + "distanceFromStart":1.875 + }, + { + "elevation":[ + 345.47736721935661, + 363.18776661379422 + ], + "pace":[ + 340.82303041339082, + 404.71689228682374 + ], + "heartRate":[ + 125.1949698433959, + 131.31354363122026 + ], + "distanceFromStart":2.25 + }, + { + "elevation":[ + 346.23343025200535, + 497.23376445462401 + ], + "pace":[ + 261.27629148816021, + 331.68516208719467 + ], + "heartRate":[ + 131.67810544238606, + 154.26779645311458 + ], + "distanceFromStart":2.625 + }, + { + "elevation":[ + 491.57378483134391, + 547.49535224251053 + ], + "pace":[ + 296.05298644112088, + 401.14092967732398 + ], + "heartRate":[ + 151.36398089694217, + 166.20454793289232 + ], + "distanceFromStart":3 + }, + { + "elevation":[ + 472.06803233416338, + 531.92570520228401 + ], + "pace":[ + 395.50830663514012, + 401.67837917543591 + ], + "heartRate":[ + 134.41798110234078, + 151.90886697564241 + ], + "distanceFromStart":3.375 + }, + { + "elevation":[ + 339.81419476005283, + 461.03832527824829 + ], + "pace":[ + 395.31160487975183, + 404.49550455974907 + ], + "heartRate":[ + 129.97753472415462, + 138.13531094848992 + ], + "distanceFromStart":3.75 + }, + { + "elevation":[ + 303.1495508565697, + 342.3532820173541 + ], + "pace":[ + 395.02844559698116, + 402.65878340653796 + ], + "heartRate":[ + 127.72304232462609, + 133.26322270764186 + ], + "distanceFromStart":4.125 + } + ] + }, + { + "name":"Lonesome Ridge Trail", + "id":1002, + "distance":4.5, + "difficulty":3, + "observations":[ + { + "elevation":[ + 291.65263635636268, + 309.26016677925196 + ], + "pace":[ + 396.08716481908732, + 403.68937873525232 + ], + "heartRate":[ + 117.16351898665887, + 121.95815455919609 + ], + "distanceFromStart":0 + }, + { + "elevation":[ + 299.24001936628116, + 317.44584350790012 + ], + "pace":[ + 380.19020240756623, + 395.3978319010256 + ], + "heartRate":[ + 117.6410892152911, + 124.82185220506081 + ], + "distanceFromStart":0.375 + }, + { + "elevation":[ + 303.62145464574394, + 336.05569457646544 + ], + "pace":[ + 380.55927782266116, + 397.60789726832775 + ], + "heartRate":[ + 121.52696452049059, + 127.31525441110122 + ], + "distanceFromStart":0.75 + }, + { + "elevation":[ + 319.90393365162629, + 346.26966025518789 + ], + "pace":[ + 357.94116421258531, + 398.0750288648062 + ], + "heartRate":[ + 123.75908585923588, + 132.77069404486801 + ], + "distanceFromStart":1.125 + }, + { + "elevation":[ + 354.17104439267905, + 403.57031216972939 + ], + "pace":[ + 335.07385149392701, + 397.82674381875808 + ], + "heartRate":[ + 130.8235194572915, + 140.55700591418218 + ], + "distanceFromStart":1.5 + }, + { + "elevation":[ + 357.42992871175124, + 385.92155620623635 + ], + "pace":[ + 395.16168913839374, + 404.60294066527558 + ], + "heartRate":[ + 131.5456052446734, + 134.65984504627627 + ], + "distanceFromStart":1.875 + }, + { + "elevation":[ + 345.47736721935661, + 363.18776661379422 + ], + "pace":[ + 340.82303041339082, + 404.71689228682374 + ], + "heartRate":[ + 125.1949698433959, + 131.31354363122026 + ], + "distanceFromStart":2.25 + }, + { + "elevation":[ + 346.23343025200535, + 497.23376445462401 + ], + "pace":[ + 261.27629148816021, + 331.68516208719467 + ], + "heartRate":[ + 131.67810544238606, + 154.26779645311458 + ], + "distanceFromStart":2.625 + }, + { + "elevation":[ + 491.57378483134391, + 547.49535224251053 + ], + "pace":[ + 296.05298644112088, + 401.14092967732398 + ], + "heartRate":[ + 151.36398089694217, + 166.20454793289232 + ], + "distanceFromStart":3 + }, + { + "elevation":[ + 472.06803233416338, + 531.92570520228401 + ], + "pace":[ + 395.50830663514012, + 401.67837917543591 + ], + "heartRate":[ + 134.41798110234078, + 151.90886697564241 + ], + "distanceFromStart":3.375 + }, + { + "elevation":[ + 339.81419476005283, + 461.03832527824829 + ], + "pace":[ + 395.31160487975183, + 404.49550455974907 + ], + "heartRate":[ + 129.97753472415462, + 138.13531094848992 + ], + "distanceFromStart":3.75 + }, + { + "elevation":[ + 303.1495508565697, + 342.3532820173541 + ], + "pace":[ + 395.02844559698116, + 402.65878340653796 + ], + "heartRate":[ + 127.72304232462609, + 133.26322270764186 + ], + "distanceFromStart":4.125 + } + ] + }, + { + "name":"Lonesome Ridge Trail", + "id":1003, + "distance":4.5, + "difficulty":3, + "observations":[ + { + "elevation":[ + 291.65263635636268, + 309.26016677925196 + ], + "pace":[ + 396.08716481908732, + 403.68937873525232 + ], + "heartRate":[ + 117.16351898665887, + 121.95815455919609 + ], + "distanceFromStart":0 + }, + { + "elevation":[ + 299.24001936628116, + 317.44584350790012 + ], + "pace":[ + 380.19020240756623, + 395.3978319010256 + ], + "heartRate":[ + 117.6410892152911, + 124.82185220506081 + ], + "distanceFromStart":0.375 + }, + { + "elevation":[ + 303.62145464574394, + 336.05569457646544 + ], + "pace":[ + 380.55927782266116, + 397.60789726832775 + ], + "heartRate":[ + 121.52696452049059, + 127.31525441110122 + ], + "distanceFromStart":0.75 + }, + { + "elevation":[ + 319.90393365162629, + 346.26966025518789 + ], + "pace":[ + 357.94116421258531, + 398.0750288648062 + ], + "heartRate":[ + 123.75908585923588, + 132.77069404486801 + ], + "distanceFromStart":1.125 + }, + { + "elevation":[ + 354.17104439267905, + 403.57031216972939 + ], + "pace":[ + 335.07385149392701, + 397.82674381875808 + ], + "heartRate":[ + 130.8235194572915, + 140.55700591418218 + ], + "distanceFromStart":1.5 + }, + { + "elevation":[ + 357.42992871175124, + 385.92155620623635 + ], + "pace":[ + 395.16168913839374, + 404.60294066527558 + ], + "heartRate":[ + 131.5456052446734, + 134.65984504627627 + ], + "distanceFromStart":1.875 + }, + { + "elevation":[ + 345.47736721935661, + 363.18776661379422 + ], + "pace":[ + 340.82303041339082, + 404.71689228682374 + ], + "heartRate":[ + 125.1949698433959, + 131.31354363122026 + ], + "distanceFromStart":2.25 + }, + { + "elevation":[ + 346.23343025200535, + 497.23376445462401 + ], + "pace":[ + 261.27629148816021, + 331.68516208719467 + ], + "heartRate":[ + 131.67810544238606, + 154.26779645311458 + ], + "distanceFromStart":2.625 + }, + { + "elevation":[ + 491.57378483134391, + 547.49535224251053 + ], + "pace":[ + 296.05298644112088, + 401.14092967732398 + ], + "heartRate":[ + 151.36398089694217, + 166.20454793289232 + ], + "distanceFromStart":3 + }, + { + "elevation":[ + 472.06803233416338, + 531.92570520228401 + ], + "pace":[ + 395.50830663514012, + 401.67837917543591 + ], + "heartRate":[ + 134.41798110234078, + 151.90886697564241 + ], + "distanceFromStart":3.375 + }, + { + "elevation":[ + 339.81419476005283, + 461.03832527824829 + ], + "pace":[ + 395.31160487975183, + 404.49550455974907 + ], + "heartRate":[ + 129.97753472415462, + 138.13531094848992 + ], + "distanceFromStart":3.75 + }, + { + "elevation":[ + 303.1495508565697, + 342.3532820173541 + ], + "pace":[ + 395.02844559698116, + 402.65878340653796 + ], + "heartRate":[ + 127.72304232462609, + 133.26322270764186 + ], + "distanceFromStart":4.125 + } + ] + }, + { + "name":"Lonesome Ridge Trail", + "id":1004, + "distance":4.5, + "difficulty":3, + "observations":[ + { + "elevation":[ + 291.65263635636268, + 309.26016677925196 + ], + "pace":[ + 396.08716481908732, + 403.68937873525232 + ], + "heartRate":[ + 117.16351898665887, + 121.95815455919609 + ], + "distanceFromStart":0 + }, + { + "elevation":[ + 299.24001936628116, + 317.44584350790012 + ], + "pace":[ + 380.19020240756623, + 395.3978319010256 + ], + "heartRate":[ + 117.6410892152911, + 124.82185220506081 + ], + "distanceFromStart":0.375 + }, + { + "elevation":[ + 303.62145464574394, + 336.05569457646544 + ], + "pace":[ + 380.55927782266116, + 397.60789726832775 + ], + "heartRate":[ + 121.52696452049059, + 127.31525441110122 + ], + "distanceFromStart":0.75 + }, + { + "elevation":[ + 319.90393365162629, + 346.26966025518789 + ], + "pace":[ + 357.94116421258531, + 398.0750288648062 + ], + "heartRate":[ + 123.75908585923588, + 132.77069404486801 + ], + "distanceFromStart":1.125 + }, + { + "elevation":[ + 354.17104439267905, + 403.57031216972939 + ], + "pace":[ + 335.07385149392701, + 397.82674381875808 + ], + "heartRate":[ + 130.8235194572915, + 140.55700591418218 + ], + "distanceFromStart":1.5 + }, + { + "elevation":[ + 357.42992871175124, + 385.92155620623635 + ], + "pace":[ + 395.16168913839374, + 404.60294066527558 + ], + "heartRate":[ + 131.5456052446734, + 134.65984504627627 + ], + "distanceFromStart":1.875 + }, + { + "elevation":[ + 345.47736721935661, + 363.18776661379422 + ], + "pace":[ + 340.82303041339082, + 404.71689228682374 + ], + "heartRate":[ + 125.1949698433959, + 131.31354363122026 + ], + "distanceFromStart":2.25 + }, + { + "elevation":[ + 346.23343025200535, + 497.23376445462401 + ], + "pace":[ + 261.27629148816021, + 331.68516208719467 + ], + "heartRate":[ + 131.67810544238606, + 154.26779645311458 + ], + "distanceFromStart":2.625 + }, + { + "elevation":[ + 491.57378483134391, + 547.49535224251053 + ], + "pace":[ + 296.05298644112088, + 401.14092967732398 + ], + "heartRate":[ + 151.36398089694217, + 166.20454793289232 + ], + "distanceFromStart":3 + }, + { + "elevation":[ + 472.06803233416338, + 531.92570520228401 + ], + "pace":[ + 395.50830663514012, + 401.67837917543591 + ], + "heartRate":[ + 134.41798110234078, + 151.90886697564241 + ], + "distanceFromStart":3.375 + }, + { + "elevation":[ + 339.81419476005283, + 461.03832527824829 + ], + "pace":[ + 395.31160487975183, + 404.49550455974907 + ], + "heartRate":[ + 129.97753472415462, + 138.13531094848992 + ], + "distanceFromStart":3.75 + }, + { + "elevation":[ + 303.1495508565697, + 342.3532820173541 + ], + "pace":[ + 395.02844559698116, + 402.65878340653796 + ], + "heartRate":[ + 127.72304232462609, + 133.26322270764186 + ], + "distanceFromStart":4.125 + } + ] + }, + { + "name":"Lonesome Ridge Trail", + "id":1005, + "distance":4.5, + "difficulty":3, + "observations":[ + { + "elevation":[ + 291.65263635636268, + 309.26016677925196 + ], + "pace":[ + 396.08716481908732, + 403.68937873525232 + ], + "heartRate":[ + 117.16351898665887, + 121.95815455919609 + ], + "distanceFromStart":0 + }, + { + "elevation":[ + 299.24001936628116, + 317.44584350790012 + ], + "pace":[ + 380.19020240756623, + 395.3978319010256 + ], + "heartRate":[ + 117.6410892152911, + 124.82185220506081 + ], + "distanceFromStart":0.375 + }, + { + "elevation":[ + 303.62145464574394, + 336.05569457646544 + ], + "pace":[ + 380.55927782266116, + 397.60789726832775 + ], + "heartRate":[ + 121.52696452049059, + 127.31525441110122 + ], + "distanceFromStart":0.75 + }, + { + "elevation":[ + 319.90393365162629, + 346.26966025518789 + ], + "pace":[ + 357.94116421258531, + 398.0750288648062 + ], + "heartRate":[ + 123.75908585923588, + 132.77069404486801 + ], + "distanceFromStart":1.125 + }, + { + "elevation":[ + 354.17104439267905, + 403.57031216972939 + ], + "pace":[ + 335.07385149392701, + 397.82674381875808 + ], + "heartRate":[ + 130.8235194572915, + 140.55700591418218 + ], + "distanceFromStart":1.5 + }, + { + "elevation":[ + 357.42992871175124, + 385.92155620623635 + ], + "pace":[ + 395.16168913839374, + 404.60294066527558 + ], + "heartRate":[ + 131.5456052446734, + 134.65984504627627 + ], + "distanceFromStart":1.875 + }, + { + "elevation":[ + 345.47736721935661, + 363.18776661379422 + ], + "pace":[ + 340.82303041339082, + 404.71689228682374 + ], + "heartRate":[ + 125.1949698433959, + 131.31354363122026 + ], + "distanceFromStart":2.25 + }, + { + "elevation":[ + 346.23343025200535, + 497.23376445462401 + ], + "pace":[ + 261.27629148816021, + 331.68516208719467 + ], + "heartRate":[ + 131.67810544238606, + 154.26779645311458 + ], + "distanceFromStart":2.625 + }, + { + "elevation":[ + 491.57378483134391, + 547.49535224251053 + ], + "pace":[ + 296.05298644112088, + 401.14092967732398 + ], + "heartRate":[ + 151.36398089694217, + 166.20454793289232 + ], + "distanceFromStart":3 + }, + { + "elevation":[ + 472.06803233416338, + 531.92570520228401 + ], + "pace":[ + 395.50830663514012, + 401.67837917543591 + ], + "heartRate":[ + 134.41798110234078, + 151.90886697564241 + ], + "distanceFromStart":3.375 + }, + { + "elevation":[ + 339.81419476005283, + 461.03832527824829 + ], + "pace":[ + 395.31160487975183, + 404.49550455974907 + ], + "heartRate":[ + 129.97753472415462, + 138.13531094848992 + ], + "distanceFromStart":3.75 + }, + { + "elevation":[ + 303.1495508565697, + 342.3532820173541 + ], + "pace":[ + 395.02844559698116, + 402.65878340653796 + ], + "heartRate":[ + 127.72304232462609, + 133.26322270764186 + ], + "distanceFromStart":4.125 + } + ] + }, + { + "name":"Lonesome Ridge Trail", + "id":1006, + "distance":4.5, + "difficulty":3, + "observations":[ + { + "elevation":[ + 291.65263635636268, + 309.26016677925196 + ], + "pace":[ + 396.08716481908732, + 403.68937873525232 + ], + "heartRate":[ + 117.16351898665887, + 121.95815455919609 + ], + "distanceFromStart":0 + }, + { + "elevation":[ + 299.24001936628116, + 317.44584350790012 + ], + "pace":[ + 380.19020240756623, + 395.3978319010256 + ], + "heartRate":[ + 117.6410892152911, + 124.82185220506081 + ], + "distanceFromStart":0.375 + }, + { + "elevation":[ + 303.62145464574394, + 336.05569457646544 + ], + "pace":[ + 380.55927782266116, + 397.60789726832775 + ], + "heartRate":[ + 121.52696452049059, + 127.31525441110122 + ], + "distanceFromStart":0.75 + }, + { + "elevation":[ + 319.90393365162629, + 346.26966025518789 + ], + "pace":[ + 357.94116421258531, + 398.0750288648062 + ], + "heartRate":[ + 123.75908585923588, + 132.77069404486801 + ], + "distanceFromStart":1.125 + }, + { + "elevation":[ + 354.17104439267905, + 403.57031216972939 + ], + "pace":[ + 335.07385149392701, + 397.82674381875808 + ], + "heartRate":[ + 130.8235194572915, + 140.55700591418218 + ], + "distanceFromStart":1.5 + }, + { + "elevation":[ + 357.42992871175124, + 385.92155620623635 + ], + "pace":[ + 395.16168913839374, + 404.60294066527558 + ], + "heartRate":[ + 131.5456052446734, + 134.65984504627627 + ], + "distanceFromStart":1.875 + }, + { + "elevation":[ + 345.47736721935661, + 363.18776661379422 + ], + "pace":[ + 340.82303041339082, + 404.71689228682374 + ], + "heartRate":[ + 125.1949698433959, + 131.31354363122026 + ], + "distanceFromStart":2.25 + }, + { + "elevation":[ + 346.23343025200535, + 497.23376445462401 + ], + "pace":[ + 261.27629148816021, + 331.68516208719467 + ], + "heartRate":[ + 131.67810544238606, + 154.26779645311458 + ], + "distanceFromStart":2.625 + }, + { + "elevation":[ + 491.57378483134391, + 547.49535224251053 + ], + "pace":[ + 296.05298644112088, + 401.14092967732398 + ], + "heartRate":[ + 151.36398089694217, + 166.20454793289232 + ], + "distanceFromStart":3 + }, + { + "elevation":[ + 472.06803233416338, + 531.92570520228401 + ], + "pace":[ + 395.50830663514012, + 401.67837917543591 + ], + "heartRate":[ + 134.41798110234078, + 151.90886697564241 + ], + "distanceFromStart":3.375 + }, + { + "elevation":[ + 339.81419476005283, + 461.03832527824829 + ], + "pace":[ + 395.31160487975183, + 404.49550455974907 + ], + "heartRate":[ + 129.97753472415462, + 138.13531094848992 + ], + "distanceFromStart":3.75 + }, + { + "elevation":[ + 303.1495508565697, + 342.3532820173541 + ], + "pace":[ + 395.02844559698116, + 402.65878340653796 + ], + "heartRate":[ + 127.72304232462609, + 133.26322270764186 + ], + "distanceFromStart":4.125 + } + ] + }, + { + "name":"Lonesome Ridge Trail", + "id":1007, + "distance":4.5, + "difficulty":3, + "observations":[ + { + "elevation":[ + 291.65263635636268, + 309.26016677925196 + ], + "pace":[ + 396.08716481908732, + 403.68937873525232 + ], + "heartRate":[ + 117.16351898665887, + 121.95815455919609 + ], + "distanceFromStart":0 + }, + { + "elevation":[ + 299.24001936628116, + 317.44584350790012 + ], + "pace":[ + 380.19020240756623, + 395.3978319010256 + ], + "heartRate":[ + 117.6410892152911, + 124.82185220506081 + ], + "distanceFromStart":0.375 + }, + { + "elevation":[ + 303.62145464574394, + 336.05569457646544 + ], + "pace":[ + 380.55927782266116, + 397.60789726832775 + ], + "heartRate":[ + 121.52696452049059, + 127.31525441110122 + ], + "distanceFromStart":0.75 + }, + { + "elevation":[ + 319.90393365162629, + 346.26966025518789 + ], + "pace":[ + 357.94116421258531, + 398.0750288648062 + ], + "heartRate":[ + 123.75908585923588, + 132.77069404486801 + ], + "distanceFromStart":1.125 + }, + { + "elevation":[ + 354.17104439267905, + 403.57031216972939 + ], + "pace":[ + 335.07385149392701, + 397.82674381875808 + ], + "heartRate":[ + 130.8235194572915, + 140.55700591418218 + ], + "distanceFromStart":1.5 + }, + { + "elevation":[ + 357.42992871175124, + 385.92155620623635 + ], + "pace":[ + 395.16168913839374, + 404.60294066527558 + ], + "heartRate":[ + 131.5456052446734, + 134.65984504627627 + ], + "distanceFromStart":1.875 + }, + { + "elevation":[ + 345.47736721935661, + 363.18776661379422 + ], + "pace":[ + 340.82303041339082, + 404.71689228682374 + ], + "heartRate":[ + 125.1949698433959, + 131.31354363122026 + ], + "distanceFromStart":2.25 + }, + { + "elevation":[ + 346.23343025200535, + 497.23376445462401 + ], + "pace":[ + 261.27629148816021, + 331.68516208719467 + ], + "heartRate":[ + 131.67810544238606, + 154.26779645311458 + ], + "distanceFromStart":2.625 + }, + { + "elevation":[ + 491.57378483134391, + 547.49535224251053 + ], + "pace":[ + 296.05298644112088, + 401.14092967732398 + ], + "heartRate":[ + 151.36398089694217, + 166.20454793289232 + ], + "distanceFromStart":3 + }, + { + "elevation":[ + 472.06803233416338, + 531.92570520228401 + ], + "pace":[ + 395.50830663514012, + 401.67837917543591 + ], + "heartRate":[ + 134.41798110234078, + 151.90886697564241 + ], + "distanceFromStart":3.375 + }, + { + "elevation":[ + 339.81419476005283, + 461.03832527824829 + ], + "pace":[ + 395.31160487975183, + 404.49550455974907 + ], + "heartRate":[ + 129.97753472415462, + 138.13531094848992 + ], + "distanceFromStart":3.75 + }, + { + "elevation":[ + 303.1495508565697, + 342.3532820173541 + ], + "pace":[ + 395.02844559698116, + 402.65878340653796 + ], + "heartRate":[ + 127.72304232462609, + 133.26322270764186 + ], + "distanceFromStart":4.125 + } + ] + }, + { + "name":"Lonesome Ridge Trail", + "id":1008, + "distance":4.5, + "difficulty":3, + "observations":[ + { + "elevation":[ + 291.65263635636268, + 309.26016677925196 + ], + "pace":[ + 396.08716481908732, + 403.68937873525232 + ], + "heartRate":[ + 117.16351898665887, + 121.95815455919609 + ], + "distanceFromStart":0 + }, + { + "elevation":[ + 299.24001936628116, + 317.44584350790012 + ], + "pace":[ + 380.19020240756623, + 395.3978319010256 + ], + "heartRate":[ + 117.6410892152911, + 124.82185220506081 + ], + "distanceFromStart":0.375 + }, + { + "elevation":[ + 303.62145464574394, + 336.05569457646544 + ], + "pace":[ + 380.55927782266116, + 397.60789726832775 + ], + "heartRate":[ + 121.52696452049059, + 127.31525441110122 + ], + "distanceFromStart":0.75 + }, + { + "elevation":[ + 319.90393365162629, + 346.26966025518789 + ], + "pace":[ + 357.94116421258531, + 398.0750288648062 + ], + "heartRate":[ + 123.75908585923588, + 132.77069404486801 + ], + "distanceFromStart":1.125 + }, + { + "elevation":[ + 354.17104439267905, + 403.57031216972939 + ], + "pace":[ + 335.07385149392701, + 397.82674381875808 + ], + "heartRate":[ + 130.8235194572915, + 140.55700591418218 + ], + "distanceFromStart":1.5 + }, + { + "elevation":[ + 357.42992871175124, + 385.92155620623635 + ], + "pace":[ + 395.16168913839374, + 404.60294066527558 + ], + "heartRate":[ + 131.5456052446734, + 134.65984504627627 + ], + "distanceFromStart":1.875 + }, + { + "elevation":[ + 345.47736721935661, + 363.18776661379422 + ], + "pace":[ + 340.82303041339082, + 404.71689228682374 + ], + "heartRate":[ + 125.1949698433959, + 131.31354363122026 + ], + "distanceFromStart":2.25 + }, + { + "elevation":[ + 346.23343025200535, + 497.23376445462401 + ], + "pace":[ + 261.27629148816021, + 331.68516208719467 + ], + "heartRate":[ + 131.67810544238606, + 154.26779645311458 + ], + "distanceFromStart":2.625 + }, + { + "elevation":[ + 491.57378483134391, + 547.49535224251053 + ], + "pace":[ + 296.05298644112088, + 401.14092967732398 + ], + "heartRate":[ + 151.36398089694217, + 166.20454793289232 + ], + "distanceFromStart":3 + }, + { + "elevation":[ + 472.06803233416338, + 531.92570520228401 + ], + "pace":[ + 395.50830663514012, + 401.67837917543591 + ], + "heartRate":[ + 134.41798110234078, + 151.90886697564241 + ], + "distanceFromStart":3.375 + }, + { + "elevation":[ + 339.81419476005283, + 461.03832527824829 + ], + "pace":[ + 395.31160487975183, + 404.49550455974907 + ], + "heartRate":[ + 129.97753472415462, + 138.13531094848992 + ], + "distanceFromStart":3.75 + }, + { + "elevation":[ + 303.1495508565697, + 342.3532820173541 + ], + "pace":[ + 395.02844559698116, + 402.65878340653796 + ], + "heartRate":[ + 127.72304232462609, + 133.26322270764186 + ], + "distanceFromStart":4.125 + } + ] + }, + { + "name":"Lonesome Ridge Trail", + "id":1009, + "distance":4.5, + "difficulty":3, + "observations":[ + { + "elevation":[ + 291.65263635636268, + 309.26016677925196 + ], + "pace":[ + 396.08716481908732, + 403.68937873525232 + ], + "heartRate":[ + 117.16351898665887, + 121.95815455919609 + ], + "distanceFromStart":0 + }, + { + "elevation":[ + 299.24001936628116, + 317.44584350790012 + ], + "pace":[ + 380.19020240756623, + 395.3978319010256 + ], + "heartRate":[ + 117.6410892152911, + 124.82185220506081 + ], + "distanceFromStart":0.375 + }, + { + "elevation":[ + 303.62145464574394, + 336.05569457646544 + ], + "pace":[ + 380.55927782266116, + 397.60789726832775 + ], + "heartRate":[ + 121.52696452049059, + 127.31525441110122 + ], + "distanceFromStart":0.75 + }, + { + "elevation":[ + 319.90393365162629, + 346.26966025518789 + ], + "pace":[ + 357.94116421258531, + 398.0750288648062 + ], + "heartRate":[ + 123.75908585923588, + 132.77069404486801 + ], + "distanceFromStart":1.125 + }, + { + "elevation":[ + 354.17104439267905, + 403.57031216972939 + ], + "pace":[ + 335.07385149392701, + 397.82674381875808 + ], + "heartRate":[ + 130.8235194572915, + 140.55700591418218 + ], + "distanceFromStart":1.5 + }, + { + "elevation":[ + 357.42992871175124, + 385.92155620623635 + ], + "pace":[ + 395.16168913839374, + 404.60294066527558 + ], + "heartRate":[ + 131.5456052446734, + 134.65984504627627 + ], + "distanceFromStart":1.875 + }, + { + "elevation":[ + 345.47736721935661, + 363.18776661379422 + ], + "pace":[ + 340.82303041339082, + 404.71689228682374 + ], + "heartRate":[ + 125.1949698433959, + 131.31354363122026 + ], + "distanceFromStart":2.25 + }, + { + "elevation":[ + 346.23343025200535, + 497.23376445462401 + ], + "pace":[ + 261.27629148816021, + 331.68516208719467 + ], + "heartRate":[ + 131.67810544238606, + 154.26779645311458 + ], + "distanceFromStart":2.625 + }, + { + "elevation":[ + 491.57378483134391, + 547.49535224251053 + ], + "pace":[ + 296.05298644112088, + 401.14092967732398 + ], + "heartRate":[ + 151.36398089694217, + 166.20454793289232 + ], + "distanceFromStart":3 + }, + { + "elevation":[ + 472.06803233416338, + 531.92570520228401 + ], + "pace":[ + 395.50830663514012, + 401.67837917543591 + ], + "heartRate":[ + 134.41798110234078, + 151.90886697564241 + ], + "distanceFromStart":3.375 + }, + { + "elevation":[ + 339.81419476005283, + 461.03832527824829 + ], + "pace":[ + 395.31160487975183, + 404.49550455974907 + ], + "heartRate":[ + 129.97753472415462, + 138.13531094848992 + ], + "distanceFromStart":3.75 + }, + { + "elevation":[ + 303.1495508565697, + 342.3532820173541 + ], + "pace":[ + 395.02844559698116, + 402.65878340653796 + ], + "heartRate":[ + 127.72304232462609, + 133.26322270764186 + ], + "distanceFromStart":4.125 + } + ] + }, + { + "name":"Lonesome Ridge Trail", + "id":1010, + "distance":4.5, + "difficulty":3, + "observations":[ + { + "elevation":[ + 291.65263635636268, + 309.26016677925196 + ], + "pace":[ + 396.08716481908732, + 403.68937873525232 + ], + "heartRate":[ + 117.16351898665887, + 121.95815455919609 + ], + "distanceFromStart":0 + }, + { + "elevation":[ + 299.24001936628116, + 317.44584350790012 + ], + "pace":[ + 380.19020240756623, + 395.3978319010256 + ], + "heartRate":[ + 117.6410892152911, + 124.82185220506081 + ], + "distanceFromStart":0.375 + }, + { + "elevation":[ + 303.62145464574394, + 336.05569457646544 + ], + "pace":[ + 380.55927782266116, + 397.60789726832775 + ], + "heartRate":[ + 121.52696452049059, + 127.31525441110122 + ], + "distanceFromStart":0.75 + }, + { + "elevation":[ + 319.90393365162629, + 346.26966025518789 + ], + "pace":[ + 357.94116421258531, + 398.0750288648062 + ], + "heartRate":[ + 123.75908585923588, + 132.77069404486801 + ], + "distanceFromStart":1.125 + }, + { + "elevation":[ + 354.17104439267905, + 403.57031216972939 + ], + "pace":[ + 335.07385149392701, + 397.82674381875808 + ], + "heartRate":[ + 130.8235194572915, + 140.55700591418218 + ], + "distanceFromStart":1.5 + }, + { + "elevation":[ + 357.42992871175124, + 385.92155620623635 + ], + "pace":[ + 395.16168913839374, + 404.60294066527558 + ], + "heartRate":[ + 131.5456052446734, + 134.65984504627627 + ], + "distanceFromStart":1.875 + }, + { + "elevation":[ + 345.47736721935661, + 363.18776661379422 + ], + "pace":[ + 340.82303041339082, + 404.71689228682374 + ], + "heartRate":[ + 125.1949698433959, + 131.31354363122026 + ], + "distanceFromStart":2.25 + }, + { + "elevation":[ + 346.23343025200535, + 497.23376445462401 + ], + "pace":[ + 261.27629148816021, + 331.68516208719467 + ], + "heartRate":[ + 131.67810544238606, + 154.26779645311458 + ], + "distanceFromStart":2.625 + }, + { + "elevation":[ + 491.57378483134391, + 547.49535224251053 + ], + "pace":[ + 296.05298644112088, + 401.14092967732398 + ], + "heartRate":[ + 151.36398089694217, + 166.20454793289232 + ], + "distanceFromStart":3 + }, + { + "elevation":[ + 472.06803233416338, + 531.92570520228401 + ], + "pace":[ + 395.50830663514012, + 401.67837917543591 + ], + "heartRate":[ + 134.41798110234078, + 151.90886697564241 + ], + "distanceFromStart":3.375 + }, + { + "elevation":[ + 339.81419476005283, + 461.03832527824829 + ], + "pace":[ + 395.31160487975183, + 404.49550455974907 + ], + "heartRate":[ + 129.97753472415462, + 138.13531094848992 + ], + "distanceFromStart":3.75 + }, + { + "elevation":[ + 303.1495508565697, + 342.3532820173541 + ], + "pace":[ + 395.02844559698116, + 402.65878340653796 + ], + "heartRate":[ + 127.72304232462609, + 133.26322270764186 + ], + "distanceFromStart":4.125 + } + ] + } +] diff --git a/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Resources/icybay.jpg b/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Resources/icybay.jpg new file mode 100644 index 0000000..feb1764 Binary files /dev/null and b/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Resources/icybay.jpg differ diff --git a/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Resources/lakemcdonald.jpg b/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Resources/lakemcdonald.jpg new file mode 100644 index 0000000..bd9d6b9 Binary files /dev/null and b/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Resources/lakemcdonald.jpg differ diff --git a/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Resources/landmarkData.json b/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Resources/landmarkData.json new file mode 100644 index 0000000..e5b14fc --- /dev/null +++ b/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Resources/landmarkData.json @@ -0,0 +1,182 @@ +[ + { + "name": "Turtle Rock", + "category": "Rivers", + "city": "Twentynine Palms", + "state": "California", + "id": 1001, + "isFeatured": true, + "isFavorite": true, + "park": "Joshua Tree National Park", + "coordinates": { + "longitude": -116.166868, + "latitude": 34.011286 + }, + "imageName": "turtlerock" + }, + { + "name": "Silver Salmon Creek", + "category": "Lakes", + "city": "Port Alsworth", + "state": "Alaska", + "id": 1002, + "isFeatured": false, + "isFavorite": false, + "park": "Lake Clark National Park and Preserve", + "coordinates": { + "longitude": -152.665167, + "latitude": 59.980167 + }, + "imageName": "silversalmoncreek" + }, + { + "name": "Chilkoot Trail", + "category": "Mountains", + "city": "Skagway", + "state": "Alaska", + "id": 1003, + "isFeatured": false, + "isFavorite": true, + "park": "Klondike Gold Rush National Historical Park", + "coordinates": { + "longitude": -135.334571, + "latitude": 59.560551 + }, + "imageName": "chilkoottrail" + }, + { + "name": "St. Mary Lake", + "category": "Lakes", + "city": "Browning", + "state": "Montana", + "id": 1004, + "isFeatured": true, + "isFavorite": true, + "park": "Glacier National Park", + "coordinates": { + "longitude": -113.536248, + "latitude": 48.69423 + }, + "imageName": "stmarylake" + }, + { + "name": "Twin Lake", + "category": "Lakes", + "city": "Twin Lakes", + "state": "Alaska", + "id": 1005, + "isFeatured": false, + "isFavorite": false, + "park": "Lake Clark National Park and Preserve", + "coordinates": { + "longitude": -153.849883, + "latitude": 60.641684 + }, + "imageName": "twinlake" + }, + { + "name": "Lake McDonald", + "category": "Mountains", + "city": "West Glacier", + "state": "Montana", + "id": 1006, + "isFeatured": false, + "isFavorite": false, + "park": "Glacier National Park", + "coordinates": { + "longitude": -113.934831, + "latitude": 48.56002 + }, + "imageName": "lakemcdonald" + }, + { + "name": "Charley Rivers", + "category": "Rivers", + "city": "Eaking", + "state": "Alaska", + "id": 1007, + "isFeatured": true, + "isFavorite": false, + "park": "Charley Rivers National Preserve", + "coordinates": { + "longitude": -143.122586, + "latitude": 65.350021 + }, + "imageName": "charleyrivers", + }, + { + "name": "Icy Bay", + "category": "Mountains", + "city": "Icy Bay", + "state": "Alaska", + "id": 1008, + "isFeatured": false, + "isFavorite": false, + "park": "Wrangell-St. Elias National Park and Preserve", + "coordinates": { + "longitude": -141.518167, + "latitude": 60.089917 + }, + "imageName": "icybay" + }, + { + "name": "Rainbow Lake", + "category": "Lakes", + "city": "Willow", + "state": "Alaska", + "id": 1009, + "isFeatured": false, + "isFavorite": false, + "park": "State Recreation Area", + "coordinates": { + "longitude": -150.086103, + "latitude": 61.694334 + }, + "imageName": "rainbowlake" + }, + { + "name": "Hidden Lake", + "category": "Lakes", + "city": "Newhalem", + "state": "Washington", + "id": 1010, + "isFeatured": false, + "isFavorite": false, + "park": "North Cascades National Park", + "coordinates": { + "longitude": -121.17799, + "latitude": 48.495442 + }, + "imageName": "hiddenlake" + }, + { + "name": "Chincoteague", + "category": "Rivers", + "city": "Chincoteague", + "state": "Virginia", + "id": 1011, + "isFeatured": false, + "isFavorite": false, + "park": "Chincoteague National Wildlife Refuge", + "coordinates": { + "longitude": -75.383212, + "latitude": 37.91531 + }, + "imageName": "chincoteague" + }, + { + "name": "Lake Umbagog", + "category": "Lakes", + "city": "Errol", + "state": "New Hampshire", + "id": 1012, + "isFeatured": true, + "isFavorite": false, + "park": "Umbagog National Wildlife Refuge", + "coordinates": { + "longitude": -71.056816, + "latitude": 44.747408 + }, + "imageName": "umbagog" + } +] diff --git a/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Resources/rainbowlake.jpg b/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Resources/rainbowlake.jpg new file mode 100644 index 0000000..6da43dd Binary files /dev/null and b/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Resources/rainbowlake.jpg differ diff --git a/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Resources/silversalmoncreek.jpg b/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Resources/silversalmoncreek.jpg new file mode 100644 index 0000000..f657532 Binary files /dev/null and b/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Resources/silversalmoncreek.jpg differ diff --git a/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Resources/stmarylake.jpg b/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Resources/stmarylake.jpg new file mode 100644 index 0000000..1c71de4 Binary files /dev/null and b/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Resources/stmarylake.jpg differ diff --git a/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Resources/turtlerock.jpg b/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Resources/turtlerock.jpg new file mode 100644 index 0000000..f7a6e6d Binary files /dev/null and b/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Resources/turtlerock.jpg differ diff --git a/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Resources/twinlake.jpg b/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Resources/twinlake.jpg new file mode 100644 index 0000000..3e7a57c Binary files /dev/null and b/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Resources/twinlake.jpg differ diff --git a/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Resources/umbagog.jpg b/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Resources/umbagog.jpg new file mode 100644 index 0000000..56291c6 Binary files /dev/null and b/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Resources/umbagog.jpg differ diff --git a/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/SceneDelegate.swift b/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/SceneDelegate.swift new file mode 100644 index 0000000..0f5f17e --- /dev/null +++ b/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/SceneDelegate.swift @@ -0,0 +1,56 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +The scene delegate. +*/ + +import UIKit +import SwiftUI + +class SceneDelegate: UIResponder, UIWindowSceneDelegate { + + var window: UIWindow? + + func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { + // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`. + // If using a storyboard, the `window` property will automatically be initialized and attached to the scene. + // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead). + + // Use a UIHostingController as window root view controller + let window = UIWindow(frame: UIScreen.main.bounds) + window.rootViewController = UIHostingController(rootView: CategoryHome().environmentObject(UserData())) + self.window = window + window.makeKeyAndVisible() + } + + func sceneDidDisconnect(_ scene: UIScene) { + // Called as the scene is being released by the system. + // This occurs shortly after the scene enters the background, or when its session is discarded. + // Release any resources associated with this scene that can be re-created the next time the scene connects. + // The scene may re-connect later, as its session was not neccessarily discarded (see `application:didDiscardSceneSessions` instead). + } + + func sceneDidBecomeActive(_ scene: UIScene) { + // Called when the scene has moved from an inactive state to an active state. + // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive. + } + + func sceneWillResignActive(_ scene: UIScene) { + // Called when the scene will move from an active state to an inactive state. + // This may occur due to temporary interruptions (ex. an incoming phone call). + } + + func sceneWillEnterForeground(_ scene: UIScene) { + // Called as the scene transitions from the background to the foreground. + // Use this method to undo the changes made on entering the background. + } + + func sceneDidEnterBackground(_ scene: UIScene) { + // Called as the scene transitions from the foreground to the background. + // Use this method to save data, release shared resources, and store enough scene-specific state information + // to restore the scene back to its current state. + } + +} + diff --git a/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Supporting Views/Badge.swift b/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Supporting Views/Badge.swift new file mode 100644 index 0000000..59f03b2 --- /dev/null +++ b/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Supporting Views/Badge.swift @@ -0,0 +1,41 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A view that displays a badge. +*/ + +import SwiftUI + +struct Badge: View { + static let rotationCount = 8 + + var badgeSymbols: some View { + ForEach(0.. + var overallRange: Range + + var heightRatio: Length { + max(Length(magnitude(of: range) / magnitude(of: overallRange)), 0.15) + } + + var offsetRatio: Length { + Length((range.lowerBound - overallRange.lowerBound) / magnitude(of: overallRange)) + } + + var animation: Animation { + Animation.spring(initialVelocity: 5) + .speed(2) + .delay(0.03 * Double(index)) + } + + var body: some View { + Capsule() + .fill(Color.white) + .frame(height: height * heightRatio, alignment: .bottom) + .offset(x: 0, y: height * -offsetRatio) + .animation(animation) + } +} + +#if DEBUG +struct GraphCapsule_Previews: PreviewProvider { + static var previews: some View { + GraphCapsule(index: 0, height: 150, range: 10..<50, overallRange: 0..<100) + } +} +#endif diff --git a/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Supporting Views/HikeGraph.swift b/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Supporting Views/HikeGraph.swift new file mode 100644 index 0000000..7df5194 --- /dev/null +++ b/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Supporting Views/HikeGraph.swift @@ -0,0 +1,74 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +The elevation, heart rate, and pace of a hike plotted on a graph. +*/ + +import SwiftUI + +func rangeOfRanges(_ ranges: C) -> Range + where C.Element == Range { + guard !ranges.isEmpty else { return 0..<0 } + let low = ranges.lazy.map { $0.lowerBound }.min()! + let high = ranges.lazy.map { $0.upperBound }.max()! + return low..) -> Double { + return range.upperBound - range.lowerBound +} + +struct HikeGraph: View { + var hike: Hike + var path: KeyPath> + + var color: Color { + switch path { + case \.elevation: + return .gray + case \.heartRate: + return Color(hue: 0, saturation: 0.5, brightness: 0.7) + case \.pace: + return Color(hue: 0.7, saturation: 0.4, brightness: 0.7) + default: + return .black + } + } + + var body: some View { + let data = hike.observations + let overallRange = rangeOfRanges(data.lazy.map { $0[keyPath: self.path] }) + let maxMagnitude = data.map { magnitude(of: $0[keyPath: path]) }.max()! + let heightRatio = 1 - Length(maxMagnitude / magnitude(of: overallRange)) + + return GeometryReader { proxy in + HStack(alignment: .bottom, spacing: proxy.size.width / 120) { + ForEach(data.indices) { index in + GraphCapsule( + index: index, + height: proxy.size.height, + range: data[index][keyPath: self.path], + overallRange: overallRange) + .colorMultiply(self.color) + } + .offset(x: 0, y: proxy.size.height * heightRatio) + } + } + } +} + +#if DEBUG +struct HikeGraph_Previews: PreviewProvider { + static var previews: some View { + Group { + HikeGraph(hike: hikeData[0], path: \.elevation) + .frame(height: 200) + HikeGraph(hike: hikeData[0], path: \.heartRate) + .frame(height: 200) + HikeGraph(hike: hikeData[0], path: \.pace) + .frame(height: 200) + } + } +} +#endif diff --git a/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Supporting Views/LandmarkRow.swift b/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Supporting Views/LandmarkRow.swift new file mode 100644 index 0000000..2f8110c --- /dev/null +++ b/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Supporting Views/LandmarkRow.swift @@ -0,0 +1,38 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A single row to be displayed in a list of landmarks. +*/ + +import SwiftUI + +struct LandmarkRow: View { + var landmark: Landmark + + var body: some View { + HStack { + landmark.image(forSize: 50) + Text(verbatim: landmark.name) + Spacer() + + if landmark.isFavorite { + Image(systemName: "star.fill") + .imageScale(.medium) + .foregroundColor(.yellow) + } + } + } +} + +#if DEBUG +struct LandmarkRow_Previews: PreviewProvider { + static var previews: some View { + Group { + LandmarkRow(landmark: landmarkData[0]) + LandmarkRow(landmark: landmarkData[1]) + } + .previewLayout(.fixed(width: 300, height: 70)) + } +} +#endif diff --git a/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Supporting Views/MapView.swift b/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Supporting Views/MapView.swift new file mode 100644 index 0000000..5a8c64b --- /dev/null +++ b/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Supporting Views/MapView.swift @@ -0,0 +1,31 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A view that hosts an `MKMapView`. +*/ + +import SwiftUI +import MapKit + +struct MapView: UIViewRepresentable { + var coordinate: CLLocationCoordinate2D + + func makeUIView(context: Context) -> MKMapView { + MKMapView(frame: .zero) + } + + func updateUIView(_ view: MKMapView, context: Context) { + let span = MKCoordinateSpan(latitudeDelta: 0.02, longitudeDelta: 0.02) + let region = MKCoordinateRegion(center: coordinate, span: span) + view.setRegion(region, animated: true) + } +} + +#if DEBUG +struct MapView_Previews: PreviewProvider { + static var previews: some View { + MapView(coordinate: landmarkData[0].locationCoordinate) + } +} +#endif diff --git a/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Supporting Views/RotatedBadgeSymbol.swift b/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Supporting Views/RotatedBadgeSymbol.swift new file mode 100644 index 0000000..a7e4b53 --- /dev/null +++ b/Other Projects/Working With UIControls/StartingPoint/Landmarks/Landmarks/Supporting Views/RotatedBadgeSymbol.swift @@ -0,0 +1,26 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A view that displays a rotated version of a badge symbol. +*/ + +import SwiftUI + +struct RotatedBadgeSymbol: View { + let angle: Angle + + var body: some View { + BadgeSymbol() + .padding(-60) + .rotationEffect(angle, anchor: .bottom) + } +} + +#if DEBUG +struct RotatedBadgeSymbol_Previews: PreviewProvider { + static var previews: some View { + RotatedBadgeSymbol(angle: .init(degrees: 5)) + } +} +#endif diff --git a/Other Projects/Working With UIControls/StartingPoint/Landmarks/WorkingWithUIControls.xcodeproj/.xcodesamplecode.plist b/Other Projects/Working With UIControls/StartingPoint/Landmarks/WorkingWithUIControls.xcodeproj/.xcodesamplecode.plist new file mode 100644 index 0000000..5dd5da8 --- /dev/null +++ b/Other Projects/Working With UIControls/StartingPoint/Landmarks/WorkingWithUIControls.xcodeproj/.xcodesamplecode.plist @@ -0,0 +1,5 @@ + + + + + diff --git a/Other Projects/Working With UIControls/StartingPoint/Landmarks/WorkingWithUIControls.xcodeproj/project.pbxproj b/Other Projects/Working With UIControls/StartingPoint/Landmarks/WorkingWithUIControls.xcodeproj/project.pbxproj new file mode 100644 index 0000000..0cffe0c --- /dev/null +++ b/Other Projects/Working With UIControls/StartingPoint/Landmarks/WorkingWithUIControls.xcodeproj/project.pbxproj @@ -0,0 +1,537 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 50; + objects = { + +/* Begin PBXBuildFile section */ + B7310DD1229F6839001079B9 /* HexagonParameters.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7310DD0229F6839001079B9 /* HexagonParameters.swift */; }; + B7310DD3229F6CA9001079B9 /* Badge.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7310DD2229F6CA9001079B9 /* Badge.swift */; }; + B7394866229F194000C47603 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7394865229F194000C47603 /* AppDelegate.swift */; }; + B7394868229F194000C47603 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7394867229F194000C47603 /* SceneDelegate.swift */; }; + B739486A229F194000C47603 /* LandmarkDetail.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7394869229F194000C47603 /* LandmarkDetail.swift */; }; + B739486C229F194200C47603 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B739486B229F194200C47603 /* Assets.xcassets */; }; + B739486F229F194200C47603 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B739486E229F194200C47603 /* Preview Assets.xcassets */; }; + B7394872229F194200C47603 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B7394870229F194200C47603 /* LaunchScreen.storyboard */; }; + B739487A229F1B3F00C47603 /* CircleImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7394879229F1B3F00C47603 /* CircleImage.swift */; }; + B739487C229F1B6800C47603 /* MapView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B739487B229F1B6800C47603 /* MapView.swift */; }; + B7394881229F28B900C47603 /* Landmark.swift in Sources */ = {isa = PBXBuildFile; fileRef = B739487F229F28B900C47603 /* Landmark.swift */; }; + B7394882229F28B900C47603 /* Data.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7394880229F28B900C47603 /* Data.swift */; }; + B7394891229F292F00C47603 /* rainbowlake.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B7394884229F292D00C47603 /* rainbowlake.jpg */; }; + B7394893229F292F00C47603 /* icybay.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B7394886229F292E00C47603 /* icybay.jpg */; }; + B7394894229F292F00C47603 /* lakemcdonald.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B7394887229F292E00C47603 /* lakemcdonald.jpg */; }; + B7394895229F292F00C47603 /* turtlerock.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B7394888229F292E00C47603 /* turtlerock.jpg */; }; + B7394896229F292F00C47603 /* umbagog.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B7394889229F292E00C47603 /* umbagog.jpg */; }; + B7394897229F292F00C47603 /* hiddenlake.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B739488A229F292E00C47603 /* hiddenlake.jpg */; }; + B7394898229F292F00C47603 /* stmarylake.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B739488B229F292E00C47603 /* stmarylake.jpg */; }; + B7394899229F292F00C47603 /* twinlake.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B739488C229F292E00C47603 /* twinlake.jpg */; }; + B739489A229F292F00C47603 /* silversalmoncreek.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B739488D229F292E00C47603 /* silversalmoncreek.jpg */; }; + B739489B229F292F00C47603 /* landmarkData.json in Resources */ = {isa = PBXBuildFile; fileRef = B739488E229F292E00C47603 /* landmarkData.json */; }; + B739489C229F292F00C47603 /* chincoteague.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B739488F229F292F00C47603 /* chincoteague.jpg */; }; + B739489D229F292F00C47603 /* chilkoottrail.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B7394890229F292F00C47603 /* chilkoottrail.jpg */; }; + B739489F229F2D9700C47603 /* LandmarkRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = B739489E229F2D9700C47603 /* LandmarkRow.swift */; }; + B73948A1229F2E1F00C47603 /* LandmarkList.swift in Sources */ = {isa = PBXBuildFile; fileRef = B73948A0229F2E1F00C47603 /* LandmarkList.swift */; }; + B73948A3229F3E2200C47603 /* charleyrivers.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B73948A2229F3E2200C47603 /* charleyrivers.jpg */; }; + B7D2AAC5229F4D7C0061E5F5 /* UserData.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7D2AAC4229F4D7C0061E5F5 /* UserData.swift */; }; + B7D587AE229F7382006E8DCF /* BadgeBackground.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7D587AD229F7382006E8DCF /* BadgeBackground.swift */; }; + B7D587B0229F73C1006E8DCF /* BadgeSymbol.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7D587AF229F73C1006E8DCF /* BadgeSymbol.swift */; }; + B7D587B2229F7406006E8DCF /* RotatedBadgeSymbol.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7D587B1229F7406006E8DCF /* RotatedBadgeSymbol.swift */; }; + B7D587B6229F825D006E8DCF /* HikeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7D587B5229F825D006E8DCF /* HikeView.swift */; }; + B7D587B8229F826D006E8DCF /* GraphCapsule.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7D587B7229F826D006E8DCF /* GraphCapsule.swift */; }; + B7D587BA229F8288006E8DCF /* Hike.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7D587B9229F8288006E8DCF /* Hike.swift */; }; + B7D587BC229F82EB006E8DCF /* HikeDetail.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7D587BB229F82EB006E8DCF /* HikeDetail.swift */; }; + B7D587BE229F82FF006E8DCF /* HikeGraph.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7D587BD229F82FF006E8DCF /* HikeGraph.swift */; }; + B7D587C0229F830B006E8DCF /* hikeData.json in Resources */ = {isa = PBXBuildFile; fileRef = B7D587BF229F830B006E8DCF /* hikeData.json */; }; + B7D587D222A0892C006E8DCF /* Home.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7D587D122A0892C006E8DCF /* Home.swift */; }; + B7D587D422A08965006E8DCF /* CategoryRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7D587D322A08965006E8DCF /* CategoryRow.swift */; }; + B7D587D622A08C97006E8DCF /* Profile.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7D587D522A08C97006E8DCF /* Profile.swift */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + A6DAFAD0A6DAE9D000000001 /* SampleCode.xcconfig */ = {isa = PBXFileReference; name = SampleCode.xcconfig; path = ../Configuration/SampleCode.xcconfig; sourceTree = ""; }; + A6FA8160A6FAB53000000001 /* LICENSE.txt */ = {isa = PBXFileReference; includeInIndex = 1; path = LICENSE.txt; sourceTree = ""; }; + B7310DD0229F6839001079B9 /* HexagonParameters.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HexagonParameters.swift; sourceTree = ""; }; + B7310DD2229F6CA9001079B9 /* Badge.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Badge.swift; sourceTree = ""; }; + B7394862229F194000C47603 /* Landmarks.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Landmarks.app; sourceTree = BUILT_PRODUCTS_DIR; }; + B7394865229F194000C47603 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + B7394867229F194000C47603 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; + B7394869229F194000C47603 /* LandmarkDetail.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LandmarkDetail.swift; sourceTree = ""; }; + B739486B229F194200C47603 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + B739486E229F194200C47603 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; + B7394871229F194200C47603 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + B7394873229F194200C47603 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + B7394879229F1B3F00C47603 /* CircleImage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CircleImage.swift; sourceTree = ""; }; + B739487B229F1B6800C47603 /* MapView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapView.swift; sourceTree = ""; }; + B739487F229F28B900C47603 /* Landmark.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Landmark.swift; sourceTree = ""; }; + B7394880229F28B900C47603 /* Data.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Data.swift; sourceTree = ""; }; + B7394884229F292D00C47603 /* rainbowlake.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = rainbowlake.jpg; sourceTree = ""; }; + B7394886229F292E00C47603 /* icybay.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = icybay.jpg; sourceTree = ""; }; + B7394887229F292E00C47603 /* lakemcdonald.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = lakemcdonald.jpg; sourceTree = ""; }; + B7394888229F292E00C47603 /* turtlerock.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = turtlerock.jpg; sourceTree = ""; }; + B7394889229F292E00C47603 /* umbagog.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = umbagog.jpg; sourceTree = ""; }; + B739488A229F292E00C47603 /* hiddenlake.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = hiddenlake.jpg; sourceTree = ""; }; + B739488B229F292E00C47603 /* stmarylake.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = stmarylake.jpg; sourceTree = ""; }; + B739488C229F292E00C47603 /* twinlake.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = twinlake.jpg; sourceTree = ""; }; + B739488D229F292E00C47603 /* silversalmoncreek.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = silversalmoncreek.jpg; sourceTree = ""; }; + B739488E229F292E00C47603 /* landmarkData.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = landmarkData.json; sourceTree = ""; }; + B739488F229F292F00C47603 /* chincoteague.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = chincoteague.jpg; sourceTree = ""; }; + B7394890229F292F00C47603 /* chilkoottrail.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = chilkoottrail.jpg; sourceTree = ""; }; + B739489E229F2D9700C47603 /* LandmarkRow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = LandmarkRow.swift; path = "Supporting Views/LandmarkRow.swift"; sourceTree = ""; }; + B73948A0229F2E1F00C47603 /* LandmarkList.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LandmarkList.swift; sourceTree = ""; }; + B73948A2229F3E2200C47603 /* charleyrivers.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = charleyrivers.jpg; sourceTree = ""; }; + B7D2AAC4229F4D7C0061E5F5 /* UserData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserData.swift; sourceTree = ""; }; + B7D587AD229F7382006E8DCF /* BadgeBackground.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BadgeBackground.swift; sourceTree = ""; }; + B7D587AF229F73C1006E8DCF /* BadgeSymbol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BadgeSymbol.swift; sourceTree = ""; }; + B7D587B1229F7406006E8DCF /* RotatedBadgeSymbol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RotatedBadgeSymbol.swift; sourceTree = ""; }; + B7D587B5229F825D006E8DCF /* HikeView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HikeView.swift; sourceTree = ""; }; + B7D587B7229F826D006E8DCF /* GraphCapsule.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GraphCapsule.swift; sourceTree = ""; }; + B7D587B9229F8288006E8DCF /* Hike.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Hike.swift; sourceTree = ""; }; + B7D587BB229F82EB006E8DCF /* HikeDetail.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HikeDetail.swift; sourceTree = ""; }; + B7D587BD229F82FF006E8DCF /* HikeGraph.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HikeGraph.swift; sourceTree = ""; }; + B7D587BF229F830B006E8DCF /* hikeData.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = hikeData.json; sourceTree = ""; }; + B7D587D122A0892C006E8DCF /* Home.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Home.swift; sourceTree = ""; }; + B7D587D322A08965006E8DCF /* CategoryRow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CategoryRow.swift; sourceTree = ""; }; + B7D587D522A08C97006E8DCF /* Profile.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Profile.swift; sourceTree = ""; }; + C4E4AAA0C4E4035000000001 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; name = README.md; path = ../README.md; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + B739485F229F194000C47603 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + A6DAF630A6DAF5F000000001 /* Configuration */ = { + isa = PBXGroup; + children = ( + A6DAFAD0A6DAE9D000000001 /* SampleCode.xcconfig */, + ); + name = Configuration; + sourceTree = ""; + }; + A6FAC320A6FA669000000001 /* LICENSE */ = { + isa = PBXGroup; + children = ( + A6FA8160A6FAB53000000001 /* LICENSE.txt */, + ); + name = LICENSE; + path = ../LICENSE; + sourceTree = ""; + }; + B7394859229F194000C47603 = { + isa = PBXGroup; + children = ( + C4E4AAA0C4E4035000000001 /* README.md */, + B7394864229F194000C47603 /* Landmarks */, + B7394863229F194000C47603 /* Products */, + A6DAF630A6DAF5F000000001 /* Configuration */, + A6FAC320A6FA669000000001 /* LICENSE */, + ); + sourceTree = ""; + }; + B7394863229F194000C47603 /* Products */ = { + isa = PBXGroup; + children = ( + B7394862229F194000C47603 /* Landmarks.app */, + ); + name = Products; + sourceTree = ""; + }; + B7394864229F194000C47603 /* Landmarks */ = { + isa = PBXGroup; + children = ( + B739487E229F282200C47603 /* Models */, + B7394865229F194000C47603 /* AppDelegate.swift */, + B7394867229F194000C47603 /* SceneDelegate.swift */, + B7D587D122A0892C006E8DCF /* Home.swift */, + B7D587D322A08965006E8DCF /* CategoryRow.swift */, + B73948A0229F2E1F00C47603 /* LandmarkList.swift */, + B739489E229F2D9700C47603 /* LandmarkRow.swift */, + B7394869229F194000C47603 /* LandmarkDetail.swift */, + B7D587B5229F825D006E8DCF /* HikeView.swift */, + B7D587BB229F82EB006E8DCF /* HikeDetail.swift */, + B7310DD0229F6839001079B9 /* HexagonParameters.swift */, + B739487D229F1C0100C47603 /* Supporting Views */, + B7394883229F291A00C47603 /* Resources */, + B739486B229F194200C47603 /* Assets.xcassets */, + B7394870229F194200C47603 /* LaunchScreen.storyboard */, + B7394873229F194200C47603 /* Info.plist */, + B739486D229F194200C47603 /* Preview Content */, + ); + path = Landmarks; + sourceTree = ""; + }; + B739486D229F194200C47603 /* Preview Content */ = { + isa = PBXGroup; + children = ( + B739486E229F194200C47603 /* Preview Assets.xcassets */, + ); + path = "Preview Content"; + sourceTree = ""; + }; + B739487D229F1C0100C47603 /* Supporting Views */ = { + isa = PBXGroup; + children = ( + B7394879229F1B3F00C47603 /* CircleImage.swift */, + B739487B229F1B6800C47603 /* MapView.swift */, + B7310DD2229F6CA9001079B9 /* Badge.swift */, + B7D587AF229F73C1006E8DCF /* BadgeSymbol.swift */, + B7D587B1229F7406006E8DCF /* RotatedBadgeSymbol.swift */, + B7D587AD229F7382006E8DCF /* BadgeBackground.swift */, + B7D587BD229F82FF006E8DCF /* HikeGraph.swift */, + B7D587B7229F826D006E8DCF /* GraphCapsule.swift */, + ); + path = "Supporting Views"; + sourceTree = ""; + }; + B739487E229F282200C47603 /* Models */ = { + isa = PBXGroup; + children = ( + B7D587D522A08C97006E8DCF /* Profile.swift */, + B7394880229F28B900C47603 /* Data.swift */, + B739487F229F28B900C47603 /* Landmark.swift */, + B7D587B9229F8288006E8DCF /* Hike.swift */, + B7D2AAC4229F4D7C0061E5F5 /* UserData.swift */, + ); + path = Models; + sourceTree = ""; + }; + B7394883229F291A00C47603 /* Resources */ = { + isa = PBXGroup; + children = ( + B739488E229F292E00C47603 /* landmarkData.json */, + B7D587BF229F830B006E8DCF /* hikeData.json */, + B7394890229F292F00C47603 /* chilkoottrail.jpg */, + B739488F229F292F00C47603 /* chincoteague.jpg */, + B739488A229F292E00C47603 /* hiddenlake.jpg */, + B7394886229F292E00C47603 /* icybay.jpg */, + B7394887229F292E00C47603 /* lakemcdonald.jpg */, + B7394884229F292D00C47603 /* rainbowlake.jpg */, + B739488D229F292E00C47603 /* silversalmoncreek.jpg */, + B739488B229F292E00C47603 /* stmarylake.jpg */, + B7394888229F292E00C47603 /* turtlerock.jpg */, + B739488C229F292E00C47603 /* twinlake.jpg */, + B7394889229F292E00C47603 /* umbagog.jpg */, + B73948A2229F3E2200C47603 /* charleyrivers.jpg */, + ); + path = Resources; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + B7394861229F194000C47603 /* Landmarks */ = { + isa = PBXNativeTarget; + buildConfigurationList = B7394876229F194200C47603 /* Build configuration list for PBXNativeTarget "Landmarks" */; + buildPhases = ( + B739485E229F194000C47603 /* Sources */, + B739485F229F194000C47603 /* Frameworks */, + B7394860229F194000C47603 /* Resources */, + C602AC70C605937000000001, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Landmarks; + productName = Landmarks; + productReference = B7394862229F194000C47603 /* Landmarks.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + B739485A229F194000C47603 /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 1100; + LastUpgradeCheck = 1100; + ORGANIZATIONNAME = Apple; + TargetAttributes = { + B7394861229F194000C47603 = { + CreatedOnToolsVersion = 11.0; + }; + }; + }; + buildConfigurationList = B739485D229F194000C47603 /* Build configuration list for PBXProject "WorkingWithUIControls" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = B7394859229F194000C47603; + productRefGroup = B7394863229F194000C47603 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + B7394861229F194000C47603 /* Landmarks */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + B7394860229F194000C47603 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + B739489A229F292F00C47603 /* silversalmoncreek.jpg in Resources */, + B7394894229F292F00C47603 /* lakemcdonald.jpg in Resources */, + B7D587C0229F830B006E8DCF /* hikeData.json in Resources */, + B7394872229F194200C47603 /* LaunchScreen.storyboard in Resources */, + B73948A3229F3E2200C47603 /* charleyrivers.jpg in Resources */, + B7394891229F292F00C47603 /* rainbowlake.jpg in Resources */, + B739486F229F194200C47603 /* Preview Assets.xcassets in Resources */, + B7394895229F292F00C47603 /* turtlerock.jpg in Resources */, + B739486C229F194200C47603 /* Assets.xcassets in Resources */, + B7394899229F292F00C47603 /* twinlake.jpg in Resources */, + B7394896229F292F00C47603 /* umbagog.jpg in Resources */, + B739489D229F292F00C47603 /* chilkoottrail.jpg in Resources */, + B739489C229F292F00C47603 /* chincoteague.jpg in Resources */, + B739489B229F292F00C47603 /* landmarkData.json in Resources */, + B7394893229F292F00C47603 /* icybay.jpg in Resources */, + B7394897229F292F00C47603 /* hiddenlake.jpg in Resources */, + B7394898229F292F00C47603 /* stmarylake.jpg in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + B739485E229F194000C47603 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + B7394882229F28B900C47603 /* Data.swift in Sources */, + B7310DD3229F6CA9001079B9 /* Badge.swift in Sources */, + B7394866229F194000C47603 /* AppDelegate.swift in Sources */, + B7D587D622A08C97006E8DCF /* Profile.swift in Sources */, + B7D587B8229F826D006E8DCF /* GraphCapsule.swift in Sources */, + B7D587D422A08965006E8DCF /* CategoryRow.swift in Sources */, + B739487A229F1B3F00C47603 /* CircleImage.swift in Sources */, + B739487C229F1B6800C47603 /* MapView.swift in Sources */, + B7D587BA229F8288006E8DCF /* Hike.swift in Sources */, + B7D587BC229F82EB006E8DCF /* HikeDetail.swift in Sources */, + B7D587B6229F825D006E8DCF /* HikeView.swift in Sources */, + B7310DD1229F6839001079B9 /* HexagonParameters.swift in Sources */, + B73948A1229F2E1F00C47603 /* LandmarkList.swift in Sources */, + B7D587B0229F73C1006E8DCF /* BadgeSymbol.swift in Sources */, + B7D587B2229F7406006E8DCF /* RotatedBadgeSymbol.swift in Sources */, + B7D587D222A0892C006E8DCF /* Home.swift in Sources */, + B7D587BE229F82FF006E8DCF /* HikeGraph.swift in Sources */, + B7394868229F194000C47603 /* SceneDelegate.swift in Sources */, + B7D587AE229F7382006E8DCF /* BadgeBackground.swift in Sources */, + B739486A229F194000C47603 /* LandmarkDetail.swift in Sources */, + B739489F229F2D9700C47603 /* LandmarkRow.swift in Sources */, + B7D2AAC5229F4D7C0061E5F5 /* UserData.swift in Sources */, + B7394881229F28B900C47603 /* Landmark.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + B7394870229F194200C47603 /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + B7394871229F194200C47603 /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + B7394874229F194200C47603 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = A6DAFAD0A6DAE9D000000001 /* SampleCode.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + B7394875229F194200C47603 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = A6DAFAD0A6DAE9D000000001 /* SampleCode.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + B7394877229F194200C47603 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = A6DAFAD0A6DAE9D000000001 /* SampleCode.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_ASSET_PATHS = "Landmarks/Preview\\ Content"; + DEVELOPMENT_TEAM = ""; + ENABLE_PREVIEWS = YES; + INFOPLIST_FILE = Landmarks/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = "com.example.apple-samplecode.Landmarks${SAMPLE_CODE_DISAMBIGUATOR}"; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + B7394878229F194200C47603 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = A6DAFAD0A6DAE9D000000001 /* SampleCode.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_ASSET_PATHS = "Landmarks/Preview\\ Content"; + DEVELOPMENT_TEAM = ""; + ENABLE_PREVIEWS = YES; + INFOPLIST_FILE = Landmarks/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = "com.example.apple-samplecode.Landmarks${SAMPLE_CODE_DISAMBIGUATOR}"; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + B739485D229F194000C47603 /* Build configuration list for PBXProject "WorkingWithUIControls" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + B7394874229F194200C47603 /* Debug */, + B7394875229F194200C47603 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + B7394876229F194200C47603 /* Build configuration list for PBXNativeTarget "Landmarks" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + B7394877229F194200C47603 /* Debug */, + B7394878229F194200C47603 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = B739485A229F194000C47603 /* Project object */; +} diff --git a/Other Projects/Working With UIControls/StartingPoint/Landmarks/WorkingWithUIControls.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/Other Projects/Working With UIControls/StartingPoint/Landmarks/WorkingWithUIControls.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 0000000..3ddf867 --- /dev/null +++ b/Other Projects/Working With UIControls/StartingPoint/Landmarks/WorkingWithUIControls.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,8 @@ + + + + + BuildSystemType + Latest + + diff --git a/Other Projects/Working With UIControls/StartingPoint/README.md b/Other Projects/Working With UIControls/StartingPoint/README.md new file mode 100644 index 0000000..3314238 --- /dev/null +++ b/Other Projects/Working With UIControls/StartingPoint/README.md @@ -0,0 +1,3 @@ +# Working with UI Controls + +Use this project to code along with the [Working with UI Controls](https://developer.apple.com/tutorials/swiftui/working-with-ui-controls) tutorial. \ No newline at end of file diff --git a/Other Projects/iPadOS Scenes/BehindTheScenes.xcodeproj/project.pbxproj b/Other Projects/iPadOS Scenes/BehindTheScenes.xcodeproj/project.pbxproj new file mode 100644 index 0000000..f3fefa7 --- /dev/null +++ b/Other Projects/iPadOS Scenes/BehindTheScenes.xcodeproj/project.pbxproj @@ -0,0 +1,339 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 50; + objects = { + +/* Begin PBXBuildFile section */ + DB30CC3722A67A7800FAF43E /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB30CC3622A67A7800FAF43E /* AppDelegate.swift */; }; + DB30CC3922A67A7800FAF43E /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB30CC3822A67A7800FAF43E /* SceneDelegate.swift */; }; + DB30CC3B22A67A7800FAF43E /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB30CC3A22A67A7800FAF43E /* ViewController.swift */; }; + DB30CC4022A67A7A00FAF43E /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = DB30CC3F22A67A7A00FAF43E /* Assets.xcassets */; }; + DB30CC4322A67A7A00FAF43E /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = DB30CC4122A67A7A00FAF43E /* LaunchScreen.storyboard */; }; + DB30CC6B22A6937800FAF43E /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB30CC6A22A6937800FAF43E /* ContentView.swift */; }; + DB30CC6D22A6953A00FAF43E /* SwiftUISceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB30CC6C22A6953A00FAF43E /* SwiftUISceneDelegate.swift */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + DB30CC3322A67A7800FAF43E /* BehindTheScenes.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = BehindTheScenes.app; sourceTree = BUILT_PRODUCTS_DIR; }; + DB30CC3622A67A7800FAF43E /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + DB30CC3822A67A7800FAF43E /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; + DB30CC3A22A67A7800FAF43E /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; + DB30CC3F22A67A7A00FAF43E /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + DB30CC4222A67A7A00FAF43E /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + DB30CC4422A67A7A00FAF43E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + DB30CC6A22A6937800FAF43E /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; }; + DB30CC6C22A6953A00FAF43E /* SwiftUISceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SwiftUISceneDelegate.swift; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + DB30CC3022A67A7800FAF43E /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + DB30CC2A22A67A7800FAF43E = { + isa = PBXGroup; + children = ( + DB30CC3522A67A7800FAF43E /* BehindTheScenes */, + DB30CC3422A67A7800FAF43E /* Products */, + ); + sourceTree = ""; + }; + DB30CC3422A67A7800FAF43E /* Products */ = { + isa = PBXGroup; + children = ( + DB30CC3322A67A7800FAF43E /* BehindTheScenes.app */, + ); + name = Products; + sourceTree = ""; + }; + DB30CC3522A67A7800FAF43E /* BehindTheScenes */ = { + isa = PBXGroup; + children = ( + DB30CC3622A67A7800FAF43E /* AppDelegate.swift */, + DB30CC3822A67A7800FAF43E /* SceneDelegate.swift */, + DB30CC6C22A6953A00FAF43E /* SwiftUISceneDelegate.swift */, + DB30CC3A22A67A7800FAF43E /* ViewController.swift */, + DB30CC6A22A6937800FAF43E /* ContentView.swift */, + DB30CC3F22A67A7A00FAF43E /* Assets.xcassets */, + DB30CC4122A67A7A00FAF43E /* LaunchScreen.storyboard */, + DB30CC4422A67A7A00FAF43E /* Info.plist */, + ); + path = BehindTheScenes; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + DB30CC3222A67A7800FAF43E /* BehindTheScenes */ = { + isa = PBXNativeTarget; + buildConfigurationList = DB30CC4722A67A7A00FAF43E /* Build configuration list for PBXNativeTarget "BehindTheScenes" */; + buildPhases = ( + DB30CC2F22A67A7800FAF43E /* Sources */, + DB30CC3022A67A7800FAF43E /* Frameworks */, + DB30CC3122A67A7800FAF43E /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = BehindTheScenes; + productName = BehindTheScenes; + productReference = DB30CC3322A67A7800FAF43E /* BehindTheScenes.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + DB30CC2B22A67A7800FAF43E /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 1100; + LastUpgradeCheck = 1100; + ORGANIZATIONNAME = "Two Lives Left"; + TargetAttributes = { + DB30CC3222A67A7800FAF43E = { + CreatedOnToolsVersion = 11.0; + }; + }; + }; + buildConfigurationList = DB30CC2E22A67A7800FAF43E /* Build configuration list for PBXProject "BehindTheScenes" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = DB30CC2A22A67A7800FAF43E; + productRefGroup = DB30CC3422A67A7800FAF43E /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + DB30CC3222A67A7800FAF43E /* BehindTheScenes */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + DB30CC3122A67A7800FAF43E /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + DB30CC4322A67A7A00FAF43E /* LaunchScreen.storyboard in Resources */, + DB30CC4022A67A7A00FAF43E /* Assets.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + DB30CC2F22A67A7800FAF43E /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + DB30CC3B22A67A7800FAF43E /* ViewController.swift in Sources */, + DB30CC6D22A6953A00FAF43E /* SwiftUISceneDelegate.swift in Sources */, + DB30CC3722A67A7800FAF43E /* AppDelegate.swift in Sources */, + DB30CC3922A67A7800FAF43E /* SceneDelegate.swift in Sources */, + DB30CC6B22A6937800FAF43E /* ContentView.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + DB30CC4122A67A7A00FAF43E /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + DB30CC4222A67A7A00FAF43E /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + DB30CC4522A67A7A00FAF43E /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + DB30CC4622A67A7A00FAF43E /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + DB30CC4822A67A7A00FAF43E /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = G5S3RZ43N7; + INFOPLIST_FILE = BehindTheScenes/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.twolivesleft.BehindTheScenes; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + DB30CC4922A67A7A00FAF43E /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = G5S3RZ43N7; + INFOPLIST_FILE = BehindTheScenes/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.twolivesleft.BehindTheScenes; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + DB30CC2E22A67A7800FAF43E /* Build configuration list for PBXProject "BehindTheScenes" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + DB30CC4522A67A7A00FAF43E /* Debug */, + DB30CC4622A67A7A00FAF43E /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + DB30CC4722A67A7A00FAF43E /* Build configuration list for PBXNativeTarget "BehindTheScenes" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + DB30CC4822A67A7A00FAF43E /* Debug */, + DB30CC4922A67A7A00FAF43E /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = DB30CC2B22A67A7800FAF43E /* Project object */; +} diff --git a/Other Projects/iPadOS Scenes/BehindTheScenes/AppDelegate.swift b/Other Projects/iPadOS Scenes/BehindTheScenes/AppDelegate.swift new file mode 100644 index 0000000..7c4c79f --- /dev/null +++ b/Other Projects/iPadOS Scenes/BehindTheScenes/AppDelegate.swift @@ -0,0 +1,62 @@ +// +// AppDelegate.swift +// BehindTheScenes +// +// Created by Simeon Saint-Saens on 4/6/19. +// Copyright © 2019 Two Lives Left. All rights reserved. +// + +import UIKit + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + + var sceneCount = 0 + + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { + // Override point for customization after application launch. + return true + } + + func applicationWillTerminate(_ application: UIApplication) { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. + } + + // MARK: UISceneSession Lifecycle + + func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration { + // Called when a new scene session is being created. + // Use this method to select a configuration to create the new scene with. + sceneCount += 1 + + connectingSceneSession.userInfo = ["SceneCount" : sceneCount ] + + var sceneDelegateClass: AnyClass = SceneDelegate.self + + if let activity = options.userActivities.first, + let sceneType = SceneType(rawValue: activity.activityType) { + + switch sceneType { + case .uikitScene: + sceneDelegateClass = SceneDelegate.self + case .swiftuiScene: + sceneDelegateClass = SwiftUISceneDelegate.self + } + } + + let config = UISceneConfiguration(name: nil, sessionRole: connectingSceneSession.role) + config.sceneClass = UIWindowScene.self + config.delegateClass = sceneDelegateClass + + return config + } + + func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) { + // Called when the user discards a scene session. + // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions. + // Use this method to release any resources that were specific to the discarded scenes, as they will not return. + } + + +} + diff --git a/Other Projects/iPadOS Scenes/BehindTheScenes/Assets.xcassets/AppIcon.appiconset/Contents.json b/Other Projects/iPadOS Scenes/BehindTheScenes/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..d8db8d6 --- /dev/null +++ b/Other Projects/iPadOS Scenes/BehindTheScenes/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,98 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "83.5x83.5", + "scale" : "2x" + }, + { + "idiom" : "ios-marketing", + "size" : "1024x1024", + "scale" : "1x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/iPadOS Scenes/BehindTheScenes/Assets.xcassets/Contents.json b/Other Projects/iPadOS Scenes/BehindTheScenes/Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/Other Projects/iPadOS Scenes/BehindTheScenes/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Other Projects/iPadOS Scenes/BehindTheScenes/Base.lproj/LaunchScreen.storyboard b/Other Projects/iPadOS Scenes/BehindTheScenes/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000..865e932 --- /dev/null +++ b/Other Projects/iPadOS Scenes/BehindTheScenes/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Other Projects/iPadOS Scenes/BehindTheScenes/ContentView.swift b/Other Projects/iPadOS Scenes/BehindTheScenes/ContentView.swift new file mode 100644 index 0000000..6da7761 --- /dev/null +++ b/Other Projects/iPadOS Scenes/BehindTheScenes/ContentView.swift @@ -0,0 +1,21 @@ +// +// ContentView.swift +// BehindTheScenes +// +// Created by Simeon Saint-Saens on 4/6/19. +// Copyright © 2019 Two Lives Left. All rights reserved. +// + +import SwiftUI + +struct ContentView : View { + let count: Int + + var body: some View { + VStack { + Text("Scene \(count)") + Text("This is a SwiftUI View 🚀") + } + } +} + diff --git a/Other Projects/iPadOS Scenes/BehindTheScenes/Info.plist b/Other Projects/iPadOS Scenes/BehindTheScenes/Info.plist new file mode 100644 index 0000000..73e8d2e --- /dev/null +++ b/Other Projects/iPadOS Scenes/BehindTheScenes/Info.plist @@ -0,0 +1,62 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + $(PRODUCT_BUNDLE_PACKAGE_TYPE) + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UIApplicationSceneManifest + + UIApplicationSupportsMultipleScenes + + UISceneConfigurations + + UIWindowSceneSessionRoleApplication + + + UILaunchStoryboardName + LaunchScreen + UISceneConfigurationName + Default Configuration + UISceneDelegateClassName + $(PRODUCT_MODULE_NAME).SceneDelegate + + + + + UILaunchStoryboardName + LaunchScreen + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/Other Projects/iPadOS Scenes/BehindTheScenes/SceneDelegate.swift b/Other Projects/iPadOS Scenes/BehindTheScenes/SceneDelegate.swift new file mode 100644 index 0000000..f86f739 --- /dev/null +++ b/Other Projects/iPadOS Scenes/BehindTheScenes/SceneDelegate.swift @@ -0,0 +1,64 @@ +// +// SceneDelegate.swift +// BehindTheScenes +// +// Created by Simeon Saint-Saens on 4/6/19. +// Copyright © 2019 Two Lives Left. All rights reserved. +// + +import UIKit + +class SceneDelegate: UIResponder, UIWindowSceneDelegate { + + var window: UIWindow? + + func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { + // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`. + // If using a storyboard, the `window` property will automatically be initialized and attached to the scene. + // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead). + guard let windowScene = (scene as? UIWindowScene) else { return } + + let count = session.userInfo?["SceneCount"] as? Int ?? 0 + + window = UIWindow(windowScene: windowScene) + window?.rootViewController = ViewController(count: count) + window?.makeKeyAndVisible() + } + + func sceneDidDisconnect(_ scene: UIScene) { + // Called as the scene is being released by the system. + // This occurs shortly after the scene enters the background, or when its session is discarded. + // Release any resources associated with this scene that can be re-created the next time the scene connects. + // The scene may re-connect later, as its session was not neccessarily discarded (see `application:didDiscardSceneSessions` instead). + } + + func sceneDidBecomeActive(_ scene: UIScene) { + // Called when the scene has moved from an inactive state to an active state. + // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive. + } + + func sceneWillResignActive(_ scene: UIScene) { + // Called when the scene will move from an active state to an inactive state. + // This may occur due to temporary interruptions (ex. an incoming phone call). + } + + func sceneWillEnterForeground(_ scene: UIScene) { + // Called as the scene transitions from the background to the foreground. + // Use this method to undo the changes made on entering the background. + } + + func sceneDidEnterBackground(_ scene: UIScene) { + // Called as the scene transitions from the foreground to the background. + // Use this method to save data, release shared resources, and store enough scene-specific state information + // to restore the scene back to its current state. + } + + func scene(_ scene: UIScene, continue userActivity: NSUserActivity) { + print("Continuing \(String(describing: userActivity.userInfo?["count"]))") + } + + func scene(_ scene: UIScene, didUpdate userActivity: NSUserActivity) { + print("Updating user activity") + } +} + diff --git a/Other Projects/iPadOS Scenes/BehindTheScenes/SwiftUISceneDelegate.swift b/Other Projects/iPadOS Scenes/BehindTheScenes/SwiftUISceneDelegate.swift new file mode 100644 index 0000000..dce55fc --- /dev/null +++ b/Other Projects/iPadOS Scenes/BehindTheScenes/SwiftUISceneDelegate.swift @@ -0,0 +1,27 @@ +// +// SwiftUISceneDelegate.swift +// BehindTheScenes +// +// Created by Simeon Saint-Saens on 4/6/19. +// Copyright © 2019 Two Lives Left. All rights reserved. +// + +import UIKit +import SwiftUI + +class SwiftUISceneDelegate: UIResponder, UIWindowSceneDelegate { + var window: UIWindow? + + func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { + // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`. + // If using a storyboard, the `window` property will automatically be initialized and attached to the scene. + // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead). + guard let windowScene = (scene as? UIWindowScene) else { return } + + let count = session.userInfo?["SceneCount"] as? Int ?? 0 + + window = UIWindow(windowScene: windowScene) + window?.rootViewController = UIHostingController(rootView: ContentView(count: count)) + window?.makeKeyAndVisible() + } +} diff --git a/Other Projects/iPadOS Scenes/BehindTheScenes/ViewController.swift b/Other Projects/iPadOS Scenes/BehindTheScenes/ViewController.swift new file mode 100644 index 0000000..1ac2439 --- /dev/null +++ b/Other Projects/iPadOS Scenes/BehindTheScenes/ViewController.swift @@ -0,0 +1,86 @@ +// +// ViewController.swift +// BehindTheScenes +// +// Created by Simeon Saint-Saens on 4/6/19. +// Copyright © 2019 Two Lives Left. All rights reserved. +// + +import UIKit + +enum SceneType: String { + case uikitScene + case swiftuiScene +} + +class ViewController: UIViewController { + + let count: Int + + init(count: Int) { + self.count = count + + super.init(nibName: nil, bundle: nil) + } + + required init?(coder: NSCoder) { + fatalError("NO THANKS XCODE") + } + + override func viewDidLoad() { + print("Loading view controller") + + super.viewDidLoad() + + view.backgroundColor = UIColor(white: 0.9, alpha: 1) + + let button = UIButton(type: .system) + button.addTarget(self, action: #selector(openScene(_:)), for: .touchUpInside) + button.setTitle("Request New Scene", for: .normal) + + view.addSubview(button) + button.translatesAutoresizingMaskIntoConstraints = false + + button.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true + button.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true + + let swiftUIbutton = UIButton(type: .system) + swiftUIbutton.addTarget(self, action: #selector(openSwiftUIScene(_:)), for: .touchUpInside) + swiftUIbutton.setTitle("Request Swift UI Test Scene", for: .normal) + + view.addSubview(swiftUIbutton) + swiftUIbutton.translatesAutoresizingMaskIntoConstraints = false + + swiftUIbutton.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true + swiftUIbutton.topAnchor.constraint(equalTo: button.bottomAnchor, constant: 16).isActive = true + + let countLabel = UILabel() + countLabel.text = "\(count)" + countLabel.textAlignment = .center + countLabel.textColor = .black + countLabel.font = UIFont.systemFont(ofSize: 144, weight: .heavy) + + view.addSubview(countLabel) + countLabel.translatesAutoresizingMaskIntoConstraints = false + + countLabel.bottomAnchor.constraint(equalTo: button.topAnchor, constant: -30).isActive = true + countLabel.centerXAnchor.constraint(equalTo: button.centerXAnchor).isActive = true + } + + @objc private func openScene(_ sender: Any) { + let activity = NSUserActivity(activityType: SceneType.uikitScene.rawValue) + + UIApplication.shared.requestSceneSessionActivation(nil, userActivity: activity, options: nil, errorHandler: { + print($0) + }) + } + + @objc private func openSwiftUIScene(_ sender: Any) { + let activity = NSUserActivity(activityType: SceneType.swiftuiScene.rawValue) + + UIApplication.shared.requestSceneSessionActivation(nil, userActivity: activity, options: nil, errorHandler: { + print($0) + }) + } +} + diff --git a/Previews/animatable-cards.gif b/Previews/animatable-cards.gif new file mode 100644 index 0000000..0f4d63b Binary files /dev/null and b/Previews/animatable-cards.gif differ diff --git a/Previews/animatable-cards.mov b/Previews/animatable-cards.mov new file mode 100644 index 0000000..b610889 Binary files /dev/null and b/Previews/animatable-cards.mov differ diff --git a/Previews/area-to-card.gif b/Previews/area-to-card.gif new file mode 100644 index 0000000..e0cee25 Binary files /dev/null and b/Previews/area-to-card.gif differ diff --git a/Previews/area-to-card.mov b/Previews/area-to-card.mov new file mode 100644 index 0000000..ad4af90 Binary files /dev/null and b/Previews/area-to-card.mov differ diff --git a/Resources/2048game.png b/Resources/2048game.png new file mode 100644 index 0000000..9982845 Binary files /dev/null and b/Resources/2048game.png differ diff --git a/Resources/AnimatingViewsAndTransitions.png b/Resources/AnimatingViewsAndTransitions.png new file mode 100644 index 0000000..4561dfd Binary files /dev/null and b/Resources/AnimatingViewsAndTransitions.png differ diff --git a/Resources/AsyncImageLoading.gif b/Resources/AsyncImageLoading.gif new file mode 100644 index 0000000..a2bf36b Binary files /dev/null and b/Resources/AsyncImageLoading.gif differ diff --git a/Resources/BuildingListsAndNavigation.png b/Resources/BuildingListsAndNavigation.png new file mode 100644 index 0000000..14604c5 Binary files /dev/null and b/Resources/BuildingListsAndNavigation.png differ diff --git a/Resources/Calculator.png b/Resources/Calculator.png new file mode 100644 index 0000000..de7a4f7 Binary files /dev/null and b/Resources/Calculator.png differ diff --git a/Resources/Cards.gif b/Resources/Cards.gif new file mode 100644 index 0000000..0aef115 Binary files /dev/null and b/Resources/Cards.gif differ diff --git a/Resources/CombineUsingGitHubAPI.png b/Resources/CombineUsingGitHubAPI.png new file mode 100644 index 0000000..278656c Binary files /dev/null and b/Resources/CombineUsingGitHubAPI.png differ diff --git a/Resources/ComposingComplexInterfaces.png b/Resources/ComposingComplexInterfaces.png new file mode 100644 index 0000000..32b636f Binary files /dev/null and b/Resources/ComposingComplexInterfaces.png differ diff --git a/Resources/CreatingAndCombiningViews.png b/Resources/CreatingAndCombiningViews.png new file mode 100644 index 0000000..f8692a4 Binary files /dev/null and b/Resources/CreatingAndCombiningViews.png differ diff --git a/Resources/DrawingPathsAndShapes.png b/Resources/DrawingPathsAndShapes.png new file mode 100644 index 0000000..807bab5 Binary files /dev/null and b/Resources/DrawingPathsAndShapes.png differ diff --git a/Resources/ExampleToDoApp.png b/Resources/ExampleToDoApp.png new file mode 100644 index 0000000..a12ed1b Binary files /dev/null and b/Resources/ExampleToDoApp.png differ diff --git a/Resources/File.swift b/Resources/File.swift new file mode 100644 index 0000000..0099ee1 --- /dev/null +++ b/Resources/File.swift @@ -0,0 +1 @@ +print("https://github.com/IvanVorobei/awesome-ios-ui") diff --git a/Resources/Flux.gif b/Resources/Flux.gif new file mode 100644 index 0000000..e457bd6 Binary files /dev/null and b/Resources/Flux.gif differ diff --git a/Resources/GitHubSearch.png b/Resources/GitHubSearch.png new file mode 100644 index 0000000..8245ece Binary files /dev/null and b/Resources/GitHubSearch.png differ diff --git a/Resources/HandlingUserInput.png b/Resources/HandlingUserInput.png new file mode 100644 index 0000000..09fe868 Binary files /dev/null and b/Resources/HandlingUserInput.png differ diff --git a/Resources/InterfacingWithUIKit.png b/Resources/InterfacingWithUIKit.png new file mode 100644 index 0000000..580bc25 Binary files /dev/null and b/Resources/InterfacingWithUIKit.png differ diff --git a/Resources/Jike.png b/Resources/Jike.png new file mode 100644 index 0000000..05f0508 Binary files /dev/null and b/Resources/Jike.png differ diff --git a/Resources/PureGenius.gif b/Resources/PureGenius.gif new file mode 100644 index 0000000..f538a1d Binary files /dev/null and b/Resources/PureGenius.gif differ diff --git a/Resources/SFSymbols.gif b/Resources/SFSymbols.gif new file mode 100644 index 0000000..9606053 Binary files /dev/null and b/Resources/SFSymbols.gif differ diff --git a/Resources/SwiftUICurrency.png b/Resources/SwiftUICurrency.png new file mode 100644 index 0000000..217dc02 Binary files /dev/null and b/Resources/SwiftUICurrency.png differ diff --git a/Resources/SwiftUIDownloadView.gif b/Resources/SwiftUIDownloadView.gif new file mode 100644 index 0000000..0c7125e Binary files /dev/null and b/Resources/SwiftUIDownloadView.gif differ diff --git a/Resources/SwiftUISideMenu.gif b/Resources/SwiftUISideMenu.gif new file mode 100644 index 0000000..f29945a Binary files /dev/null and b/Resources/SwiftUISideMenu.gif differ diff --git a/Resources/TimeTravel.gif b/Resources/TimeTravel.gif new file mode 100644 index 0000000..824c0c1 Binary files /dev/null and b/Resources/TimeTravel.gif differ diff --git a/Resources/TransitionBlur.png b/Resources/TransitionBlur.png new file mode 100644 index 0000000..849b417 Binary files /dev/null and b/Resources/TransitionBlur.png differ diff --git a/Resources/WWDCPlayer.png b/Resources/WWDCPlayer.png new file mode 100644 index 0000000..4de6688 Binary files /dev/null and b/Resources/WWDCPlayer.png differ diff --git a/Resources/WorkingWithUIControls.png b/Resources/WorkingWithUIControls.png new file mode 100644 index 0000000..e9bc64f Binary files /dev/null and b/Resources/WorkingWithUIControls.png differ diff --git a/Resources/WorkingWithUIControls2.png b/Resources/WorkingWithUIControls2.png new file mode 100644 index 0000000..30b3b79 Binary files /dev/null and b/Resources/WorkingWithUIControls2.png differ diff --git a/Resources/iPadOSScenes.jpeg b/Resources/iPadOSScenes.jpeg new file mode 100644 index 0000000..6b66eb2 Binary files /dev/null and b/Resources/iPadOSScenes.jpeg differ diff --git a/Resources/icon.png b/Resources/icon.png new file mode 100644 index 0000000..30db7ac Binary files /dev/null and b/Resources/icon.png differ