From c2e86d431d976f54c9954034eb5871e6f8e1fec3 Mon Sep 17 00:00:00 2001 From: Anand Verma Date: Tue, 11 Aug 2020 11:42:24 +0530 Subject: [PATCH] Project Setup --- AVStackController.xcodeproj/project.pbxproj | 495 ++++++++++++++++++ .../contents.xcworkspacedata | 7 + .../xcshareddata/IDEWorkspaceChecks.plist | 8 + .../UserInterfaceState.xcuserstate | Bin 0 -> 15977 bytes .../xcschemes/xcschememanagement.plist | 14 + AVStackController/AVStackController.h | 19 + AVStackController/Info.plist | 22 + .../Sources/BottomPopupDismissAnimator.swift | 33 ++ ...tomPopupDismissInteractionController.swift | 68 +++ .../Sources/BottomPopupPresentAnimator.swift | 34 ++ .../BottomPopupPresentationController.swift | 74 +++ .../BottomPopupTransitionHandler.swift | 58 ++ .../Sources/BottomPopupUtils.swift | 52 ++ .../Sources/BottomPopupViewController.swift | 96 ++++ .../AVStackControllerTests.swift | 34 ++ AVStackControllerTests/Info.plist | 22 + 16 files changed, 1036 insertions(+) create mode 100644 AVStackController.xcodeproj/project.pbxproj create mode 100644 AVStackController.xcodeproj/project.xcworkspace/contents.xcworkspacedata create mode 100644 AVStackController.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist create mode 100644 AVStackController.xcodeproj/project.xcworkspace/xcuserdata/anandverma.xcuserdatad/UserInterfaceState.xcuserstate create mode 100644 AVStackController.xcodeproj/xcuserdata/anandverma.xcuserdatad/xcschemes/xcschememanagement.plist create mode 100644 AVStackController/AVStackController.h create mode 100644 AVStackController/Info.plist create mode 100755 AVStackController/Sources/BottomPopupDismissAnimator.swift create mode 100755 AVStackController/Sources/BottomPopupDismissInteractionController.swift create mode 100755 AVStackController/Sources/BottomPopupPresentAnimator.swift create mode 100755 AVStackController/Sources/BottomPopupPresentationController.swift create mode 100755 AVStackController/Sources/BottomPopupTransitionHandler.swift create mode 100755 AVStackController/Sources/BottomPopupUtils.swift create mode 100755 AVStackController/Sources/BottomPopupViewController.swift create mode 100644 AVStackControllerTests/AVStackControllerTests.swift create mode 100644 AVStackControllerTests/Info.plist diff --git a/AVStackController.xcodeproj/project.pbxproj b/AVStackController.xcodeproj/project.pbxproj new file mode 100644 index 0000000..26c0843 --- /dev/null +++ b/AVStackController.xcodeproj/project.pbxproj @@ -0,0 +1,495 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 50; + objects = { + +/* Begin PBXBuildFile section */ + B85D1F0C24E26C53003F8385 /* AVStackController.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B85D1F0224E26C53003F8385 /* AVStackController.framework */; }; + B85D1F1124E26C53003F8385 /* AVStackControllerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B85D1F1024E26C53003F8385 /* AVStackControllerTests.swift */; }; + B85D1F1324E26C53003F8385 /* AVStackController.h in Headers */ = {isa = PBXBuildFile; fileRef = B85D1F0524E26C53003F8385 /* AVStackController.h */; settings = {ATTRIBUTES = (Public, ); }; }; + B85D1F2424E26CAA003F8385 /* BottomPopupPresentationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B85D1F1D24E26CAA003F8385 /* BottomPopupPresentationController.swift */; }; + B85D1F2524E26CAA003F8385 /* BottomPopupDismissAnimator.swift in Sources */ = {isa = PBXBuildFile; fileRef = B85D1F1E24E26CAA003F8385 /* BottomPopupDismissAnimator.swift */; }; + B85D1F2624E26CAA003F8385 /* BottomPopupPresentAnimator.swift in Sources */ = {isa = PBXBuildFile; fileRef = B85D1F1F24E26CAA003F8385 /* BottomPopupPresentAnimator.swift */; }; + B85D1F2724E26CAA003F8385 /* BottomPopupDismissInteractionController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B85D1F2024E26CAA003F8385 /* BottomPopupDismissInteractionController.swift */; }; + B85D1F2824E26CAA003F8385 /* BottomPopupTransitionHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = B85D1F2124E26CAA003F8385 /* BottomPopupTransitionHandler.swift */; }; + B85D1F2924E26CAA003F8385 /* BottomPopupViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B85D1F2224E26CAA003F8385 /* BottomPopupViewController.swift */; }; + B85D1F2A24E26CAA003F8385 /* BottomPopupUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = B85D1F2324E26CAA003F8385 /* BottomPopupUtils.swift */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + B85D1F0D24E26C53003F8385 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = B85D1EF924E26C53003F8385 /* Project object */; + proxyType = 1; + remoteGlobalIDString = B85D1F0124E26C53003F8385; + remoteInfo = AVStackController; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + B85D1F0224E26C53003F8385 /* AVStackController.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = AVStackController.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + B85D1F0524E26C53003F8385 /* AVStackController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AVStackController.h; sourceTree = ""; }; + B85D1F0624E26C53003F8385 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + B85D1F0B24E26C53003F8385 /* AVStackControllerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = AVStackControllerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + B85D1F1024E26C53003F8385 /* AVStackControllerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AVStackControllerTests.swift; sourceTree = ""; }; + B85D1F1224E26C53003F8385 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + B85D1F1D24E26CAA003F8385 /* BottomPopupPresentationController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BottomPopupPresentationController.swift; sourceTree = ""; }; + B85D1F1E24E26CAA003F8385 /* BottomPopupDismissAnimator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BottomPopupDismissAnimator.swift; sourceTree = ""; }; + B85D1F1F24E26CAA003F8385 /* BottomPopupPresentAnimator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BottomPopupPresentAnimator.swift; sourceTree = ""; }; + B85D1F2024E26CAA003F8385 /* BottomPopupDismissInteractionController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BottomPopupDismissInteractionController.swift; sourceTree = ""; }; + B85D1F2124E26CAA003F8385 /* BottomPopupTransitionHandler.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BottomPopupTransitionHandler.swift; sourceTree = ""; }; + B85D1F2224E26CAA003F8385 /* BottomPopupViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BottomPopupViewController.swift; sourceTree = ""; }; + B85D1F2324E26CAA003F8385 /* BottomPopupUtils.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BottomPopupUtils.swift; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + B85D1EFF24E26C53003F8385 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + B85D1F0824E26C53003F8385 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + B85D1F0C24E26C53003F8385 /* AVStackController.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + B85D1EF824E26C53003F8385 = { + isa = PBXGroup; + children = ( + B85D1F0424E26C53003F8385 /* AVStackController */, + B85D1F0F24E26C53003F8385 /* AVStackControllerTests */, + B85D1F0324E26C53003F8385 /* Products */, + ); + sourceTree = ""; + }; + B85D1F0324E26C53003F8385 /* Products */ = { + isa = PBXGroup; + children = ( + B85D1F0224E26C53003F8385 /* AVStackController.framework */, + B85D1F0B24E26C53003F8385 /* AVStackControllerTests.xctest */, + ); + name = Products; + sourceTree = ""; + }; + B85D1F0424E26C53003F8385 /* AVStackController */ = { + isa = PBXGroup; + children = ( + B85D1F1C24E26C75003F8385 /* Sources */, + B85D1F0524E26C53003F8385 /* AVStackController.h */, + B85D1F0624E26C53003F8385 /* Info.plist */, + ); + path = AVStackController; + sourceTree = ""; + }; + B85D1F0F24E26C53003F8385 /* AVStackControllerTests */ = { + isa = PBXGroup; + children = ( + B85D1F1024E26C53003F8385 /* AVStackControllerTests.swift */, + B85D1F1224E26C53003F8385 /* Info.plist */, + ); + path = AVStackControllerTests; + sourceTree = ""; + }; + B85D1F1C24E26C75003F8385 /* Sources */ = { + isa = PBXGroup; + children = ( + B85D1F1E24E26CAA003F8385 /* BottomPopupDismissAnimator.swift */, + B85D1F2024E26CAA003F8385 /* BottomPopupDismissInteractionController.swift */, + B85D1F1F24E26CAA003F8385 /* BottomPopupPresentAnimator.swift */, + B85D1F1D24E26CAA003F8385 /* BottomPopupPresentationController.swift */, + B85D1F2124E26CAA003F8385 /* BottomPopupTransitionHandler.swift */, + B85D1F2324E26CAA003F8385 /* BottomPopupUtils.swift */, + B85D1F2224E26CAA003F8385 /* BottomPopupViewController.swift */, + ); + path = Sources; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + B85D1EFD24E26C53003F8385 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + B85D1F1324E26C53003F8385 /* AVStackController.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + B85D1F0124E26C53003F8385 /* AVStackController */ = { + isa = PBXNativeTarget; + buildConfigurationList = B85D1F1624E26C53003F8385 /* Build configuration list for PBXNativeTarget "AVStackController" */; + buildPhases = ( + B85D1EFD24E26C53003F8385 /* Headers */, + B85D1EFE24E26C53003F8385 /* Sources */, + B85D1EFF24E26C53003F8385 /* Frameworks */, + B85D1F0024E26C53003F8385 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = AVStackController; + productName = AVStackController; + productReference = B85D1F0224E26C53003F8385 /* AVStackController.framework */; + productType = "com.apple.product-type.framework"; + }; + B85D1F0A24E26C53003F8385 /* AVStackControllerTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = B85D1F1924E26C53003F8385 /* Build configuration list for PBXNativeTarget "AVStackControllerTests" */; + buildPhases = ( + B85D1F0724E26C53003F8385 /* Sources */, + B85D1F0824E26C53003F8385 /* Frameworks */, + B85D1F0924E26C53003F8385 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + B85D1F0E24E26C53003F8385 /* PBXTargetDependency */, + ); + name = AVStackControllerTests; + productName = AVStackControllerTests; + productReference = B85D1F0B24E26C53003F8385 /* AVStackControllerTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + B85D1EF924E26C53003F8385 /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 1100; + LastUpgradeCheck = 1100; + ORGANIZATIONNAME = AVSwiftHub; + TargetAttributes = { + B85D1F0124E26C53003F8385 = { + CreatedOnToolsVersion = 11.0; + LastSwiftMigration = 1100; + }; + B85D1F0A24E26C53003F8385 = { + CreatedOnToolsVersion = 11.0; + }; + }; + }; + buildConfigurationList = B85D1EFC24E26C53003F8385 /* Build configuration list for PBXProject "AVStackController" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = B85D1EF824E26C53003F8385; + productRefGroup = B85D1F0324E26C53003F8385 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + B85D1F0124E26C53003F8385 /* AVStackController */, + B85D1F0A24E26C53003F8385 /* AVStackControllerTests */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + B85D1F0024E26C53003F8385 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + B85D1F0924E26C53003F8385 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + B85D1EFE24E26C53003F8385 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + B85D1F2524E26CAA003F8385 /* BottomPopupDismissAnimator.swift in Sources */, + B85D1F2724E26CAA003F8385 /* BottomPopupDismissInteractionController.swift in Sources */, + B85D1F2924E26CAA003F8385 /* BottomPopupViewController.swift in Sources */, + B85D1F2624E26CAA003F8385 /* BottomPopupPresentAnimator.swift in Sources */, + B85D1F2424E26CAA003F8385 /* BottomPopupPresentationController.swift in Sources */, + B85D1F2824E26CAA003F8385 /* BottomPopupTransitionHandler.swift in Sources */, + B85D1F2A24E26CAA003F8385 /* BottomPopupUtils.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + B85D1F0724E26C53003F8385 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + B85D1F1124E26C53003F8385 /* AVStackControllerTests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + B85D1F0E24E26C53003F8385 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = B85D1F0124E26C53003F8385 /* AVStackController */; + targetProxy = B85D1F0D24E26C53003F8385 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin XCBuildConfiguration section */ + B85D1F1424E26C53003F8385 /* 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; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + B85D1F1524E26C53003F8385 /* 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; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + B85D1F1724E26C53003F8385 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_STYLE = Automatic; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = AVStackController/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.AVStackController.AVStackController; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + SKIP_INSTALL = YES; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + B85D1F1824E26C53003F8385 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_STYLE = Automatic; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = AVStackController/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.AVStackController.AVStackController; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + SKIP_INSTALL = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; + B85D1F1A24E26C53003F8385 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + CODE_SIGN_STYLE = Automatic; + INFOPLIST_FILE = AVStackControllerTests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.AVStackController.AVStackControllerTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + B85D1F1B24E26C53003F8385 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + CODE_SIGN_STYLE = Automatic; + INFOPLIST_FILE = AVStackControllerTests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.AVStackController.AVStackControllerTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + B85D1EFC24E26C53003F8385 /* Build configuration list for PBXProject "AVStackController" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + B85D1F1424E26C53003F8385 /* Debug */, + B85D1F1524E26C53003F8385 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + B85D1F1624E26C53003F8385 /* Build configuration list for PBXNativeTarget "AVStackController" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + B85D1F1724E26C53003F8385 /* Debug */, + B85D1F1824E26C53003F8385 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + B85D1F1924E26C53003F8385 /* Build configuration list for PBXNativeTarget "AVStackControllerTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + B85D1F1A24E26C53003F8385 /* Debug */, + B85D1F1B24E26C53003F8385 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = B85D1EF924E26C53003F8385 /* Project object */; +} diff --git a/AVStackController.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/AVStackController.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..5e87bc2 --- /dev/null +++ b/AVStackController.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/AVStackController.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/AVStackController.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/AVStackController.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/AVStackController.xcodeproj/project.xcworkspace/xcuserdata/anandverma.xcuserdatad/UserInterfaceState.xcuserstate b/AVStackController.xcodeproj/project.xcworkspace/xcuserdata/anandverma.xcuserdatad/UserInterfaceState.xcuserstate new file mode 100644 index 0000000000000000000000000000000000000000..83e9165551866c3c9ea83bebf5c774d7f93becec GIT binary patch literal 15977 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 literal 0 HcmV?d00001 diff --git a/AVStackController.xcodeproj/xcuserdata/anandverma.xcuserdatad/xcschemes/xcschememanagement.plist b/AVStackController.xcodeproj/xcuserdata/anandverma.xcuserdatad/xcschemes/xcschememanagement.plist new file mode 100644 index 0000000..d507e54 --- /dev/null +++ b/AVStackController.xcodeproj/xcuserdata/anandverma.xcuserdatad/xcschemes/xcschememanagement.plist @@ -0,0 +1,14 @@ + + + + + SchemeUserState + + AVStackController.xcscheme_^#shared#^_ + + orderHint + 0 + + + + diff --git a/AVStackController/AVStackController.h b/AVStackController/AVStackController.h new file mode 100644 index 0000000..8b4791f --- /dev/null +++ b/AVStackController/AVStackController.h @@ -0,0 +1,19 @@ +// +// AVStackController.h +// AVStackController +// +// Created by Anand Verma on 11/08/20. +// Copyright © 2020 AVSwiftHub. All rights reserved. +// + +#import + +//! Project version number for AVStackController. +FOUNDATION_EXPORT double AVStackControllerVersionNumber; + +//! Project version string for AVStackController. +FOUNDATION_EXPORT const unsigned char AVStackControllerVersionString[]; + +// In this header, you should import all the public headers of your framework using statements like #import + + diff --git a/AVStackController/Info.plist b/AVStackController/Info.plist new file mode 100644 index 0000000..9bcb244 --- /dev/null +++ b/AVStackController/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 + $(CURRENT_PROJECT_VERSION) + + diff --git a/AVStackController/Sources/BottomPopupDismissAnimator.swift b/AVStackController/Sources/BottomPopupDismissAnimator.swift new file mode 100755 index 0000000..d5f5c96 --- /dev/null +++ b/AVStackController/Sources/BottomPopupDismissAnimator.swift @@ -0,0 +1,33 @@ +// +// DraggableDismissAnimator.swift +// CREDAssignment +// +// Created by Anand Verma on 10/08/20. +// Copyright © 2020 CRED. All rights reserved. +// + + +import UIKit + +final class BottomPopupDismissAnimator: NSObject, UIViewControllerAnimatedTransitioning { + private unowned var attributesOwner: BottomPresentableViewController + + init(attributesOwner: BottomPresentableViewController) { + self.attributesOwner = attributesOwner + } + + func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval { + return attributesOwner.popupDismissDuration + } + + func animateTransition(using transitionContext: UIViewControllerContextTransitioning) { + let fromVC = transitionContext.viewController(forKey: .from)! + let dismissFrame = CGRect(origin: CGPoint(x: 0, y: UIScreen.main.bounds.size.height), size: fromVC.view.frame.size) + + UIView.animate(withDuration: transitionDuration(using: transitionContext), animations: { + fromVC.view.frame = dismissFrame + }) { (_) in + transitionContext.completeTransition(!transitionContext.transitionWasCancelled) + } + } +} diff --git a/AVStackController/Sources/BottomPopupDismissInteractionController.swift b/AVStackController/Sources/BottomPopupDismissInteractionController.swift new file mode 100755 index 0000000..6de1a00 --- /dev/null +++ b/AVStackController/Sources/BottomPopupDismissInteractionController.swift @@ -0,0 +1,68 @@ +// +// DraggableDismissInteractionController.swift +// CREDAssignment +// +// Created by Anand Verma on 10/08/20. +// Copyright © 2020 CRED. All rights reserved. +// + +import UIKit + +protocol BottomPopupDismissInteractionControllerDelegate: class { + func dismissInteractionPercentChanged(from oldValue: CGFloat, to newValue: CGFloat) +} + +final class BottomPopupDismissInteractionController: UIPercentDrivenInteractiveTransition { + private let kMinPercentOfVisiblePartToCompleteAnimation = CGFloat(0.5) + private let kSwipeDownThreshold = CGFloat(1000) + private weak var presentedViewController: BottomPresentableViewController? + private weak var transitioningDelegate: BottomPopupTransitionHandler? + private unowned var attributesDelegate: BottomPopupAttributesDelegate + weak var delegate: BottomPopupDismissInteractionControllerDelegate? + + private var currentPercent: CGFloat = 0 { + didSet { + delegate?.dismissInteractionPercentChanged(from: oldValue, to: currentPercent) + } + } + + init(presentedViewController: BottomPresentableViewController?, attributesDelegate: BottomPopupAttributesDelegate) { + self.presentedViewController = presentedViewController + self.transitioningDelegate = presentedViewController?.transitioningDelegate as? BottomPopupTransitionHandler + self.attributesDelegate = attributesDelegate + super.init() + preparePanGesture(in: presentedViewController?.view) + } + + private func finishAnimation(withVelocity velocity: CGPoint) { + if currentPercent > kMinPercentOfVisiblePartToCompleteAnimation || velocity.y > kSwipeDownThreshold { + finish() + } else { + cancel() + } + } + + private func preparePanGesture(in view: UIView?) { + let panGesture = UIPanGestureRecognizer(target: self, action: #selector(handlePanGesture(_:))) + presentedViewController?.view?.addGestureRecognizer(panGesture) + } + + @objc private func handlePanGesture(_ pan: UIPanGestureRecognizer) { + guard attributesDelegate.popupShouldBeganDismiss else { return } + + let translationY = pan.translation(in: presentedViewController?.view).y + currentPercent = min(max(translationY/(presentedViewController?.view.frame.size.height ?? 0), 0), 1) + + switch pan.state { + case .began: + transitioningDelegate?.isInteractiveDismissStarted = true + presentedViewController?.dismiss(animated: true, completion: nil) + case .changed: + update(currentPercent) + default: + let velocity = pan.velocity(in: presentedViewController?.view) + transitioningDelegate?.isInteractiveDismissStarted = false + finishAnimation(withVelocity: velocity) + } + } +} diff --git a/AVStackController/Sources/BottomPopupPresentAnimator.swift b/AVStackController/Sources/BottomPopupPresentAnimator.swift new file mode 100755 index 0000000..cf5ace8 --- /dev/null +++ b/AVStackController/Sources/BottomPopupPresentAnimator.swift @@ -0,0 +1,34 @@ +// +// DraggablePresentAnimator.swift +// CREDAssignment +// +// Created by Anand Verma on 10/08/20. +// Copyright © 2020 CRED. All rights reserved. +// + +import UIKit + +final class BottomPopupPresentAnimator: NSObject, UIViewControllerAnimatedTransitioning { + private unowned var attributesOwner: BottomPresentableViewController + + init(attributesOwner: BottomPresentableViewController) { + self.attributesOwner = attributesOwner + } + + func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval { + return attributesOwner.popupPresentDuration + } + + func animateTransition(using transitionContext: UIViewControllerContextTransitioning) { + let toVC = transitionContext.viewController(forKey: .to)! + transitionContext.containerView.addSubview(toVC.view) + let presentFrame = transitionContext.finalFrame(for: toVC) + let initialFrame = CGRect(origin: CGPoint(x: 0, y: UIScreen.main.bounds.size.height), size: presentFrame.size) + toVC.view.frame = initialFrame + UIView.animate(withDuration: transitionDuration(using: transitionContext), animations: { + toVC.view.frame = presentFrame + }) { (_) in + transitionContext.completeTransition(true) + } + } +} diff --git a/AVStackController/Sources/BottomPopupPresentationController.swift b/AVStackController/Sources/BottomPopupPresentationController.swift new file mode 100755 index 0000000..c007409 --- /dev/null +++ b/AVStackController/Sources/BottomPopupPresentationController.swift @@ -0,0 +1,74 @@ +// +// BottomPopupPresentationController.swift +// CREDAssignment +// +// Created by Anand Verma on 10/08/20. +// Copyright © 2020 CRED. All rights reserved. +// + + +import UIKit + +final class BottomPopupPresentationController: UIPresentationController { + private var dimmingView: UIView! + private unowned var attributesDelegate: BottomPopupAttributesDelegate + + override var frameOfPresentedViewInContainerView: CGRect { + get { + return CGRect(origin: CGPoint(x: 0, y: UIScreen.main.bounds.size.height - attributesDelegate.popupHeight), size: CGSize(width: presentedViewController.view.frame.size.width, height: attributesDelegate.popupHeight)) + } + } + + private func changeDimmingViewAlphaAlongWithAnimation(to alpha: CGFloat) { + guard let coordinator = presentedViewController.transitionCoordinator else { + dimmingView.backgroundColor = UIColor.black.withAlphaComponent(alpha) + return + } + + coordinator.animate(alongsideTransition: { _ in + self.dimmingView.backgroundColor = UIColor.black.withAlphaComponent(alpha) + }) + } + + init(presentedViewController: UIViewController, presenting presentingViewController: UIViewController?, attributesDelegate: BottomPopupAttributesDelegate) { + self.attributesDelegate = attributesDelegate + super.init(presentedViewController: presentedViewController, presenting: presentingViewController) + setupDimmingView() + } + + override func containerViewWillLayoutSubviews() { + presentedView?.frame = frameOfPresentedViewInContainerView + } + + override func presentationTransitionWillBegin() { + containerView?.insertSubview(dimmingView, at: 0) + changeDimmingViewAlphaAlongWithAnimation(to: attributesDelegate.popupDimmingViewAlpha) + } + + override func dismissalTransitionWillBegin() { + changeDimmingViewAlphaAlongWithAnimation(to: 0) + } + + @objc private func handleTap(_ tap: UITapGestureRecognizer) { + guard attributesDelegate.popupShouldBeganDismiss else { return } + presentedViewController.dismiss(animated: true, completion: nil) + } + + @objc private func handleSwipe(_ swipe: UISwipeGestureRecognizer) { + guard attributesDelegate.popupShouldBeganDismiss else { return } + presentedViewController.dismiss(animated: true, completion: nil) + } +} + +private extension BottomPopupPresentationController { + func setupDimmingView() { + dimmingView = UIView() + dimmingView.frame = CGRect(origin: .zero, size: UIScreen.main.bounds.size) + dimmingView.backgroundColor = UIColor.black.withAlphaComponent(0) + let tapGesture = UITapGestureRecognizer(target: self, action: #selector(handleTap(_:))) + let swipeGesture = UISwipeGestureRecognizer(target: self, action: #selector(handleSwipe(_:))) + swipeGesture.direction = [.down, .up] + dimmingView.isUserInteractionEnabled = true + [tapGesture, swipeGesture].forEach { dimmingView.addGestureRecognizer($0) } + } +} diff --git a/AVStackController/Sources/BottomPopupTransitionHandler.swift b/AVStackController/Sources/BottomPopupTransitionHandler.swift new file mode 100755 index 0000000..f138da4 --- /dev/null +++ b/AVStackController/Sources/BottomPopupTransitionHandler.swift @@ -0,0 +1,58 @@ +// +// DraggableTransitioningDelegate.swift +// CREDAssignment +// +// Created by Anand Verma on 10/08/20. +// Copyright © 2020 CRED. All rights reserved. +// + +import UIKit + +final class BottomPopupTransitionHandler: NSObject, UIViewControllerTransitioningDelegate { + private let presentAnimator: BottomPopupPresentAnimator + private let dismissAnimator: BottomPopupDismissAnimator + private var interactionController: BottomPopupDismissInteractionController? + private unowned var popupViewController: BottomPresentableViewController + fileprivate weak var popupDelegate: BottomPopupDelegate? + + var isInteractiveDismissStarted = false + + init(popupViewController: BottomPresentableViewController) { + self.popupViewController = popupViewController + + presentAnimator = BottomPopupPresentAnimator(attributesOwner: popupViewController) + dismissAnimator = BottomPopupDismissAnimator(attributesOwner: popupViewController) + } + + //MARK: Public + func notifyViewLoaded(withPopupDelegate delegate: BottomPopupDelegate?) { + self.popupDelegate = delegate + if popupViewController.popupShouldDismissInteractivelty { + interactionController = BottomPopupDismissInteractionController(presentedViewController: popupViewController, attributesDelegate: popupViewController) + interactionController?.delegate = self + } + } + + //MARK: Specific animators + func presentationController(forPresented presented: UIViewController, presenting: UIViewController?, source: UIViewController) -> UIPresentationController? { + return BottomPopupPresentationController(presentedViewController: presented, presenting: presenting, attributesDelegate: popupViewController) + } + + func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? { + return presentAnimator + } + + func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? { + return dismissAnimator + } + + func interactionControllerForDismissal(using animator: UIViewControllerAnimatedTransitioning) -> UIViewControllerInteractiveTransitioning? { + return isInteractiveDismissStarted ? interactionController : nil + } +} + +extension BottomPopupTransitionHandler: BottomPopupDismissInteractionControllerDelegate { + func dismissInteractionPercentChanged(from oldValue: CGFloat, to newValue: CGFloat) { + popupDelegate?.bottomPopupDismissInteractionPercentChanged(from: oldValue, to: newValue) + } +} diff --git a/AVStackController/Sources/BottomPopupUtils.swift b/AVStackController/Sources/BottomPopupUtils.swift new file mode 100755 index 0000000..3b55093 --- /dev/null +++ b/AVStackController/Sources/BottomPopupUtils.swift @@ -0,0 +1,52 @@ +// +// BottomPopupUtils.swift +// CREDAssignment +// +// Created by Anand Verma on 10/08/20. +// Copyright © 2020 CRED. All rights reserved. +// + + +import UIKit + +typealias BottomPresentableViewController = BottomPopupAttributesDelegate & UIViewController + +public protocol BottomPopupDelegate: class { + func bottomPopupViewLoaded() + func bottomPopupWillAppear() + func bottomPopupDidAppear() + func bottomPopupWillDismiss() + func bottomPopupDidDismiss() + func bottomPopupDismissInteractionPercentChanged(from oldValue: CGFloat, to newValue: CGFloat) +} + +public extension BottomPopupDelegate { + func bottomPopupViewLoaded() { } + func bottomPopupWillAppear() { } + func bottomPopupDidAppear() { } + func bottomPopupWillDismiss() { } + func bottomPopupDidDismiss() { } + func bottomPopupDismissInteractionPercentChanged(from oldValue: CGFloat, to newValue: CGFloat) { } +} + +public protocol BottomPopupAttributesDelegate: class { + var popupHeight: CGFloat { get } + var popupTopCornerRadius: CGFloat { get } + var popupPresentDuration: Double { get } + var popupDismissDuration: Double { get } + var popupShouldDismissInteractivelty: Bool { get } + var popupDimmingViewAlpha: CGFloat { get } + var popupShouldBeganDismiss: Bool { get } + var popupViewAccessibilityIdentifier: String { get } +} + +public struct BottomPopupConstants { + static let kDefaultHeight: CGFloat = 377.0 + static let kDefaultTopCornerRadius: CGFloat = 10.0 + static let kDefaultPresentDuration = 0.5 + static let kDefaultDismissDuration = 0.5 + static let dismissInteractively = true + static let shouldBeganDismiss = true + static let kDimmingViewDefaultAlphaValue: CGFloat = 0.5 + static let defaultPopupViewAccessibilityIdentifier: String = "bottomPopupView" +} diff --git a/AVStackController/Sources/BottomPopupViewController.swift b/AVStackController/Sources/BottomPopupViewController.swift new file mode 100755 index 0000000..9cae91c --- /dev/null +++ b/AVStackController/Sources/BottomPopupViewController.swift @@ -0,0 +1,96 @@ +// +// BottomPopupViewController.swift +// CREDAssignment +// +// Created by Anand Verma on 10/08/20. +// Copyright © 2020 CRED. All rights reserved. +// + + +import UIKit + +open class BottomPopupViewController: UIViewController, BottomPopupAttributesDelegate { + private var transitionHandler: BottomPopupTransitionHandler? + open weak var popupDelegate: BottomPopupDelegate? + + // MARK: Initializations + + override public init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) { + super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil) + + initialize() + } + + required public init?(coder aDecoder: NSCoder) { + super.init(coder: aDecoder) + + initialize() + } + + open override func viewDidLoad() { + + super.viewDidLoad() + transitionHandler?.notifyViewLoaded(withPopupDelegate: popupDelegate) + popupDelegate?.bottomPopupViewLoaded() + self.view.accessibilityIdentifier = popupViewAccessibilityIdentifier + } + + open override func viewWillAppear(_ animated: Bool) { + super.viewWillAppear(animated) + + curveTopCorners() + popupDelegate?.bottomPopupWillAppear() + } + + open override func viewDidAppear(_ animated: Bool) { + super.viewDidAppear(animated) + + popupDelegate?.bottomPopupDidAppear() + } + + open override func viewWillDisappear(_ animated: Bool) { + super.viewWillDisappear(animated) + + popupDelegate?.bottomPopupWillDismiss() + } + + open override func viewDidDisappear(_ animated: Bool) { + super.viewDidDisappear(animated) + + popupDelegate?.bottomPopupDidDismiss() + } + + //MARK: Private Methods + + private func initialize() { + transitionHandler = BottomPopupTransitionHandler(popupViewController: self) + transitioningDelegate = transitionHandler + modalPresentationStyle = .custom + } + + private func curveTopCorners() { + let path = UIBezierPath(roundedRect: self.view.bounds, byRoundingCorners: [.topLeft, .topRight], cornerRadii: CGSize(width: popupTopCornerRadius, height: 0)) + let maskLayer = CAShapeLayer() + maskLayer.frame = self.view.bounds + maskLayer.path = path.cgPath + self.view.layer.mask = maskLayer + } + + //MARK: BottomPopupAttributesDelegate Variables + + open var popupHeight: CGFloat { return BottomPopupConstants.kDefaultHeight } + + open var popupTopCornerRadius: CGFloat { return BottomPopupConstants.kDefaultTopCornerRadius } + + open var popupPresentDuration: Double { return BottomPopupConstants.kDefaultPresentDuration } + + open var popupDismissDuration: Double { return BottomPopupConstants.kDefaultDismissDuration } + + open var popupShouldDismissInteractivelty: Bool { return BottomPopupConstants.dismissInteractively } + + open var popupDimmingViewAlpha: CGFloat { return BottomPopupConstants.kDimmingViewDefaultAlphaValue } + + open var popupShouldBeganDismiss: Bool { return BottomPopupConstants.shouldBeganDismiss } + + open var popupViewAccessibilityIdentifier: String { return BottomPopupConstants.defaultPopupViewAccessibilityIdentifier } +} diff --git a/AVStackControllerTests/AVStackControllerTests.swift b/AVStackControllerTests/AVStackControllerTests.swift new file mode 100644 index 0000000..9148b3a --- /dev/null +++ b/AVStackControllerTests/AVStackControllerTests.swift @@ -0,0 +1,34 @@ +// +// AVStackControllerTests.swift +// AVStackControllerTests +// +// Created by Anand Verma on 11/08/20. +// Copyright © 2020 AVSwiftHub. All rights reserved. +// + +import XCTest +@testable import AVStackController + +class AVStackControllerTests: XCTestCase { + + override func setUp() { + // Put setup code here. This method is called before the invocation of each test method in the class. + } + + override func tearDown() { + // Put teardown code here. This method is called after the invocation of each test method in the class. + } + + func testExample() { + // This is an example of a functional test case. + // Use XCTAssert and related functions to verify your tests produce the correct results. + } + + func testPerformanceExample() { + // This is an example of a performance test case. + self.measure { + // Put the code you want to measure the time of here. + } + } + +} diff --git a/AVStackControllerTests/Info.plist b/AVStackControllerTests/Info.plist new file mode 100644 index 0000000..64d65ca --- /dev/null +++ b/AVStackControllerTests/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 + +