diff --git a/0135-swiftui-animation-pt1/Animations/Animations.xcodeproj/project.pbxproj b/0135-swiftui-animation-pt1/Animations/Animations.xcodeproj/project.pbxproj new file mode 100644 index 00000000..45e3deef --- /dev/null +++ b/0135-swiftui-animation-pt1/Animations/Animations.xcodeproj/project.pbxproj @@ -0,0 +1,579 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 50; + objects = { + +/* Begin PBXBuildFile section */ + 2A89E3BF25D2F8BE00A1EF57 /* AnimationsApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A89E3BE25D2F8BE00A1EF57 /* AnimationsApp.swift */; }; + 2A89E3C125D2F8BE00A1EF57 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A89E3C025D2F8BE00A1EF57 /* ContentView.swift */; }; + 2A89E3C325D2F8BE00A1EF57 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 2A89E3C225D2F8BE00A1EF57 /* Assets.xcassets */; }; + 2A89E3C625D2F8BE00A1EF57 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 2A89E3C525D2F8BE00A1EF57 /* Preview Assets.xcassets */; }; + 2A89E3D125D2F8BE00A1EF57 /* AnimationsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A89E3D025D2F8BE00A1EF57 /* AnimationsTests.swift */; }; + 2A89E3DC25D2F8BF00A1EF57 /* AnimationsUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A89E3DB25D2F8BF00A1EF57 /* AnimationsUITests.swift */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 2A89E3CD25D2F8BE00A1EF57 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 2A89E3B325D2F8BE00A1EF57 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 2A89E3BA25D2F8BE00A1EF57; + remoteInfo = Animations; + }; + 2A89E3D825D2F8BF00A1EF57 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 2A89E3B325D2F8BE00A1EF57 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 2A89E3BA25D2F8BE00A1EF57; + remoteInfo = Animations; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + 2A89E3BB25D2F8BE00A1EF57 /* Animations.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Animations.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 2A89E3BE25D2F8BE00A1EF57 /* AnimationsApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnimationsApp.swift; sourceTree = ""; }; + 2A89E3C025D2F8BE00A1EF57 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; }; + 2A89E3C225D2F8BE00A1EF57 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 2A89E3C525D2F8BE00A1EF57 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; + 2A89E3C725D2F8BE00A1EF57 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 2A89E3CC25D2F8BE00A1EF57 /* AnimationsTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = AnimationsTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 2A89E3D025D2F8BE00A1EF57 /* AnimationsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnimationsTests.swift; sourceTree = ""; }; + 2A89E3D225D2F8BE00A1EF57 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 2A89E3D725D2F8BF00A1EF57 /* AnimationsUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = AnimationsUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 2A89E3DB25D2F8BF00A1EF57 /* AnimationsUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnimationsUITests.swift; sourceTree = ""; }; + 2A89E3DD25D2F8BF00A1EF57 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 2A89E3B825D2F8BE00A1EF57 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 2A89E3C925D2F8BE00A1EF57 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 2A89E3D425D2F8BF00A1EF57 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 2A89E3B225D2F8BE00A1EF57 = { + isa = PBXGroup; + children = ( + 2A89E3BD25D2F8BE00A1EF57 /* Animations */, + 2A89E3CF25D2F8BE00A1EF57 /* AnimationsTests */, + 2A89E3DA25D2F8BF00A1EF57 /* AnimationsUITests */, + 2A89E3BC25D2F8BE00A1EF57 /* Products */, + ); + sourceTree = ""; + }; + 2A89E3BC25D2F8BE00A1EF57 /* Products */ = { + isa = PBXGroup; + children = ( + 2A89E3BB25D2F8BE00A1EF57 /* Animations.app */, + 2A89E3CC25D2F8BE00A1EF57 /* AnimationsTests.xctest */, + 2A89E3D725D2F8BF00A1EF57 /* AnimationsUITests.xctest */, + ); + name = Products; + sourceTree = ""; + }; + 2A89E3BD25D2F8BE00A1EF57 /* Animations */ = { + isa = PBXGroup; + children = ( + 2A89E3BE25D2F8BE00A1EF57 /* AnimationsApp.swift */, + 2A89E3C025D2F8BE00A1EF57 /* ContentView.swift */, + 2A89E3C225D2F8BE00A1EF57 /* Assets.xcassets */, + 2A89E3C725D2F8BE00A1EF57 /* Info.plist */, + 2A89E3C425D2F8BE00A1EF57 /* Preview Content */, + ); + path = Animations; + sourceTree = ""; + }; + 2A89E3C425D2F8BE00A1EF57 /* Preview Content */ = { + isa = PBXGroup; + children = ( + 2A89E3C525D2F8BE00A1EF57 /* Preview Assets.xcassets */, + ); + path = "Preview Content"; + sourceTree = ""; + }; + 2A89E3CF25D2F8BE00A1EF57 /* AnimationsTests */ = { + isa = PBXGroup; + children = ( + 2A89E3D025D2F8BE00A1EF57 /* AnimationsTests.swift */, + 2A89E3D225D2F8BE00A1EF57 /* Info.plist */, + ); + path = AnimationsTests; + sourceTree = ""; + }; + 2A89E3DA25D2F8BF00A1EF57 /* AnimationsUITests */ = { + isa = PBXGroup; + children = ( + 2A89E3DB25D2F8BF00A1EF57 /* AnimationsUITests.swift */, + 2A89E3DD25D2F8BF00A1EF57 /* Info.plist */, + ); + path = AnimationsUITests; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 2A89E3BA25D2F8BE00A1EF57 /* Animations */ = { + isa = PBXNativeTarget; + buildConfigurationList = 2A89E3E025D2F8BF00A1EF57 /* Build configuration list for PBXNativeTarget "Animations" */; + buildPhases = ( + 2A89E3B725D2F8BE00A1EF57 /* Sources */, + 2A89E3B825D2F8BE00A1EF57 /* Frameworks */, + 2A89E3B925D2F8BE00A1EF57 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Animations; + productName = Animations; + productReference = 2A89E3BB25D2F8BE00A1EF57 /* Animations.app */; + productType = "com.apple.product-type.application"; + }; + 2A89E3CB25D2F8BE00A1EF57 /* AnimationsTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 2A89E3E325D2F8BF00A1EF57 /* Build configuration list for PBXNativeTarget "AnimationsTests" */; + buildPhases = ( + 2A89E3C825D2F8BE00A1EF57 /* Sources */, + 2A89E3C925D2F8BE00A1EF57 /* Frameworks */, + 2A89E3CA25D2F8BE00A1EF57 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 2A89E3CE25D2F8BE00A1EF57 /* PBXTargetDependency */, + ); + name = AnimationsTests; + productName = AnimationsTests; + productReference = 2A89E3CC25D2F8BE00A1EF57 /* AnimationsTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; + 2A89E3D625D2F8BF00A1EF57 /* AnimationsUITests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 2A89E3E625D2F8BF00A1EF57 /* Build configuration list for PBXNativeTarget "AnimationsUITests" */; + buildPhases = ( + 2A89E3D325D2F8BF00A1EF57 /* Sources */, + 2A89E3D425D2F8BF00A1EF57 /* Frameworks */, + 2A89E3D525D2F8BF00A1EF57 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 2A89E3D925D2F8BF00A1EF57 /* PBXTargetDependency */, + ); + name = AnimationsUITests; + productName = AnimationsUITests; + productReference = 2A89E3D725D2F8BF00A1EF57 /* AnimationsUITests.xctest */; + productType = "com.apple.product-type.bundle.ui-testing"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 2A89E3B325D2F8BE00A1EF57 /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 1240; + LastUpgradeCheck = 1240; + TargetAttributes = { + 2A89E3BA25D2F8BE00A1EF57 = { + CreatedOnToolsVersion = 12.4; + }; + 2A89E3CB25D2F8BE00A1EF57 = { + CreatedOnToolsVersion = 12.4; + TestTargetID = 2A89E3BA25D2F8BE00A1EF57; + }; + 2A89E3D625D2F8BF00A1EF57 = { + CreatedOnToolsVersion = 12.4; + TestTargetID = 2A89E3BA25D2F8BE00A1EF57; + }; + }; + }; + buildConfigurationList = 2A89E3B625D2F8BE00A1EF57 /* Build configuration list for PBXProject "Animations" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 2A89E3B225D2F8BE00A1EF57; + productRefGroup = 2A89E3BC25D2F8BE00A1EF57 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 2A89E3BA25D2F8BE00A1EF57 /* Animations */, + 2A89E3CB25D2F8BE00A1EF57 /* AnimationsTests */, + 2A89E3D625D2F8BF00A1EF57 /* AnimationsUITests */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 2A89E3B925D2F8BE00A1EF57 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 2A89E3C625D2F8BE00A1EF57 /* Preview Assets.xcassets in Resources */, + 2A89E3C325D2F8BE00A1EF57 /* Assets.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 2A89E3CA25D2F8BE00A1EF57 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 2A89E3D525D2F8BF00A1EF57 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 2A89E3B725D2F8BE00A1EF57 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 2A89E3C125D2F8BE00A1EF57 /* ContentView.swift in Sources */, + 2A89E3BF25D2F8BE00A1EF57 /* AnimationsApp.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 2A89E3C825D2F8BE00A1EF57 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 2A89E3D125D2F8BE00A1EF57 /* AnimationsTests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 2A89E3D325D2F8BF00A1EF57 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 2A89E3DC25D2F8BF00A1EF57 /* AnimationsUITests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 2A89E3CE25D2F8BE00A1EF57 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 2A89E3BA25D2F8BE00A1EF57 /* Animations */; + targetProxy = 2A89E3CD25D2F8BE00A1EF57 /* PBXContainerItemProxy */; + }; + 2A89E3D925D2F8BF00A1EF57 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 2A89E3BA25D2F8BE00A1EF57 /* Animations */; + targetProxy = 2A89E3D825D2F8BF00A1EF57 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin XCBuildConfiguration section */ + 2A89E3DE25D2F8BF00A1EF57 /* 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_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + 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 = 14.4; + 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; + }; + 2A89E3DF25D2F8BF00A1EF57 /* 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_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + 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 = 14.4; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 2A89E3E125D2F8BF00A1EF57 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_ASSET_PATHS = "\"Animations/Preview Content\""; + ENABLE_PREVIEWS = YES; + INFOPLIST_FILE = Animations/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 14.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = co.pointfree.Animations; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 2A89E3E225D2F8BF00A1EF57 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_ASSET_PATHS = "\"Animations/Preview Content\""; + ENABLE_PREVIEWS = YES; + INFOPLIST_FILE = Animations/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 14.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = co.pointfree.Animations; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; + 2A89E3E425D2F8BF00A1EF57 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + INFOPLIST_FILE = AnimationsTests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 14.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = co.pointfree.AnimationsTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Animations.app/Animations"; + }; + name = Debug; + }; + 2A89E3E525D2F8BF00A1EF57 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + INFOPLIST_FILE = AnimationsTests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 14.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = co.pointfree.AnimationsTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Animations.app/Animations"; + }; + name = Release; + }; + 2A89E3E725D2F8BF00A1EF57 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + CODE_SIGN_STYLE = Automatic; + INFOPLIST_FILE = AnimationsUITests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = co.pointfree.AnimationsUITests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = Animations; + }; + name = Debug; + }; + 2A89E3E825D2F8BF00A1EF57 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + CODE_SIGN_STYLE = Automatic; + INFOPLIST_FILE = AnimationsUITests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = co.pointfree.AnimationsUITests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = Animations; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 2A89E3B625D2F8BE00A1EF57 /* Build configuration list for PBXProject "Animations" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 2A89E3DE25D2F8BF00A1EF57 /* Debug */, + 2A89E3DF25D2F8BF00A1EF57 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 2A89E3E025D2F8BF00A1EF57 /* Build configuration list for PBXNativeTarget "Animations" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 2A89E3E125D2F8BF00A1EF57 /* Debug */, + 2A89E3E225D2F8BF00A1EF57 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 2A89E3E325D2F8BF00A1EF57 /* Build configuration list for PBXNativeTarget "AnimationsTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 2A89E3E425D2F8BF00A1EF57 /* Debug */, + 2A89E3E525D2F8BF00A1EF57 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 2A89E3E625D2F8BF00A1EF57 /* Build configuration list for PBXNativeTarget "AnimationsUITests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 2A89E3E725D2F8BF00A1EF57 /* Debug */, + 2A89E3E825D2F8BF00A1EF57 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 2A89E3B325D2F8BE00A1EF57 /* Project object */; +} diff --git a/0135-swiftui-animation-pt1/Animations/Animations.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/0135-swiftui-animation-pt1/Animations/Animations.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000..919434a6 --- /dev/null +++ b/0135-swiftui-animation-pt1/Animations/Animations.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/0135-swiftui-animation-pt1/Animations/Animations.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/0135-swiftui-animation-pt1/Animations/Animations.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 00000000..18d98100 --- /dev/null +++ b/0135-swiftui-animation-pt1/Animations/Animations.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/0135-swiftui-animation-pt1/Animations/Animations/AnimationsApp.swift b/0135-swiftui-animation-pt1/Animations/Animations/AnimationsApp.swift new file mode 100644 index 00000000..5f576c9b --- /dev/null +++ b/0135-swiftui-animation-pt1/Animations/Animations/AnimationsApp.swift @@ -0,0 +1,17 @@ +// +// AnimationsApp.swift +// Animations +// +// Created by Point-Free on 2/9/21. +// + +import SwiftUI + +@main +struct AnimationsApp: App { + var body: some Scene { + WindowGroup { + ContentView() + } + } +} diff --git a/0135-swiftui-animation-pt1/Animations/Animations/Assets.xcassets/AccentColor.colorset/Contents.json b/0135-swiftui-animation-pt1/Animations/Animations/Assets.xcassets/AccentColor.colorset/Contents.json new file mode 100644 index 00000000..eb878970 --- /dev/null +++ b/0135-swiftui-animation-pt1/Animations/Animations/Assets.xcassets/AccentColor.colorset/Contents.json @@ -0,0 +1,11 @@ +{ + "colors" : [ + { + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/0135-swiftui-animation-pt1/Animations/Animations/Assets.xcassets/AppIcon.appiconset/Contents.json b/0135-swiftui-animation-pt1/Animations/Animations/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 00000000..9221b9bb --- /dev/null +++ b/0135-swiftui-animation-pt1/Animations/Animations/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,98 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "scale" : "2x", + "size" : "20x20" + }, + { + "idiom" : "iphone", + "scale" : "3x", + "size" : "20x20" + }, + { + "idiom" : "iphone", + "scale" : "2x", + "size" : "29x29" + }, + { + "idiom" : "iphone", + "scale" : "3x", + "size" : "29x29" + }, + { + "idiom" : "iphone", + "scale" : "2x", + "size" : "40x40" + }, + { + "idiom" : "iphone", + "scale" : "3x", + "size" : "40x40" + }, + { + "idiom" : "iphone", + "scale" : "2x", + "size" : "60x60" + }, + { + "idiom" : "iphone", + "scale" : "3x", + "size" : "60x60" + }, + { + "idiom" : "ipad", + "scale" : "1x", + "size" : "20x20" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "size" : "20x20" + }, + { + "idiom" : "ipad", + "scale" : "1x", + "size" : "29x29" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "size" : "29x29" + }, + { + "idiom" : "ipad", + "scale" : "1x", + "size" : "40x40" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "size" : "40x40" + }, + { + "idiom" : "ipad", + "scale" : "1x", + "size" : "76x76" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "size" : "76x76" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "size" : "83.5x83.5" + }, + { + "idiom" : "ios-marketing", + "scale" : "1x", + "size" : "1024x1024" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/0135-swiftui-animation-pt1/Animations/Animations/Assets.xcassets/Contents.json b/0135-swiftui-animation-pt1/Animations/Animations/Assets.xcassets/Contents.json new file mode 100644 index 00000000..73c00596 --- /dev/null +++ b/0135-swiftui-animation-pt1/Animations/Animations/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/0135-swiftui-animation-pt1/Animations/Animations/ContentView.swift b/0135-swiftui-animation-pt1/Animations/Animations/ContentView.swift new file mode 100644 index 00000000..e25c4054 --- /dev/null +++ b/0135-swiftui-animation-pt1/Animations/Animations/ContentView.swift @@ -0,0 +1,97 @@ +import SwiftUI + +struct ContentView: View { + @State var circleCenter = CGPoint.zero + @State var circleColor = Color.black + @State var isCircleScaled = false + @State var isResetting = false + + var body: some View { + VStack { + Circle() + .fill(self.circleColor) +// .animation(.linear) + .overlay(Text("Hi")) + .frame(width: 50, height: 50) + .scaleEffect(self.isCircleScaled ? 2 : 1) +// .animation(nil, value: self.isCircleScaled) +// .animation(.disabled) + .offset(x: self.circleCenter.x - 25, y: self.circleCenter.y - 25) +// .animation(self.isResetting ? nil : .spring(response: 0.3, dampingFraction: 0.1)) + .gesture( + DragGesture(minimumDistance: 0).onChanged { value in + withAnimation(.spring(response: 0.3, dampingFraction: 0.1)) { + self.circleCenter = value.location + } + } + ) + .foregroundColor(self.isCircleScaled ? .red : nil) +// if self.isCircleScaled { +// circle.foregroundColor(.red) +// } else { +// circle +// } + + Toggle( + "Scale", + isOn: self.$isCircleScaled.animation(.spring(response: 0.3, dampingFraction: 0.1)) + +// Binding( +// get: { self.isCircleScaled }, +// set: { isOn in +// withAnimation(.spring(response: 0.3, dampingFraction: 0.1)) { +// self.isCircleScaled = isOn +// } +// } +// ) + + ) + + Button("Cycle colors") { + [Color.red, .blue, .green, .purple, .black] + .enumerated() + .forEach { offset, color in + DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(offset)) { + withAnimation(.linear) { + self.circleColor = color + } + + // withAnimation: (() -> R) -> R + // Async = ((A) -> Void) -> Void + // ((A) -> R) -> R + } + } +// DispatchQueue.main.asyncAfter(deadline: .now() + 1) { +// self.circleColor = .blue +// } +// DispatchQueue.main.asyncAfter(deadline: .now() + 2) { +// self.circleColor = .green +// } +// DispatchQueue.main.asyncAfter(deadline: .now() + 3) { +// self.circleColor = .purple +// } +// DispatchQueue.main.asyncAfter(deadline: .now() + 4) { +// self.circleColor = .black +// } + } + + Button("Reset") { +// self.isResetting = true + withAnimation { + self.circleCenter = .zero + self.circleColor = .black + } + self.isCircleScaled = false +// DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(1)) { +// self.isResetting = false +// } + } + } + } +} + +struct ContentView_Previews: PreviewProvider { + static var previews: some View { + ContentView() + } +} diff --git a/0135-swiftui-animation-pt1/Animations/Animations/Info.plist b/0135-swiftui-animation-pt1/Animations/Animations/Info.plist new file mode 100644 index 00000000..efc211a0 --- /dev/null +++ b/0135-swiftui-animation-pt1/Animations/Animations/Info.plist @@ -0,0 +1,50 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + $(PRODUCT_BUNDLE_PACKAGE_TYPE) + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UIApplicationSceneManifest + + UIApplicationSupportsMultipleScenes + + + UIApplicationSupportsIndirectInputEvents + + UILaunchScreen + + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/0135-swiftui-animation-pt1/Animations/Animations/Preview Content/Preview Assets.xcassets/Contents.json b/0135-swiftui-animation-pt1/Animations/Animations/Preview Content/Preview Assets.xcassets/Contents.json new file mode 100644 index 00000000..73c00596 --- /dev/null +++ b/0135-swiftui-animation-pt1/Animations/Animations/Preview Content/Preview Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/0135-swiftui-animation-pt1/Animations/AnimationsTests/AnimationsTests.swift b/0135-swiftui-animation-pt1/Animations/AnimationsTests/AnimationsTests.swift new file mode 100644 index 00000000..60c4557e --- /dev/null +++ b/0135-swiftui-animation-pt1/Animations/AnimationsTests/AnimationsTests.swift @@ -0,0 +1,33 @@ +// +// AnimationsTests.swift +// AnimationsTests +// +// Created by Point-Free on 2/9/21. +// + +import XCTest +@testable import Animations + +class AnimationsTests: XCTestCase { + + override func setUpWithError() throws { + // Put setup code here. This method is called before the invocation of each test method in the class. + } + + override func tearDownWithError() throws { + // Put teardown code here. This method is called after the invocation of each test method in the class. + } + + func testExample() throws { + // This is an example of a functional test case. + // Use XCTAssert and related functions to verify your tests produce the correct results. + } + + func testPerformanceExample() throws { + // This is an example of a performance test case. + self.measure { + // Put the code you want to measure the time of here. + } + } + +} diff --git a/0135-swiftui-animation-pt1/Animations/AnimationsTests/Info.plist b/0135-swiftui-animation-pt1/Animations/AnimationsTests/Info.plist new file mode 100644 index 00000000..64d65ca4 --- /dev/null +++ b/0135-swiftui-animation-pt1/Animations/AnimationsTests/Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + $(PRODUCT_BUNDLE_PACKAGE_TYPE) + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + + diff --git a/0135-swiftui-animation-pt1/Animations/AnimationsUITests/AnimationsUITests.swift b/0135-swiftui-animation-pt1/Animations/AnimationsUITests/AnimationsUITests.swift new file mode 100644 index 00000000..d8144177 --- /dev/null +++ b/0135-swiftui-animation-pt1/Animations/AnimationsUITests/AnimationsUITests.swift @@ -0,0 +1,42 @@ +// +// AnimationsUITests.swift +// AnimationsUITests +// +// Created by Point-Free on 2/9/21. +// + +import XCTest + +class AnimationsUITests: XCTestCase { + + override func setUpWithError() throws { + // Put setup code here. This method is called before the invocation of each test method in the class. + + // In UI tests it is usually best to stop immediately when a failure occurs. + continueAfterFailure = false + + // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this. + } + + override func tearDownWithError() throws { + // Put teardown code here. This method is called after the invocation of each test method in the class. + } + + func testExample() throws { + // UI tests must launch the application that they test. + let app = XCUIApplication() + app.launch() + + // Use recording to get started writing UI tests. + // Use XCTAssert and related functions to verify your tests produce the correct results. + } + + func testLaunchPerformance() throws { + if #available(macOS 10.15, iOS 13.0, tvOS 13.0, *) { + // This measures how long it takes to launch your application. + measure(metrics: [XCTApplicationLaunchMetric()]) { + XCUIApplication().launch() + } + } + } +} diff --git a/0135-swiftui-animation-pt1/Animations/AnimationsUITests/Info.plist b/0135-swiftui-animation-pt1/Animations/AnimationsUITests/Info.plist new file mode 100644 index 00000000..64d65ca4 --- /dev/null +++ b/0135-swiftui-animation-pt1/Animations/AnimationsUITests/Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + $(PRODUCT_BUNDLE_PACKAGE_TYPE) + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + + diff --git a/0135-swiftui-animation-pt1/README.md b/0135-swiftui-animation-pt1/README.md new file mode 100644 index 00000000..83b0209f --- /dev/null +++ b/0135-swiftui-animation-pt1/README.md @@ -0,0 +1,5 @@ +## [Point-Free](https://www.pointfree.co) + +> #### This directory contains code from Point-Free Episode: [SwiftUI Animation: The Basics](https://www.pointfree.co/episodes/ep135-swiftui-animation-the-basics) +> +> One of the most impressive features of SwiftUI is its animation system. Let's explore the various flavors of animation, such as implicit versus explicit and synchronous versus asynchronous, to help prepare us for how animation works with the Composable Architecture. diff --git a/README.md b/README.md index 6ec679dc..e3166797 100644 --- a/README.md +++ b/README.md @@ -133,3 +133,7 @@ This repository is the home of code written on episodes of [Point-Free](https:// 1. [Parsing Performance: Protocols](0129-parsing-performance-pt3) 1. [Parsing Performance: The Point](0130-parsing-performance-pt4) 1. [Concise Forms: SwiftUI](0131-concise-forms-pt1) +1. [Concise Forms: Composable Architecture](0132-concise-forms-pt2) +1. [Concise Forms: Bye Bye Boilerplate](0133-concise-forms-pt3) +1. [Concise Forms: The Point](0134-concise-forms-pt4) +1. [SwiftUI Animation: The Basics](0135-swiftui-animation-pt1)