Add Project 17 concepts showcase

This commit is contained in:
CypherPoet 2020-01-18 05:18:47 -06:00
parent 8d677b48c5
commit f8cfacae28
24 changed files with 1819 additions and 0 deletions

View File

@ -0,0 +1,443 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 50;
objects = {
/* Begin PBXBuildFile section */
F326142523D16901009EC215 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = F326142423D16901009EC215 /* AppDelegate.swift */; };
F326142723D16901009EC215 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = F326142623D16901009EC215 /* SceneDelegate.swift */; };
F326142B23D16905009EC215 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = F326142A23D16905009EC215 /* Assets.xcassets */; };
F326142E23D16905009EC215 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = F326142D23D16905009EC215 /* Preview Assets.xcassets */; };
F326143E23D16953009EC215 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F326143C23D16953009EC215 /* LaunchScreen.storyboard */; };
F326144023D1699C009EC215 /* RootView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F326143F23D1699C009EC215 /* RootView.swift */; };
F326144423D17682009EC215 /* MagnificationGestureExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = F326144323D17682009EC215 /* MagnificationGestureExample.swift */; };
F326144623D1769B009EC215 /* RotationGestureExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = F326144523D1769B009EC215 /* RotationGestureExample.swift */; };
F326144823D176E7009EC215 /* BasicLongPressGestureExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = F326144723D176E7009EC215 /* BasicLongPressGestureExample.swift */; };
F326144C23D26D1F009EC215 /* NestedGesturesExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = F326144B23D26D1F009EC215 /* NestedGesturesExample.swift */; };
F326144E23D27C06009EC215 /* GestureSequencingExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = F326144D23D27C06009EC215 /* GestureSequencingExample.swift */; };
F326145223D2AAB7009EC215 /* UIKitHapticsExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = F326145123D2AAB7009EC215 /* UIKitHapticsExample.swift */; };
F326145423D2FF4B009EC215 /* CoreHapticsExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = F326145323D2FF4B009EC215 /* CoreHapticsExample.swift */; };
F326145623D31201009EC215 /* CoreHapticsExample+ViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = F326145523D31201009EC215 /* CoreHapticsExample+ViewModel.swift */; };
F326145923D319D7009EC215 /* AllowsHitTestingExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = F326145823D319D7009EC215 /* AllowsHitTestingExample.swift */; };
F326145B23D31E94009EC215 /* ContentShapeExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = F326145A23D31E94009EC215 /* ContentShapeExample.swift */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
F326142123D16901009EC215 /* Project17Concepts.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Project17Concepts.app; sourceTree = BUILT_PRODUCTS_DIR; };
F326142423D16901009EC215 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
F326142623D16901009EC215 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = "<group>"; };
F326142A23D16905009EC215 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
F326142D23D16905009EC215 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = "<group>"; };
F326143223D16905009EC215 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
F326143D23D16953009EC215 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Project17Concepts/Base.lproj/LaunchScreen.storyboard; sourceTree = SOURCE_ROOT; };
F326143F23D1699C009EC215 /* RootView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RootView.swift; sourceTree = "<group>"; };
F326144323D17682009EC215 /* MagnificationGestureExample.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MagnificationGestureExample.swift; sourceTree = "<group>"; };
F326144523D1769B009EC215 /* RotationGestureExample.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RotationGestureExample.swift; sourceTree = "<group>"; };
F326144723D176E7009EC215 /* BasicLongPressGestureExample.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BasicLongPressGestureExample.swift; sourceTree = "<group>"; };
F326144B23D26D1F009EC215 /* NestedGesturesExample.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NestedGesturesExample.swift; sourceTree = "<group>"; };
F326144D23D27C06009EC215 /* GestureSequencingExample.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GestureSequencingExample.swift; sourceTree = "<group>"; };
F326145123D2AAB7009EC215 /* UIKitHapticsExample.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIKitHapticsExample.swift; sourceTree = "<group>"; };
F326145323D2FF4B009EC215 /* CoreHapticsExample.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CoreHapticsExample.swift; sourceTree = "<group>"; };
F326145523D31201009EC215 /* CoreHapticsExample+ViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CoreHapticsExample+ViewModel.swift"; sourceTree = "<group>"; };
F326145823D319D7009EC215 /* AllowsHitTestingExample.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AllowsHitTestingExample.swift; sourceTree = "<group>"; };
F326145A23D31E94009EC215 /* ContentShapeExample.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentShapeExample.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
F326141E23D16901009EC215 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
F326141823D16901009EC215 = {
isa = PBXGroup;
children = (
F326142323D16901009EC215 /* Project17Concepts */,
F326142223D16901009EC215 /* Products */,
);
sourceTree = "<group>";
};
F326142223D16901009EC215 /* Products */ = {
isa = PBXGroup;
children = (
F326142123D16901009EC215 /* Project17Concepts.app */,
);
name = Products;
sourceTree = "<group>";
};
F326142323D16901009EC215 /* Project17Concepts */ = {
isa = PBXGroup;
children = (
F326143223D16905009EC215 /* Info.plist */,
F326143B23D16926009EC215 /* App */,
F326142C23D16905009EC215 /* Preview Content */,
F326143923D16918009EC215 /* Resources */,
F326143A23D1691F009EC215 /* Reusables */,
F326143823D16913009EC215 /* Scenes */,
);
path = Project17Concepts;
sourceTree = "<group>";
};
F326142C23D16905009EC215 /* Preview Content */ = {
isa = PBXGroup;
children = (
F326142D23D16905009EC215 /* Preview Assets.xcassets */,
);
path = "Preview Content";
sourceTree = "<group>";
};
F326143823D16913009EC215 /* Scenes */ = {
isa = PBXGroup;
children = (
F326144F23D2AA98009EC215 /* Gestures */,
F326143F23D1699C009EC215 /* RootView.swift */,
F326145723D319C3009EC215 /* Hit Testing */,
F326145023D2AAAA009EC215 /* Haptics */,
);
path = Scenes;
sourceTree = "<group>";
};
F326143923D16918009EC215 /* Resources */ = {
isa = PBXGroup;
children = (
F326142A23D16905009EC215 /* Assets.xcassets */,
);
path = Resources;
sourceTree = "<group>";
};
F326143A23D1691F009EC215 /* Reusables */ = {
isa = PBXGroup;
children = (
);
path = Reusables;
sourceTree = "<group>";
};
F326143B23D16926009EC215 /* App */ = {
isa = PBXGroup;
children = (
F326143C23D16953009EC215 /* LaunchScreen.storyboard */,
F326142423D16901009EC215 /* AppDelegate.swift */,
F326142623D16901009EC215 /* SceneDelegate.swift */,
);
path = App;
sourceTree = "<group>";
};
F326144F23D2AA98009EC215 /* Gestures */ = {
isa = PBXGroup;
children = (
F326144723D176E7009EC215 /* BasicLongPressGestureExample.swift */,
F326144323D17682009EC215 /* MagnificationGestureExample.swift */,
F326144D23D27C06009EC215 /* GestureSequencingExample.swift */,
F326144B23D26D1F009EC215 /* NestedGesturesExample.swift */,
F326144523D1769B009EC215 /* RotationGestureExample.swift */,
);
path = Gestures;
sourceTree = "<group>";
};
F326145023D2AAAA009EC215 /* Haptics */ = {
isa = PBXGroup;
children = (
F326145123D2AAB7009EC215 /* UIKitHapticsExample.swift */,
F326145323D2FF4B009EC215 /* CoreHapticsExample.swift */,
F326145523D31201009EC215 /* CoreHapticsExample+ViewModel.swift */,
);
path = Haptics;
sourceTree = "<group>";
};
F326145723D319C3009EC215 /* Hit Testing */ = {
isa = PBXGroup;
children = (
F326145823D319D7009EC215 /* AllowsHitTestingExample.swift */,
F326145A23D31E94009EC215 /* ContentShapeExample.swift */,
);
path = "Hit Testing";
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
F326142023D16901009EC215 /* Project17Concepts */ = {
isa = PBXNativeTarget;
buildConfigurationList = F326143523D16905009EC215 /* Build configuration list for PBXNativeTarget "Project17Concepts" */;
buildPhases = (
F326141D23D16901009EC215 /* Sources */,
F326141E23D16901009EC215 /* Frameworks */,
F326141F23D16901009EC215 /* Resources */,
);
buildRules = (
);
dependencies = (
);
name = Project17Concepts;
productName = Project17Concepts;
productReference = F326142123D16901009EC215 /* Project17Concepts.app */;
productType = "com.apple.product-type.application";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
F326141923D16901009EC215 /* Project object */ = {
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 1130;
LastUpgradeCheck = 1130;
ORGANIZATIONNAME = CypherPoet;
TargetAttributes = {
F326142023D16901009EC215 = {
CreatedOnToolsVersion = 11.3.1;
};
};
};
buildConfigurationList = F326141C23D16901009EC215 /* Build configuration list for PBXProject "Project17Concepts" */;
compatibilityVersion = "Xcode 9.3";
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
en,
Base,
);
mainGroup = F326141823D16901009EC215;
productRefGroup = F326142223D16901009EC215 /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
F326142023D16901009EC215 /* Project17Concepts */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
F326141F23D16901009EC215 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
F326143E23D16953009EC215 /* LaunchScreen.storyboard in Resources */,
F326142E23D16905009EC215 /* Preview Assets.xcassets in Resources */,
F326142B23D16905009EC215 /* Assets.xcassets in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
F326141D23D16901009EC215 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
F326145623D31201009EC215 /* CoreHapticsExample+ViewModel.swift in Sources */,
F326145B23D31E94009EC215 /* ContentShapeExample.swift in Sources */,
F326145923D319D7009EC215 /* AllowsHitTestingExample.swift in Sources */,
F326145423D2FF4B009EC215 /* CoreHapticsExample.swift in Sources */,
F326142523D16901009EC215 /* AppDelegate.swift in Sources */,
F326144823D176E7009EC215 /* BasicLongPressGestureExample.swift in Sources */,
F326145223D2AAB7009EC215 /* UIKitHapticsExample.swift in Sources */,
F326142723D16901009EC215 /* SceneDelegate.swift in Sources */,
F326144623D1769B009EC215 /* RotationGestureExample.swift in Sources */,
F326144C23D26D1F009EC215 /* NestedGesturesExample.swift in Sources */,
F326144423D17682009EC215 /* MagnificationGestureExample.swift in Sources */,
F326144E23D27C06009EC215 /* GestureSequencingExample.swift in Sources */,
F326144023D1699C009EC215 /* RootView.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXVariantGroup section */
F326143C23D16953009EC215 /* LaunchScreen.storyboard */ = {
isa = PBXVariantGroup;
children = (
F326143D23D16953009EC215 /* Base */,
);
name = LaunchScreen.storyboard;
sourceTree = "<group>";
};
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
F326143323D16905009EC215 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 13.2;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
};
name = Debug;
};
F326143423D16905009EC215 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 13.2;
MTL_ENABLE_DEBUG_INFO = NO;
MTL_FAST_MATH = YES;
SDKROOT = iphoneos;
SWIFT_COMPILATION_MODE = wholemodule;
SWIFT_OPTIMIZATION_LEVEL = "-O";
VALIDATE_PRODUCT = YES;
};
name = Release;
};
F326143623D16905009EC215 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_ASSET_PATHS = "\"Project17Concepts/Preview Content\"";
DEVELOPMENT_TEAM = QRXXH2RKAG;
ENABLE_PREVIEWS = YES;
INFOPLIST_FILE = Project17Concepts/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = io.github.cypherpoet.Project17Concepts;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
};
F326143723D16905009EC215 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_ASSET_PATHS = "\"Project17Concepts/Preview Content\"";
DEVELOPMENT_TEAM = QRXXH2RKAG;
ENABLE_PREVIEWS = YES;
INFOPLIST_FILE = Project17Concepts/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = io.github.cypherpoet.Project17Concepts;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
F326141C23D16901009EC215 /* Build configuration list for PBXProject "Project17Concepts" */ = {
isa = XCConfigurationList;
buildConfigurations = (
F326143323D16905009EC215 /* Debug */,
F326143423D16905009EC215 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
F326143523D16905009EC215 /* Build configuration list for PBXNativeTarget "Project17Concepts" */ = {
isa = XCConfigurationList;
buildConfigurations = (
F326143623D16905009EC215 /* Debug */,
F326143723D16905009EC215 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = F326141923D16901009EC215 /* Project object */;
}

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:Project17Concepts.xcodeproj">
</FileRef>
</Workspace>

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>

View File

@ -0,0 +1,37 @@
//
// AppDelegate.swift
// Project17Concepts
//
// Created by Brian Sipple on 1/16/20.
// Copyright © 2020 CypherPoet. All rights reserved.
//
import UIKit
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
return true
}
// MARK: UISceneSession Lifecycle
func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
// Called when a new scene session is being created.
// Use this method to select a configuration to create the new scene with.
return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
}
func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) {
// Called when the user discards a scene session.
// If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
// Use this method to release any resources that were specific to the discarded scenes, as they will not return.
}
}

View File

@ -0,0 +1,67 @@
//
// SceneDelegate.swift
// Project17Concepts
//
// Created by Brian Sipple on 1/16/20.
// Copyright © 2020 CypherPoet. All rights reserved.
//
import UIKit
import SwiftUI
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
// Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
// If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
// This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
// Use a UIHostingController as window root view controller.
if let windowScene = scene as? UIWindowScene {
let window = UIWindow(windowScene: windowScene)
// Create the SwiftUI view that provides the window contents.
let entryView = RootView()
window.rootViewController = UIHostingController(rootView: entryView)
self.window = window
window.makeKeyAndVisible()
}
}
func sceneDidDisconnect(_ scene: UIScene) {
// Called as the scene is being released by the system.
// This occurs shortly after the scene enters the background, or when its session is discarded.
// Release any resources associated with this scene that can be re-created the next time the scene connects.
// The scene may re-connect later, as its session was not neccessarily discarded (see `application:didDiscardSceneSessions` instead).
}
func sceneDidBecomeActive(_ scene: UIScene) {
// Called when the scene has moved from an inactive state to an active state.
// Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive.
}
func sceneWillResignActive(_ scene: UIScene) {
// Called when the scene will move from an active state to an inactive state.
// This may occur due to temporary interruptions (ex. an incoming phone call).
}
func sceneWillEnterForeground(_ scene: UIScene) {
// Called as the scene transitions from the background to the foreground.
// Use this method to undo the changes made on entering the background.
}
func sceneDidEnterBackground(_ scene: UIScene) {
// Called as the scene transitions from the foreground to the background.
// Use this method to save data, release shared resources, and store enough scene-specific state information
// to restore the scene back to its current state.
}
}

View File

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="13122.16" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13104.12"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--View Controller-->
<scene sceneID="EHf-IW-A2E">
<objects>
<viewController id="01J-lp-oVM" sceneMemberID="viewController">
<view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" xcode11CocoaTouchSystemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
<viewLayoutGuide key="safeArea" id="6Tk-OE-BBY"/>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="53" y="375"/>
</scene>
</scenes>
</document>

View File

@ -0,0 +1,60 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>UIApplicationSceneManifest</key>
<dict>
<key>UIApplicationSupportsMultipleScenes</key>
<false/>
<key>UISceneConfigurations</key>
<dict>
<key>UIWindowSceneSessionRoleApplication</key>
<array>
<dict>
<key>UISceneConfigurationName</key>
<string>Default Configuration</string>
<key>UISceneDelegateClassName</key>
<string>$(PRODUCT_MODULE_NAME).SceneDelegate</string>
</dict>
</array>
</dict>
</dict>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIRequiredDeviceCapabilities</key>
<array>
<string>armv7</string>
</array>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
</dict>
</plist>

View File

@ -0,0 +1,6 @@
{
"info" : {
"version" : 1,
"author" : "xcode"
}
}

View File

@ -0,0 +1,98 @@
{
"images" : [
{
"idiom" : "iphone",
"size" : "20x20",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "20x20",
"scale" : "3x"
},
{
"idiom" : "iphone",
"size" : "29x29",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "29x29",
"scale" : "3x"
},
{
"idiom" : "iphone",
"size" : "40x40",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "40x40",
"scale" : "3x"
},
{
"idiom" : "iphone",
"size" : "60x60",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "60x60",
"scale" : "3x"
},
{
"idiom" : "ipad",
"size" : "20x20",
"scale" : "1x"
},
{
"idiom" : "ipad",
"size" : "20x20",
"scale" : "2x"
},
{
"idiom" : "ipad",
"size" : "29x29",
"scale" : "1x"
},
{
"idiom" : "ipad",
"size" : "29x29",
"scale" : "2x"
},
{
"idiom" : "ipad",
"size" : "40x40",
"scale" : "1x"
},
{
"idiom" : "ipad",
"size" : "40x40",
"scale" : "2x"
},
{
"idiom" : "ipad",
"size" : "76x76",
"scale" : "1x"
},
{
"idiom" : "ipad",
"size" : "76x76",
"scale" : "2x"
},
{
"idiom" : "ipad",
"size" : "83.5x83.5",
"scale" : "2x"
},
{
"idiom" : "ios-marketing",
"size" : "1024x1024",
"scale" : "1x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

View File

@ -0,0 +1,6 @@
{
"info" : {
"version" : 1,
"author" : "xcode"
}
}

View File

@ -0,0 +1,21 @@
{
"images" : [
{
"idiom" : "universal",
"filename" : "paris.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 MiB

View File

@ -0,0 +1,53 @@
//
// BasicLongPressGestureExample.swift
// Project17Concepts
//
// Created by CypherPoet on 1/16/20.
//
//
import SwiftUI
struct BasicLongPressGestureExample {
}
// MARK: - View
extension BasicLongPressGestureExample: View {
var body: some View {
// 🔑
// 1) As soon as you press down the change closure will
// be called with its parameter set to true.
//
// 2) If you release before the gesture has been recognized
// (so, if you release after 1 second when using a 2-second recognizer),
// the change closure will be called with its parameter set to false.
//
// 3) If you hold down for the full length of the recognizer, then the change
// closure will be called with its parameter set to false (because the
// gesture is no longer in flight),
// and your completion closure will be called too.
Text("Long Press Gestures")
.onLongPressGesture(
minimumDuration: 3,
maximumDistance: .infinity,
pressing: { (isPressing) in
print("Is Pressing: \(isPressing)")
},
perform: {
print("Performing long press action")
}
)
}
}
// MARK: - Preview
struct GesturesExample_Previews: PreviewProvider {
static var previews: some View {
BasicLongPressGestureExample()
}
}

View File

@ -0,0 +1,115 @@
//
// GestureSequencingExample.swift
// Project17Concepts
//
// Created by CypherPoet on 1/17/20.
//
//
import SwiftUI
struct GestureSequencingExample {
@GestureState private var dragSequenceState: DragSequenceState = .inactive
}
// MARK: - View
extension GestureSequencingExample: View {
var body: some View {
VStack(spacing: 42) {
Text("Drag the Circle (After Long Pressing First!)")
.font(.headline)
Circle()
.fill(Color.orange)
.frame(width: 100, height: 100)
.scaleEffect(dragSequenceState.currentScale)
.offset(dragSequenceState.currentOffset)
.gesture(longPressDragGesture)
.animation(Animation.easeOut(duration: 0.2))
}
}
}
// MARK: - Computeds
extension GestureSequencingExample {
}
// MARK: - View Variables
extension GestureSequencingExample {
var longPressDragGesture: some Gesture {
SequenceGesture(circleLongPress, circleDrag)
.updating($dragSequenceState) { value, state, transation in
switch value {
case .first(_):
// User is pressing on the screen
state = .longPressing
case .second(_, let dragValue):
// User is still pressing after long press happened
state = .dragging(translation: dragValue?.translation ?? CGSize.zero)
}
}
}
var circleLongPress: LongPressGesture {
LongPressGesture(minimumDuration: 1)
}
var circleDrag: DragGesture {
DragGesture()
}
}
// MARK: - Private Helpers
private extension GestureSequencingExample {
}
extension GestureSequencingExample {
enum DragSequenceState {
case inactive
case longPressing
case dragging(translation: CGSize)
var currentScale: CGFloat {
switch self {
case .inactive:
return 1.0
case .longPressing:
return 0.8
case .dragging(_) :
return 1.2
}
}
var currentOffset: CGSize {
switch self {
case .inactive,
.longPressing:
return .zero
case .dragging(let offset):
return offset
}
}
}
}
// MARK: - Preview
struct GestureSequencingExample_Previews: PreviewProvider {
static var previews: some View {
GestureSequencingExample()
}
}

View File

@ -0,0 +1,74 @@
//
// MagnificationGestureExample.swift
// Project17Concepts
//
// Created by CypherPoet on 1/16/20.
//
//
import SwiftUI
struct MagnificationGestureExample {
@GestureState private var magnificationState: CGFloat = 1.0
}
// MARK: - View
extension MagnificationGestureExample: View {
var body: some View {
VStack {
Spacer()
Image("paris")
.resizable()
.scaledToFit()
.scaleEffect(magnificationState)
.gesture(magnificationGesture)
Text("Magnify Me")
.font(.headline)
Spacer()
}
.navigationBarTitle("Magnification")
}
}
// MARK: - Computeds
extension MagnificationGestureExample {
}
// MARK: - View Variables
extension MagnificationGestureExample {
var magnificationGesture: some Gesture {
MagnificationGesture()
.updating($magnificationState) { (magnificationValue, state, transaction) in
state = magnificationValue
}
.onChanged { value in
print("onChanged || Value: \(value)")
}
.onEnded { value in
print("onEnded || Value: \(value)")
}
}
}
// MARK: - Preview
struct MagnificationGestureExample_Previews: PreviewProvider {
static var previews: some View {
NavigationView {
MagnificationGestureExample()
}
}
}

View File

@ -0,0 +1,112 @@
//
// NestedGesturesExample.swift
// Project17Concepts
//
// Created by CypherPoet on 1/17/20.
//
//
import SwiftUI
struct NestedGesturesExample {
@State private var rectangleColor = Color.orange
}
// MARK: - View
extension NestedGesturesExample: View {
var body: some View {
VStack {
VStack {
ZStack {
Rectangle()
.fill(rectangleColor)
.frame(width: 180, height: 40)
Text("Inner")
.onTapGesture {
self.toggleRectangleColor()
}
}
VStack {
Text("Outer")
}
}
Spacer()
VStack {
ZStack {
Rectangle()
.fill(rectangleColor)
.frame(width: 180, height: 40)
Text("Inner")
.onTapGesture {
self.rectangleColor = .purple
}
}
VStack {
Text("High-Priority Outer")
.highPriorityGesture(
TapGesture()
.onEnded { self.toggleRectangleColor() }
)
}
}
Spacer()
VStack {
Text("Simultaneous Gesture")
.onTapGesture { self.toggleRectangleColor() }
}
.background(
Rectangle()
.fill(rectangleColor)
.frame(width: 180, height: 40)
)
.simultaneousGesture(
TapGesture()
.onEnded {
print("Simultaneous Tap!")
}
)
}
.padding(.vertical, 100)
}
}
// MARK: - Computeds
extension NestedGesturesExample {
}
// MARK: - View Variables
extension NestedGesturesExample {
}
// MARK: - Private Helpers
private extension NestedGesturesExample {
func toggleRectangleColor() {
rectangleColor = rectangleColor == .orange ? .purple : .orange
}
}
// MARK: - Preview
struct NestedGesturesExample_Previews: PreviewProvider {
static var previews: some View {
NestedGesturesExample()
}
}

View File

@ -0,0 +1,76 @@
//
// RotationGestureExample.swift
// Project17Concepts
//
// Created by CypherPoet on 1/16/20.
//
//
import SwiftUI
struct RotationGestureExample {
// @GestureState private var rotationState: CGFloat = 1.0
@State private var rotationAngle: Angle = .zero
}
// MARK: - View
extension RotationGestureExample: View {
var body: some View {
VStack {
Spacer()
Image("paris")
.resizable()
.scaledToFit()
.rotationEffect(rotationAngle)
.gesture(rotationGesture)
Text("Rotate Me")
.font(.headline)
Spacer()
}
.navigationBarTitle("Rotation")
}
}
// MARK: - Computeds
extension RotationGestureExample {
}
// MARK: - View Variables
extension RotationGestureExample {
var rotationGesture: some Gesture {
RotationGesture()
// .updating($rotationState) { (rotationValue, state, transaction) in
// state = rotationValue
// }
.onChanged { value in
self.rotationAngle = value
print("onChanged || Value: \(value)")
}
.onEnded { value in
print("onEnded || Value: \(value)")
}
}
}
// MARK: - Preview
struct RotationGestureExample_Previews: PreviewProvider {
static var previews: some View {
NavigationView {
RotationGestureExample()
}
}
}

View File

@ -0,0 +1,59 @@
//
// CoreHapticsExample+ViewModel.swift
// Project17Concepts
//
// Created by CypherPoet on 1/18/20.
//
//
import Foundation
import CoreHaptics
extension CoreHapticsExample {
final class ViewModel: ObservableObject {
private let hapticsState: HapticsState
private var hapticsEngine: CHHapticEngine!
init(hapticsState: HapticsState = .init()) {
self.hapticsState = hapticsState
}
}
}
extension CoreHapticsExample.ViewModel {
var supportsHaptics: Bool { hapticsState.supportsHaptics }
var hapticsPlayer: CHHapticPatternPlayer? {
do {
let pattern = try CHHapticPattern(events: HapticEventList.standardSuccess, parameters: [])
return try hapticsEngine.makePlayer(with: pattern)
} catch {
// TODO: Better error handling here?
return nil
}
}
}
extension CoreHapticsExample.ViewModel {
func onAppear() {
guard supportsHaptics else {
print("No haptics support")
return
}
do {
self.hapticsEngine = try CHHapticEngine()
try self.hapticsEngine.start()
} catch {
print("Error while making haptics engine: \(error.localizedDescription)")
}
}
}

View File

@ -0,0 +1,90 @@
//
// CoreHapticsExample.swift
// Project17Concepts
//
// Created by CypherPoet on 1/18/20.
//
//
import SwiftUI
import CoreHaptics
enum HapticEventList {
static let standardSuccess = [
CHHapticEvent(
eventType: .hapticTransient,
parameters: [
CHHapticEventParameter(parameterID: .hapticIntensity, value: 1),
CHHapticEventParameter(parameterID: .hapticSharpness, value: 1),
],
relativeTime: 0
)
]
}
struct HapticsState {
var supportsHaptics: Bool
init() {
self.supportsHaptics = CHHapticEngine.capabilitiesForHardware().supportsHaptics
}
}
struct CoreHapticsExample {
@ObservedObject var viewModel = ViewModel(hapticsState: .init())
}
// MARK: - View
extension CoreHapticsExample: View {
var body: some View {
VStack(spacing: 42) {
Text("Haptics Support: \(viewModel.supportsHaptics ? "Enabled" : "Disabled")")
Button(action: {
try? self.viewModel.hapticsPlayer?.start(atTime: CHHapticTimeImmediate)
}) {
Text("Success")
.foregroundColor(.primary)
.padding()
.frame(width: 188)
}
.background(Color.green)
.cornerRadius(8)
.shadow(radius: 4)
.disabled(!viewModel.supportsHaptics)
}
.onAppear(perform: viewModel.onAppear)
}
}
// MARK: - Computeds
extension CoreHapticsExample {
}
// MARK: - View Variables
extension CoreHapticsExample {
}
// MARK: - Private Helpers
private extension CoreHapticsExample {
}
// MARK: - Preview
struct CoreHapticsExample_Previews: PreviewProvider {
static var previews: some View {
CoreHapticsExample()
}
}

View File

@ -0,0 +1,89 @@
//
// UIKitHapticsExample.swift
// Project17Concepts
//
// Created by CypherPoet on 1/17/20.
//
//
import SwiftUI
struct UIKitHapticsExample {
let notificationFeedbackGenerator = UINotificationFeedbackGenerator()
}
// MARK: - View
extension UIKitHapticsExample: View {
var body: some View {
VStack(spacing: 22) {
Button(action: {
self.notificationFeedbackGenerator.notificationOccurred(.success)
}) {
Text("Success")
.foregroundColor(.primary)
.padding()
.frame(width: 188)
}
.background(Color.green)
.cornerRadius(8)
.shadow(radius: 4)
Button(action: {
self.notificationFeedbackGenerator.notificationOccurred(.warning)
}) {
Text("Warning")
.foregroundColor(.primary)
.padding()
.frame(width: 188)
}
.background(Color.yellow)
.cornerRadius(8)
.shadow(radius: 4)
Button(action: {
self.notificationFeedbackGenerator.notificationOccurred(.error)
}) {
Text("Error")
.foregroundColor(.primary)
.padding()
.frame(width: 188)
}
.background(Color.red)
.cornerRadius(8)
.shadow(radius: 4)
}.onAppear {
self.notificationFeedbackGenerator.prepare()
}
}
}
// MARK: - Computeds
extension UIKitHapticsExample {
}
// MARK: - View Variables
extension UIKitHapticsExample {
}
// MARK: - Private Helpers
private extension UIKitHapticsExample {
}
// MARK: - Preview
struct UIKitHapticsExample_Previews: PreviewProvider {
static var previews: some View {
UIKitHapticsExample()
}
}

View File

@ -0,0 +1,111 @@
//
// AllowsHitTestingExample.swift
// Project17Concepts
//
// Created by CypherPoet on 1/18/20.
//
//
import SwiftUI
struct AllowsHitTestingExample {
@State var tappedShapeState: TappedShapeState = .none
}
// MARK: - View
extension AllowsHitTestingExample: View {
var body: some View {
VStack(spacing: 40) {
Spacer()
Text("Tapped Shape: \(tappedShapeState.displayText)")
.font(.title)
VStack(spacing: 10) {
Text("Circle With Hit Testing")
.font(.headline)
ZStack {
Rectangle()
.fill(Color.purple)
.onTapGesture { self.tappedShapeState = .rectangle }
Circle()
.fill(Color.orange)
.onTapGesture { self.tappedShapeState = .circle }
.padding()
}
.frame(width: 200, height: 200)
}
VStack(spacing: 10) {
Text("Circle Without Hit Testing")
.font(.headline)
ZStack {
Rectangle()
.fill(Color.purple)
.onTapGesture { self.tappedShapeState = .rectangle }
Circle()
.fill(Color.orange)
.onTapGesture { self.tappedShapeState = .circle }
.padding()
.allowsHitTesting(false)
}
.frame(width: 200, height: 200)
}
Spacer()
}
}
}
// MARK: - Computeds
extension AllowsHitTestingExample {
}
// MARK: - View Variables
extension AllowsHitTestingExample {
}
// MARK: - Private Helpers
private extension AllowsHitTestingExample {
}
extension AllowsHitTestingExample {
enum TappedShapeState {
case none
case circle
case rectangle
var displayText: String {
switch self {
case .none:
return "Nothing Yet"
case .circle:
return "Circle"
case .rectangle:
return "Rectangle"
}
}
}
}
// MARK: - Preview
struct AllowsHitTestingExample_Previews: PreviewProvider {
static var previews: some View {
AllowsHitTestingExample()
}
}

View File

@ -0,0 +1,118 @@
//
// ContentShapeExample.swift
// Project17Concepts
//
// Created by CypherPoet on 1/18/20.
//
//
import SwiftUI
struct ContentShapeExample {
@State var tappedViewState: TappedViewState = .none
}
// MARK: - View
extension ContentShapeExample: View {
var body: some View {
VStack(spacing: 40) {
Spacer()
Text("Tapped View: \(tappedViewState.displayText)")
.font(.title)
VStack(spacing: 10) {
Text("Circle With Rectangle Content Shape")
.font(.headline)
ZStack {
Rectangle()
.fill(Color.purple)
.onTapGesture { self.tappedViewState = .rectangle }
Circle()
.fill(Color.orange)
.onTapGesture { self.tappedViewState = .circle }
.padding()
.contentShape(Rectangle())
}
.frame(width: 200, height: 200)
}
VStack(spacing: 10) {
Text("VStack with Spacer")
.font(.headline)
VStack {
Rectangle()
.fill(Color.pink)
.frame(width: 200, height: 100)
Spacer()
.frame(width: 200, height: 100)
Rectangle()
.fill(Color.pink)
.frame(width: 200, height: 100)
}
.border(Color.black, width: 4)
.contentShape(Rectangle()) // 🔑 Uncomment to have the Spacer's area be hit tested
.onTapGesture { self.tappedViewState = .vStack }
}
Spacer()
}
}
}
// MARK: - Computeds
extension ContentShapeExample {
}
// MARK: - View Variables
extension ContentShapeExample {
}
// MARK: - Private Helpers
private extension ContentShapeExample {
}
extension ContentShapeExample {
enum TappedViewState {
case none
case circle
case rectangle
case vStack
var displayText: String {
switch self {
case .none:
return "Nothing Yet"
case .circle:
return "Circle"
case .rectangle:
return "Rectangle"
case .vStack:
return "VStack"
}
}
}
}
// MARK: - Preview
struct ContentShapeExample_Previews: PreviewProvider {
static var previews: some View {
ContentShapeExample()
}
}

View File

@ -0,0 +1,102 @@
//
// RootView.swift
// Project17Concepts
//
// Created by CypherPoet on 1/16/20.
//
//
import SwiftUI
struct RootView {
}
// MARK: - View
extension RootView: View {
var body: some View {
NavigationView {
List {
Section(header: Text("Gestures")) {
NavigationLink(
"Basic Long Press Gestures",
destination: BasicLongPressGestureExample()
)
NavigationLink(
"Magnification Gesture",
destination: MagnificationGestureExample()
)
NavigationLink(
"Rotation Gesture",
destination: RotationGestureExample()
)
NavigationLink(
"Nested Gestures",
destination: NestedGesturesExample()
)
NavigationLink(
"Gesture Sequencing",
destination: GestureSequencingExample()
)
}
Section(header: Text("Core Haptics")) {
NavigationLink(
"UIKit Haptics",
destination: UIKitHapticsExample()
)
NavigationLink(
"Core Haptics",
destination: CoreHapticsExample()
)
}
Section(header: Text("Hit Testing")) {
NavigationLink(
"Allowing Hit Testing",
destination: AllowsHitTestingExample()
)
NavigationLink(
"Specifying Content Shape",
destination: ContentShapeExample()
)
}
}
.navigationBarTitle("Project 17 Concepts")
.listStyle(GroupedListStyle())
}
}
}
// MARK: - Computeds
extension RootView {
}
// MARK: - View Variables
extension RootView {
}
// MARK: - Preview
struct RootView_Previews: PreviewProvider {
static var previews: some View {
RootView()
}
}

42
day-086/README.md Normal file
View File

@ -0,0 +1,42 @@
# Day 86: _Project 17: Flashzilla_ (Part One)
_Follow along at https://www.hackingwithswift.com/100/swiftui/86_.
<br/>
# 📒 Field Notes
This day covers Part One of _`Project 17`_ in the [100 Days of SwiftUI Challenge](https://www.hackingwithswift.com/100/swiftui/86).
It focuses on several specific topics:
- Flashzilla: Introduction
- How to use gestures in SwiftUI
- Making vibrations with UINotificationFeedbackGenerator and Core Haptics
- Disabling user interactivity with allowsHitTesting()
## Flashzilla: Introduction
From the project description:
> In this project were going to build an app that helps users learn things using flashcards cards with one thing written on the front, such as “to buy”, and another thing written on the other side, such as “comprar”.
## How to use gestures in SwiftUI
My intuition for when to use `@GestureState` vs `@State` when updating the UI via gestures remains a bit tenuous -- but I'm definitely seeing how the former can be useful: `@GestureState` is way of telling SwiftUI that this value can _only_ be mutated during a gesture's `updating` callback. `@State` is much more liberal.
## Making vibrations with UINotificationFeedbackGenerator and Core Haptics
## Disabling user interactivity with allowsHitTesting()