├── LICENSE ├── demo.gif ├── demo.mov ├── Shared ├── Assets.xcassets │ ├── Contents.json │ ├── AccentColor.colorset │ │ └── Contents.json │ └── AppIcon.appiconset │ │ └── Contents.json ├── phantom.xcdatamodeld │ ├── .xccurrentversion │ └── Shared.xcdatamodel │ │ └── contents ├── phantomApp.swift ├── Persistence.swift └── ContentView.swift ├── phantom.xcodeproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist ├── xcuserdata │ └── twodayslate.xcuserdatad │ │ └── xcschemes │ │ └── xcschememanagement.plist └── project.pbxproj ├── README.md ├── macOS ├── macOS.entitlements └── Info.plist ├── Tests iOS ├── Info.plist └── Tests_iOS.swift ├── Tests macOS ├── Info.plist └── Tests_macOS.swift └── iOS └── Info.plist /LICENSE: -------------------------------------------------------------------------------- 1 | "Attribution-NonCommercial-ShareAlike 4.0 International" license -------------------------------------------------------------------------------- /demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/twodayslate/phantom_swiftui/main/demo.gif -------------------------------------------------------------------------------- /demo.mov: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/twodayslate/phantom_swiftui/main/demo.mov -------------------------------------------------------------------------------- /Shared/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /phantom.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Phantom 2 | 3 | [![Demo](https://raw.githubusercontent.com/twodayslate/phantom_swiftui/main/demo.gif)](https://raw.githubusercontent.com/twodayslate/phantom_swiftui/main/demo.mov) 4 | 5 | A quick demo application for a [Phantom wallet](https://phantom.app/) proposal screen -------------------------------------------------------------------------------- /Shared/phantom.xcdatamodeld/.xccurrentversion: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | _XCCurrentVersionName 6 | Shared.xcdatamodel 7 | 8 | 9 | -------------------------------------------------------------------------------- /phantom.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Shared/Assets.xcassets/AccentColor.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "platform" : "tvos", 6 | "reference" : "systemPurpleColor" 7 | }, 8 | "idiom" : "universal" 9 | } 10 | ], 11 | "info" : { 12 | "author" : "xcode", 13 | "version" : 1 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /macOS/macOS.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | com.apple.security.files.user-selected.read-only 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Shared/phantomApp.swift: -------------------------------------------------------------------------------- 1 | // 2 | // phantomApp.swift 3 | // Shared 4 | // 5 | // Created by Zachary Gorak on 7/29/21. 6 | // 7 | 8 | import SwiftUI 9 | 10 | @main 11 | struct phantomApp: App { 12 | let persistenceController = PersistenceController.shared 13 | 14 | var body: some Scene { 15 | WindowGroup { 16 | ContentView() 17 | .environment(\.managedObjectContext, persistenceController.container.viewContext) 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /phantom.xcodeproj/xcuserdata/twodayslate.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | phantom (iOS).xcscheme_^#shared#^_ 8 | 9 | orderHint 10 | 0 11 | 12 | phantom (macOS).xcscheme_^#shared#^_ 13 | 14 | orderHint 15 | 1 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /Shared/phantom.xcdatamodeld/Shared.xcdatamodel/contents: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Tests iOS/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /Tests macOS/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 | 22 | 23 | -------------------------------------------------------------------------------- /macOS/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | LSMinimumSystemVersion 24 | $(MACOSX_DEPLOYMENT_TARGET) 25 | 26 | 27 | -------------------------------------------------------------------------------- /Tests iOS/Tests_iOS.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Tests_iOS.swift 3 | // Tests iOS 4 | // 5 | // Created by Zachary Gorak on 7/29/21. 6 | // 7 | 8 | import XCTest 9 | 10 | class Tests_iOS: XCTestCase { 11 | 12 | override func setUpWithError() throws { 13 | // Put setup code here. This method is called before the invocation of each test method in the class. 14 | 15 | // In UI tests it is usually best to stop immediately when a failure occurs. 16 | continueAfterFailure = false 17 | 18 | // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this. 19 | } 20 | 21 | override func tearDownWithError() throws { 22 | // Put teardown code here. This method is called after the invocation of each test method in the class. 23 | } 24 | 25 | func testExample() throws { 26 | // UI tests must launch the application that they test. 27 | let app = XCUIApplication() 28 | app.launch() 29 | 30 | // Use recording to get started writing UI tests. 31 | // Use XCTAssert and related functions to verify your tests produce the correct results. 32 | } 33 | 34 | func testLaunchPerformance() throws { 35 | if #available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 7.0, *) { 36 | // This measures how long it takes to launch your application. 37 | measure(metrics: [XCTApplicationLaunchMetric()]) { 38 | XCUIApplication().launch() 39 | } 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /Tests macOS/Tests_macOS.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Tests_macOS.swift 3 | // Tests macOS 4 | // 5 | // Created by Zachary Gorak on 7/29/21. 6 | // 7 | 8 | import XCTest 9 | 10 | class Tests_macOS: XCTestCase { 11 | 12 | override func setUpWithError() throws { 13 | // Put setup code here. This method is called before the invocation of each test method in the class. 14 | 15 | // In UI tests it is usually best to stop immediately when a failure occurs. 16 | continueAfterFailure = false 17 | 18 | // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this. 19 | } 20 | 21 | override func tearDownWithError() throws { 22 | // Put teardown code here. This method is called after the invocation of each test method in the class. 23 | } 24 | 25 | func testExample() throws { 26 | // UI tests must launch the application that they test. 27 | let app = XCUIApplication() 28 | app.launch() 29 | 30 | // Use recording to get started writing UI tests. 31 | // Use XCTAssert and related functions to verify your tests produce the correct results. 32 | } 33 | 34 | func testLaunchPerformance() throws { 35 | if #available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 7.0, *) { 36 | // This measures how long it takes to launch your application. 37 | measure(metrics: [XCTApplicationLaunchMetric()]) { 38 | XCUIApplication().launch() 39 | } 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /iOS/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UIApplicationSceneManifest 24 | 25 | UIApplicationSupportsMultipleScenes 26 | 27 | 28 | UIApplicationSupportsIndirectInputEvents 29 | 30 | UILaunchScreen 31 | 32 | UIRequiredDeviceCapabilities 33 | 34 | armv7 35 | 36 | UISupportedInterfaceOrientations 37 | 38 | UIInterfaceOrientationPortrait 39 | UIInterfaceOrientationLandscapeLeft 40 | UIInterfaceOrientationLandscapeRight 41 | 42 | UISupportedInterfaceOrientations~ipad 43 | 44 | UIInterfaceOrientationPortrait 45 | UIInterfaceOrientationPortraitUpsideDown 46 | UIInterfaceOrientationLandscapeLeft 47 | UIInterfaceOrientationLandscapeRight 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /Shared/Persistence.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Persistence.swift 3 | // Shared 4 | // 5 | // Created by Zachary Gorak on 7/29/21. 6 | // 7 | 8 | import CoreData 9 | 10 | struct PersistenceController { 11 | static let shared = PersistenceController() 12 | 13 | static var preview: PersistenceController = { 14 | let result = PersistenceController(inMemory: true) 15 | let viewContext = result.container.viewContext 16 | for _ in 0..<10 { 17 | let newItem = Item(context: viewContext) 18 | newItem.timestamp = Date() 19 | } 20 | do { 21 | try viewContext.save() 22 | } catch { 23 | // Replace this implementation with code to handle the error appropriately. 24 | // fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. 25 | let nsError = error as NSError 26 | fatalError("Unresolved error \(nsError), \(nsError.userInfo)") 27 | } 28 | return result 29 | }() 30 | 31 | let container: NSPersistentCloudKitContainer 32 | 33 | init(inMemory: Bool = false) { 34 | container = NSPersistentCloudKitContainer(name: "phantom") 35 | if inMemory { 36 | container.persistentStoreDescriptions.first!.url = URL(fileURLWithPath: "/dev/null") 37 | } 38 | container.loadPersistentStores(completionHandler: { (storeDescription, error) in 39 | if let error = error as NSError? { 40 | // Replace this implementation with code to handle the error appropriately. 41 | // fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. 42 | 43 | /* 44 | Typical reasons for an error here include: 45 | * The parent directory does not exist, cannot be created, or disallows writing. 46 | * The persistent store is not accessible, due to permissions or data protection when the device is locked. 47 | * The device is out of space. 48 | * The store could not be migrated to the current model version. 49 | Check the error message to determine what the actual problem was. 50 | */ 51 | fatalError("Unresolved error \(error), \(error.userInfo)") 52 | } 53 | }) 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /Shared/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "scale" : "2x", 6 | "size" : "20x20" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "scale" : "3x", 11 | "size" : "20x20" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "scale" : "2x", 16 | "size" : "29x29" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "scale" : "3x", 21 | "size" : "29x29" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "scale" : "2x", 26 | "size" : "40x40" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "scale" : "3x", 31 | "size" : "40x40" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "scale" : "2x", 36 | "size" : "60x60" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "scale" : "3x", 41 | "size" : "60x60" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "scale" : "1x", 46 | "size" : "20x20" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "scale" : "2x", 51 | "size" : "20x20" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "scale" : "1x", 56 | "size" : "29x29" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "scale" : "2x", 61 | "size" : "29x29" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "scale" : "1x", 66 | "size" : "40x40" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "scale" : "2x", 71 | "size" : "40x40" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "scale" : "1x", 76 | "size" : "76x76" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "scale" : "2x", 81 | "size" : "76x76" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "scale" : "2x", 86 | "size" : "83.5x83.5" 87 | }, 88 | { 89 | "idiom" : "ios-marketing", 90 | "scale" : "1x", 91 | "size" : "1024x1024" 92 | }, 93 | { 94 | "idiom" : "mac", 95 | "scale" : "1x", 96 | "size" : "16x16" 97 | }, 98 | { 99 | "idiom" : "mac", 100 | "scale" : "2x", 101 | "size" : "16x16" 102 | }, 103 | { 104 | "idiom" : "mac", 105 | "scale" : "1x", 106 | "size" : "32x32" 107 | }, 108 | { 109 | "idiom" : "mac", 110 | "scale" : "2x", 111 | "size" : "32x32" 112 | }, 113 | { 114 | "idiom" : "mac", 115 | "scale" : "1x", 116 | "size" : "128x128" 117 | }, 118 | { 119 | "idiom" : "mac", 120 | "scale" : "2x", 121 | "size" : "128x128" 122 | }, 123 | { 124 | "idiom" : "mac", 125 | "scale" : "1x", 126 | "size" : "256x256" 127 | }, 128 | { 129 | "idiom" : "mac", 130 | "scale" : "2x", 131 | "size" : "256x256" 132 | }, 133 | { 134 | "idiom" : "mac", 135 | "scale" : "1x", 136 | "size" : "512x512" 137 | }, 138 | { 139 | "idiom" : "mac", 140 | "scale" : "2x", 141 | "size" : "512x512" 142 | } 143 | ], 144 | "info" : { 145 | "author" : "xcode", 146 | "version" : 1 147 | } 148 | } 149 | -------------------------------------------------------------------------------- /Shared/ContentView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ContentView.swift 3 | // Shared 4 | // 5 | // Created by Zachary Gorak on 7/29/21. 6 | // 7 | 8 | import SwiftUI 9 | import CoreData 10 | 11 | //extension Color { 12 | // static var phantomPurple: Color { 13 | // return Color(UIColor(red: 0x94/0xff, green: 0, blue: 0xff, alpha: 1.0)) 14 | // } 15 | //} 16 | 17 | struct ContentView: View { 18 | @Environment(\.managedObjectContext) private var viewContext 19 | 20 | @State var scrollOffset: CGFloat = 0 21 | @State var headerSize: CGSize = .zero 22 | @State var priceSize: CGSize = .zero 23 | @State var topSafeArea: CGFloat = 0 24 | 25 | var body: some View { 26 | ZStack(alignment: .top){ 27 | GeometryReader { proxy -> Color in 28 | print("safe area", proxy.safeAreaInsets) 29 | DispatchQueue.main.async { 30 | 31 | topSafeArea = proxy.safeAreaInsets.top 32 | 33 | } 34 | return .clear 35 | } 36 | ScrollView { 37 | // Fake Navigation Header 38 | VStack(spacing: 0) { 39 | VStack(alignment: .leading) { 40 | ZStack { 41 | HStack(alignment: .center) { 42 | //GeometryReader { proxy in 43 | Spacer() 44 | 45 | Text("Wallet 1").font(.headline).bold().foregroundColor(.accentColor).padding(.horizontal).background(GeometryReader { proxy -> Color in 46 | 47 | DispatchQueue.main.async { 48 | withAnimation { 49 | headerSize = proxy.size 50 | } 51 | } 52 | 53 | return .clear 54 | }) 55 | .offset(x: self.scrollOffset >= 0 ? 0 : -(UIScreen.main.bounds.midX - self.headerSize.width/2) * self.headerPercentage) 56 | .offset(y: headerSize.height/3 * self.headerPercentage) 57 | 58 | Spacer() 59 | } 60 | HStack(alignment: .center) { 61 | //GeometryReader { proxy in 62 | 63 | Spacer() 64 | 65 | Text("$17,382.82").transition(AnyTransition.asymmetric(insertion: .move(edge: .trailing), removal: .move(edge: .trailing))).padding(.horizontal) 66 | .offset(x: self.scrollOffset >= 0 ? 100 : 100 * (1.0-self.headerPercentage)) 67 | .offset(y: headerSize.height/3 * self.headerPercentage) 68 | 69 | 70 | } 71 | } 72 | 73 | 74 | HStack(alignment: .center) { 75 | Spacer() 76 | //if self.scrollOffset >= 0 { 77 | Text("1fRFgFkx7-Y9EKu7W9efmLalK_XFXqV10s5wTlZIp60").foregroundColor(.gray).font(.caption2) 78 | .padding(.bottom, 4.0) 79 | .transition(AnyTransition.asymmetric(insertion: .move(edge: .bottom), removal: .move(edge: .bottom)).combined(with: .opacity)) 80 | .opacity(self.scrollOffset >= 0 ? 1.0 : 1.0-Double(self.headerPercentage)) 81 | //} 82 | Spacer() 83 | } 84 | 85 | }.padding(.top, topSafeArea) 86 | 87 | Divider() 88 | } 89 | .background(Color(UIColor.secondarySystemBackground)) 90 | .offset(y:-self.scrollOffset) 91 | .zIndex(1.0).background(GeometryReader { proxy -> Color in 92 | let minY = proxy.frame(in: .global).minY 93 | //print("header", proxy.frame(in: .global), proxy.frame(in: .local)) 94 | print(minY, self.headerPercentage, proxy.safeAreaInsets.top) 95 | DispatchQueue.main.async { 96 | //withAnimation { 97 | self.scrollOffset = minY 98 | //} 99 | } 100 | 101 | return .clear 102 | }) 103 | 104 | VStack { 105 | Text("$17,382.82").font(.largeTitle).bold() 106 | HStack { 107 | Spacer() 108 | Text("+$1,399.22").font(.title3).foregroundColor(.green) 109 | Text("+13.3%").font(.title3).foregroundColor(.green).padding(4.0).background(Color.green.opacity(0.2)).cornerRadius(8.0) 110 | Spacer() 111 | } 112 | }.padding() 113 | .background(GeometryReader { proxy -> Color in 114 | 115 | DispatchQueue.main.async { 116 | withAnimation { 117 | priceSize = proxy.size 118 | } 119 | } 120 | 121 | return .clear 122 | }) 123 | .opacity(self.scrollOffset >= 0 ? 1.0 : 1.0-Double(self.headerPercentage)).zIndex(0.0) 124 | 125 | ForEach(0..<10) { _ in 126 | HStack(alignment: .center) { 127 | 128 | Image(systemName: "bitcoinsign.circle.fill").imageScale(.large) 129 | 130 | VStack(alignment: .leading) { 131 | Text("Solana").font(.headline) 132 | Text("3.14 SOL").foregroundColor(.gray).font(.callout) 133 | } 134 | Spacer() 135 | VStack(alignment:.trailing) { 136 | Text("$10,389.92") 137 | Text("+1,399.22").foregroundColor(.green) 138 | }.font(.subheadline) 139 | }.padding().background(Color(UIColor.secondarySystemFill)).cornerRadius(8.0).padding([.horizontal]) 140 | 141 | } 142 | } 143 | .ignoresSafeArea() 144 | VStack { 145 | Spacer() 146 | HStack { 147 | Button(action: /*@START_MENU_TOKEN@*/{}/*@END_MENU_TOKEN@*/, label: { 148 | HStack { 149 | Spacer() 150 | Image(systemName: "tray.and.arrow.down") 151 | Text("Recieve").bold() 152 | Spacer() 153 | } 154 | 155 | }).padding(8.0).background(Color(UIColor.secondarySystemBackground)).cornerRadius(8).overlay(RoundedRectangle(cornerRadius: 8).stroke(Color(UIColor.separator), lineWidth: 1.0)) 156 | Button(action: /*@START_MENU_TOKEN@*/{}/*@END_MENU_TOKEN@*/, label: { 157 | HStack { 158 | Spacer() 159 | Image(systemName: "paperplane") 160 | Text("Send").bold() 161 | Spacer() 162 | } 163 | }).padding(8.0).background(Color(UIColor.secondarySystemBackground)).cornerRadius(8).overlay(RoundedRectangle(cornerRadius: 8).stroke(Color(UIColor.separator), lineWidth: 1.0)) 164 | }.padding(.horizontal, 6.0).padding(.vertical) 165 | } 166 | } 167 | } 168 | 169 | 170 | var headerPercentage: CGFloat { 171 | if self.scrollOffset > 0 { 172 | return 0 173 | } 174 | 175 | return min(1.0, (abs(self.scrollOffset) / priceSize.height)) 176 | } 177 | } 178 | 179 | struct ContentView_Previews: PreviewProvider { 180 | static var previews: some View { 181 | Group { 182 | ContentView().environment(\.managedObjectContext, PersistenceController.preview.container.viewContext) 183 | ContentView().environment(\.managedObjectContext, PersistenceController.preview.container.viewContext).preferredColorScheme(.dark) 184 | } 185 | } 186 | } 187 | -------------------------------------------------------------------------------- /phantom.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 50; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | F6A2170C26B3A5A300A428C5 /* Tests_iOS.swift in Sources */ = {isa = PBXBuildFile; fileRef = F6A2170B26B3A5A300A428C5 /* Tests_iOS.swift */; }; 11 | F6A2171726B3A5A300A428C5 /* Tests_macOS.swift in Sources */ = {isa = PBXBuildFile; fileRef = F6A2171626B3A5A300A428C5 /* Tests_macOS.swift */; }; 12 | F6A2171926B3A5A300A428C5 /* phantom.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = F6A216ED26B3A5A200A428C5 /* phantom.xcdatamodeld */; }; 13 | F6A2171A26B3A5A300A428C5 /* phantom.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = F6A216ED26B3A5A200A428C5 /* phantom.xcdatamodeld */; }; 14 | F6A2171B26B3A5A300A428C5 /* phantomApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = F6A216EF26B3A5A200A428C5 /* phantomApp.swift */; }; 15 | F6A2171C26B3A5A300A428C5 /* phantomApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = F6A216EF26B3A5A200A428C5 /* phantomApp.swift */; }; 16 | F6A2171D26B3A5A300A428C5 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F6A216F026B3A5A200A428C5 /* ContentView.swift */; }; 17 | F6A2171E26B3A5A300A428C5 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F6A216F026B3A5A200A428C5 /* ContentView.swift */; }; 18 | F6A2171F26B3A5A300A428C5 /* Persistence.swift in Sources */ = {isa = PBXBuildFile; fileRef = F6A216F126B3A5A200A428C5 /* Persistence.swift */; }; 19 | F6A2172026B3A5A300A428C5 /* Persistence.swift in Sources */ = {isa = PBXBuildFile; fileRef = F6A216F126B3A5A200A428C5 /* Persistence.swift */; }; 20 | F6A2172126B3A5A300A428C5 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = F6A216F226B3A5A300A428C5 /* Assets.xcassets */; }; 21 | F6A2172226B3A5A300A428C5 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = F6A216F226B3A5A300A428C5 /* Assets.xcassets */; }; 22 | /* End PBXBuildFile section */ 23 | 24 | /* Begin PBXContainerItemProxy section */ 25 | F6A2170826B3A5A300A428C5 /* PBXContainerItemProxy */ = { 26 | isa = PBXContainerItemProxy; 27 | containerPortal = F6A216E826B3A5A200A428C5 /* Project object */; 28 | proxyType = 1; 29 | remoteGlobalIDString = F6A216F626B3A5A300A428C5; 30 | remoteInfo = "phantom (iOS)"; 31 | }; 32 | F6A2171326B3A5A300A428C5 /* PBXContainerItemProxy */ = { 33 | isa = PBXContainerItemProxy; 34 | containerPortal = F6A216E826B3A5A200A428C5 /* Project object */; 35 | proxyType = 1; 36 | remoteGlobalIDString = F6A216FE26B3A5A300A428C5; 37 | remoteInfo = "phantom (macOS)"; 38 | }; 39 | /* End PBXContainerItemProxy section */ 40 | 41 | /* Begin PBXFileReference section */ 42 | F6A216EE26B3A5A200A428C5 /* Shared.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = Shared.xcdatamodel; sourceTree = ""; }; 43 | F6A216EF26B3A5A200A428C5 /* phantomApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = phantomApp.swift; sourceTree = ""; }; 44 | F6A216F026B3A5A200A428C5 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; }; 45 | F6A216F126B3A5A200A428C5 /* Persistence.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Persistence.swift; sourceTree = ""; }; 46 | F6A216F226B3A5A300A428C5 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 47 | F6A216F726B3A5A300A428C5 /* phantom.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = phantom.app; sourceTree = BUILT_PRODUCTS_DIR; }; 48 | F6A216FA26B3A5A300A428C5 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 49 | F6A216FF26B3A5A300A428C5 /* phantom.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = phantom.app; sourceTree = BUILT_PRODUCTS_DIR; }; 50 | F6A2170126B3A5A300A428C5 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 51 | F6A2170226B3A5A300A428C5 /* macOS.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = macOS.entitlements; sourceTree = ""; }; 52 | F6A2170726B3A5A300A428C5 /* Tests iOS.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "Tests iOS.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; 53 | F6A2170B26B3A5A300A428C5 /* Tests_iOS.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Tests_iOS.swift; sourceTree = ""; }; 54 | F6A2170D26B3A5A300A428C5 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 55 | F6A2171226B3A5A300A428C5 /* Tests macOS.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "Tests macOS.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; 56 | F6A2171626B3A5A300A428C5 /* Tests_macOS.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Tests_macOS.swift; sourceTree = ""; }; 57 | F6A2171826B3A5A300A428C5 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 58 | /* End PBXFileReference section */ 59 | 60 | /* Begin PBXFrameworksBuildPhase section */ 61 | F6A216F426B3A5A300A428C5 /* Frameworks */ = { 62 | isa = PBXFrameworksBuildPhase; 63 | buildActionMask = 2147483647; 64 | files = ( 65 | ); 66 | runOnlyForDeploymentPostprocessing = 0; 67 | }; 68 | F6A216FC26B3A5A300A428C5 /* Frameworks */ = { 69 | isa = PBXFrameworksBuildPhase; 70 | buildActionMask = 2147483647; 71 | files = ( 72 | ); 73 | runOnlyForDeploymentPostprocessing = 0; 74 | }; 75 | F6A2170426B3A5A300A428C5 /* Frameworks */ = { 76 | isa = PBXFrameworksBuildPhase; 77 | buildActionMask = 2147483647; 78 | files = ( 79 | ); 80 | runOnlyForDeploymentPostprocessing = 0; 81 | }; 82 | F6A2170F26B3A5A300A428C5 /* Frameworks */ = { 83 | isa = PBXFrameworksBuildPhase; 84 | buildActionMask = 2147483647; 85 | files = ( 86 | ); 87 | runOnlyForDeploymentPostprocessing = 0; 88 | }; 89 | /* End PBXFrameworksBuildPhase section */ 90 | 91 | /* Begin PBXGroup section */ 92 | F6A216E726B3A5A200A428C5 = { 93 | isa = PBXGroup; 94 | children = ( 95 | F6A216EC26B3A5A200A428C5 /* Shared */, 96 | F6A216F926B3A5A300A428C5 /* iOS */, 97 | F6A2170026B3A5A300A428C5 /* macOS */, 98 | F6A2170A26B3A5A300A428C5 /* Tests iOS */, 99 | F6A2171526B3A5A300A428C5 /* Tests macOS */, 100 | F6A216F826B3A5A300A428C5 /* Products */, 101 | ); 102 | sourceTree = ""; 103 | }; 104 | F6A216EC26B3A5A200A428C5 /* Shared */ = { 105 | isa = PBXGroup; 106 | children = ( 107 | F6A216EF26B3A5A200A428C5 /* phantomApp.swift */, 108 | F6A216F026B3A5A200A428C5 /* ContentView.swift */, 109 | F6A216F126B3A5A200A428C5 /* Persistence.swift */, 110 | F6A216F226B3A5A300A428C5 /* Assets.xcassets */, 111 | F6A216ED26B3A5A200A428C5 /* phantom.xcdatamodeld */, 112 | ); 113 | path = Shared; 114 | sourceTree = ""; 115 | }; 116 | F6A216F826B3A5A300A428C5 /* Products */ = { 117 | isa = PBXGroup; 118 | children = ( 119 | F6A216F726B3A5A300A428C5 /* phantom.app */, 120 | F6A216FF26B3A5A300A428C5 /* phantom.app */, 121 | F6A2170726B3A5A300A428C5 /* Tests iOS.xctest */, 122 | F6A2171226B3A5A300A428C5 /* Tests macOS.xctest */, 123 | ); 124 | name = Products; 125 | sourceTree = ""; 126 | }; 127 | F6A216F926B3A5A300A428C5 /* iOS */ = { 128 | isa = PBXGroup; 129 | children = ( 130 | F6A216FA26B3A5A300A428C5 /* Info.plist */, 131 | ); 132 | path = iOS; 133 | sourceTree = ""; 134 | }; 135 | F6A2170026B3A5A300A428C5 /* macOS */ = { 136 | isa = PBXGroup; 137 | children = ( 138 | F6A2170126B3A5A300A428C5 /* Info.plist */, 139 | F6A2170226B3A5A300A428C5 /* macOS.entitlements */, 140 | ); 141 | path = macOS; 142 | sourceTree = ""; 143 | }; 144 | F6A2170A26B3A5A300A428C5 /* Tests iOS */ = { 145 | isa = PBXGroup; 146 | children = ( 147 | F6A2170B26B3A5A300A428C5 /* Tests_iOS.swift */, 148 | F6A2170D26B3A5A300A428C5 /* Info.plist */, 149 | ); 150 | path = "Tests iOS"; 151 | sourceTree = ""; 152 | }; 153 | F6A2171526B3A5A300A428C5 /* Tests macOS */ = { 154 | isa = PBXGroup; 155 | children = ( 156 | F6A2171626B3A5A300A428C5 /* Tests_macOS.swift */, 157 | F6A2171826B3A5A300A428C5 /* Info.plist */, 158 | ); 159 | path = "Tests macOS"; 160 | sourceTree = ""; 161 | }; 162 | /* End PBXGroup section */ 163 | 164 | /* Begin PBXNativeTarget section */ 165 | F6A216F626B3A5A300A428C5 /* phantom (iOS) */ = { 166 | isa = PBXNativeTarget; 167 | buildConfigurationList = F6A2172526B3A5A300A428C5 /* Build configuration list for PBXNativeTarget "phantom (iOS)" */; 168 | buildPhases = ( 169 | F6A216F326B3A5A300A428C5 /* Sources */, 170 | F6A216F426B3A5A300A428C5 /* Frameworks */, 171 | F6A216F526B3A5A300A428C5 /* Resources */, 172 | ); 173 | buildRules = ( 174 | ); 175 | dependencies = ( 176 | ); 177 | name = "phantom (iOS)"; 178 | productName = "phantom (iOS)"; 179 | productReference = F6A216F726B3A5A300A428C5 /* phantom.app */; 180 | productType = "com.apple.product-type.application"; 181 | }; 182 | F6A216FE26B3A5A300A428C5 /* phantom (macOS) */ = { 183 | isa = PBXNativeTarget; 184 | buildConfigurationList = F6A2172826B3A5A300A428C5 /* Build configuration list for PBXNativeTarget "phantom (macOS)" */; 185 | buildPhases = ( 186 | F6A216FB26B3A5A300A428C5 /* Sources */, 187 | F6A216FC26B3A5A300A428C5 /* Frameworks */, 188 | F6A216FD26B3A5A300A428C5 /* Resources */, 189 | ); 190 | buildRules = ( 191 | ); 192 | dependencies = ( 193 | ); 194 | name = "phantom (macOS)"; 195 | productName = "phantom (macOS)"; 196 | productReference = F6A216FF26B3A5A300A428C5 /* phantom.app */; 197 | productType = "com.apple.product-type.application"; 198 | }; 199 | F6A2170626B3A5A300A428C5 /* Tests iOS */ = { 200 | isa = PBXNativeTarget; 201 | buildConfigurationList = F6A2172B26B3A5A300A428C5 /* Build configuration list for PBXNativeTarget "Tests iOS" */; 202 | buildPhases = ( 203 | F6A2170326B3A5A300A428C5 /* Sources */, 204 | F6A2170426B3A5A300A428C5 /* Frameworks */, 205 | F6A2170526B3A5A300A428C5 /* Resources */, 206 | ); 207 | buildRules = ( 208 | ); 209 | dependencies = ( 210 | F6A2170926B3A5A300A428C5 /* PBXTargetDependency */, 211 | ); 212 | name = "Tests iOS"; 213 | productName = "Tests iOS"; 214 | productReference = F6A2170726B3A5A300A428C5 /* Tests iOS.xctest */; 215 | productType = "com.apple.product-type.bundle.ui-testing"; 216 | }; 217 | F6A2171126B3A5A300A428C5 /* Tests macOS */ = { 218 | isa = PBXNativeTarget; 219 | buildConfigurationList = F6A2172E26B3A5A300A428C5 /* Build configuration list for PBXNativeTarget "Tests macOS" */; 220 | buildPhases = ( 221 | F6A2170E26B3A5A300A428C5 /* Sources */, 222 | F6A2170F26B3A5A300A428C5 /* Frameworks */, 223 | F6A2171026B3A5A300A428C5 /* Resources */, 224 | ); 225 | buildRules = ( 226 | ); 227 | dependencies = ( 228 | F6A2171426B3A5A300A428C5 /* PBXTargetDependency */, 229 | ); 230 | name = "Tests macOS"; 231 | productName = "Tests macOS"; 232 | productReference = F6A2171226B3A5A300A428C5 /* Tests macOS.xctest */; 233 | productType = "com.apple.product-type.bundle.ui-testing"; 234 | }; 235 | /* End PBXNativeTarget section */ 236 | 237 | /* Begin PBXProject section */ 238 | F6A216E826B3A5A200A428C5 /* Project object */ = { 239 | isa = PBXProject; 240 | attributes = { 241 | LastSwiftUpdateCheck = 1250; 242 | LastUpgradeCheck = 1250; 243 | TargetAttributes = { 244 | F6A216F626B3A5A300A428C5 = { 245 | CreatedOnToolsVersion = 12.5.1; 246 | }; 247 | F6A216FE26B3A5A300A428C5 = { 248 | CreatedOnToolsVersion = 12.5.1; 249 | }; 250 | F6A2170626B3A5A300A428C5 = { 251 | CreatedOnToolsVersion = 12.5.1; 252 | TestTargetID = F6A216F626B3A5A300A428C5; 253 | }; 254 | F6A2171126B3A5A300A428C5 = { 255 | CreatedOnToolsVersion = 12.5.1; 256 | TestTargetID = F6A216FE26B3A5A300A428C5; 257 | }; 258 | }; 259 | }; 260 | buildConfigurationList = F6A216EB26B3A5A200A428C5 /* Build configuration list for PBXProject "phantom" */; 261 | compatibilityVersion = "Xcode 9.3"; 262 | developmentRegion = en; 263 | hasScannedForEncodings = 0; 264 | knownRegions = ( 265 | en, 266 | Base, 267 | ); 268 | mainGroup = F6A216E726B3A5A200A428C5; 269 | productRefGroup = F6A216F826B3A5A300A428C5 /* Products */; 270 | projectDirPath = ""; 271 | projectRoot = ""; 272 | targets = ( 273 | F6A216F626B3A5A300A428C5 /* phantom (iOS) */, 274 | F6A216FE26B3A5A300A428C5 /* phantom (macOS) */, 275 | F6A2170626B3A5A300A428C5 /* Tests iOS */, 276 | F6A2171126B3A5A300A428C5 /* Tests macOS */, 277 | ); 278 | }; 279 | /* End PBXProject section */ 280 | 281 | /* Begin PBXResourcesBuildPhase section */ 282 | F6A216F526B3A5A300A428C5 /* Resources */ = { 283 | isa = PBXResourcesBuildPhase; 284 | buildActionMask = 2147483647; 285 | files = ( 286 | F6A2172126B3A5A300A428C5 /* Assets.xcassets in Resources */, 287 | ); 288 | runOnlyForDeploymentPostprocessing = 0; 289 | }; 290 | F6A216FD26B3A5A300A428C5 /* Resources */ = { 291 | isa = PBXResourcesBuildPhase; 292 | buildActionMask = 2147483647; 293 | files = ( 294 | F6A2172226B3A5A300A428C5 /* Assets.xcassets in Resources */, 295 | ); 296 | runOnlyForDeploymentPostprocessing = 0; 297 | }; 298 | F6A2170526B3A5A300A428C5 /* Resources */ = { 299 | isa = PBXResourcesBuildPhase; 300 | buildActionMask = 2147483647; 301 | files = ( 302 | ); 303 | runOnlyForDeploymentPostprocessing = 0; 304 | }; 305 | F6A2171026B3A5A300A428C5 /* Resources */ = { 306 | isa = PBXResourcesBuildPhase; 307 | buildActionMask = 2147483647; 308 | files = ( 309 | ); 310 | runOnlyForDeploymentPostprocessing = 0; 311 | }; 312 | /* End PBXResourcesBuildPhase section */ 313 | 314 | /* Begin PBXSourcesBuildPhase section */ 315 | F6A216F326B3A5A300A428C5 /* Sources */ = { 316 | isa = PBXSourcesBuildPhase; 317 | buildActionMask = 2147483647; 318 | files = ( 319 | F6A2171926B3A5A300A428C5 /* phantom.xcdatamodeld in Sources */, 320 | F6A2171F26B3A5A300A428C5 /* Persistence.swift in Sources */, 321 | F6A2171B26B3A5A300A428C5 /* phantomApp.swift in Sources */, 322 | F6A2171D26B3A5A300A428C5 /* ContentView.swift in Sources */, 323 | ); 324 | runOnlyForDeploymentPostprocessing = 0; 325 | }; 326 | F6A216FB26B3A5A300A428C5 /* Sources */ = { 327 | isa = PBXSourcesBuildPhase; 328 | buildActionMask = 2147483647; 329 | files = ( 330 | F6A2171A26B3A5A300A428C5 /* phantom.xcdatamodeld in Sources */, 331 | F6A2172026B3A5A300A428C5 /* Persistence.swift in Sources */, 332 | F6A2171C26B3A5A300A428C5 /* phantomApp.swift in Sources */, 333 | F6A2171E26B3A5A300A428C5 /* ContentView.swift in Sources */, 334 | ); 335 | runOnlyForDeploymentPostprocessing = 0; 336 | }; 337 | F6A2170326B3A5A300A428C5 /* Sources */ = { 338 | isa = PBXSourcesBuildPhase; 339 | buildActionMask = 2147483647; 340 | files = ( 341 | F6A2170C26B3A5A300A428C5 /* Tests_iOS.swift in Sources */, 342 | ); 343 | runOnlyForDeploymentPostprocessing = 0; 344 | }; 345 | F6A2170E26B3A5A300A428C5 /* Sources */ = { 346 | isa = PBXSourcesBuildPhase; 347 | buildActionMask = 2147483647; 348 | files = ( 349 | F6A2171726B3A5A300A428C5 /* Tests_macOS.swift in Sources */, 350 | ); 351 | runOnlyForDeploymentPostprocessing = 0; 352 | }; 353 | /* End PBXSourcesBuildPhase section */ 354 | 355 | /* Begin PBXTargetDependency section */ 356 | F6A2170926B3A5A300A428C5 /* PBXTargetDependency */ = { 357 | isa = PBXTargetDependency; 358 | target = F6A216F626B3A5A300A428C5 /* phantom (iOS) */; 359 | targetProxy = F6A2170826B3A5A300A428C5 /* PBXContainerItemProxy */; 360 | }; 361 | F6A2171426B3A5A300A428C5 /* PBXTargetDependency */ = { 362 | isa = PBXTargetDependency; 363 | target = F6A216FE26B3A5A300A428C5 /* phantom (macOS) */; 364 | targetProxy = F6A2171326B3A5A300A428C5 /* PBXContainerItemProxy */; 365 | }; 366 | /* End PBXTargetDependency section */ 367 | 368 | /* Begin XCBuildConfiguration section */ 369 | F6A2172326B3A5A300A428C5 /* Debug */ = { 370 | isa = XCBuildConfiguration; 371 | buildSettings = { 372 | ALWAYS_SEARCH_USER_PATHS = NO; 373 | CLANG_ANALYZER_NONNULL = YES; 374 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 375 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 376 | CLANG_CXX_LIBRARY = "libc++"; 377 | CLANG_ENABLE_MODULES = YES; 378 | CLANG_ENABLE_OBJC_ARC = YES; 379 | CLANG_ENABLE_OBJC_WEAK = YES; 380 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 381 | CLANG_WARN_BOOL_CONVERSION = YES; 382 | CLANG_WARN_COMMA = YES; 383 | CLANG_WARN_CONSTANT_CONVERSION = YES; 384 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 385 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 386 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 387 | CLANG_WARN_EMPTY_BODY = YES; 388 | CLANG_WARN_ENUM_CONVERSION = YES; 389 | CLANG_WARN_INFINITE_RECURSION = YES; 390 | CLANG_WARN_INT_CONVERSION = YES; 391 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 392 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 393 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 394 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 395 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 396 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 397 | CLANG_WARN_STRICT_PROTOTYPES = YES; 398 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 399 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 400 | CLANG_WARN_UNREACHABLE_CODE = YES; 401 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 402 | COPY_PHASE_STRIP = NO; 403 | DEBUG_INFORMATION_FORMAT = dwarf; 404 | ENABLE_STRICT_OBJC_MSGSEND = YES; 405 | ENABLE_TESTABILITY = YES; 406 | GCC_C_LANGUAGE_STANDARD = gnu11; 407 | GCC_DYNAMIC_NO_PIC = NO; 408 | GCC_NO_COMMON_BLOCKS = YES; 409 | GCC_OPTIMIZATION_LEVEL = 0; 410 | GCC_PREPROCESSOR_DEFINITIONS = ( 411 | "DEBUG=1", 412 | "$(inherited)", 413 | ); 414 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 415 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 416 | GCC_WARN_UNDECLARED_SELECTOR = YES; 417 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 418 | GCC_WARN_UNUSED_FUNCTION = YES; 419 | GCC_WARN_UNUSED_VARIABLE = YES; 420 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 421 | MTL_FAST_MATH = YES; 422 | ONLY_ACTIVE_ARCH = YES; 423 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 424 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 425 | }; 426 | name = Debug; 427 | }; 428 | F6A2172426B3A5A300A428C5 /* Release */ = { 429 | isa = XCBuildConfiguration; 430 | buildSettings = { 431 | ALWAYS_SEARCH_USER_PATHS = NO; 432 | CLANG_ANALYZER_NONNULL = YES; 433 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 434 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 435 | CLANG_CXX_LIBRARY = "libc++"; 436 | CLANG_ENABLE_MODULES = YES; 437 | CLANG_ENABLE_OBJC_ARC = YES; 438 | CLANG_ENABLE_OBJC_WEAK = YES; 439 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 440 | CLANG_WARN_BOOL_CONVERSION = YES; 441 | CLANG_WARN_COMMA = YES; 442 | CLANG_WARN_CONSTANT_CONVERSION = YES; 443 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 444 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 445 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 446 | CLANG_WARN_EMPTY_BODY = YES; 447 | CLANG_WARN_ENUM_CONVERSION = YES; 448 | CLANG_WARN_INFINITE_RECURSION = YES; 449 | CLANG_WARN_INT_CONVERSION = YES; 450 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 451 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 452 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 453 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 454 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 455 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 456 | CLANG_WARN_STRICT_PROTOTYPES = YES; 457 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 458 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 459 | CLANG_WARN_UNREACHABLE_CODE = YES; 460 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 461 | COPY_PHASE_STRIP = NO; 462 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 463 | ENABLE_NS_ASSERTIONS = NO; 464 | ENABLE_STRICT_OBJC_MSGSEND = YES; 465 | GCC_C_LANGUAGE_STANDARD = gnu11; 466 | GCC_NO_COMMON_BLOCKS = YES; 467 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 468 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 469 | GCC_WARN_UNDECLARED_SELECTOR = YES; 470 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 471 | GCC_WARN_UNUSED_FUNCTION = YES; 472 | GCC_WARN_UNUSED_VARIABLE = YES; 473 | MTL_ENABLE_DEBUG_INFO = NO; 474 | MTL_FAST_MATH = YES; 475 | SWIFT_COMPILATION_MODE = wholemodule; 476 | SWIFT_OPTIMIZATION_LEVEL = "-O"; 477 | }; 478 | name = Release; 479 | }; 480 | F6A2172626B3A5A300A428C5 /* Debug */ = { 481 | isa = XCBuildConfiguration; 482 | buildSettings = { 483 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 484 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; 485 | CODE_SIGN_STYLE = Automatic; 486 | DEVELOPMENT_TEAM = C6L3992RFB; 487 | ENABLE_PREVIEWS = YES; 488 | INFOPLIST_FILE = iOS/Info.plist; 489 | IPHONEOS_DEPLOYMENT_TARGET = 14.0; 490 | LD_RUNPATH_SEARCH_PATHS = ( 491 | "$(inherited)", 492 | "@executable_path/Frameworks", 493 | ); 494 | PRODUCT_BUNDLE_IDENTIFIER = com.twodayslate.phantom; 495 | PRODUCT_NAME = phantom; 496 | SDKROOT = iphoneos; 497 | SWIFT_VERSION = 5.0; 498 | TARGETED_DEVICE_FAMILY = "1,2"; 499 | }; 500 | name = Debug; 501 | }; 502 | F6A2172726B3A5A300A428C5 /* Release */ = { 503 | isa = XCBuildConfiguration; 504 | buildSettings = { 505 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 506 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; 507 | CODE_SIGN_STYLE = Automatic; 508 | DEVELOPMENT_TEAM = C6L3992RFB; 509 | ENABLE_PREVIEWS = YES; 510 | INFOPLIST_FILE = iOS/Info.plist; 511 | IPHONEOS_DEPLOYMENT_TARGET = 14.0; 512 | LD_RUNPATH_SEARCH_PATHS = ( 513 | "$(inherited)", 514 | "@executable_path/Frameworks", 515 | ); 516 | PRODUCT_BUNDLE_IDENTIFIER = com.twodayslate.phantom; 517 | PRODUCT_NAME = phantom; 518 | SDKROOT = iphoneos; 519 | SWIFT_VERSION = 5.0; 520 | TARGETED_DEVICE_FAMILY = "1,2"; 521 | VALIDATE_PRODUCT = YES; 522 | }; 523 | name = Release; 524 | }; 525 | F6A2172926B3A5A300A428C5 /* Debug */ = { 526 | isa = XCBuildConfiguration; 527 | buildSettings = { 528 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 529 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; 530 | CODE_SIGN_ENTITLEMENTS = macOS/macOS.entitlements; 531 | CODE_SIGN_STYLE = Automatic; 532 | COMBINE_HIDPI_IMAGES = YES; 533 | DEVELOPMENT_TEAM = C6L3992RFB; 534 | ENABLE_HARDENED_RUNTIME = YES; 535 | ENABLE_PREVIEWS = YES; 536 | INFOPLIST_FILE = macOS/Info.plist; 537 | LD_RUNPATH_SEARCH_PATHS = ( 538 | "$(inherited)", 539 | "@executable_path/../Frameworks", 540 | ); 541 | MACOSX_DEPLOYMENT_TARGET = 11.0; 542 | PRODUCT_BUNDLE_IDENTIFIER = com.twodayslate.phantom; 543 | PRODUCT_NAME = phantom; 544 | SDKROOT = macosx; 545 | SWIFT_VERSION = 5.0; 546 | }; 547 | name = Debug; 548 | }; 549 | F6A2172A26B3A5A300A428C5 /* Release */ = { 550 | isa = XCBuildConfiguration; 551 | buildSettings = { 552 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 553 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; 554 | CODE_SIGN_ENTITLEMENTS = macOS/macOS.entitlements; 555 | CODE_SIGN_STYLE = Automatic; 556 | COMBINE_HIDPI_IMAGES = YES; 557 | DEVELOPMENT_TEAM = C6L3992RFB; 558 | ENABLE_HARDENED_RUNTIME = YES; 559 | ENABLE_PREVIEWS = YES; 560 | INFOPLIST_FILE = macOS/Info.plist; 561 | LD_RUNPATH_SEARCH_PATHS = ( 562 | "$(inherited)", 563 | "@executable_path/../Frameworks", 564 | ); 565 | MACOSX_DEPLOYMENT_TARGET = 11.0; 566 | PRODUCT_BUNDLE_IDENTIFIER = com.twodayslate.phantom; 567 | PRODUCT_NAME = phantom; 568 | SDKROOT = macosx; 569 | SWIFT_VERSION = 5.0; 570 | }; 571 | name = Release; 572 | }; 573 | F6A2172C26B3A5A300A428C5 /* Debug */ = { 574 | isa = XCBuildConfiguration; 575 | buildSettings = { 576 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 577 | CODE_SIGN_STYLE = Automatic; 578 | DEVELOPMENT_TEAM = C6L3992RFB; 579 | INFOPLIST_FILE = "Tests iOS/Info.plist"; 580 | IPHONEOS_DEPLOYMENT_TARGET = 14.5; 581 | LD_RUNPATH_SEARCH_PATHS = ( 582 | "$(inherited)", 583 | "@executable_path/Frameworks", 584 | "@loader_path/Frameworks", 585 | ); 586 | PRODUCT_BUNDLE_IDENTIFIER = "com.twodayslate.Tests-iOS"; 587 | PRODUCT_NAME = "$(TARGET_NAME)"; 588 | SDKROOT = iphoneos; 589 | SWIFT_VERSION = 5.0; 590 | TARGETED_DEVICE_FAMILY = "1,2"; 591 | TEST_TARGET_NAME = "phantom (iOS)"; 592 | }; 593 | name = Debug; 594 | }; 595 | F6A2172D26B3A5A300A428C5 /* Release */ = { 596 | isa = XCBuildConfiguration; 597 | buildSettings = { 598 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 599 | CODE_SIGN_STYLE = Automatic; 600 | DEVELOPMENT_TEAM = C6L3992RFB; 601 | INFOPLIST_FILE = "Tests iOS/Info.plist"; 602 | IPHONEOS_DEPLOYMENT_TARGET = 14.5; 603 | LD_RUNPATH_SEARCH_PATHS = ( 604 | "$(inherited)", 605 | "@executable_path/Frameworks", 606 | "@loader_path/Frameworks", 607 | ); 608 | PRODUCT_BUNDLE_IDENTIFIER = "com.twodayslate.Tests-iOS"; 609 | PRODUCT_NAME = "$(TARGET_NAME)"; 610 | SDKROOT = iphoneos; 611 | SWIFT_VERSION = 5.0; 612 | TARGETED_DEVICE_FAMILY = "1,2"; 613 | TEST_TARGET_NAME = "phantom (iOS)"; 614 | VALIDATE_PRODUCT = YES; 615 | }; 616 | name = Release; 617 | }; 618 | F6A2172F26B3A5A300A428C5 /* Debug */ = { 619 | isa = XCBuildConfiguration; 620 | buildSettings = { 621 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 622 | CODE_SIGN_STYLE = Automatic; 623 | COMBINE_HIDPI_IMAGES = YES; 624 | DEVELOPMENT_TEAM = C6L3992RFB; 625 | INFOPLIST_FILE = "Tests macOS/Info.plist"; 626 | LD_RUNPATH_SEARCH_PATHS = ( 627 | "$(inherited)", 628 | "@executable_path/../Frameworks", 629 | "@loader_path/../Frameworks", 630 | ); 631 | MACOSX_DEPLOYMENT_TARGET = 11.3; 632 | PRODUCT_BUNDLE_IDENTIFIER = "com.twodayslate.Tests-macOS"; 633 | PRODUCT_NAME = "$(TARGET_NAME)"; 634 | SDKROOT = macosx; 635 | SWIFT_VERSION = 5.0; 636 | TEST_TARGET_NAME = "phantom (macOS)"; 637 | }; 638 | name = Debug; 639 | }; 640 | F6A2173026B3A5A300A428C5 /* Release */ = { 641 | isa = XCBuildConfiguration; 642 | buildSettings = { 643 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 644 | CODE_SIGN_STYLE = Automatic; 645 | COMBINE_HIDPI_IMAGES = YES; 646 | DEVELOPMENT_TEAM = C6L3992RFB; 647 | INFOPLIST_FILE = "Tests macOS/Info.plist"; 648 | LD_RUNPATH_SEARCH_PATHS = ( 649 | "$(inherited)", 650 | "@executable_path/../Frameworks", 651 | "@loader_path/../Frameworks", 652 | ); 653 | MACOSX_DEPLOYMENT_TARGET = 11.3; 654 | PRODUCT_BUNDLE_IDENTIFIER = "com.twodayslate.Tests-macOS"; 655 | PRODUCT_NAME = "$(TARGET_NAME)"; 656 | SDKROOT = macosx; 657 | SWIFT_VERSION = 5.0; 658 | TEST_TARGET_NAME = "phantom (macOS)"; 659 | }; 660 | name = Release; 661 | }; 662 | /* End XCBuildConfiguration section */ 663 | 664 | /* Begin XCConfigurationList section */ 665 | F6A216EB26B3A5A200A428C5 /* Build configuration list for PBXProject "phantom" */ = { 666 | isa = XCConfigurationList; 667 | buildConfigurations = ( 668 | F6A2172326B3A5A300A428C5 /* Debug */, 669 | F6A2172426B3A5A300A428C5 /* Release */, 670 | ); 671 | defaultConfigurationIsVisible = 0; 672 | defaultConfigurationName = Release; 673 | }; 674 | F6A2172526B3A5A300A428C5 /* Build configuration list for PBXNativeTarget "phantom (iOS)" */ = { 675 | isa = XCConfigurationList; 676 | buildConfigurations = ( 677 | F6A2172626B3A5A300A428C5 /* Debug */, 678 | F6A2172726B3A5A300A428C5 /* Release */, 679 | ); 680 | defaultConfigurationIsVisible = 0; 681 | defaultConfigurationName = Release; 682 | }; 683 | F6A2172826B3A5A300A428C5 /* Build configuration list for PBXNativeTarget "phantom (macOS)" */ = { 684 | isa = XCConfigurationList; 685 | buildConfigurations = ( 686 | F6A2172926B3A5A300A428C5 /* Debug */, 687 | F6A2172A26B3A5A300A428C5 /* Release */, 688 | ); 689 | defaultConfigurationIsVisible = 0; 690 | defaultConfigurationName = Release; 691 | }; 692 | F6A2172B26B3A5A300A428C5 /* Build configuration list for PBXNativeTarget "Tests iOS" */ = { 693 | isa = XCConfigurationList; 694 | buildConfigurations = ( 695 | F6A2172C26B3A5A300A428C5 /* Debug */, 696 | F6A2172D26B3A5A300A428C5 /* Release */, 697 | ); 698 | defaultConfigurationIsVisible = 0; 699 | defaultConfigurationName = Release; 700 | }; 701 | F6A2172E26B3A5A300A428C5 /* Build configuration list for PBXNativeTarget "Tests macOS" */ = { 702 | isa = XCConfigurationList; 703 | buildConfigurations = ( 704 | F6A2172F26B3A5A300A428C5 /* Debug */, 705 | F6A2173026B3A5A300A428C5 /* Release */, 706 | ); 707 | defaultConfigurationIsVisible = 0; 708 | defaultConfigurationName = Release; 709 | }; 710 | /* End XCConfigurationList section */ 711 | 712 | /* Begin XCVersionGroup section */ 713 | F6A216ED26B3A5A200A428C5 /* phantom.xcdatamodeld */ = { 714 | isa = XCVersionGroup; 715 | children = ( 716 | F6A216EE26B3A5A200A428C5 /* Shared.xcdatamodel */, 717 | ); 718 | currentVersion = F6A216EE26B3A5A200A428C5 /* Shared.xcdatamodel */; 719 | path = phantom.xcdatamodeld; 720 | sourceTree = ""; 721 | versionGroupType = wrapper.xcdatamodel; 722 | }; 723 | /* End XCVersionGroup section */ 724 | }; 725 | rootObject = F6A216E826B3A5A200A428C5 /* Project object */; 726 | } 727 | --------------------------------------------------------------------------------