├── .DS_Store
├── .gitattributes
├── AnimationDemo
├── AnimationDemo.xcodeproj
│ ├── project.pbxproj
│ ├── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ ├── xcshareddata
│ │ │ └── IDEWorkspaceChecks.plist
│ │ └── xcuserdata
│ │ │ └── neilsmyth.xcuserdatad
│ │ │ └── UserInterfaceState.xcuserstate
│ └── xcuserdata
│ │ └── neilsmyth.xcuserdatad
│ │ └── xcschemes
│ │ └── xcschememanagement.plist
└── AnimationDemo
│ ├── AppDelegate.swift
│ ├── Assets.xcassets
│ ├── AppIcon.appiconset
│ │ └── Contents.json
│ └── Contents.json
│ ├── Base.lproj
│ └── LaunchScreen.storyboard
│ ├── ContentView.swift
│ ├── Info.plist
│ ├── Preview Content
│ └── Preview Assets.xcassets
│ │ └── Contents.json
│ └── SceneDelegate.swift
├── CarAssets.xcassets
├── Contents.json
├── chevrolet_volt.imageset
│ ├── Contents.json
│ └── chevrolet_volt.jpg
├── nissan_leaf.imageset
│ ├── Contents.json
│ └── nissan_leaf.jpg
├── tesla_model_3.imageset
│ ├── Contents.json
│ └── tesla_model_3.jpg
├── tesla_model_s.imageset
│ ├── Contents.json
│ └── tesla_model_s.jpg
└── toyota_prius.imageset
│ ├── Contents.json
│ └── toyota_prius.jpg
├── CarData
└── carData.json
├── ContextMenuDemo
├── ContextMenuDemo.xcodeproj
│ ├── project.pbxproj
│ ├── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ ├── xcshareddata
│ │ │ └── IDEWorkspaceChecks.plist
│ │ └── xcuserdata
│ │ │ └── neilsmyth.xcuserdatad
│ │ │ └── UserInterfaceState.xcuserstate
│ └── xcuserdata
│ │ └── neilsmyth.xcuserdatad
│ │ └── xcschemes
│ │ └── xcschememanagement.plist
└── ContextMenuDemo
│ ├── AppDelegate.swift
│ ├── Assets.xcassets
│ ├── AppIcon.appiconset
│ │ └── Contents.json
│ └── Contents.json
│ ├── Base.lproj
│ └── LaunchScreen.storyboard
│ ├── ContentView.swift
│ ├── Info.plist
│ ├── Preview Content
│ └── Preview Assets.xcassets
│ │ └── Contents.json
│ └── SceneDelegate.swift
├── DrawDemo
├── DrawDemo.xcodeproj
│ ├── project.pbxproj
│ ├── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ ├── xcshareddata
│ │ │ └── IDEWorkspaceChecks.plist
│ │ └── xcuserdata
│ │ │ └── neilsmyth.xcuserdatad
│ │ │ └── UserInterfaceState.xcuserstate
│ └── xcuserdata
│ │ └── neilsmyth.xcuserdatad
│ │ └── xcschemes
│ │ └── xcschememanagement.plist
└── DrawDemo
│ ├── AppDelegate.swift
│ ├── Assets.xcassets
│ ├── AppIcon.appiconset
│ │ └── Contents.json
│ └── Contents.json
│ ├── Base.lproj
│ └── LaunchScreen.storyboard
│ ├── ContentView.swift
│ ├── Info.plist
│ ├── Preview Content
│ └── Preview Assets.xcassets
│ │ └── Contents.json
│ └── SceneDelegate.swift
├── GestureDemo
├── GestureDemo.xcodeproj
│ ├── project.pbxproj
│ ├── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ ├── xcshareddata
│ │ │ └── IDEWorkspaceChecks.plist
│ │ └── xcuserdata
│ │ │ └── neilsmyth.xcuserdatad
│ │ │ └── UserInterfaceState.xcuserstate
│ └── xcuserdata
│ │ └── neilsmyth.xcuserdatad
│ │ └── xcschemes
│ │ └── xcschememanagement.plist
└── GestureDemo
│ ├── AppDelegate.swift
│ ├── Assets.xcassets
│ ├── AppIcon.appiconset
│ │ └── Contents.json
│ └── Contents.json
│ ├── Base.lproj
│ └── LaunchScreen.storyboard
│ ├── ContentView.swift
│ ├── Info.plist
│ ├── Preview Content
│ └── Preview Assets.xcassets
│ │ └── Contents.json
│ └── SceneDelegate.swift
├── HostingControllerDemo
├── HostingControllerDemo.xcodeproj
│ ├── project.pbxproj
│ ├── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ ├── xcshareddata
│ │ │ └── IDEWorkspaceChecks.plist
│ │ └── xcuserdata
│ │ │ └── neilsmyth.xcuserdatad
│ │ │ └── UserInterfaceState.xcuserstate
│ └── xcuserdata
│ │ └── neilsmyth.xcuserdatad
│ │ └── xcschemes
│ │ └── xcschememanagement.plist
├── HostingControllerDemo
│ ├── AppDelegate.swift
│ ├── Assets.xcassets
│ │ ├── AppIcon.appiconset
│ │ │ └── Contents.json
│ │ └── Contents.json
│ ├── Base.lproj
│ │ ├── LaunchScreen.storyboard
│ │ └── Main.storyboard
│ ├── Info.plist
│ ├── SceneDelegate.swift
│ └── ViewController.swift
└── SwiftUIView.swift
├── LearnSwift.playground
├── Pages
│ ├── Live View Example.xcplaygroundpage
│ │ ├── Contents.swift
│ │ └── timeline.xctimeline
│ ├── UIKit Examples.xcplaygroundpage
│ │ ├── Contents.swift
│ │ ├── Resources
│ │ │ └── waterfall.png
│ │ └── timeline.xctimeline
│ └── Untitled Page.xcplaygroundpage
│ │ ├── Contents.swift
│ │ └── timeline.xctimeline
├── contents.xcplayground
└── playground.xcworkspace
│ ├── contents.xcworkspacedata
│ ├── xcshareddata
│ └── IDEWorkspaceChecks.plist
│ └── xcuserdata
│ └── neilsmyth.xcuserdatad
│ └── UserInterfaceState.xcuserstate
├── ListNavDemo
├── ListNavDemo.xcodeproj
│ ├── project.pbxproj
│ ├── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ ├── xcshareddata
│ │ │ └── IDEWorkspaceChecks.plist
│ │ └── xcuserdata
│ │ │ └── neilsmyth.xcuserdatad
│ │ │ └── UserInterfaceState.xcuserstate
│ └── xcuserdata
│ │ └── neilsmyth.xcuserdatad
│ │ └── xcschemes
│ │ └── xcschememanagement.plist
└── ListNavDemo
│ ├── AddNewCar.swift
│ ├── AppDelegate.swift
│ ├── Assets.xcassets
│ ├── AppIcon.appiconset
│ │ └── Contents.json
│ └── Contents.json
│ ├── Base.lproj
│ └── LaunchScreen.storyboard
│ ├── Car.swift
│ ├── CarAssets.xcassets
│ ├── Contents.json
│ ├── chevrolet_volt.imageset
│ │ ├── Contents.json
│ │ └── chevrolet_volt.jpg
│ ├── nissan_leaf.imageset
│ │ ├── Contents.json
│ │ └── nissan_leaf.jpg
│ ├── tesla_model_3.imageset
│ │ ├── Contents.json
│ │ └── tesla_model_3.jpg
│ ├── tesla_model_s.imageset
│ │ ├── Contents.json
│ │ └── tesla_model_s.jpg
│ └── toyota_prius.imageset
│ │ ├── Contents.json
│ │ └── toyota_prius.jpg
│ ├── CarData.swift
│ ├── CarDetail.swift
│ ├── CarStore.swift
│ ├── ContentView.swift
│ ├── Info.plist
│ ├── Preview Content
│ └── Preview Assets.xcassets
│ │ └── Contents.json
│ ├── SceneDelegate.swift
│ └── carData.json
├── ObservableDemo
├── ObservableDemo.xcodeproj
│ ├── project.pbxproj
│ ├── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ ├── xcshareddata
│ │ │ └── IDEWorkspaceChecks.plist
│ │ └── xcuserdata
│ │ │ └── neilsmyth.xcuserdatad
│ │ │ └── UserInterfaceState.xcuserstate
│ └── xcuserdata
│ │ └── neilsmyth.xcuserdatad
│ │ └── xcschemes
│ │ └── xcschememanagement.plist
└── ObservableDemo
│ ├── AppDelegate.swift
│ ├── Assets.xcassets
│ ├── AppIcon.appiconset
│ │ └── Contents.json
│ └── Contents.json
│ ├── Base.lproj
│ └── LaunchScreen.storyboard
│ ├── ContentView.swift
│ ├── Info.plist
│ ├── Preview Content
│ └── Preview Assets.xcassets
│ │ └── Contents.json
│ ├── SceneDelegate.swift
│ ├── SecondView.swift
│ └── TimerData.swift
├── README.md
├── SwiftUIDemo
├── SwiftUIDemo.xcodeproj
│ ├── project.pbxproj
│ ├── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ ├── xcshareddata
│ │ │ └── IDEWorkspaceChecks.plist
│ │ └── xcuserdata
│ │ │ └── neilsmyth.xcuserdatad
│ │ │ └── UserInterfaceState.xcuserstate
│ └── xcuserdata
│ │ └── neilsmyth.xcuserdatad
│ │ └── xcschemes
│ │ └── xcschememanagement.plist
└── SwiftUIDemo
│ ├── AppDelegate.swift
│ ├── Assets.xcassets
│ ├── AppIcon.appiconset
│ │ └── Contents.json
│ └── Contents.json
│ ├── Base.lproj
│ └── LaunchScreen.storyboard
│ ├── ContentView.swift
│ ├── Info.plist
│ ├── Preview Content
│ └── Preview Assets.xcassets
│ │ └── Contents.json
│ └── SceneDelegate.swift
├── TabViewDemo
├── TabViewDemo.xcodeproj
│ ├── project.pbxproj
│ ├── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ ├── xcshareddata
│ │ │ └── IDEWorkspaceChecks.plist
│ │ └── xcuserdata
│ │ │ └── neilsmyth.xcuserdatad
│ │ │ └── UserInterfaceState.xcuserstate
│ └── xcuserdata
│ │ └── neilsmyth.xcuserdatad
│ │ └── xcschemes
│ │ └── xcschememanagement.plist
└── TabViewDemo
│ ├── AppDelegate.swift
│ ├── Assets.xcassets
│ ├── AppIcon.appiconset
│ │ └── Contents.json
│ └── Contents.json
│ ├── Base.lproj
│ └── LaunchScreen.storyboard
│ ├── ContentView.swift
│ ├── Info.plist
│ ├── Preview Content
│ └── Preview Assets.xcassets
│ │ └── Contents.json
│ └── SceneDelegate.swift
├── UIViewDemo
├── MyScrollView.swift
├── UIViewDemo.xcodeproj
│ ├── project.pbxproj
│ ├── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ ├── xcshareddata
│ │ │ └── IDEWorkspaceChecks.plist
│ │ └── xcuserdata
│ │ │ └── neilsmyth.xcuserdatad
│ │ │ └── UserInterfaceState.xcuserstate
│ └── xcuserdata
│ │ └── neilsmyth.xcuserdatad
│ │ └── xcschemes
│ │ └── xcschememanagement.plist
└── UIViewDemo
│ ├── AppDelegate.swift
│ ├── Assets.xcassets
│ ├── AppIcon.appiconset
│ │ └── Contents.json
│ └── Contents.json
│ ├── Base.lproj
│ └── LaunchScreen.storyboard
│ ├── ContentView.swift
│ ├── Info.plist
│ ├── Preview Content
│ └── Preview Assets.xcassets
│ │ └── Contents.json
│ └── SceneDelegate.swift
├── ViewControllerDemo
├── MyImagePicker.swift
├── ViewControllerDemo.xcodeproj
│ ├── project.pbxproj
│ ├── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ ├── xcshareddata
│ │ │ └── IDEWorkspaceChecks.plist
│ │ └── xcuserdata
│ │ │ └── neilsmyth.xcuserdatad
│ │ │ └── UserInterfaceState.xcuserstate
│ └── xcuserdata
│ │ └── neilsmyth.xcuserdatad
│ │ └── xcschemes
│ │ └── xcschememanagement.plist
└── ViewControllerDemo
│ ├── AppDelegate.swift
│ ├── Assets.xcassets
│ ├── AppIcon.appiconset
│ │ └── Contents.json
│ └── Contents.json
│ ├── Base.lproj
│ └── LaunchScreen.storyboard
│ ├── ContentView.swift
│ ├── Info.plist
│ ├── Preview Content
│ └── Preview Assets.xcassets
│ │ └── Contents.json
│ └── SceneDelegate.swift
└── playground_images
├── .DS_Store
└── waterfall.png
/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Jpub/SwiftUI/defbcdd40638ec4d8d55e6693e7c878a00b1d135/.DS_Store
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
--------------------------------------------------------------------------------
/AnimationDemo/AnimationDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/AnimationDemo/AnimationDemo.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/AnimationDemo/AnimationDemo.xcodeproj/project.xcworkspace/xcuserdata/neilsmyth.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Jpub/SwiftUI/defbcdd40638ec4d8d55e6693e7c878a00b1d135/AnimationDemo/AnimationDemo.xcodeproj/project.xcworkspace/xcuserdata/neilsmyth.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/AnimationDemo/AnimationDemo.xcodeproj/xcuserdata/neilsmyth.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | AnimationDemo.xcscheme_^#shared#^_
8 |
9 | orderHint
10 | 0
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/AnimationDemo/AnimationDemo/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // AnimationDemo
4 | //
5 | // Created by Neil Smyth on 10/16/19.
6 | // Copyright © 2019 eBookFrenzy. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | @UIApplicationMain
12 | class AppDelegate: UIResponder, UIApplicationDelegate {
13 |
14 |
15 |
16 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
17 | // Override point for customization after application launch.
18 | return true
19 | }
20 |
21 | // MARK: UISceneSession Lifecycle
22 |
23 | func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
24 | // Called when a new scene session is being created.
25 | // Use this method to select a configuration to create the new scene with.
26 | return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
27 | }
28 |
29 | func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) {
30 | // Called when the user discards a scene session.
31 | // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
32 | // Use this method to release any resources that were specific to the discarded scenes, as they will not return.
33 | }
34 |
35 |
36 | }
37 |
38 |
--------------------------------------------------------------------------------
/AnimationDemo/AnimationDemo/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "20x20",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "20x20",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "29x29",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "29x29",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "40x40",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "40x40",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "iphone",
35 | "size" : "60x60",
36 | "scale" : "2x"
37 | },
38 | {
39 | "idiom" : "iphone",
40 | "size" : "60x60",
41 | "scale" : "3x"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "size" : "20x20",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "size" : "20x20",
51 | "scale" : "2x"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "size" : "29x29",
56 | "scale" : "1x"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "size" : "29x29",
61 | "scale" : "2x"
62 | },
63 | {
64 | "idiom" : "ipad",
65 | "size" : "40x40",
66 | "scale" : "1x"
67 | },
68 | {
69 | "idiom" : "ipad",
70 | "size" : "40x40",
71 | "scale" : "2x"
72 | },
73 | {
74 | "idiom" : "ipad",
75 | "size" : "76x76",
76 | "scale" : "1x"
77 | },
78 | {
79 | "idiom" : "ipad",
80 | "size" : "76x76",
81 | "scale" : "2x"
82 | },
83 | {
84 | "idiom" : "ipad",
85 | "size" : "83.5x83.5",
86 | "scale" : "2x"
87 | },
88 | {
89 | "idiom" : "ios-marketing",
90 | "size" : "1024x1024",
91 | "scale" : "1x"
92 | }
93 | ],
94 | "info" : {
95 | "version" : 1,
96 | "author" : "xcode"
97 | }
98 | }
--------------------------------------------------------------------------------
/AnimationDemo/AnimationDemo/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/AnimationDemo/AnimationDemo/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/AnimationDemo/AnimationDemo/ContentView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ContentView.swift
3 | // AnimationDemo
4 | //
5 | // Created by Neil Smyth on 10/16/19.
6 | // Copyright © 2019 eBookFrenzy. All rights reserved.
7 | //
8 |
9 | import SwiftUI
10 |
11 | struct ContentView: View {
12 |
13 | @State private var isButtonVisible: Bool = true
14 |
15 | var body: some View {
16 | VStack {
17 | Toggle(isOn:$isButtonVisible.animation(
18 | .linear(duration: 2))) {
19 | Text("Show/Hide Button")
20 | }
21 | .padding()
22 |
23 | if isButtonVisible {
24 | Button(action: {}) {
25 | Text("Example Button")
26 |
27 | }
28 | .font(.largeTitle)
29 | .transition(.asymmetric(insertion: .scale, removal: .slide))
30 | }
31 | }
32 |
33 | }
34 | }
35 |
36 | extension AnyTransition {
37 | static var fadeAndMove: AnyTransition {
38 | AnyTransition.opacity.combined(with: .move(edge: .top))
39 | }
40 | }
41 |
42 | struct ContentView_Previews: PreviewProvider {
43 | static var previews: some View {
44 | ContentView()
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/AnimationDemo/AnimationDemo/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE)
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 | LSRequiresIPhoneOS
22 |
23 | UIApplicationSceneManifest
24 |
25 | UIApplicationSupportsMultipleScenes
26 |
27 | UISceneConfigurations
28 |
29 | UIWindowSceneSessionRoleApplication
30 |
31 |
32 | UISceneConfigurationName
33 | Default Configuration
34 | UISceneDelegateClassName
35 | $(PRODUCT_MODULE_NAME).SceneDelegate
36 |
37 |
38 |
39 |
40 | UILaunchStoryboardName
41 | LaunchScreen
42 | UIRequiredDeviceCapabilities
43 |
44 | armv7
45 |
46 | UISupportedInterfaceOrientations
47 |
48 | UIInterfaceOrientationPortrait
49 | UIInterfaceOrientationLandscapeLeft
50 | UIInterfaceOrientationLandscapeRight
51 |
52 | UISupportedInterfaceOrientations~ipad
53 |
54 | UIInterfaceOrientationPortrait
55 | UIInterfaceOrientationPortraitUpsideDown
56 | UIInterfaceOrientationLandscapeLeft
57 | UIInterfaceOrientationLandscapeRight
58 |
59 |
60 |
61 |
--------------------------------------------------------------------------------
/AnimationDemo/AnimationDemo/Preview Content/Preview Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/AnimationDemo/AnimationDemo/SceneDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SceneDelegate.swift
3 | // AnimationDemo
4 | //
5 | // Created by Neil Smyth on 10/16/19.
6 | // Copyright © 2019 eBookFrenzy. All rights reserved.
7 | //
8 |
9 | import UIKit
10 | import SwiftUI
11 |
12 | class SceneDelegate: UIResponder, UIWindowSceneDelegate {
13 |
14 | var window: UIWindow?
15 |
16 |
17 | func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
18 | // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
19 | // If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
20 | // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
21 |
22 | // Create the SwiftUI view that provides the window contents.
23 | let contentView = ContentView()
24 |
25 | // Use a UIHostingController as window root view controller.
26 | if let windowScene = scene as? UIWindowScene {
27 | let window = UIWindow(windowScene: windowScene)
28 | window.rootViewController = UIHostingController(rootView: contentView)
29 | self.window = window
30 | window.makeKeyAndVisible()
31 | }
32 | }
33 |
34 | func sceneDidDisconnect(_ scene: UIScene) {
35 | // Called as the scene is being released by the system.
36 | // This occurs shortly after the scene enters the background, or when its session is discarded.
37 | // Release any resources associated with this scene that can be re-created the next time the scene connects.
38 | // The scene may re-connect later, as its session was not neccessarily discarded (see `application:didDiscardSceneSessions` instead).
39 | }
40 |
41 | func sceneDidBecomeActive(_ scene: UIScene) {
42 | // Called when the scene has moved from an inactive state to an active state.
43 | // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive.
44 | }
45 |
46 | func sceneWillResignActive(_ scene: UIScene) {
47 | // Called when the scene will move from an active state to an inactive state.
48 | // This may occur due to temporary interruptions (ex. an incoming phone call).
49 | }
50 |
51 | func sceneWillEnterForeground(_ scene: UIScene) {
52 | // Called as the scene transitions from the background to the foreground.
53 | // Use this method to undo the changes made on entering the background.
54 | }
55 |
56 | func sceneDidEnterBackground(_ scene: UIScene) {
57 | // Called as the scene transitions from the foreground to the background.
58 | // Use this method to save data, release shared resources, and store enough scene-specific state information
59 | // to restore the scene back to its current state.
60 | }
61 |
62 |
63 | }
64 |
65 |
--------------------------------------------------------------------------------
/CarAssets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/CarAssets.xcassets/chevrolet_volt.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "chevrolet_volt.jpg",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/CarAssets.xcassets/chevrolet_volt.imageset/chevrolet_volt.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Jpub/SwiftUI/defbcdd40638ec4d8d55e6693e7c878a00b1d135/CarAssets.xcassets/chevrolet_volt.imageset/chevrolet_volt.jpg
--------------------------------------------------------------------------------
/CarAssets.xcassets/nissan_leaf.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "nissan_leaf.jpg",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/CarAssets.xcassets/nissan_leaf.imageset/nissan_leaf.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Jpub/SwiftUI/defbcdd40638ec4d8d55e6693e7c878a00b1d135/CarAssets.xcassets/nissan_leaf.imageset/nissan_leaf.jpg
--------------------------------------------------------------------------------
/CarAssets.xcassets/tesla_model_3.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "tesla_model_3.jpg",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/CarAssets.xcassets/tesla_model_3.imageset/tesla_model_3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Jpub/SwiftUI/defbcdd40638ec4d8d55e6693e7c878a00b1d135/CarAssets.xcassets/tesla_model_3.imageset/tesla_model_3.jpg
--------------------------------------------------------------------------------
/CarAssets.xcassets/tesla_model_s.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "tesla_model_s.jpg",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/CarAssets.xcassets/tesla_model_s.imageset/tesla_model_s.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Jpub/SwiftUI/defbcdd40638ec4d8d55e6693e7c878a00b1d135/CarAssets.xcassets/tesla_model_s.imageset/tesla_model_s.jpg
--------------------------------------------------------------------------------
/CarAssets.xcassets/toyota_prius.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "toyota_prius.jpg",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/CarAssets.xcassets/toyota_prius.imageset/toyota_prius.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Jpub/SwiftUI/defbcdd40638ec4d8d55e6693e7c878a00b1d135/CarAssets.xcassets/toyota_prius.imageset/toyota_prius.jpg
--------------------------------------------------------------------------------
/CarData/carData.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "id": "aa32jj887hhg55",
4 | "name": "Tesla Model 3",
5 | "description": "Luxury 4-door all-electic car. Range of 310 miles. 0-60mph in 3.2 seconds",
6 | "isHybrid": false,
7 | "imageName": "tesla_model_3"
8 | },
9 | {
10 | "id": "bb32jj887hhg77",
11 | "name": "Tesla Model S",
12 | "description": "5-door lift-back electric car. Performance model has a three-phase, four-pole AC induction 416 hp (310 kW) and 443 ft⋅lb (601 N⋅m) rear-mounted electric motor",
13 | "isHybrid": false,
14 | "imageName": "tesla_model_s"
15 | },
16 | {
17 | "id": "cc32jj887hhg66",
18 | "name": "Toyota Prius",
19 | "description": "5-door liftback full hybrid electric automobile developed by Toyota.",
20 | "isHybrid": true,
21 | "imageName": "toyota_prius"
22 | },
23 | {
24 | "id": "dd32jj887hhg88",
25 | "name": "Nissan Leaf",
26 | "description": "A compact five-door hatchback all-electric car manufactured by Nissan",
27 | "isHybrid": false,
28 | "imageName": "nissan_leaf"
29 | },
30 | {
31 | "id": "ee32jj887hhg99",
32 | "name": "Chevrolet Volt",
33 | "description": "5-door hatchback plug-in hybrid car manufactured by General Motors.",
34 | "isHybrid": true,
35 | "imageName": "chevrolet_volt"
36 | }
37 |
38 | ]
39 |
--------------------------------------------------------------------------------
/ContextMenuDemo/ContextMenuDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/ContextMenuDemo/ContextMenuDemo.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ContextMenuDemo/ContextMenuDemo.xcodeproj/project.xcworkspace/xcuserdata/neilsmyth.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Jpub/SwiftUI/defbcdd40638ec4d8d55e6693e7c878a00b1d135/ContextMenuDemo/ContextMenuDemo.xcodeproj/project.xcworkspace/xcuserdata/neilsmyth.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/ContextMenuDemo/ContextMenuDemo.xcodeproj/xcuserdata/neilsmyth.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | ContextMenuDemo.xcscheme_^#shared#^_
8 |
9 | orderHint
10 | 0
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/ContextMenuDemo/ContextMenuDemo/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // ContextMenuDemo
4 | //
5 | // Created by Neil Smyth on 10/15/19.
6 | // Copyright © 2019 eBookFrenzy. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | @UIApplicationMain
12 | class AppDelegate: UIResponder, UIApplicationDelegate {
13 |
14 |
15 |
16 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
17 | // Override point for customization after application launch.
18 | return true
19 | }
20 |
21 | // MARK: UISceneSession Lifecycle
22 |
23 | func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
24 | // Called when a new scene session is being created.
25 | // Use this method to select a configuration to create the new scene with.
26 | return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
27 | }
28 |
29 | func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) {
30 | // Called when the user discards a scene session.
31 | // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
32 | // Use this method to release any resources that were specific to the discarded scenes, as they will not return.
33 | }
34 |
35 |
36 | }
37 |
38 |
--------------------------------------------------------------------------------
/ContextMenuDemo/ContextMenuDemo/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "20x20",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "20x20",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "29x29",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "29x29",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "40x40",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "40x40",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "iphone",
35 | "size" : "60x60",
36 | "scale" : "2x"
37 | },
38 | {
39 | "idiom" : "iphone",
40 | "size" : "60x60",
41 | "scale" : "3x"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "size" : "20x20",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "size" : "20x20",
51 | "scale" : "2x"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "size" : "29x29",
56 | "scale" : "1x"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "size" : "29x29",
61 | "scale" : "2x"
62 | },
63 | {
64 | "idiom" : "ipad",
65 | "size" : "40x40",
66 | "scale" : "1x"
67 | },
68 | {
69 | "idiom" : "ipad",
70 | "size" : "40x40",
71 | "scale" : "2x"
72 | },
73 | {
74 | "idiom" : "ipad",
75 | "size" : "76x76",
76 | "scale" : "1x"
77 | },
78 | {
79 | "idiom" : "ipad",
80 | "size" : "76x76",
81 | "scale" : "2x"
82 | },
83 | {
84 | "idiom" : "ipad",
85 | "size" : "83.5x83.5",
86 | "scale" : "2x"
87 | },
88 | {
89 | "idiom" : "ios-marketing",
90 | "size" : "1024x1024",
91 | "scale" : "1x"
92 | }
93 | ],
94 | "info" : {
95 | "version" : 1,
96 | "author" : "xcode"
97 | }
98 | }
--------------------------------------------------------------------------------
/ContextMenuDemo/ContextMenuDemo/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/ContextMenuDemo/ContextMenuDemo/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/ContextMenuDemo/ContextMenuDemo/ContentView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ContentView.swift
3 | // ContextMenuDemo
4 | //
5 | // Created by Neil Smyth on 10/15/19.
6 | // Copyright © 2019 eBookFrenzy. All rights reserved.
7 | //
8 |
9 | import SwiftUI
10 |
11 | struct ContentView: View {
12 |
13 | @State private var foregroundColor: Color = Color.black
14 | @State private var backgroundColor: Color = Color.white
15 |
16 | var body: some View {
17 | Text("Hello World")
18 | .font(.largeTitle)
19 | .padding()
20 | .foregroundColor(foregroundColor)
21 | .background(backgroundColor)
22 | .contextMenu {
23 | Button(action: {
24 | self.foregroundColor = .black
25 | self.backgroundColor = .white
26 | }) {
27 | Text("Normal Colors")
28 | .font(.caption)
29 | Image(systemName: "paintbrush")
30 | }
31 |
32 | Button(action: {
33 | self.foregroundColor = .white
34 | self.backgroundColor = .black
35 | }) {
36 | Text("Inverted Colors")
37 | Image(systemName: "paintbrush.fill")
38 | }
39 | }
40 | }
41 | }
42 |
43 | struct ContentView_Previews: PreviewProvider {
44 | static var previews: some View {
45 | ContentView()
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/ContextMenuDemo/ContextMenuDemo/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE)
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 | LSRequiresIPhoneOS
22 |
23 | UIApplicationSceneManifest
24 |
25 | UIApplicationSupportsMultipleScenes
26 |
27 | UISceneConfigurations
28 |
29 | UIWindowSceneSessionRoleApplication
30 |
31 |
32 | UISceneConfigurationName
33 | Default Configuration
34 | UISceneDelegateClassName
35 | $(PRODUCT_MODULE_NAME).SceneDelegate
36 |
37 |
38 |
39 |
40 | UILaunchStoryboardName
41 | LaunchScreen
42 | UIRequiredDeviceCapabilities
43 |
44 | armv7
45 |
46 | UISupportedInterfaceOrientations
47 |
48 | UIInterfaceOrientationPortrait
49 | UIInterfaceOrientationLandscapeLeft
50 | UIInterfaceOrientationLandscapeRight
51 |
52 | UISupportedInterfaceOrientations~ipad
53 |
54 | UIInterfaceOrientationPortrait
55 | UIInterfaceOrientationPortraitUpsideDown
56 | UIInterfaceOrientationLandscapeLeft
57 | UIInterfaceOrientationLandscapeRight
58 |
59 |
60 |
61 |
--------------------------------------------------------------------------------
/ContextMenuDemo/ContextMenuDemo/Preview Content/Preview Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/ContextMenuDemo/ContextMenuDemo/SceneDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SceneDelegate.swift
3 | // ContextMenuDemo
4 | //
5 | // Created by Neil Smyth on 10/15/19.
6 | // Copyright © 2019 eBookFrenzy. All rights reserved.
7 | //
8 |
9 | import UIKit
10 | import SwiftUI
11 |
12 | class SceneDelegate: UIResponder, UIWindowSceneDelegate {
13 |
14 | var window: UIWindow?
15 |
16 |
17 | func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
18 | // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
19 | // If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
20 | // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
21 |
22 | // Create the SwiftUI view that provides the window contents.
23 | let contentView = ContentView()
24 |
25 | // Use a UIHostingController as window root view controller.
26 | if let windowScene = scene as? UIWindowScene {
27 | let window = UIWindow(windowScene: windowScene)
28 | window.rootViewController = UIHostingController(rootView: contentView)
29 | self.window = window
30 | window.makeKeyAndVisible()
31 | }
32 | }
33 |
34 | func sceneDidDisconnect(_ scene: UIScene) {
35 | // Called as the scene is being released by the system.
36 | // This occurs shortly after the scene enters the background, or when its session is discarded.
37 | // Release any resources associated with this scene that can be re-created the next time the scene connects.
38 | // The scene may re-connect later, as its session was not neccessarily discarded (see `application:didDiscardSceneSessions` instead).
39 | }
40 |
41 | func sceneDidBecomeActive(_ scene: UIScene) {
42 | // Called when the scene has moved from an inactive state to an active state.
43 | // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive.
44 | }
45 |
46 | func sceneWillResignActive(_ scene: UIScene) {
47 | // Called when the scene will move from an active state to an inactive state.
48 | // This may occur due to temporary interruptions (ex. an incoming phone call).
49 | }
50 |
51 | func sceneWillEnterForeground(_ scene: UIScene) {
52 | // Called as the scene transitions from the background to the foreground.
53 | // Use this method to undo the changes made on entering the background.
54 | }
55 |
56 | func sceneDidEnterBackground(_ scene: UIScene) {
57 | // Called as the scene transitions from the foreground to the background.
58 | // Use this method to save data, release shared resources, and store enough scene-specific state information
59 | // to restore the scene back to its current state.
60 | }
61 |
62 |
63 | }
64 |
65 |
--------------------------------------------------------------------------------
/DrawDemo/DrawDemo.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 50;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 88F3D77E23576A41003F0E58 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 88F3D77D23576A41003F0E58 /* AppDelegate.swift */; };
11 | 88F3D78023576A41003F0E58 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 88F3D77F23576A41003F0E58 /* SceneDelegate.swift */; };
12 | 88F3D78223576A41003F0E58 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 88F3D78123576A41003F0E58 /* ContentView.swift */; };
13 | 88F3D78423576A45003F0E58 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 88F3D78323576A45003F0E58 /* Assets.xcassets */; };
14 | 88F3D78723576A45003F0E58 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 88F3D78623576A45003F0E58 /* Preview Assets.xcassets */; };
15 | 88F3D78A23576A45003F0E58 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 88F3D78823576A45003F0E58 /* LaunchScreen.storyboard */; };
16 | /* End PBXBuildFile section */
17 |
18 | /* Begin PBXFileReference section */
19 | 88F3D77A23576A41003F0E58 /* DrawDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = DrawDemo.app; sourceTree = BUILT_PRODUCTS_DIR; };
20 | 88F3D77D23576A41003F0E58 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
21 | 88F3D77F23576A41003F0E58 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; };
22 | 88F3D78123576A41003F0E58 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; };
23 | 88F3D78323576A45003F0E58 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
24 | 88F3D78623576A45003F0E58 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; };
25 | 88F3D78923576A45003F0E58 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; };
26 | 88F3D78B23576A45003F0E58 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
27 | /* End PBXFileReference section */
28 |
29 | /* Begin PBXFrameworksBuildPhase section */
30 | 88F3D77723576A41003F0E58 /* Frameworks */ = {
31 | isa = PBXFrameworksBuildPhase;
32 | buildActionMask = 2147483647;
33 | files = (
34 | );
35 | runOnlyForDeploymentPostprocessing = 0;
36 | };
37 | /* End PBXFrameworksBuildPhase section */
38 |
39 | /* Begin PBXGroup section */
40 | 88F3D77123576A41003F0E58 = {
41 | isa = PBXGroup;
42 | children = (
43 | 88F3D77C23576A41003F0E58 /* DrawDemo */,
44 | 88F3D77B23576A41003F0E58 /* Products */,
45 | );
46 | sourceTree = "";
47 | };
48 | 88F3D77B23576A41003F0E58 /* Products */ = {
49 | isa = PBXGroup;
50 | children = (
51 | 88F3D77A23576A41003F0E58 /* DrawDemo.app */,
52 | );
53 | name = Products;
54 | sourceTree = "";
55 | };
56 | 88F3D77C23576A41003F0E58 /* DrawDemo */ = {
57 | isa = PBXGroup;
58 | children = (
59 | 88F3D77D23576A41003F0E58 /* AppDelegate.swift */,
60 | 88F3D77F23576A41003F0E58 /* SceneDelegate.swift */,
61 | 88F3D78123576A41003F0E58 /* ContentView.swift */,
62 | 88F3D78323576A45003F0E58 /* Assets.xcassets */,
63 | 88F3D78823576A45003F0E58 /* LaunchScreen.storyboard */,
64 | 88F3D78B23576A45003F0E58 /* Info.plist */,
65 | 88F3D78523576A45003F0E58 /* Preview Content */,
66 | );
67 | path = DrawDemo;
68 | sourceTree = "";
69 | };
70 | 88F3D78523576A45003F0E58 /* Preview Content */ = {
71 | isa = PBXGroup;
72 | children = (
73 | 88F3D78623576A45003F0E58 /* Preview Assets.xcassets */,
74 | );
75 | path = "Preview Content";
76 | sourceTree = "";
77 | };
78 | /* End PBXGroup section */
79 |
80 | /* Begin PBXNativeTarget section */
81 | 88F3D77923576A41003F0E58 /* DrawDemo */ = {
82 | isa = PBXNativeTarget;
83 | buildConfigurationList = 88F3D78E23576A45003F0E58 /* Build configuration list for PBXNativeTarget "DrawDemo" */;
84 | buildPhases = (
85 | 88F3D77623576A41003F0E58 /* Sources */,
86 | 88F3D77723576A41003F0E58 /* Frameworks */,
87 | 88F3D77823576A41003F0E58 /* Resources */,
88 | );
89 | buildRules = (
90 | );
91 | dependencies = (
92 | );
93 | name = DrawDemo;
94 | productName = DrawDemo;
95 | productReference = 88F3D77A23576A41003F0E58 /* DrawDemo.app */;
96 | productType = "com.apple.product-type.application";
97 | };
98 | /* End PBXNativeTarget section */
99 |
100 | /* Begin PBXProject section */
101 | 88F3D77223576A41003F0E58 /* Project object */ = {
102 | isa = PBXProject;
103 | attributes = {
104 | LastSwiftUpdateCheck = 1100;
105 | LastUpgradeCheck = 1100;
106 | ORGANIZATIONNAME = eBookFrenzy;
107 | TargetAttributes = {
108 | 88F3D77923576A41003F0E58 = {
109 | CreatedOnToolsVersion = 11.0;
110 | };
111 | };
112 | };
113 | buildConfigurationList = 88F3D77523576A41003F0E58 /* Build configuration list for PBXProject "DrawDemo" */;
114 | compatibilityVersion = "Xcode 9.3";
115 | developmentRegion = en;
116 | hasScannedForEncodings = 0;
117 | knownRegions = (
118 | en,
119 | Base,
120 | );
121 | mainGroup = 88F3D77123576A41003F0E58;
122 | productRefGroup = 88F3D77B23576A41003F0E58 /* Products */;
123 | projectDirPath = "";
124 | projectRoot = "";
125 | targets = (
126 | 88F3D77923576A41003F0E58 /* DrawDemo */,
127 | );
128 | };
129 | /* End PBXProject section */
130 |
131 | /* Begin PBXResourcesBuildPhase section */
132 | 88F3D77823576A41003F0E58 /* Resources */ = {
133 | isa = PBXResourcesBuildPhase;
134 | buildActionMask = 2147483647;
135 | files = (
136 | 88F3D78A23576A45003F0E58 /* LaunchScreen.storyboard in Resources */,
137 | 88F3D78723576A45003F0E58 /* Preview Assets.xcassets in Resources */,
138 | 88F3D78423576A45003F0E58 /* Assets.xcassets in Resources */,
139 | );
140 | runOnlyForDeploymentPostprocessing = 0;
141 | };
142 | /* End PBXResourcesBuildPhase section */
143 |
144 | /* Begin PBXSourcesBuildPhase section */
145 | 88F3D77623576A41003F0E58 /* Sources */ = {
146 | isa = PBXSourcesBuildPhase;
147 | buildActionMask = 2147483647;
148 | files = (
149 | 88F3D77E23576A41003F0E58 /* AppDelegate.swift in Sources */,
150 | 88F3D78023576A41003F0E58 /* SceneDelegate.swift in Sources */,
151 | 88F3D78223576A41003F0E58 /* ContentView.swift in Sources */,
152 | );
153 | runOnlyForDeploymentPostprocessing = 0;
154 | };
155 | /* End PBXSourcesBuildPhase section */
156 |
157 | /* Begin PBXVariantGroup section */
158 | 88F3D78823576A45003F0E58 /* LaunchScreen.storyboard */ = {
159 | isa = PBXVariantGroup;
160 | children = (
161 | 88F3D78923576A45003F0E58 /* Base */,
162 | );
163 | name = LaunchScreen.storyboard;
164 | sourceTree = "";
165 | };
166 | /* End PBXVariantGroup section */
167 |
168 | /* Begin XCBuildConfiguration section */
169 | 88F3D78C23576A45003F0E58 /* Debug */ = {
170 | isa = XCBuildConfiguration;
171 | buildSettings = {
172 | ALWAYS_SEARCH_USER_PATHS = NO;
173 | CLANG_ANALYZER_NONNULL = YES;
174 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
175 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
176 | CLANG_CXX_LIBRARY = "libc++";
177 | CLANG_ENABLE_MODULES = YES;
178 | CLANG_ENABLE_OBJC_ARC = YES;
179 | CLANG_ENABLE_OBJC_WEAK = YES;
180 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
181 | CLANG_WARN_BOOL_CONVERSION = YES;
182 | CLANG_WARN_COMMA = YES;
183 | CLANG_WARN_CONSTANT_CONVERSION = YES;
184 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
185 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
186 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
187 | CLANG_WARN_EMPTY_BODY = YES;
188 | CLANG_WARN_ENUM_CONVERSION = YES;
189 | CLANG_WARN_INFINITE_RECURSION = YES;
190 | CLANG_WARN_INT_CONVERSION = YES;
191 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
192 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
193 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
194 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
195 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
196 | CLANG_WARN_STRICT_PROTOTYPES = YES;
197 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
198 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
199 | CLANG_WARN_UNREACHABLE_CODE = YES;
200 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
201 | COPY_PHASE_STRIP = NO;
202 | DEBUG_INFORMATION_FORMAT = dwarf;
203 | ENABLE_STRICT_OBJC_MSGSEND = YES;
204 | ENABLE_TESTABILITY = YES;
205 | GCC_C_LANGUAGE_STANDARD = gnu11;
206 | GCC_DYNAMIC_NO_PIC = NO;
207 | GCC_NO_COMMON_BLOCKS = YES;
208 | GCC_OPTIMIZATION_LEVEL = 0;
209 | GCC_PREPROCESSOR_DEFINITIONS = (
210 | "DEBUG=1",
211 | "$(inherited)",
212 | );
213 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
214 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
215 | GCC_WARN_UNDECLARED_SELECTOR = YES;
216 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
217 | GCC_WARN_UNUSED_FUNCTION = YES;
218 | GCC_WARN_UNUSED_VARIABLE = YES;
219 | IPHONEOS_DEPLOYMENT_TARGET = 13.0;
220 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
221 | MTL_FAST_MATH = YES;
222 | ONLY_ACTIVE_ARCH = YES;
223 | SDKROOT = iphoneos;
224 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
225 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
226 | };
227 | name = Debug;
228 | };
229 | 88F3D78D23576A45003F0E58 /* Release */ = {
230 | isa = XCBuildConfiguration;
231 | buildSettings = {
232 | ALWAYS_SEARCH_USER_PATHS = NO;
233 | CLANG_ANALYZER_NONNULL = YES;
234 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
235 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
236 | CLANG_CXX_LIBRARY = "libc++";
237 | CLANG_ENABLE_MODULES = YES;
238 | CLANG_ENABLE_OBJC_ARC = YES;
239 | CLANG_ENABLE_OBJC_WEAK = YES;
240 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
241 | CLANG_WARN_BOOL_CONVERSION = YES;
242 | CLANG_WARN_COMMA = YES;
243 | CLANG_WARN_CONSTANT_CONVERSION = YES;
244 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
245 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
246 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
247 | CLANG_WARN_EMPTY_BODY = YES;
248 | CLANG_WARN_ENUM_CONVERSION = YES;
249 | CLANG_WARN_INFINITE_RECURSION = YES;
250 | CLANG_WARN_INT_CONVERSION = YES;
251 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
252 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
253 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
254 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
255 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
256 | CLANG_WARN_STRICT_PROTOTYPES = YES;
257 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
258 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
259 | CLANG_WARN_UNREACHABLE_CODE = YES;
260 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
261 | COPY_PHASE_STRIP = NO;
262 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
263 | ENABLE_NS_ASSERTIONS = NO;
264 | ENABLE_STRICT_OBJC_MSGSEND = YES;
265 | GCC_C_LANGUAGE_STANDARD = gnu11;
266 | GCC_NO_COMMON_BLOCKS = YES;
267 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
268 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
269 | GCC_WARN_UNDECLARED_SELECTOR = YES;
270 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
271 | GCC_WARN_UNUSED_FUNCTION = YES;
272 | GCC_WARN_UNUSED_VARIABLE = YES;
273 | IPHONEOS_DEPLOYMENT_TARGET = 13.0;
274 | MTL_ENABLE_DEBUG_INFO = NO;
275 | MTL_FAST_MATH = YES;
276 | SDKROOT = iphoneos;
277 | SWIFT_COMPILATION_MODE = wholemodule;
278 | SWIFT_OPTIMIZATION_LEVEL = "-O";
279 | VALIDATE_PRODUCT = YES;
280 | };
281 | name = Release;
282 | };
283 | 88F3D78F23576A45003F0E58 /* Debug */ = {
284 | isa = XCBuildConfiguration;
285 | buildSettings = {
286 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
287 | CODE_SIGN_STYLE = Automatic;
288 | DEVELOPMENT_ASSET_PATHS = "\"DrawDemo/Preview Content\"";
289 | DEVELOPMENT_TEAM = 2UTH99GSB7;
290 | ENABLE_PREVIEWS = YES;
291 | INFOPLIST_FILE = DrawDemo/Info.plist;
292 | LD_RUNPATH_SEARCH_PATHS = (
293 | "$(inherited)",
294 | "@executable_path/Frameworks",
295 | );
296 | PRODUCT_BUNDLE_IDENTIFIER = com.ebookfrenzy.DrawDemo;
297 | PRODUCT_NAME = "$(TARGET_NAME)";
298 | SWIFT_VERSION = 5.0;
299 | TARGETED_DEVICE_FAMILY = "1,2";
300 | };
301 | name = Debug;
302 | };
303 | 88F3D79023576A45003F0E58 /* Release */ = {
304 | isa = XCBuildConfiguration;
305 | buildSettings = {
306 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
307 | CODE_SIGN_STYLE = Automatic;
308 | DEVELOPMENT_ASSET_PATHS = "\"DrawDemo/Preview Content\"";
309 | DEVELOPMENT_TEAM = 2UTH99GSB7;
310 | ENABLE_PREVIEWS = YES;
311 | INFOPLIST_FILE = DrawDemo/Info.plist;
312 | LD_RUNPATH_SEARCH_PATHS = (
313 | "$(inherited)",
314 | "@executable_path/Frameworks",
315 | );
316 | PRODUCT_BUNDLE_IDENTIFIER = com.ebookfrenzy.DrawDemo;
317 | PRODUCT_NAME = "$(TARGET_NAME)";
318 | SWIFT_VERSION = 5.0;
319 | TARGETED_DEVICE_FAMILY = "1,2";
320 | };
321 | name = Release;
322 | };
323 | /* End XCBuildConfiguration section */
324 |
325 | /* Begin XCConfigurationList section */
326 | 88F3D77523576A41003F0E58 /* Build configuration list for PBXProject "DrawDemo" */ = {
327 | isa = XCConfigurationList;
328 | buildConfigurations = (
329 | 88F3D78C23576A45003F0E58 /* Debug */,
330 | 88F3D78D23576A45003F0E58 /* Release */,
331 | );
332 | defaultConfigurationIsVisible = 0;
333 | defaultConfigurationName = Release;
334 | };
335 | 88F3D78E23576A45003F0E58 /* Build configuration list for PBXNativeTarget "DrawDemo" */ = {
336 | isa = XCConfigurationList;
337 | buildConfigurations = (
338 | 88F3D78F23576A45003F0E58 /* Debug */,
339 | 88F3D79023576A45003F0E58 /* Release */,
340 | );
341 | defaultConfigurationIsVisible = 0;
342 | defaultConfigurationName = Release;
343 | };
344 | /* End XCConfigurationList section */
345 | };
346 | rootObject = 88F3D77223576A41003F0E58 /* Project object */;
347 | }
348 |
--------------------------------------------------------------------------------
/DrawDemo/DrawDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/DrawDemo/DrawDemo.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/DrawDemo/DrawDemo.xcodeproj/project.xcworkspace/xcuserdata/neilsmyth.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Jpub/SwiftUI/defbcdd40638ec4d8d55e6693e7c878a00b1d135/DrawDemo/DrawDemo.xcodeproj/project.xcworkspace/xcuserdata/neilsmyth.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/DrawDemo/DrawDemo.xcodeproj/xcuserdata/neilsmyth.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | DrawDemo.xcscheme_^#shared#^_
8 |
9 | orderHint
10 | 0
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/DrawDemo/DrawDemo/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // DrawDemo
4 | //
5 | // Created by Neil Smyth on 10/16/19.
6 | // Copyright © 2019 eBookFrenzy. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | @UIApplicationMain
12 | class AppDelegate: UIResponder, UIApplicationDelegate {
13 |
14 |
15 |
16 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
17 | // Override point for customization after application launch.
18 | return true
19 | }
20 |
21 | // MARK: UISceneSession Lifecycle
22 |
23 | func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
24 | // Called when a new scene session is being created.
25 | // Use this method to select a configuration to create the new scene with.
26 | return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
27 | }
28 |
29 | func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) {
30 | // Called when the user discards a scene session.
31 | // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
32 | // Use this method to release any resources that were specific to the discarded scenes, as they will not return.
33 | }
34 |
35 |
36 | }
37 |
38 |
--------------------------------------------------------------------------------
/DrawDemo/DrawDemo/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "20x20",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "20x20",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "29x29",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "29x29",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "40x40",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "40x40",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "iphone",
35 | "size" : "60x60",
36 | "scale" : "2x"
37 | },
38 | {
39 | "idiom" : "iphone",
40 | "size" : "60x60",
41 | "scale" : "3x"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "size" : "20x20",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "size" : "20x20",
51 | "scale" : "2x"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "size" : "29x29",
56 | "scale" : "1x"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "size" : "29x29",
61 | "scale" : "2x"
62 | },
63 | {
64 | "idiom" : "ipad",
65 | "size" : "40x40",
66 | "scale" : "1x"
67 | },
68 | {
69 | "idiom" : "ipad",
70 | "size" : "40x40",
71 | "scale" : "2x"
72 | },
73 | {
74 | "idiom" : "ipad",
75 | "size" : "76x76",
76 | "scale" : "1x"
77 | },
78 | {
79 | "idiom" : "ipad",
80 | "size" : "76x76",
81 | "scale" : "2x"
82 | },
83 | {
84 | "idiom" : "ipad",
85 | "size" : "83.5x83.5",
86 | "scale" : "2x"
87 | },
88 | {
89 | "idiom" : "ios-marketing",
90 | "size" : "1024x1024",
91 | "scale" : "1x"
92 | }
93 | ],
94 | "info" : {
95 | "version" : 1,
96 | "author" : "xcode"
97 | }
98 | }
--------------------------------------------------------------------------------
/DrawDemo/DrawDemo/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/DrawDemo/DrawDemo/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/DrawDemo/DrawDemo/ContentView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ContentView.swift
3 | // DrawDemo
4 | //
5 | // Created by Neil Smyth on 10/16/19.
6 | // Copyright © 2019 eBookFrenzy. All rights reserved.
7 | //
8 |
9 | import SwiftUI
10 |
11 | struct ContentView: View {
12 |
13 | let colors = Gradient(colors: [Color.red, Color.yellow,
14 | Color.green, Color.blue, Color.purple])
15 |
16 | var body: some View {
17 |
18 | MyShape()
19 | .fill(RadialGradient(gradient: colors,
20 | center: .center,
21 | startRadius: CGFloat(0),
22 | endRadius: CGFloat(300)))
23 | .background(LinearGradient(gradient: Gradient(colors:
24 | [Color.black, Color.white]),
25 | startPoint: .topLeading,
26 | endPoint: .bottomTrailing))
27 | .frame(width: 360, height: 350)
28 | }
29 | }
30 |
31 |
32 | struct MyShape: Shape {
33 | func path(in rect: CGRect) -> Path {
34 | var path = Path()
35 |
36 | path.move(to: CGPoint(x: rect.minX, y: rect.minY))
37 | path.addQuadCurve(to: CGPoint(x: rect.minX, y: rect.maxY),
38 | control: CGPoint(x: rect.midX, y: rect.midY))
39 | path.addLine(to: CGPoint(x: rect.minX, y: rect.maxY))
40 | path.addLine(to: CGPoint(x: rect.maxX, y: rect.maxY))
41 | path.closeSubpath()
42 | return path
43 | }
44 | }
45 |
46 | struct ContentView_Previews: PreviewProvider {
47 | static var previews: some View {
48 | ContentView()
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/DrawDemo/DrawDemo/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE)
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 | LSRequiresIPhoneOS
22 |
23 | UIApplicationSceneManifest
24 |
25 | UIApplicationSupportsMultipleScenes
26 |
27 | UISceneConfigurations
28 |
29 | UIWindowSceneSessionRoleApplication
30 |
31 |
32 | UISceneConfigurationName
33 | Default Configuration
34 | UISceneDelegateClassName
35 | $(PRODUCT_MODULE_NAME).SceneDelegate
36 |
37 |
38 |
39 |
40 | UILaunchStoryboardName
41 | LaunchScreen
42 | UIRequiredDeviceCapabilities
43 |
44 | armv7
45 |
46 | UISupportedInterfaceOrientations
47 |
48 | UIInterfaceOrientationPortrait
49 | UIInterfaceOrientationLandscapeLeft
50 | UIInterfaceOrientationLandscapeRight
51 |
52 | UISupportedInterfaceOrientations~ipad
53 |
54 | UIInterfaceOrientationPortrait
55 | UIInterfaceOrientationPortraitUpsideDown
56 | UIInterfaceOrientationLandscapeLeft
57 | UIInterfaceOrientationLandscapeRight
58 |
59 |
60 |
61 |
--------------------------------------------------------------------------------
/DrawDemo/DrawDemo/Preview Content/Preview Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/DrawDemo/DrawDemo/SceneDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SceneDelegate.swift
3 | // DrawDemo
4 | //
5 | // Created by Neil Smyth on 10/16/19.
6 | // Copyright © 2019 eBookFrenzy. All rights reserved.
7 | //
8 |
9 | import UIKit
10 | import SwiftUI
11 |
12 | class SceneDelegate: UIResponder, UIWindowSceneDelegate {
13 |
14 | var window: UIWindow?
15 |
16 |
17 | func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
18 | // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
19 | // If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
20 | // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
21 |
22 | // Create the SwiftUI view that provides the window contents.
23 | let contentView = ContentView()
24 |
25 | // Use a UIHostingController as window root view controller.
26 | if let windowScene = scene as? UIWindowScene {
27 | let window = UIWindow(windowScene: windowScene)
28 | window.rootViewController = UIHostingController(rootView: contentView)
29 | self.window = window
30 | window.makeKeyAndVisible()
31 | }
32 | }
33 |
34 | func sceneDidDisconnect(_ scene: UIScene) {
35 | // Called as the scene is being released by the system.
36 | // This occurs shortly after the scene enters the background, or when its session is discarded.
37 | // Release any resources associated with this scene that can be re-created the next time the scene connects.
38 | // The scene may re-connect later, as its session was not neccessarily discarded (see `application:didDiscardSceneSessions` instead).
39 | }
40 |
41 | func sceneDidBecomeActive(_ scene: UIScene) {
42 | // Called when the scene has moved from an inactive state to an active state.
43 | // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive.
44 | }
45 |
46 | func sceneWillResignActive(_ scene: UIScene) {
47 | // Called when the scene will move from an active state to an inactive state.
48 | // This may occur due to temporary interruptions (ex. an incoming phone call).
49 | }
50 |
51 | func sceneWillEnterForeground(_ scene: UIScene) {
52 | // Called as the scene transitions from the background to the foreground.
53 | // Use this method to undo the changes made on entering the background.
54 | }
55 |
56 | func sceneDidEnterBackground(_ scene: UIScene) {
57 | // Called as the scene transitions from the foreground to the background.
58 | // Use this method to save data, release shared resources, and store enough scene-specific state information
59 | // to restore the scene back to its current state.
60 | }
61 |
62 |
63 | }
64 |
65 |
--------------------------------------------------------------------------------
/GestureDemo/GestureDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/GestureDemo/GestureDemo.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/GestureDemo/GestureDemo.xcodeproj/project.xcworkspace/xcuserdata/neilsmyth.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Jpub/SwiftUI/defbcdd40638ec4d8d55e6693e7c878a00b1d135/GestureDemo/GestureDemo.xcodeproj/project.xcworkspace/xcuserdata/neilsmyth.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/GestureDemo/GestureDemo.xcodeproj/xcuserdata/neilsmyth.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | GestureDemo.xcscheme_^#shared#^_
8 |
9 | orderHint
10 | 0
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/GestureDemo/GestureDemo/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // GestureDemo
4 | //
5 | // Created by Neil Smyth on 10/16/19.
6 | // Copyright © 2019 eBookFrenzy. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | @UIApplicationMain
12 | class AppDelegate: UIResponder, UIApplicationDelegate {
13 |
14 |
15 |
16 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
17 | // Override point for customization after application launch.
18 | return true
19 | }
20 |
21 | // MARK: UISceneSession Lifecycle
22 |
23 | func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
24 | // Called when a new scene session is being created.
25 | // Use this method to select a configuration to create the new scene with.
26 | return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
27 | }
28 |
29 | func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) {
30 | // Called when the user discards a scene session.
31 | // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
32 | // Use this method to release any resources that were specific to the discarded scenes, as they will not return.
33 | }
34 |
35 |
36 | }
37 |
38 |
--------------------------------------------------------------------------------
/GestureDemo/GestureDemo/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "20x20",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "20x20",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "29x29",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "29x29",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "40x40",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "40x40",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "iphone",
35 | "size" : "60x60",
36 | "scale" : "2x"
37 | },
38 | {
39 | "idiom" : "iphone",
40 | "size" : "60x60",
41 | "scale" : "3x"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "size" : "20x20",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "size" : "20x20",
51 | "scale" : "2x"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "size" : "29x29",
56 | "scale" : "1x"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "size" : "29x29",
61 | "scale" : "2x"
62 | },
63 | {
64 | "idiom" : "ipad",
65 | "size" : "40x40",
66 | "scale" : "1x"
67 | },
68 | {
69 | "idiom" : "ipad",
70 | "size" : "40x40",
71 | "scale" : "2x"
72 | },
73 | {
74 | "idiom" : "ipad",
75 | "size" : "76x76",
76 | "scale" : "1x"
77 | },
78 | {
79 | "idiom" : "ipad",
80 | "size" : "76x76",
81 | "scale" : "2x"
82 | },
83 | {
84 | "idiom" : "ipad",
85 | "size" : "83.5x83.5",
86 | "scale" : "2x"
87 | },
88 | {
89 | "idiom" : "ios-marketing",
90 | "size" : "1024x1024",
91 | "scale" : "1x"
92 | }
93 | ],
94 | "info" : {
95 | "version" : 1,
96 | "author" : "xcode"
97 | }
98 | }
--------------------------------------------------------------------------------
/GestureDemo/GestureDemo/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/GestureDemo/GestureDemo/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/GestureDemo/GestureDemo/ContentView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ContentView.swift
3 | // GestureDemo
4 | //
5 | // Created by Neil Smyth on 10/16/19.
6 | // Copyright © 2019 eBookFrenzy. All rights reserved.
7 | //
8 |
9 | import SwiftUI
10 |
11 | struct ContentView: View {
12 |
13 | @GestureState private var offset: CGSize = .zero
14 | @State private var dragEnabled: Bool = false
15 |
16 | var body: some View {
17 |
18 | let longPressBeforeDrag = LongPressGesture(minimumDuration: 2.0)
19 | .onEnded( { _ in
20 | self.dragEnabled = true
21 | })
22 | .sequenced(before: DragGesture())
23 | .updating($offset) { value, state, transaction in
24 |
25 | switch value {
26 |
27 | case .first(true):
28 | print("Long press in progress")
29 |
30 | case .second(true, let drag):
31 | state = drag?.translation ?? .zero
32 |
33 | default: break
34 | }
35 | }
36 | .onEnded { value in
37 | self.dragEnabled = false
38 | }
39 |
40 |
41 | return Image(systemName: "hand.point.right.fill")
42 | .foregroundColor(dragEnabled ? Color.green : Color.blue)
43 | .font(.largeTitle)
44 | .offset(offset)
45 | .gesture(longPressBeforeDrag)
46 | }
47 | }
48 |
49 |
50 |
51 | struct ContentView_Previews: PreviewProvider {
52 | static var previews: some View {
53 | ContentView()
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/GestureDemo/GestureDemo/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE)
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 | LSRequiresIPhoneOS
22 |
23 | UIApplicationSceneManifest
24 |
25 | UIApplicationSupportsMultipleScenes
26 |
27 | UISceneConfigurations
28 |
29 | UIWindowSceneSessionRoleApplication
30 |
31 |
32 | UISceneConfigurationName
33 | Default Configuration
34 | UISceneDelegateClassName
35 | $(PRODUCT_MODULE_NAME).SceneDelegate
36 |
37 |
38 |
39 |
40 | UILaunchStoryboardName
41 | LaunchScreen
42 | UIRequiredDeviceCapabilities
43 |
44 | armv7
45 |
46 | UISupportedInterfaceOrientations
47 |
48 | UIInterfaceOrientationPortrait
49 | UIInterfaceOrientationLandscapeLeft
50 | UIInterfaceOrientationLandscapeRight
51 |
52 | UISupportedInterfaceOrientations~ipad
53 |
54 | UIInterfaceOrientationPortrait
55 | UIInterfaceOrientationPortraitUpsideDown
56 | UIInterfaceOrientationLandscapeLeft
57 | UIInterfaceOrientationLandscapeRight
58 |
59 |
60 |
61 |
--------------------------------------------------------------------------------
/GestureDemo/GestureDemo/Preview Content/Preview Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/GestureDemo/GestureDemo/SceneDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SceneDelegate.swift
3 | // GestureDemo
4 | //
5 | // Created by Neil Smyth on 10/16/19.
6 | // Copyright © 2019 eBookFrenzy. All rights reserved.
7 | //
8 |
9 | import UIKit
10 | import SwiftUI
11 |
12 | class SceneDelegate: UIResponder, UIWindowSceneDelegate {
13 |
14 | var window: UIWindow?
15 |
16 |
17 | func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
18 | // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
19 | // If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
20 | // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
21 |
22 | // Create the SwiftUI view that provides the window contents.
23 | let contentView = ContentView()
24 |
25 | // Use a UIHostingController as window root view controller.
26 | if let windowScene = scene as? UIWindowScene {
27 | let window = UIWindow(windowScene: windowScene)
28 | window.rootViewController = UIHostingController(rootView: contentView)
29 | self.window = window
30 | window.makeKeyAndVisible()
31 | }
32 | }
33 |
34 | func sceneDidDisconnect(_ scene: UIScene) {
35 | // Called as the scene is being released by the system.
36 | // This occurs shortly after the scene enters the background, or when its session is discarded.
37 | // Release any resources associated with this scene that can be re-created the next time the scene connects.
38 | // The scene may re-connect later, as its session was not neccessarily discarded (see `application:didDiscardSceneSessions` instead).
39 | }
40 |
41 | func sceneDidBecomeActive(_ scene: UIScene) {
42 | // Called when the scene has moved from an inactive state to an active state.
43 | // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive.
44 | }
45 |
46 | func sceneWillResignActive(_ scene: UIScene) {
47 | // Called when the scene will move from an active state to an inactive state.
48 | // This may occur due to temporary interruptions (ex. an incoming phone call).
49 | }
50 |
51 | func sceneWillEnterForeground(_ scene: UIScene) {
52 | // Called as the scene transitions from the background to the foreground.
53 | // Use this method to undo the changes made on entering the background.
54 | }
55 |
56 | func sceneDidEnterBackground(_ scene: UIScene) {
57 | // Called as the scene transitions from the foreground to the background.
58 | // Use this method to save data, release shared resources, and store enough scene-specific state information
59 | // to restore the scene back to its current state.
60 | }
61 |
62 |
63 | }
64 |
65 |
--------------------------------------------------------------------------------
/HostingControllerDemo/HostingControllerDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/HostingControllerDemo/HostingControllerDemo.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/HostingControllerDemo/HostingControllerDemo.xcodeproj/project.xcworkspace/xcuserdata/neilsmyth.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Jpub/SwiftUI/defbcdd40638ec4d8d55e6693e7c878a00b1d135/HostingControllerDemo/HostingControllerDemo.xcodeproj/project.xcworkspace/xcuserdata/neilsmyth.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/HostingControllerDemo/HostingControllerDemo.xcodeproj/xcuserdata/neilsmyth.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | HostingControllerDemo.xcscheme_^#shared#^_
8 |
9 | orderHint
10 | 0
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/HostingControllerDemo/HostingControllerDemo/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // HostingControllerDemo
4 | //
5 | // Created by Neil Smyth on 10/16/19.
6 | // Copyright © 2019 eBookFrenzy. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | @UIApplicationMain
12 | class AppDelegate: UIResponder, UIApplicationDelegate {
13 |
14 |
15 |
16 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
17 | // Override point for customization after application launch.
18 | return true
19 | }
20 |
21 | // MARK: UISceneSession Lifecycle
22 |
23 | func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
24 | // Called when a new scene session is being created.
25 | // Use this method to select a configuration to create the new scene with.
26 | return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
27 | }
28 |
29 | func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) {
30 | // Called when the user discards a scene session.
31 | // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
32 | // Use this method to release any resources that were specific to the discarded scenes, as they will not return.
33 | }
34 |
35 |
36 | }
37 |
38 |
--------------------------------------------------------------------------------
/HostingControllerDemo/HostingControllerDemo/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "20x20",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "20x20",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "29x29",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "29x29",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "40x40",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "40x40",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "iphone",
35 | "size" : "60x60",
36 | "scale" : "2x"
37 | },
38 | {
39 | "idiom" : "iphone",
40 | "size" : "60x60",
41 | "scale" : "3x"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "size" : "20x20",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "size" : "20x20",
51 | "scale" : "2x"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "size" : "29x29",
56 | "scale" : "1x"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "size" : "29x29",
61 | "scale" : "2x"
62 | },
63 | {
64 | "idiom" : "ipad",
65 | "size" : "40x40",
66 | "scale" : "1x"
67 | },
68 | {
69 | "idiom" : "ipad",
70 | "size" : "40x40",
71 | "scale" : "2x"
72 | },
73 | {
74 | "idiom" : "ipad",
75 | "size" : "76x76",
76 | "scale" : "1x"
77 | },
78 | {
79 | "idiom" : "ipad",
80 | "size" : "76x76",
81 | "scale" : "2x"
82 | },
83 | {
84 | "idiom" : "ipad",
85 | "size" : "83.5x83.5",
86 | "scale" : "2x"
87 | },
88 | {
89 | "idiom" : "ios-marketing",
90 | "size" : "1024x1024",
91 | "scale" : "1x"
92 | }
93 | ],
94 | "info" : {
95 | "version" : 1,
96 | "author" : "xcode"
97 | }
98 | }
--------------------------------------------------------------------------------
/HostingControllerDemo/HostingControllerDemo/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/HostingControllerDemo/HostingControllerDemo/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/HostingControllerDemo/HostingControllerDemo/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
--------------------------------------------------------------------------------
/HostingControllerDemo/HostingControllerDemo/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE)
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 | LSRequiresIPhoneOS
22 |
23 | UIApplicationSceneManifest
24 |
25 | UIApplicationSupportsMultipleScenes
26 |
27 | UISceneConfigurations
28 |
29 | UIWindowSceneSessionRoleApplication
30 |
31 |
32 | UISceneConfigurationName
33 | Default Configuration
34 | UISceneDelegateClassName
35 | $(PRODUCT_MODULE_NAME).SceneDelegate
36 | UISceneStoryboardFile
37 | Main
38 |
39 |
40 |
41 |
42 | UILaunchStoryboardName
43 | LaunchScreen
44 | UIMainStoryboardFile
45 | Main
46 | UIRequiredDeviceCapabilities
47 |
48 | armv7
49 |
50 | UISupportedInterfaceOrientations
51 |
52 | UIInterfaceOrientationPortrait
53 | UIInterfaceOrientationLandscapeLeft
54 | UIInterfaceOrientationLandscapeRight
55 |
56 | UISupportedInterfaceOrientations~ipad
57 |
58 | UIInterfaceOrientationPortrait
59 | UIInterfaceOrientationPortraitUpsideDown
60 | UIInterfaceOrientationLandscapeLeft
61 | UIInterfaceOrientationLandscapeRight
62 |
63 |
64 |
65 |
--------------------------------------------------------------------------------
/HostingControllerDemo/HostingControllerDemo/SceneDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SceneDelegate.swift
3 | // HostingControllerDemo
4 | //
5 | // Created by Neil Smyth on 10/16/19.
6 | // Copyright © 2019 eBookFrenzy. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class SceneDelegate: UIResponder, UIWindowSceneDelegate {
12 |
13 | var window: UIWindow?
14 |
15 |
16 | func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
17 | // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
18 | // If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
19 | // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
20 | guard let _ = (scene as? UIWindowScene) else { return }
21 | }
22 |
23 | func sceneDidDisconnect(_ scene: UIScene) {
24 | // Called as the scene is being released by the system.
25 | // This occurs shortly after the scene enters the background, or when its session is discarded.
26 | // Release any resources associated with this scene that can be re-created the next time the scene connects.
27 | // The scene may re-connect later, as its session was not neccessarily discarded (see `application:didDiscardSceneSessions` instead).
28 | }
29 |
30 | func sceneDidBecomeActive(_ scene: UIScene) {
31 | // Called when the scene has moved from an inactive state to an active state.
32 | // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive.
33 | }
34 |
35 | func sceneWillResignActive(_ scene: UIScene) {
36 | // Called when the scene will move from an active state to an inactive state.
37 | // This may occur due to temporary interruptions (ex. an incoming phone call).
38 | }
39 |
40 | func sceneWillEnterForeground(_ scene: UIScene) {
41 | // Called as the scene transitions from the background to the foreground.
42 | // Use this method to undo the changes made on entering the background.
43 | }
44 |
45 | func sceneDidEnterBackground(_ scene: UIScene) {
46 | // Called as the scene transitions from the foreground to the background.
47 | // Use this method to save data, release shared resources, and store enough scene-specific state information
48 | // to restore the scene back to its current state.
49 | }
50 |
51 |
52 | }
53 |
54 |
--------------------------------------------------------------------------------
/HostingControllerDemo/HostingControllerDemo/ViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.swift
3 | // HostingControllerDemo
4 | //
5 | // Created by Neil Smyth on 10/16/19.
6 | // Copyright © 2019 eBookFrenzy. All rights reserved.
7 | //
8 |
9 | import UIKit
10 | import SwiftUI
11 |
12 | class ViewController: UIViewController {
13 |
14 | override func viewDidLoad() {
15 | super.viewDidLoad()
16 |
17 | let swiftUIController = UIHostingController(rootView: SwiftUIView(text: "Integration Three"))
18 |
19 | addChild(swiftUIController)
20 | swiftUIController.view.translatesAutoresizingMaskIntoConstraints = false
21 |
22 | view.addSubview(swiftUIController.view)
23 |
24 | swiftUIController.view.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
25 | swiftUIController.view.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
26 |
27 | swiftUIController.didMove(toParent: self)
28 |
29 | }
30 |
31 | @IBSegueAction func showSwiftUIView(_ coder: NSCoder) -> UIViewController? {
32 | return UIHostingController(coder: coder,
33 | rootView: SwiftUIView(text: "Integration One"))
34 | }
35 |
36 | @IBSegueAction func embedSwiftUIView(_ coder: NSCoder) -> UIViewController? {
37 | return UIHostingController(coder: coder, rootView: SwiftUIView(text: "Integration Two"))
38 | }
39 |
40 | }
41 |
42 |
--------------------------------------------------------------------------------
/HostingControllerDemo/SwiftUIView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SwiftUIView.swift
3 | // HostingControllerDemo
4 | //
5 | // Created by Neil Smyth on 10/16/19.
6 | // Copyright © 2019 eBookFrenzy. All rights reserved.
7 | //
8 |
9 | import SwiftUI
10 |
11 | struct SwiftUIView: View {
12 |
13 | var text: String
14 |
15 | var body: some View {
16 | VStack {
17 | Text(text)
18 | HStack {
19 | Image(systemName: "smiley")
20 | Text("This is a SwiftUI View")
21 | }
22 | }
23 | .font(.largeTitle)
24 | }
25 | }
26 |
27 | struct SwiftUIView_Previews: PreviewProvider {
28 | static var previews: some View {
29 | SwiftUIView(text: "Sample Text")
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/LearnSwift.playground/Pages/Live View Example.xcplaygroundpage/Contents.swift:
--------------------------------------------------------------------------------
1 | //: [Previous](@previous)
2 |
3 | import UIKit
4 | import PlaygroundSupport
5 |
6 | let container = UIView(frame: CGRect(x: 0,y: 0,width: 200,height: 200))
7 |
8 | PlaygroundPage.current.liveView = container
9 |
10 | container.backgroundColor = UIColor.white
11 | let square = UIView(frame: CGRect(x: 50,y: 50,width: 100,height: 100))
12 | square.backgroundColor = UIColor.red
13 |
14 | container.addSubview(square)
15 |
16 | UIView.animate(withDuration: 5.0, animations: {
17 | square.backgroundColor = UIColor.blue
18 | let rotation = CGAffineTransform(rotationAngle: 3.14)
19 | square.transform = rotation
20 | })
21 |
22 |
23 | //: [Next](@next)
24 |
--------------------------------------------------------------------------------
/LearnSwift.playground/Pages/Live View Example.xcplaygroundpage/timeline.xctimeline:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/LearnSwift.playground/Pages/UIKit Examples.xcplaygroundpage/Contents.swift:
--------------------------------------------------------------------------------
1 | //: [Previous](@previous)
2 |
3 | import UIKit
4 |
5 | let myLabel = UILabel(frame: CGRect(x: 0, y: 0, width: 200, height: 50))
6 |
7 | myLabel.backgroundColor = UIColor.red
8 | myLabel.text = "Hello Swift"
9 | myLabel.textAlignment = .center
10 | myLabel.font = UIFont(name: "Georgia", size: 24)
11 | myLabel
12 |
13 | let image = UIImage(named: "waterfall")
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 | //: [Next](@next)
23 |
--------------------------------------------------------------------------------
/LearnSwift.playground/Pages/UIKit Examples.xcplaygroundpage/Resources/waterfall.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Jpub/SwiftUI/defbcdd40638ec4d8d55e6693e7c878a00b1d135/LearnSwift.playground/Pages/UIKit Examples.xcplaygroundpage/Resources/waterfall.png
--------------------------------------------------------------------------------
/LearnSwift.playground/Pages/UIKit Examples.xcplaygroundpage/timeline.xctimeline:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
9 |
10 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/LearnSwift.playground/Pages/Untitled Page.xcplaygroundpage/Contents.swift:
--------------------------------------------------------------------------------
1 | import UIKit
2 |
3 | var str = "Hello , playground"
4 |
5 | print("Welcome to Swift")
6 |
7 | /*:
8 | # Welcome to Playgrounds
9 | This is your *first* playground which is intended to demonstrate:
10 | * The use of **Quick Look**
11 | * Placing results **in-line** with the code
12 | */
13 |
14 | var x = 10
15 |
16 | for index in 1...20 {
17 | let y = index * x
18 | x -= 1
19 | print(y)
20 | }
21 |
22 |
23 |
--------------------------------------------------------------------------------
/LearnSwift.playground/Pages/Untitled Page.xcplaygroundpage/timeline.xctimeline:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/LearnSwift.playground/contents.xcplayground:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/LearnSwift.playground/playground.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/LearnSwift.playground/playground.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/LearnSwift.playground/playground.xcworkspace/xcuserdata/neilsmyth.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Jpub/SwiftUI/defbcdd40638ec4d8d55e6693e7c878a00b1d135/LearnSwift.playground/playground.xcworkspace/xcuserdata/neilsmyth.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/ListNavDemo/ListNavDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/ListNavDemo/ListNavDemo.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ListNavDemo/ListNavDemo.xcodeproj/project.xcworkspace/xcuserdata/neilsmyth.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Jpub/SwiftUI/defbcdd40638ec4d8d55e6693e7c878a00b1d135/ListNavDemo/ListNavDemo.xcodeproj/project.xcworkspace/xcuserdata/neilsmyth.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/ListNavDemo/ListNavDemo.xcodeproj/xcuserdata/neilsmyth.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | ListNavDemo.xcscheme_^#shared#^_
8 |
9 | orderHint
10 | 0
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/ListNavDemo/ListNavDemo/AddNewCar.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AddNewCar.swift
3 | // ListNavDemo
4 | //
5 | // Created by Neil Smyth on 10/15/19.
6 | // Copyright © 2019 eBookFrenzy. All rights reserved.
7 | //
8 |
9 | import SwiftUI
10 |
11 | struct AddNewCar: View {
12 |
13 | @ObservedObject var carStore : CarStore
14 |
15 | @State var isHybrid = false
16 | @State var name: String = ""
17 | @State var description: String = ""
18 |
19 | var body: some View {
20 |
21 | Form {
22 | Section(header: Text("Car Details")) {
23 | Image(systemName: "car.fill")
24 | .resizable()
25 | .aspectRatio(contentMode: .fit)
26 | .padding()
27 |
28 | DataInput(title: "Model", userInput: $name)
29 | DataInput(title: "Description", userInput: $description)
30 |
31 | Toggle(isOn: $isHybrid) {
32 | Text("Hybrid").font(.headline)
33 | }.padding()
34 | }
35 |
36 | Button(action: addNewCar) {
37 | Text("Add Car")
38 | }
39 | }
40 |
41 | }
42 |
43 | func addNewCar() {
44 | let newCar = Car(id: UUID().uuidString,
45 | name: name, description: description,
46 | isHybrid: isHybrid, imageName: "tesla_model_3" )
47 |
48 | carStore.cars.append(newCar)
49 | }
50 | }
51 |
52 |
53 | struct DataInput: View {
54 |
55 | var title: String
56 | @Binding var userInput: String
57 |
58 | var body: some View {
59 | VStack(alignment: HorizontalAlignment.leading) {
60 | Text(title)
61 | .font(.headline)
62 | TextField("Enter \(title)", text: $userInput)
63 | .textFieldStyle(RoundedBorderTextFieldStyle())
64 | }
65 | .padding()
66 | }
67 | }
68 |
69 | struct AddNewCar_Previews: PreviewProvider {
70 | static var previews: some View {
71 | AddNewCar(carStore: CarStore(cars: carData))
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/ListNavDemo/ListNavDemo/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // ListNavDemo
4 | //
5 | // Created by Neil Smyth on 10/15/19.
6 | // Copyright © 2019 eBookFrenzy. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | @UIApplicationMain
12 | class AppDelegate: UIResponder, UIApplicationDelegate {
13 |
14 |
15 |
16 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
17 | // Override point for customization after application launch.
18 | return true
19 | }
20 |
21 | // MARK: UISceneSession Lifecycle
22 |
23 | func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
24 | // Called when a new scene session is being created.
25 | // Use this method to select a configuration to create the new scene with.
26 | return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
27 | }
28 |
29 | func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) {
30 | // Called when the user discards a scene session.
31 | // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
32 | // Use this method to release any resources that were specific to the discarded scenes, as they will not return.
33 | }
34 |
35 |
36 | }
37 |
38 |
--------------------------------------------------------------------------------
/ListNavDemo/ListNavDemo/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "20x20",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "20x20",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "29x29",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "29x29",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "40x40",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "40x40",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "iphone",
35 | "size" : "60x60",
36 | "scale" : "2x"
37 | },
38 | {
39 | "idiom" : "iphone",
40 | "size" : "60x60",
41 | "scale" : "3x"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "size" : "20x20",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "size" : "20x20",
51 | "scale" : "2x"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "size" : "29x29",
56 | "scale" : "1x"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "size" : "29x29",
61 | "scale" : "2x"
62 | },
63 | {
64 | "idiom" : "ipad",
65 | "size" : "40x40",
66 | "scale" : "1x"
67 | },
68 | {
69 | "idiom" : "ipad",
70 | "size" : "40x40",
71 | "scale" : "2x"
72 | },
73 | {
74 | "idiom" : "ipad",
75 | "size" : "76x76",
76 | "scale" : "1x"
77 | },
78 | {
79 | "idiom" : "ipad",
80 | "size" : "76x76",
81 | "scale" : "2x"
82 | },
83 | {
84 | "idiom" : "ipad",
85 | "size" : "83.5x83.5",
86 | "scale" : "2x"
87 | },
88 | {
89 | "idiom" : "ios-marketing",
90 | "size" : "1024x1024",
91 | "scale" : "1x"
92 | }
93 | ],
94 | "info" : {
95 | "version" : 1,
96 | "author" : "xcode"
97 | }
98 | }
--------------------------------------------------------------------------------
/ListNavDemo/ListNavDemo/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/ListNavDemo/ListNavDemo/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/ListNavDemo/ListNavDemo/Car.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Car.swift
3 | // ListNavDemo
4 | //
5 | // Created by Neil Smyth on 10/15/19.
6 | // Copyright © 2019 eBookFrenzy. All rights reserved.
7 | //
8 |
9 | import SwiftUI
10 |
11 | struct Car : Codable, Identifiable {
12 | var id: String
13 | var name: String
14 |
15 | var description: String
16 | var isHybrid: Bool
17 |
18 | var imageName: String
19 |
20 | }
21 |
22 |
--------------------------------------------------------------------------------
/ListNavDemo/ListNavDemo/CarAssets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/ListNavDemo/ListNavDemo/CarAssets.xcassets/chevrolet_volt.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "chevrolet_volt.jpg",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/ListNavDemo/ListNavDemo/CarAssets.xcassets/chevrolet_volt.imageset/chevrolet_volt.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Jpub/SwiftUI/defbcdd40638ec4d8d55e6693e7c878a00b1d135/ListNavDemo/ListNavDemo/CarAssets.xcassets/chevrolet_volt.imageset/chevrolet_volt.jpg
--------------------------------------------------------------------------------
/ListNavDemo/ListNavDemo/CarAssets.xcassets/nissan_leaf.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "nissan_leaf.jpg",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/ListNavDemo/ListNavDemo/CarAssets.xcassets/nissan_leaf.imageset/nissan_leaf.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Jpub/SwiftUI/defbcdd40638ec4d8d55e6693e7c878a00b1d135/ListNavDemo/ListNavDemo/CarAssets.xcassets/nissan_leaf.imageset/nissan_leaf.jpg
--------------------------------------------------------------------------------
/ListNavDemo/ListNavDemo/CarAssets.xcassets/tesla_model_3.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "tesla_model_3.jpg",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/ListNavDemo/ListNavDemo/CarAssets.xcassets/tesla_model_3.imageset/tesla_model_3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Jpub/SwiftUI/defbcdd40638ec4d8d55e6693e7c878a00b1d135/ListNavDemo/ListNavDemo/CarAssets.xcassets/tesla_model_3.imageset/tesla_model_3.jpg
--------------------------------------------------------------------------------
/ListNavDemo/ListNavDemo/CarAssets.xcassets/tesla_model_s.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "tesla_model_s.jpg",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/ListNavDemo/ListNavDemo/CarAssets.xcassets/tesla_model_s.imageset/tesla_model_s.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Jpub/SwiftUI/defbcdd40638ec4d8d55e6693e7c878a00b1d135/ListNavDemo/ListNavDemo/CarAssets.xcassets/tesla_model_s.imageset/tesla_model_s.jpg
--------------------------------------------------------------------------------
/ListNavDemo/ListNavDemo/CarAssets.xcassets/toyota_prius.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "toyota_prius.jpg",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/ListNavDemo/ListNavDemo/CarAssets.xcassets/toyota_prius.imageset/toyota_prius.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Jpub/SwiftUI/defbcdd40638ec4d8d55e6693e7c878a00b1d135/ListNavDemo/ListNavDemo/CarAssets.xcassets/toyota_prius.imageset/toyota_prius.jpg
--------------------------------------------------------------------------------
/ListNavDemo/ListNavDemo/CarData.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CarData.swift
3 | // ListNavDemo
4 | //
5 | // Created by Neil Smyth on 10/15/19.
6 | // Copyright © 2019 eBookFrenzy. All rights reserved.
7 | //
8 |
9 | import UIKit
10 | import SwiftUI
11 |
12 | var carData: [Car] = loadJson("carData.json")
13 |
14 | func loadJson(_ filename: String) -> T {
15 | let data: Data
16 |
17 | guard let file = Bundle.main.url(forResource: filename,
18 | withExtension: nil)
19 | else {
20 | fatalError("\(filename) not found.")
21 | }
22 |
23 | do {
24 | data = try Data(contentsOf: file)
25 | } catch {
26 | fatalError("Could not load \(filename): (error)")
27 | }
28 |
29 | do {
30 | return try JSONDecoder().decode(T.self, from: data)
31 | } catch {
32 | fatalError("Unable to parse \(filename): (error)")
33 | }
34 | }
35 |
36 |
--------------------------------------------------------------------------------
/ListNavDemo/ListNavDemo/CarDetail.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CarDetail.swift
3 | // ListNavDemo
4 | //
5 | // Created by Neil Smyth on 10/15/19.
6 | // Copyright © 2019 eBookFrenzy. All rights reserved.
7 | //
8 |
9 | import SwiftUI
10 |
11 | struct CarDetail: View {
12 |
13 | let selectedCar: Car
14 |
15 | var body: some View {
16 | Form {
17 | Section(header: Text("Car Details")) {
18 | Image(selectedCar.imageName)
19 | .resizable()
20 | .cornerRadius(12.0)
21 | .aspectRatio(contentMode: .fit)
22 | .padding()
23 |
24 | Text(selectedCar.name)
25 | .font(.headline)
26 |
27 | Text(selectedCar.description)
28 | .font(.body)
29 |
30 | HStack {
31 | Text("Hybrid").font(.headline)
32 | Spacer()
33 | Image(systemName: selectedCar.isHybrid ?
34 | "checkmark.circle" : "xmark.circle" )
35 | }
36 |
37 |
38 | }
39 | }
40 |
41 | }
42 | }
43 |
44 | struct CarDetail_Previews: PreviewProvider {
45 | static var previews: some View {
46 | CarDetail(selectedCar: carData[0])
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/ListNavDemo/ListNavDemo/CarStore.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CarStore.swift
3 | // ListNavDemo
4 | //
5 | // Created by Neil Smyth on 10/15/19.
6 | // Copyright © 2019 eBookFrenzy. All rights reserved.
7 | //
8 |
9 | import SwiftUI
10 | import Combine
11 |
12 | class CarStore : ObservableObject {
13 |
14 | @Published var cars: [Car]
15 |
16 | init (cars: [Car] = []) {
17 | self.cars = cars
18 | }
19 | }
20 |
21 |
--------------------------------------------------------------------------------
/ListNavDemo/ListNavDemo/ContentView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ContentView.swift
3 | // ListNavDemo
4 | //
5 | // Created by Neil Smyth on 10/15/19.
6 | // Copyright © 2019 eBookFrenzy. All rights reserved.
7 | //
8 |
9 | import SwiftUI
10 |
11 | struct ContentView: View {
12 |
13 | @ObservedObject var carStore : CarStore = CarStore(cars: carData)
14 |
15 | var body: some View {
16 |
17 | NavigationView {
18 | List {
19 | ForEach(carStore.cars) { car in
20 | ListCell(car: car)
21 | }
22 | .onDelete(perform: deleteItems)
23 | .onMove(perform: moveItems)
24 |
25 | }
26 | .navigationBarTitle(Text("EV Cars"))
27 | .navigationBarItems(leading: NavigationLink(destination:
28 | AddNewCar(carStore: self.carStore)) {
29 | Text("Add")
30 | .foregroundColor(.blue)
31 | }, trailing: EditButton())
32 |
33 | }
34 | }
35 |
36 | func deleteItems(at offets: IndexSet) {
37 | carStore.cars.remove(atOffsets: offets)
38 | print("Item moved")
39 | }
40 |
41 | func moveItems(from source: IndexSet, to destination: Int) {
42 | carStore.cars.move(fromOffsets: source, toOffset: destination)
43 | print("Item deleted")
44 | }
45 |
46 | }
47 |
48 | struct ContentView_Previews: PreviewProvider {
49 | static var previews: some View {
50 | ContentView()
51 | }
52 | }
53 |
54 | struct ListCell: View {
55 |
56 | var car: Car
57 |
58 | var body: some View {
59 | NavigationLink(destination: CarDetail(selectedCar: car)) {
60 | HStack {
61 | Image(car.imageName)
62 | .resizable()
63 | .aspectRatio(contentMode: .fit)
64 | .frame(width: 100, height: 60)
65 | Text(car.name)
66 | }
67 | }
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/ListNavDemo/ListNavDemo/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE)
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 | LSRequiresIPhoneOS
22 |
23 | UIApplicationSceneManifest
24 |
25 | UIApplicationSupportsMultipleScenes
26 |
27 | UISceneConfigurations
28 |
29 | UIWindowSceneSessionRoleApplication
30 |
31 |
32 | UISceneConfigurationName
33 | Default Configuration
34 | UISceneDelegateClassName
35 | $(PRODUCT_MODULE_NAME).SceneDelegate
36 |
37 |
38 |
39 |
40 | UILaunchStoryboardName
41 | LaunchScreen
42 | UIRequiredDeviceCapabilities
43 |
44 | armv7
45 |
46 | UISupportedInterfaceOrientations
47 |
48 | UIInterfaceOrientationPortrait
49 | UIInterfaceOrientationLandscapeLeft
50 | UIInterfaceOrientationLandscapeRight
51 |
52 | UISupportedInterfaceOrientations~ipad
53 |
54 | UIInterfaceOrientationPortrait
55 | UIInterfaceOrientationPortraitUpsideDown
56 | UIInterfaceOrientationLandscapeLeft
57 | UIInterfaceOrientationLandscapeRight
58 |
59 |
60 |
61 |
--------------------------------------------------------------------------------
/ListNavDemo/ListNavDemo/Preview Content/Preview Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/ListNavDemo/ListNavDemo/SceneDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SceneDelegate.swift
3 | // ListNavDemo
4 | //
5 | // Created by Neil Smyth on 10/15/19.
6 | // Copyright © 2019 eBookFrenzy. All rights reserved.
7 | //
8 |
9 | import UIKit
10 | import SwiftUI
11 |
12 | class SceneDelegate: UIResponder, UIWindowSceneDelegate {
13 |
14 | var window: UIWindow?
15 |
16 |
17 | func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
18 | // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
19 | // If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
20 | // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
21 |
22 | // Create the SwiftUI view that provides the window contents.
23 | let contentView = ContentView()
24 |
25 | // Use a UIHostingController as window root view controller.
26 | if let windowScene = scene as? UIWindowScene {
27 | let window = UIWindow(windowScene: windowScene)
28 | window.rootViewController = UIHostingController(rootView: contentView)
29 | self.window = window
30 | window.makeKeyAndVisible()
31 | }
32 | }
33 |
34 | func sceneDidDisconnect(_ scene: UIScene) {
35 | // Called as the scene is being released by the system.
36 | // This occurs shortly after the scene enters the background, or when its session is discarded.
37 | // Release any resources associated with this scene that can be re-created the next time the scene connects.
38 | // The scene may re-connect later, as its session was not neccessarily discarded (see `application:didDiscardSceneSessions` instead).
39 | }
40 |
41 | func sceneDidBecomeActive(_ scene: UIScene) {
42 | // Called when the scene has moved from an inactive state to an active state.
43 | // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive.
44 | }
45 |
46 | func sceneWillResignActive(_ scene: UIScene) {
47 | // Called when the scene will move from an active state to an inactive state.
48 | // This may occur due to temporary interruptions (ex. an incoming phone call).
49 | }
50 |
51 | func sceneWillEnterForeground(_ scene: UIScene) {
52 | // Called as the scene transitions from the background to the foreground.
53 | // Use this method to undo the changes made on entering the background.
54 | }
55 |
56 | func sceneDidEnterBackground(_ scene: UIScene) {
57 | // Called as the scene transitions from the foreground to the background.
58 | // Use this method to save data, release shared resources, and store enough scene-specific state information
59 | // to restore the scene back to its current state.
60 | }
61 |
62 |
63 | }
64 |
65 |
--------------------------------------------------------------------------------
/ListNavDemo/ListNavDemo/carData.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "id": "aa32jj887hhg55",
4 | "name": "Tesla Model 3",
5 | "description": "Luxury 4-door all-electic car. Range of 310 miles. 0-60mph in 3.2 seconds",
6 | "isHybrid": false,
7 | "imageName": "tesla_model_3"
8 | },
9 | {
10 | "id": "bb32jj887hhg77",
11 | "name": "Tesla Model S",
12 | "description": "5-door lift-back electric car. Performance model has a three-phase, four-pole AC induction 416 hp (310 kW) and 443 ft⋅lb (601 N⋅m) rear-mounted electric motor",
13 | "isHybrid": false,
14 | "imageName": "tesla_model_s"
15 | },
16 | {
17 | "id": "cc32jj887hhg66",
18 | "name": "Toyota Prius",
19 | "description": "5-door liftback full hybrid electric automobile developed by Toyota.",
20 | "isHybrid": true,
21 | "imageName": "toyota_prius"
22 | },
23 | {
24 | "id": "dd32jj887hhg88",
25 | "name": "Nissan Leaf",
26 | "description": "A compact five-door hatchback all-electric car manufactured by Nissan",
27 | "isHybrid": false,
28 | "imageName": "nissan_leaf"
29 | },
30 | {
31 | "id": "ee32jj887hhg99",
32 | "name": "Chevrolet Volt",
33 | "description": "5-door hatchback plug-in hybrid car manufactured by General Motors.",
34 | "isHybrid": true,
35 | "imageName": "chevrolet_volt"
36 | }
37 |
38 | ]
39 |
--------------------------------------------------------------------------------
/ObservableDemo/ObservableDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/ObservableDemo/ObservableDemo.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ObservableDemo/ObservableDemo.xcodeproj/project.xcworkspace/xcuserdata/neilsmyth.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Jpub/SwiftUI/defbcdd40638ec4d8d55e6693e7c878a00b1d135/ObservableDemo/ObservableDemo.xcodeproj/project.xcworkspace/xcuserdata/neilsmyth.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/ObservableDemo/ObservableDemo.xcodeproj/xcuserdata/neilsmyth.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | ObservableDemo.xcscheme_^#shared#^_
8 |
9 | orderHint
10 | 0
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/ObservableDemo/ObservableDemo/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // ObservableDemo
4 | //
5 | // Created by Neil Smyth on 10/15/19.
6 | // Copyright © 2019 eBookFrenzy. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | @UIApplicationMain
12 | class AppDelegate: UIResponder, UIApplicationDelegate {
13 |
14 |
15 |
16 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
17 | // Override point for customization after application launch.
18 | return true
19 | }
20 |
21 | // MARK: UISceneSession Lifecycle
22 |
23 | func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
24 | // Called when a new scene session is being created.
25 | // Use this method to select a configuration to create the new scene with.
26 | return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
27 | }
28 |
29 | func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) {
30 | // Called when the user discards a scene session.
31 | // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
32 | // Use this method to release any resources that were specific to the discarded scenes, as they will not return.
33 | }
34 |
35 |
36 | }
37 |
38 |
--------------------------------------------------------------------------------
/ObservableDemo/ObservableDemo/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "20x20",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "20x20",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "29x29",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "29x29",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "40x40",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "40x40",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "iphone",
35 | "size" : "60x60",
36 | "scale" : "2x"
37 | },
38 | {
39 | "idiom" : "iphone",
40 | "size" : "60x60",
41 | "scale" : "3x"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "size" : "20x20",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "size" : "20x20",
51 | "scale" : "2x"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "size" : "29x29",
56 | "scale" : "1x"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "size" : "29x29",
61 | "scale" : "2x"
62 | },
63 | {
64 | "idiom" : "ipad",
65 | "size" : "40x40",
66 | "scale" : "1x"
67 | },
68 | {
69 | "idiom" : "ipad",
70 | "size" : "40x40",
71 | "scale" : "2x"
72 | },
73 | {
74 | "idiom" : "ipad",
75 | "size" : "76x76",
76 | "scale" : "1x"
77 | },
78 | {
79 | "idiom" : "ipad",
80 | "size" : "76x76",
81 | "scale" : "2x"
82 | },
83 | {
84 | "idiom" : "ipad",
85 | "size" : "83.5x83.5",
86 | "scale" : "2x"
87 | },
88 | {
89 | "idiom" : "ios-marketing",
90 | "size" : "1024x1024",
91 | "scale" : "1x"
92 | }
93 | ],
94 | "info" : {
95 | "version" : 1,
96 | "author" : "xcode"
97 | }
98 | }
--------------------------------------------------------------------------------
/ObservableDemo/ObservableDemo/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/ObservableDemo/ObservableDemo/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/ObservableDemo/ObservableDemo/ContentView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ContentView.swift
3 | // ObservableDemo
4 | //
5 | // Created by Neil Smyth on 10/15/19.
6 | // Copyright © 2019 eBookFrenzy. All rights reserved.
7 | //
8 |
9 | import SwiftUI
10 |
11 | struct ContentView: View {
12 |
13 | @EnvironmentObject var timerData: TimerData
14 |
15 | var body: some View {
16 | NavigationView {
17 | VStack {
18 | Text("Timer count = \(timerData.timeCount)")
19 |
20 | .font(.largeTitle)
21 | .fontWeight(.bold)
22 | .padding()
23 |
24 | Button(action: resetCount) {
25 | Text("Reset Counter")
26 | }
27 |
28 | NavigationLink(destination:
29 | SecondView(timerData: timerData)) {
30 | Text("Next Screen")
31 | }
32 | .padding()
33 |
34 | }
35 | }
36 | }
37 |
38 | func resetCount() {
39 | timerData.resetCount()
40 | }
41 |
42 | }
43 |
44 | struct ContentView_Previews: PreviewProvider {
45 | static var previews: some View {
46 | ContentView().environmentObject(TimerData())
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/ObservableDemo/ObservableDemo/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE)
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 | LSRequiresIPhoneOS
22 |
23 | UIApplicationSceneManifest
24 |
25 | UIApplicationSupportsMultipleScenes
26 |
27 | UISceneConfigurations
28 |
29 | UIWindowSceneSessionRoleApplication
30 |
31 |
32 | UISceneConfigurationName
33 | Default Configuration
34 | UISceneDelegateClassName
35 | $(PRODUCT_MODULE_NAME).SceneDelegate
36 |
37 |
38 |
39 |
40 | UILaunchStoryboardName
41 | LaunchScreen
42 | UIRequiredDeviceCapabilities
43 |
44 | armv7
45 |
46 | UISupportedInterfaceOrientations
47 |
48 | UIInterfaceOrientationPortrait
49 | UIInterfaceOrientationLandscapeLeft
50 | UIInterfaceOrientationLandscapeRight
51 |
52 | UISupportedInterfaceOrientations~ipad
53 |
54 | UIInterfaceOrientationPortrait
55 | UIInterfaceOrientationPortraitUpsideDown
56 | UIInterfaceOrientationLandscapeLeft
57 | UIInterfaceOrientationLandscapeRight
58 |
59 |
60 |
61 |
--------------------------------------------------------------------------------
/ObservableDemo/ObservableDemo/Preview Content/Preview Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/ObservableDemo/ObservableDemo/SceneDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SceneDelegate.swift
3 | // ObservableDemo
4 | //
5 | // Created by Neil Smyth on 10/15/19.
6 | // Copyright © 2019 eBookFrenzy. All rights reserved.
7 | //
8 |
9 | import UIKit
10 | import SwiftUI
11 |
12 | class SceneDelegate: UIResponder, UIWindowSceneDelegate {
13 |
14 | var window: UIWindow?
15 |
16 |
17 | func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
18 | // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
19 | // If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
20 | // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
21 |
22 | // Create the SwiftUI view that provides the window contents.
23 | let contentView = ContentView()
24 |
25 | let timerData = TimerData()
26 |
27 | // Use a UIHostingController as window root view controller.
28 | if let windowScene = scene as? UIWindowScene {
29 | let window = UIWindow(windowScene: windowScene)
30 | window.rootViewController = UIHostingController(rootView: contentView.environmentObject(timerData))
31 | self.window = window
32 | window.makeKeyAndVisible()
33 | }
34 | }
35 |
36 | func sceneDidDisconnect(_ scene: UIScene) {
37 | // Called as the scene is being released by the system.
38 | // This occurs shortly after the scene enters the background, or when its session is discarded.
39 | // Release any resources associated with this scene that can be re-created the next time the scene connects.
40 | // The scene may re-connect later, as its session was not neccessarily discarded (see `application:didDiscardSceneSessions` instead).
41 | }
42 |
43 | func sceneDidBecomeActive(_ scene: UIScene) {
44 | // Called when the scene has moved from an inactive state to an active state.
45 | // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive.
46 | }
47 |
48 | func sceneWillResignActive(_ scene: UIScene) {
49 | // Called when the scene will move from an active state to an inactive state.
50 | // This may occur due to temporary interruptions (ex. an incoming phone call).
51 | }
52 |
53 | func sceneWillEnterForeground(_ scene: UIScene) {
54 | // Called as the scene transitions from the background to the foreground.
55 | // Use this method to undo the changes made on entering the background.
56 | }
57 |
58 | func sceneDidEnterBackground(_ scene: UIScene) {
59 | // Called as the scene transitions from the foreground to the background.
60 | // Use this method to save data, release shared resources, and store enough scene-specific state information
61 | // to restore the scene back to its current state.
62 | }
63 |
64 |
65 | }
66 |
67 |
--------------------------------------------------------------------------------
/ObservableDemo/ObservableDemo/SecondView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SecondView.swift
3 | // ObservableDemo
4 | //
5 | // Created by Neil Smyth on 10/15/19.
6 | // Copyright © 2019 eBookFrenzy. All rights reserved.
7 | //
8 |
9 | import SwiftUI
10 |
11 | struct SecondView: View {
12 |
13 | @EnvironmentObject var timerData: TimerData
14 |
15 | var body: some View {
16 | VStack {
17 | Text("Second View")
18 | .font(.largeTitle)
19 | Text("Timer Count = \(timerData.timeCount)")
20 | .font(.headline)
21 | }.padding()
22 |
23 | }
24 | }
25 |
26 | struct SecondView_Previews: PreviewProvider {
27 | static var previews: some View {
28 | SecondView().environmentObject(TimerData())
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/ObservableDemo/ObservableDemo/TimerData.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TimerData.swift
3 | // ObservableDemo
4 | //
5 | // Created by Neil Smyth on 10/15/19.
6 | // Copyright © 2019 eBookFrenzy. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import Combine
11 |
12 | class TimerData : ObservableObject {
13 |
14 | @Published var timeCount = 0
15 | var timer : Timer?
16 |
17 | init() {
18 | timer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(timerDidFire), userInfo: nil, repeats: true)
19 | }
20 |
21 | @objc func timerDidFire() {
22 | timeCount += 1
23 | }
24 |
25 | func resetCount() {
26 | timeCount = 0
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # 핵심만 골라 배우는 Swift 기반의 iOS 프로그래밍
2 |
3 | 
4 |
5 | **출판사** 제이펍
6 | **원서명** SwiftUI Essentials: iOS Edition(원서 ISBN: 9781951442057)
7 | **저자명** 닐 스미스
8 | **역자명** 황반석
9 | **출판일** 2019년 월 16일
10 | **페이지** 392쪽
11 | **시리즈** I♥Mobile 38(아이러브 모바일 시리즈 38))
12 | **ISBN** 979-11-90665-02-5 (93000)
13 |
14 | [### 도서 소개 페이지 바로 가기 ###](https://jpub.tistory.com/1023)
--------------------------------------------------------------------------------
/SwiftUIDemo/SwiftUIDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/SwiftUIDemo/SwiftUIDemo.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/SwiftUIDemo/SwiftUIDemo.xcodeproj/project.xcworkspace/xcuserdata/neilsmyth.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Jpub/SwiftUI/defbcdd40638ec4d8d55e6693e7c878a00b1d135/SwiftUIDemo/SwiftUIDemo.xcodeproj/project.xcworkspace/xcuserdata/neilsmyth.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/SwiftUIDemo/SwiftUIDemo.xcodeproj/xcuserdata/neilsmyth.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | SwiftUIDemo.xcscheme_^#shared#^_
8 |
9 | orderHint
10 | 0
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/SwiftUIDemo/SwiftUIDemo/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // SwiftUIDemo
4 | //
5 | // Created by Neil Smyth on 10/15/19.
6 | // Copyright © 2019 eBookFrenzy. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | @UIApplicationMain
12 | class AppDelegate: UIResponder, UIApplicationDelegate {
13 |
14 |
15 |
16 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
17 | // Override point for customization after application launch.
18 | return true
19 | }
20 |
21 | // MARK: UISceneSession Lifecycle
22 |
23 | func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
24 | // Called when a new scene session is being created.
25 | // Use this method to select a configuration to create the new scene with.
26 | return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
27 | }
28 |
29 | func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) {
30 | // Called when the user discards a scene session.
31 | // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
32 | // Use this method to release any resources that were specific to the discarded scenes, as they will not return.
33 | }
34 |
35 |
36 | }
37 |
38 |
--------------------------------------------------------------------------------
/SwiftUIDemo/SwiftUIDemo/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "20x20",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "20x20",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "29x29",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "29x29",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "40x40",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "40x40",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "iphone",
35 | "size" : "60x60",
36 | "scale" : "2x"
37 | },
38 | {
39 | "idiom" : "iphone",
40 | "size" : "60x60",
41 | "scale" : "3x"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "size" : "20x20",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "size" : "20x20",
51 | "scale" : "2x"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "size" : "29x29",
56 | "scale" : "1x"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "size" : "29x29",
61 | "scale" : "2x"
62 | },
63 | {
64 | "idiom" : "ipad",
65 | "size" : "40x40",
66 | "scale" : "1x"
67 | },
68 | {
69 | "idiom" : "ipad",
70 | "size" : "40x40",
71 | "scale" : "2x"
72 | },
73 | {
74 | "idiom" : "ipad",
75 | "size" : "76x76",
76 | "scale" : "1x"
77 | },
78 | {
79 | "idiom" : "ipad",
80 | "size" : "76x76",
81 | "scale" : "2x"
82 | },
83 | {
84 | "idiom" : "ipad",
85 | "size" : "83.5x83.5",
86 | "scale" : "2x"
87 | },
88 | {
89 | "idiom" : "ios-marketing",
90 | "size" : "1024x1024",
91 | "scale" : "1x"
92 | }
93 | ],
94 | "info" : {
95 | "version" : 1,
96 | "author" : "xcode"
97 | }
98 | }
--------------------------------------------------------------------------------
/SwiftUIDemo/SwiftUIDemo/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/SwiftUIDemo/SwiftUIDemo/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/SwiftUIDemo/SwiftUIDemo/ContentView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ContentView.swift
3 | // SwiftUIDemo
4 | //
5 | // Created by Neil Smyth on 10/15/19.
6 | // Copyright © 2019 eBookFrenzy. All rights reserved.
7 | //
8 |
9 | import SwiftUI
10 |
11 | struct ContentView: View {
12 |
13 | var colors: [Color] = [.black, .red, .green, .blue]
14 | var colornames = ["Black", "Red", "Green", "Blue"]
15 |
16 | @State private var colorIndex = 0
17 | @State private var rotation: Double = 0
18 | @State private var text: String = "Welcome to SwiftUI"
19 |
20 | var body: some View {
21 | VStack {
22 | Spacer()
23 | Text(text)
24 | .font(/*@START_MENU_TOKEN@*/.largeTitle/*@END_MENU_TOKEN@*/)
25 | .fontWeight(.heavy)
26 | .rotationEffect(.degrees(self.rotation))
27 | .animation(.easeInOut(duration: 5))
28 | .foregroundColor(self.colors[self.colorIndex])
29 | Spacer()
30 | Divider()
31 | Slider(value: $rotation, in: 0 ... 360, step: 0.1)
32 | .padding()
33 | TextField("Enter text here", text: $text)
34 | .textFieldStyle(RoundedBorderTextFieldStyle())
35 | .padding()
36 | Picker(selection: $colorIndex, label: Text("Color")) {
37 | ForEach(0 ..< colornames.count) {
38 | Text(self.colornames[$0])
39 | .foregroundColor(self.colors[$0])
40 | }
41 | }
42 | .padding()
43 | }
44 | }
45 | }
46 |
47 | struct ContentView_Previews: PreviewProvider {
48 | static var previews: some View {
49 | ContentView()
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/SwiftUIDemo/SwiftUIDemo/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE)
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 | LSRequiresIPhoneOS
22 |
23 | UIApplicationSceneManifest
24 |
25 | UIApplicationSupportsMultipleScenes
26 |
27 | UISceneConfigurations
28 |
29 | UIWindowSceneSessionRoleApplication
30 |
31 |
32 | UISceneConfigurationName
33 | Default Configuration
34 | UISceneDelegateClassName
35 | $(PRODUCT_MODULE_NAME).SceneDelegate
36 |
37 |
38 |
39 |
40 | UILaunchStoryboardName
41 | LaunchScreen
42 | UIRequiredDeviceCapabilities
43 |
44 | armv7
45 |
46 | UISupportedInterfaceOrientations
47 |
48 | UIInterfaceOrientationPortrait
49 | UIInterfaceOrientationLandscapeLeft
50 | UIInterfaceOrientationLandscapeRight
51 |
52 | UISupportedInterfaceOrientations~ipad
53 |
54 | UIInterfaceOrientationPortrait
55 | UIInterfaceOrientationPortraitUpsideDown
56 | UIInterfaceOrientationLandscapeLeft
57 | UIInterfaceOrientationLandscapeRight
58 |
59 |
60 |
61 |
--------------------------------------------------------------------------------
/SwiftUIDemo/SwiftUIDemo/Preview Content/Preview Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/SwiftUIDemo/SwiftUIDemo/SceneDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SceneDelegate.swift
3 | // SwiftUIDemo
4 | //
5 | // Created by Neil Smyth on 10/15/19.
6 | // Copyright © 2019 eBookFrenzy. All rights reserved.
7 | //
8 |
9 | import UIKit
10 | import SwiftUI
11 |
12 | class SceneDelegate: UIResponder, UIWindowSceneDelegate {
13 |
14 | var window: UIWindow?
15 |
16 |
17 | func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
18 | // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
19 | // If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
20 | // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
21 |
22 | // Create the SwiftUI view that provides the window contents.
23 | let contentView = ContentView()
24 |
25 | // Use a UIHostingController as window root view controller.
26 | if let windowScene = scene as? UIWindowScene {
27 | let window = UIWindow(windowScene: windowScene)
28 | window.rootViewController = UIHostingController(rootView: contentView)
29 | self.window = window
30 | window.makeKeyAndVisible()
31 | }
32 | }
33 |
34 | func sceneDidDisconnect(_ scene: UIScene) {
35 | // Called as the scene is being released by the system.
36 | // This occurs shortly after the scene enters the background, or when its session is discarded.
37 | // Release any resources associated with this scene that can be re-created the next time the scene connects.
38 | // The scene may re-connect later, as its session was not neccessarily discarded (see `application:didDiscardSceneSessions` instead).
39 | }
40 |
41 | func sceneDidBecomeActive(_ scene: UIScene) {
42 | // Called when the scene has moved from an inactive state to an active state.
43 | // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive.
44 | }
45 |
46 | func sceneWillResignActive(_ scene: UIScene) {
47 | // Called when the scene will move from an active state to an inactive state.
48 | // This may occur due to temporary interruptions (ex. an incoming phone call).
49 | }
50 |
51 | func sceneWillEnterForeground(_ scene: UIScene) {
52 | // Called as the scene transitions from the background to the foreground.
53 | // Use this method to undo the changes made on entering the background.
54 | }
55 |
56 | func sceneDidEnterBackground(_ scene: UIScene) {
57 | // Called as the scene transitions from the foreground to the background.
58 | // Use this method to save data, release shared resources, and store enough scene-specific state information
59 | // to restore the scene back to its current state.
60 | }
61 |
62 |
63 | }
64 |
65 |
--------------------------------------------------------------------------------
/TabViewDemo/TabViewDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/TabViewDemo/TabViewDemo.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/TabViewDemo/TabViewDemo.xcodeproj/project.xcworkspace/xcuserdata/neilsmyth.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Jpub/SwiftUI/defbcdd40638ec4d8d55e6693e7c878a00b1d135/TabViewDemo/TabViewDemo.xcodeproj/project.xcworkspace/xcuserdata/neilsmyth.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/TabViewDemo/TabViewDemo.xcodeproj/xcuserdata/neilsmyth.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | TabViewDemo.xcscheme_^#shared#^_
8 |
9 | orderHint
10 | 0
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/TabViewDemo/TabViewDemo/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // TabViewDemo
4 | //
5 | // Created by Neil Smyth on 10/15/19.
6 | // Copyright © 2019 eBookFrenzy. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | @UIApplicationMain
12 | class AppDelegate: UIResponder, UIApplicationDelegate {
13 |
14 |
15 |
16 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
17 | // Override point for customization after application launch.
18 | return true
19 | }
20 |
21 | // MARK: UISceneSession Lifecycle
22 |
23 | func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
24 | // Called when a new scene session is being created.
25 | // Use this method to select a configuration to create the new scene with.
26 | return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
27 | }
28 |
29 | func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) {
30 | // Called when the user discards a scene session.
31 | // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
32 | // Use this method to release any resources that were specific to the discarded scenes, as they will not return.
33 | }
34 |
35 |
36 | }
37 |
38 |
--------------------------------------------------------------------------------
/TabViewDemo/TabViewDemo/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "20x20",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "20x20",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "29x29",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "29x29",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "40x40",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "40x40",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "iphone",
35 | "size" : "60x60",
36 | "scale" : "2x"
37 | },
38 | {
39 | "idiom" : "iphone",
40 | "size" : "60x60",
41 | "scale" : "3x"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "size" : "20x20",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "size" : "20x20",
51 | "scale" : "2x"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "size" : "29x29",
56 | "scale" : "1x"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "size" : "29x29",
61 | "scale" : "2x"
62 | },
63 | {
64 | "idiom" : "ipad",
65 | "size" : "40x40",
66 | "scale" : "1x"
67 | },
68 | {
69 | "idiom" : "ipad",
70 | "size" : "40x40",
71 | "scale" : "2x"
72 | },
73 | {
74 | "idiom" : "ipad",
75 | "size" : "76x76",
76 | "scale" : "1x"
77 | },
78 | {
79 | "idiom" : "ipad",
80 | "size" : "76x76",
81 | "scale" : "2x"
82 | },
83 | {
84 | "idiom" : "ipad",
85 | "size" : "83.5x83.5",
86 | "scale" : "2x"
87 | },
88 | {
89 | "idiom" : "ios-marketing",
90 | "size" : "1024x1024",
91 | "scale" : "1x"
92 | }
93 | ],
94 | "info" : {
95 | "version" : 1,
96 | "author" : "xcode"
97 | }
98 | }
--------------------------------------------------------------------------------
/TabViewDemo/TabViewDemo/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/TabViewDemo/TabViewDemo/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/TabViewDemo/TabViewDemo/ContentView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ContentView.swift
3 | // TabViewDemo
4 | //
5 | // Created by Neil Smyth on 10/15/19.
6 | // Copyright © 2019 eBookFrenzy. All rights reserved.
7 | //
8 |
9 | import SwiftUI
10 |
11 | struct ContentView: View {
12 |
13 | @State private var selection = 1
14 |
15 | var body: some View {
16 |
17 | TabView(selection: $selection) {
18 | Text("First Content View")
19 | .tabItem {
20 | Image(systemName: "1.circle")
21 | Text("Screen One")
22 | }.tag(1)
23 |
24 | Text("Second Content View")
25 | .tabItem {
26 | Image(systemName: "2.circle")
27 | Text("Screen Two")
28 | }.tag(2)
29 |
30 | Text("Third Content View")
31 | .tabItem {
32 | Image(systemName: "3.circle")
33 | Text("Screen Three")
34 | }.tag(3)
35 |
36 | }
37 | .font(.largeTitle)
38 | }
39 | }
40 |
41 | struct ContentView_Previews: PreviewProvider {
42 | static var previews: some View {
43 | ContentView()
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/TabViewDemo/TabViewDemo/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE)
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 | LSRequiresIPhoneOS
22 |
23 | UIApplicationSceneManifest
24 |
25 | UIApplicationSupportsMultipleScenes
26 |
27 | UISceneConfigurations
28 |
29 | UIWindowSceneSessionRoleApplication
30 |
31 |
32 | UISceneConfigurationName
33 | Default Configuration
34 | UISceneDelegateClassName
35 | $(PRODUCT_MODULE_NAME).SceneDelegate
36 |
37 |
38 |
39 |
40 | UILaunchStoryboardName
41 | LaunchScreen
42 | UIRequiredDeviceCapabilities
43 |
44 | armv7
45 |
46 | UISupportedInterfaceOrientations
47 |
48 | UIInterfaceOrientationPortrait
49 | UIInterfaceOrientationLandscapeLeft
50 | UIInterfaceOrientationLandscapeRight
51 |
52 | UISupportedInterfaceOrientations~ipad
53 |
54 | UIInterfaceOrientationPortrait
55 | UIInterfaceOrientationPortraitUpsideDown
56 | UIInterfaceOrientationLandscapeLeft
57 | UIInterfaceOrientationLandscapeRight
58 |
59 |
60 |
61 |
--------------------------------------------------------------------------------
/TabViewDemo/TabViewDemo/Preview Content/Preview Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/TabViewDemo/TabViewDemo/SceneDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SceneDelegate.swift
3 | // TabViewDemo
4 | //
5 | // Created by Neil Smyth on 10/15/19.
6 | // Copyright © 2019 eBookFrenzy. All rights reserved.
7 | //
8 |
9 | import UIKit
10 | import SwiftUI
11 |
12 | class SceneDelegate: UIResponder, UIWindowSceneDelegate {
13 |
14 | var window: UIWindow?
15 |
16 |
17 | func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
18 | // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
19 | // If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
20 | // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
21 |
22 | // Create the SwiftUI view that provides the window contents.
23 | let contentView = ContentView()
24 |
25 | // Use a UIHostingController as window root view controller.
26 | if let windowScene = scene as? UIWindowScene {
27 | let window = UIWindow(windowScene: windowScene)
28 | window.rootViewController = UIHostingController(rootView: contentView)
29 | self.window = window
30 | window.makeKeyAndVisible()
31 | }
32 | }
33 |
34 | func sceneDidDisconnect(_ scene: UIScene) {
35 | // Called as the scene is being released by the system.
36 | // This occurs shortly after the scene enters the background, or when its session is discarded.
37 | // Release any resources associated with this scene that can be re-created the next time the scene connects.
38 | // The scene may re-connect later, as its session was not neccessarily discarded (see `application:didDiscardSceneSessions` instead).
39 | }
40 |
41 | func sceneDidBecomeActive(_ scene: UIScene) {
42 | // Called when the scene has moved from an inactive state to an active state.
43 | // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive.
44 | }
45 |
46 | func sceneWillResignActive(_ scene: UIScene) {
47 | // Called when the scene will move from an active state to an inactive state.
48 | // This may occur due to temporary interruptions (ex. an incoming phone call).
49 | }
50 |
51 | func sceneWillEnterForeground(_ scene: UIScene) {
52 | // Called as the scene transitions from the background to the foreground.
53 | // Use this method to undo the changes made on entering the background.
54 | }
55 |
56 | func sceneDidEnterBackground(_ scene: UIScene) {
57 | // Called as the scene transitions from the foreground to the background.
58 | // Use this method to save data, release shared resources, and store enough scene-specific state information
59 | // to restore the scene back to its current state.
60 | }
61 |
62 |
63 | }
64 |
65 |
--------------------------------------------------------------------------------
/UIViewDemo/MyScrollView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MyScrollView.swift
3 | // UIViewDemo
4 | //
5 | // Created by Neil Smyth on 10/16/19.
6 | // Copyright © 2019 eBookFrenzy. All rights reserved.
7 | //
8 |
9 | import SwiftUI
10 |
11 | struct MyScrollView: UIViewRepresentable {
12 |
13 | var text: String
14 |
15 | func makeUIView(context: UIViewRepresentableContext) -> UIScrollView {
16 | let scrollView = UIScrollView()
17 | scrollView.delegate = context.coordinator
18 |
19 | scrollView.refreshControl = UIRefreshControl()
20 | scrollView.refreshControl?.addTarget(context.coordinator, action:
21 | #selector(Coordinator.handleRefresh),
22 | for: .valueChanged)
23 |
24 | let myLabel = UILabel(frame:
25 | CGRect(x: 0, y: 0, width: 300, height: 50))
26 | myLabel.text = text
27 | scrollView.addSubview(myLabel)
28 | return scrollView
29 | }
30 |
31 | func updateUIView(_ uiView: UIScrollView,
32 | context: UIViewRepresentableContext) {
33 |
34 | }
35 |
36 | func makeCoordinator() -> Coordinator {
37 | Coordinator(self)
38 | }
39 |
40 | class Coordinator: NSObject, UIScrollViewDelegate {
41 | var control: MyScrollView
42 |
43 | init(_ control: MyScrollView) {
44 | self.control = control
45 | }
46 |
47 | func scrollViewDidScroll(_ scrollView: UIScrollView) {
48 | print("View is Scrolling")
49 | }
50 |
51 | @objc func handleRefresh(sender: UIRefreshControl) {
52 | sender.endRefreshing()
53 | }
54 | }
55 |
56 | }
57 |
58 | struct MyScrollView_Previews: PreviewProvider {
59 | static var previews: some View {
60 | MyScrollView(text: "Hello World")
61 | }
62 | }
63 |
64 |
--------------------------------------------------------------------------------
/UIViewDemo/UIViewDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/UIViewDemo/UIViewDemo.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/UIViewDemo/UIViewDemo.xcodeproj/project.xcworkspace/xcuserdata/neilsmyth.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Jpub/SwiftUI/defbcdd40638ec4d8d55e6693e7c878a00b1d135/UIViewDemo/UIViewDemo.xcodeproj/project.xcworkspace/xcuserdata/neilsmyth.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/UIViewDemo/UIViewDemo.xcodeproj/xcuserdata/neilsmyth.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | UIViewDemo.xcscheme_^#shared#^_
8 |
9 | orderHint
10 | 0
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/UIViewDemo/UIViewDemo/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // UIViewDemo
4 | //
5 | // Created by Neil Smyth on 10/16/19.
6 | // Copyright © 2019 eBookFrenzy. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | @UIApplicationMain
12 | class AppDelegate: UIResponder, UIApplicationDelegate {
13 |
14 |
15 |
16 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
17 | // Override point for customization after application launch.
18 | return true
19 | }
20 |
21 | // MARK: UISceneSession Lifecycle
22 |
23 | func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
24 | // Called when a new scene session is being created.
25 | // Use this method to select a configuration to create the new scene with.
26 | return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
27 | }
28 |
29 | func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) {
30 | // Called when the user discards a scene session.
31 | // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
32 | // Use this method to release any resources that were specific to the discarded scenes, as they will not return.
33 | }
34 |
35 |
36 | }
37 |
38 |
--------------------------------------------------------------------------------
/UIViewDemo/UIViewDemo/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "20x20",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "20x20",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "29x29",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "29x29",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "40x40",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "40x40",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "iphone",
35 | "size" : "60x60",
36 | "scale" : "2x"
37 | },
38 | {
39 | "idiom" : "iphone",
40 | "size" : "60x60",
41 | "scale" : "3x"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "size" : "20x20",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "size" : "20x20",
51 | "scale" : "2x"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "size" : "29x29",
56 | "scale" : "1x"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "size" : "29x29",
61 | "scale" : "2x"
62 | },
63 | {
64 | "idiom" : "ipad",
65 | "size" : "40x40",
66 | "scale" : "1x"
67 | },
68 | {
69 | "idiom" : "ipad",
70 | "size" : "40x40",
71 | "scale" : "2x"
72 | },
73 | {
74 | "idiom" : "ipad",
75 | "size" : "76x76",
76 | "scale" : "1x"
77 | },
78 | {
79 | "idiom" : "ipad",
80 | "size" : "76x76",
81 | "scale" : "2x"
82 | },
83 | {
84 | "idiom" : "ipad",
85 | "size" : "83.5x83.5",
86 | "scale" : "2x"
87 | },
88 | {
89 | "idiom" : "ios-marketing",
90 | "size" : "1024x1024",
91 | "scale" : "1x"
92 | }
93 | ],
94 | "info" : {
95 | "version" : 1,
96 | "author" : "xcode"
97 | }
98 | }
--------------------------------------------------------------------------------
/UIViewDemo/UIViewDemo/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/UIViewDemo/UIViewDemo/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/UIViewDemo/UIViewDemo/ContentView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ContentView.swift
3 | // UIViewDemo
4 | //
5 | // Created by Neil Smyth on 10/16/19.
6 | // Copyright © 2019 eBookFrenzy. All rights reserved.
7 | //
8 |
9 | import SwiftUI
10 |
11 | struct ContentView: View {
12 | var body: some View {
13 | MyScrollView(text: "UIView in SwiftUI")
14 | }
15 | }
16 |
17 | struct ContentView_Previews: PreviewProvider {
18 | static var previews: some View {
19 | ContentView()
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/UIViewDemo/UIViewDemo/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE)
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 | LSRequiresIPhoneOS
22 |
23 | UIApplicationSceneManifest
24 |
25 | UIApplicationSupportsMultipleScenes
26 |
27 | UISceneConfigurations
28 |
29 | UIWindowSceneSessionRoleApplication
30 |
31 |
32 | UISceneConfigurationName
33 | Default Configuration
34 | UISceneDelegateClassName
35 | $(PRODUCT_MODULE_NAME).SceneDelegate
36 |
37 |
38 |
39 |
40 | UILaunchStoryboardName
41 | LaunchScreen
42 | UIRequiredDeviceCapabilities
43 |
44 | armv7
45 |
46 | UISupportedInterfaceOrientations
47 |
48 | UIInterfaceOrientationPortrait
49 | UIInterfaceOrientationLandscapeLeft
50 | UIInterfaceOrientationLandscapeRight
51 |
52 | UISupportedInterfaceOrientations~ipad
53 |
54 | UIInterfaceOrientationPortrait
55 | UIInterfaceOrientationPortraitUpsideDown
56 | UIInterfaceOrientationLandscapeLeft
57 | UIInterfaceOrientationLandscapeRight
58 |
59 |
60 |
61 |
--------------------------------------------------------------------------------
/UIViewDemo/UIViewDemo/Preview Content/Preview Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/UIViewDemo/UIViewDemo/SceneDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SceneDelegate.swift
3 | // UIViewDemo
4 | //
5 | // Created by Neil Smyth on 10/16/19.
6 | // Copyright © 2019 eBookFrenzy. All rights reserved.
7 | //
8 |
9 | import UIKit
10 | import SwiftUI
11 |
12 | class SceneDelegate: UIResponder, UIWindowSceneDelegate {
13 |
14 | var window: UIWindow?
15 |
16 |
17 | func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
18 | // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
19 | // If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
20 | // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
21 |
22 | // Create the SwiftUI view that provides the window contents.
23 | let contentView = ContentView()
24 |
25 | // Use a UIHostingController as window root view controller.
26 | if let windowScene = scene as? UIWindowScene {
27 | let window = UIWindow(windowScene: windowScene)
28 | window.rootViewController = UIHostingController(rootView: contentView)
29 | self.window = window
30 | window.makeKeyAndVisible()
31 | }
32 | }
33 |
34 | func sceneDidDisconnect(_ scene: UIScene) {
35 | // Called as the scene is being released by the system.
36 | // This occurs shortly after the scene enters the background, or when its session is discarded.
37 | // Release any resources associated with this scene that can be re-created the next time the scene connects.
38 | // The scene may re-connect later, as its session was not neccessarily discarded (see `application:didDiscardSceneSessions` instead).
39 | }
40 |
41 | func sceneDidBecomeActive(_ scene: UIScene) {
42 | // Called when the scene has moved from an inactive state to an active state.
43 | // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive.
44 | }
45 |
46 | func sceneWillResignActive(_ scene: UIScene) {
47 | // Called when the scene will move from an active state to an inactive state.
48 | // This may occur due to temporary interruptions (ex. an incoming phone call).
49 | }
50 |
51 | func sceneWillEnterForeground(_ scene: UIScene) {
52 | // Called as the scene transitions from the background to the foreground.
53 | // Use this method to undo the changes made on entering the background.
54 | }
55 |
56 | func sceneDidEnterBackground(_ scene: UIScene) {
57 | // Called as the scene transitions from the foreground to the background.
58 | // Use this method to save data, release shared resources, and store enough scene-specific state information
59 | // to restore the scene back to its current state.
60 | }
61 |
62 |
63 | }
64 |
65 |
--------------------------------------------------------------------------------
/ViewControllerDemo/MyImagePicker.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MyImagePicker.swift
3 | // ViewControllerDemo
4 | //
5 | // Created by Neil Smyth on 10/16/19.
6 | // Copyright © 2019 eBookFrenzy. All rights reserved.
7 | //
8 |
9 | import SwiftUI
10 |
11 | struct MyImagePicker: UIViewControllerRepresentable {
12 |
13 | @Binding var imagePickerVisible: Bool
14 | @Binding var selectedImage: Image?
15 |
16 | func makeUIViewController(context:
17 | UIViewControllerRepresentableContext) ->
18 | UIImagePickerController {
19 | let picker = UIImagePickerController()
20 | picker.delegate = context.coordinator
21 | return picker
22 | }
23 |
24 | func updateUIViewController(_ uiViewController:
25 | UIImagePickerController, context:
26 | UIViewControllerRepresentableContext) {
27 |
28 | }
29 |
30 | func makeCoordinator() -> Coordinator {
31 | return Coordinator(imagePickerVisible: $imagePickerVisible,
32 | selectedImage: $selectedImage)
33 | }
34 |
35 |
36 | class Coordinator: NSObject, UINavigationControllerDelegate,
37 | UIImagePickerControllerDelegate {
38 |
39 | @Binding var imagePickerVisible: Bool
40 | @Binding var selectedImage: Image?
41 |
42 | init(imagePickerVisible: Binding,
43 | selectedImage: Binding) {
44 | _imagePickerVisible = imagePickerVisible
45 | _selectedImage = selectedImage
46 | }
47 |
48 | func imagePickerController(_ picker: UIImagePickerController,
49 | didFinishPickingMediaWithInfo
50 | info: [UIImagePickerController.InfoKey : Any]) {
51 | let uiImage =
52 | info[UIImagePickerController.InfoKey.originalImage] as!
53 | UIImage
54 | selectedImage = Image(uiImage: uiImage)
55 | imagePickerVisible = false
56 | }
57 |
58 | func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
59 | imagePickerVisible = false
60 | }
61 | }
62 |
63 | }
64 | /*
65 | struct MyImagePicker_Previews: PreviewProvider {
66 | static var previews: some View {
67 | MyImagePicker()
68 | }
69 | }
70 | */
71 |
--------------------------------------------------------------------------------
/ViewControllerDemo/ViewControllerDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/ViewControllerDemo/ViewControllerDemo.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ViewControllerDemo/ViewControllerDemo.xcodeproj/project.xcworkspace/xcuserdata/neilsmyth.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Jpub/SwiftUI/defbcdd40638ec4d8d55e6693e7c878a00b1d135/ViewControllerDemo/ViewControllerDemo.xcodeproj/project.xcworkspace/xcuserdata/neilsmyth.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/ViewControllerDemo/ViewControllerDemo.xcodeproj/xcuserdata/neilsmyth.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | ViewControllerDemo.xcscheme_^#shared#^_
8 |
9 | orderHint
10 | 0
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/ViewControllerDemo/ViewControllerDemo/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // ViewControllerDemo
4 | //
5 | // Created by Neil Smyth on 10/16/19.
6 | // Copyright © 2019 eBookFrenzy. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | @UIApplicationMain
12 | class AppDelegate: UIResponder, UIApplicationDelegate {
13 |
14 |
15 |
16 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
17 | // Override point for customization after application launch.
18 | return true
19 | }
20 |
21 | // MARK: UISceneSession Lifecycle
22 |
23 | func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
24 | // Called when a new scene session is being created.
25 | // Use this method to select a configuration to create the new scene with.
26 | return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
27 | }
28 |
29 | func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) {
30 | // Called when the user discards a scene session.
31 | // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
32 | // Use this method to release any resources that were specific to the discarded scenes, as they will not return.
33 | }
34 |
35 |
36 | }
37 |
38 |
--------------------------------------------------------------------------------
/ViewControllerDemo/ViewControllerDemo/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "20x20",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "20x20",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "29x29",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "29x29",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "40x40",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "40x40",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "iphone",
35 | "size" : "60x60",
36 | "scale" : "2x"
37 | },
38 | {
39 | "idiom" : "iphone",
40 | "size" : "60x60",
41 | "scale" : "3x"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "size" : "20x20",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "size" : "20x20",
51 | "scale" : "2x"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "size" : "29x29",
56 | "scale" : "1x"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "size" : "29x29",
61 | "scale" : "2x"
62 | },
63 | {
64 | "idiom" : "ipad",
65 | "size" : "40x40",
66 | "scale" : "1x"
67 | },
68 | {
69 | "idiom" : "ipad",
70 | "size" : "40x40",
71 | "scale" : "2x"
72 | },
73 | {
74 | "idiom" : "ipad",
75 | "size" : "76x76",
76 | "scale" : "1x"
77 | },
78 | {
79 | "idiom" : "ipad",
80 | "size" : "76x76",
81 | "scale" : "2x"
82 | },
83 | {
84 | "idiom" : "ipad",
85 | "size" : "83.5x83.5",
86 | "scale" : "2x"
87 | },
88 | {
89 | "idiom" : "ios-marketing",
90 | "size" : "1024x1024",
91 | "scale" : "1x"
92 | }
93 | ],
94 | "info" : {
95 | "version" : 1,
96 | "author" : "xcode"
97 | }
98 | }
--------------------------------------------------------------------------------
/ViewControllerDemo/ViewControllerDemo/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/ViewControllerDemo/ViewControllerDemo/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/ViewControllerDemo/ViewControllerDemo/ContentView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ContentView.swift
3 | // ViewControllerDemo
4 | //
5 | // Created by Neil Smyth on 10/16/19.
6 | // Copyright © 2019 eBookFrenzy. All rights reserved.
7 | //
8 |
9 | import SwiftUI
10 |
11 | struct ContentView: View {
12 |
13 | @State var imagePickerVisible: Bool = false
14 | @State var selectedImage: Image? = Image(systemName: "photo")
15 |
16 | var body: some View {
17 | ZStack {
18 | VStack {
19 |
20 | selectedImage?
21 | .resizable()
22 | .aspectRatio(contentMode: .fit)
23 |
24 | Button(action: {
25 | withAnimation {
26 | self.imagePickerVisible.toggle()
27 | }
28 | }) {
29 | Text("Select an Image")
30 | }
31 |
32 | }.padding()
33 |
34 | if (imagePickerVisible) {
35 | MyImagePicker(imagePickerVisible:
36 | $imagePickerVisible,
37 | selectedImage: $selectedImage)
38 | }
39 | }
40 |
41 | }
42 | }
43 |
44 | struct ContentView_Previews: PreviewProvider {
45 | static var previews: some View {
46 | ContentView()
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/ViewControllerDemo/ViewControllerDemo/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE)
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 | LSRequiresIPhoneOS
22 |
23 | UIApplicationSceneManifest
24 |
25 | UIApplicationSupportsMultipleScenes
26 |
27 | UISceneConfigurations
28 |
29 | UIWindowSceneSessionRoleApplication
30 |
31 |
32 | UISceneConfigurationName
33 | Default Configuration
34 | UISceneDelegateClassName
35 | $(PRODUCT_MODULE_NAME).SceneDelegate
36 |
37 |
38 |
39 |
40 | UILaunchStoryboardName
41 | LaunchScreen
42 | UIRequiredDeviceCapabilities
43 |
44 | armv7
45 |
46 | UISupportedInterfaceOrientations
47 |
48 | UIInterfaceOrientationPortrait
49 | UIInterfaceOrientationLandscapeLeft
50 | UIInterfaceOrientationLandscapeRight
51 |
52 | UISupportedInterfaceOrientations~ipad
53 |
54 | UIInterfaceOrientationPortrait
55 | UIInterfaceOrientationPortraitUpsideDown
56 | UIInterfaceOrientationLandscapeLeft
57 | UIInterfaceOrientationLandscapeRight
58 |
59 |
60 |
61 |
--------------------------------------------------------------------------------
/ViewControllerDemo/ViewControllerDemo/Preview Content/Preview Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/ViewControllerDemo/ViewControllerDemo/SceneDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SceneDelegate.swift
3 | // ViewControllerDemo
4 | //
5 | // Created by Neil Smyth on 10/16/19.
6 | // Copyright © 2019 eBookFrenzy. All rights reserved.
7 | //
8 |
9 | import UIKit
10 | import SwiftUI
11 |
12 | class SceneDelegate: UIResponder, UIWindowSceneDelegate {
13 |
14 | var window: UIWindow?
15 |
16 |
17 | func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
18 | // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
19 | // If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
20 | // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
21 |
22 | // Create the SwiftUI view that provides the window contents.
23 | let contentView = ContentView()
24 |
25 | // Use a UIHostingController as window root view controller.
26 | if let windowScene = scene as? UIWindowScene {
27 | let window = UIWindow(windowScene: windowScene)
28 | window.rootViewController = UIHostingController(rootView: contentView)
29 | self.window = window
30 | window.makeKeyAndVisible()
31 | }
32 | }
33 |
34 | func sceneDidDisconnect(_ scene: UIScene) {
35 | // Called as the scene is being released by the system.
36 | // This occurs shortly after the scene enters the background, or when its session is discarded.
37 | // Release any resources associated with this scene that can be re-created the next time the scene connects.
38 | // The scene may re-connect later, as its session was not neccessarily discarded (see `application:didDiscardSceneSessions` instead).
39 | }
40 |
41 | func sceneDidBecomeActive(_ scene: UIScene) {
42 | // Called when the scene has moved from an inactive state to an active state.
43 | // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive.
44 | }
45 |
46 | func sceneWillResignActive(_ scene: UIScene) {
47 | // Called when the scene will move from an active state to an inactive state.
48 | // This may occur due to temporary interruptions (ex. an incoming phone call).
49 | }
50 |
51 | func sceneWillEnterForeground(_ scene: UIScene) {
52 | // Called as the scene transitions from the background to the foreground.
53 | // Use this method to undo the changes made on entering the background.
54 | }
55 |
56 | func sceneDidEnterBackground(_ scene: UIScene) {
57 | // Called as the scene transitions from the foreground to the background.
58 | // Use this method to save data, release shared resources, and store enough scene-specific state information
59 | // to restore the scene back to its current state.
60 | }
61 |
62 |
63 | }
64 |
65 |
--------------------------------------------------------------------------------
/playground_images/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Jpub/SwiftUI/defbcdd40638ec4d8d55e6693e7c878a00b1d135/playground_images/.DS_Store
--------------------------------------------------------------------------------
/playground_images/waterfall.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Jpub/SwiftUI/defbcdd40638ec4d8d55e6693e7c878a00b1d135/playground_images/waterfall.png
--------------------------------------------------------------------------------