diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e636384 --- /dev/null +++ b/.gitignore @@ -0,0 +1,39 @@ +.DS_Store +.Trashes +.localized + +build +.build +xcuserdata +DerivedData + +*.mode1v3 +*.mode2v3 +*.perspectivev3 +*.pbxuser +*.xccheckout +*.xcuserstate +*.xcscmblueprint +*.moved-aside +*.hmap +*.o +*.hmap +*.ipa +*.dSYM.zip + +timeline.xctimeline +playground.xcworkspace + +.idea +*.iml + +Pods +Carthage +Packages + +fastlane/report.xml +fastlane/Preview.html +fastlane/screenshots +fastlane/test_output + +.env diff --git a/CarLensCollectionViewLayout.podspec b/CarLensCollectionViewLayout.podspec new file mode 100644 index 0000000..4eee107 --- /dev/null +++ b/CarLensCollectionViewLayout.podspec @@ -0,0 +1,18 @@ +Pod::Spec.new do |s| + + s.name = "CarLensCollectionViewLayout" + s.version = "1.0.0" + s.summary = "An easy to use Collection View Layout for card-like animation." + + s.homepage = "https://github.com/netguru/CarLensCollectionViewLayout" + s.license = { :type => "MIT", :file => "LICENSE.md" } + s.authors = { "Anna-Mariia Shkarlinska" => "anna-mariia.shkarlinska@netguru.co", + "Michał Kwiecień" => "michal.kwiecien@netguru.co" } + + s.platform = :ios, "9.0" + s.source = { :git => "https://github.com/netguru/CarLensCollectionViewLayout.git", :tag => "#{s.version}" } + s.source_files = "CarLensCollectionViewLayout/**/*.swift" + s.swift_version = "4.2" + s.framework = "UIKit" + +end \ No newline at end of file diff --git a/CarLensCollectionViewLayout.xcodeproj/project.pbxproj b/CarLensCollectionViewLayout.xcodeproj/project.pbxproj new file mode 100644 index 0000000..1d6cc6b --- /dev/null +++ b/CarLensCollectionViewLayout.xcodeproj/project.pbxproj @@ -0,0 +1,544 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 50; + objects = { + +/* Begin PBXBuildFile section */ + 9505725E21D4D8FB009EA422 /* CarLensCollectionViewLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9505725D21D4D8FB009EA422 /* CarLensCollectionViewLayout.swift */; }; + 9505726021D4D922009EA422 /* CarLensLayoutAttributes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9505725F21D4D922009EA422 /* CarLensLayoutAttributes.swift */; }; + 9518381D21E4F04400BEA6EB /* CarLensCollectionViewLayout.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 955E4FCF21CBFB2800B4C3BB /* CarLensCollectionViewLayout.framework */; }; + 9518381E21E4F04400BEA6EB /* CarLensCollectionViewLayout.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 955E4FCF21CBFB2800B4C3BB /* CarLensCollectionViewLayout.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 9518383121E4F09900BEA6EB /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 9518382721E4F08300BEA6EB /* Main.storyboard */; }; + 9518383321E4F0B500BEA6EB /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 9518382521E4F08300BEA6EB /* LaunchScreen.storyboard */; }; + 9518383721E4F31C00BEA6EB /* CollectionViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9518382321E4F08300BEA6EB /* CollectionViewController.swift */; }; + 9518383821E4F31F00BEA6EB /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 9518382421E4F08300BEA6EB /* Assets.xcassets */; }; + 9518383921E4F32800BEA6EB /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9518382921E4F08300BEA6EB /* AppDelegate.swift */; }; + 9518383C21E4FFCA00BEA6EB /* CollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9518383B21E4FFCA00BEA6EB /* CollectionViewCell.swift */; }; + 955E4FD421CBFB2800B4C3BB /* CarLensCollectionViewLayout.h in Headers */ = {isa = PBXBuildFile; fileRef = 955E4FD221CBFB2800B4C3BB /* CarLensCollectionViewLayout.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 958D17C021D66DF00067BED6 /* CarLensCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 958D17BF21D66DF00067BED6 /* CarLensCollectionViewCell.swift */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 9518383521E4F16700BEA6EB /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 955E4FC621CBFB2800B4C3BB /* Project object */; + proxyType = 1; + remoteGlobalIDString = 955E4FCE21CBFB2800B4C3BB; + remoteInfo = CarLensCollectionViewLayout; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 9518382121E4F04400BEA6EB /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + 9518381E21E4F04400BEA6EB /* CarLensCollectionViewLayout.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 9505725D21D4D8FB009EA422 /* CarLensCollectionViewLayout.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CarLensCollectionViewLayout.swift; sourceTree = ""; }; + 9505725F21D4D922009EA422 /* CarLensLayoutAttributes.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CarLensLayoutAttributes.swift; sourceTree = ""; }; + 9518380B21E4F00000BEA6EB /* CarLensCollectionViewLayoutDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = CarLensCollectionViewLayoutDemo.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 9518382321E4F08300BEA6EB /* CollectionViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CollectionViewController.swift; sourceTree = ""; }; + 9518382421E4F08300BEA6EB /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 9518382621E4F08300BEA6EB /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 9518382821E4F08300BEA6EB /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 9518382921E4F08300BEA6EB /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 9518382A21E4F08300BEA6EB /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 9518383B21E4FFCA00BEA6EB /* CollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CollectionViewCell.swift; sourceTree = ""; }; + 955E4FCF21CBFB2800B4C3BB /* CarLensCollectionViewLayout.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = CarLensCollectionViewLayout.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 955E4FD221CBFB2800B4C3BB /* CarLensCollectionViewLayout.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CarLensCollectionViewLayout.h; sourceTree = ""; }; + 955E4FD321CBFB2800B4C3BB /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 958D17BF21D66DF00067BED6 /* CarLensCollectionViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CarLensCollectionViewCell.swift; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 9518380821E4F00000BEA6EB /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 9518381D21E4F04400BEA6EB /* CarLensCollectionViewLayout.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 955E4FCC21CBFB2800B4C3BB /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 9518382221E4F08300BEA6EB /* CarLensCollectionViewLayoutDemo */ = { + isa = PBXGroup; + children = ( + 9518382921E4F08300BEA6EB /* AppDelegate.swift */, + 9518382321E4F08300BEA6EB /* CollectionViewController.swift */, + 9518383B21E4FFCA00BEA6EB /* CollectionViewCell.swift */, + 9518384121E5166100BEA6EB /* Supporting files */, + ); + path = CarLensCollectionViewLayoutDemo; + sourceTree = ""; + }; + 9518384121E5166100BEA6EB /* Supporting files */ = { + isa = PBXGroup; + children = ( + 9518382421E4F08300BEA6EB /* Assets.xcassets */, + 9518382521E4F08300BEA6EB /* LaunchScreen.storyboard */, + 9518382721E4F08300BEA6EB /* Main.storyboard */, + 9518382A21E4F08300BEA6EB /* Info.plist */, + ); + path = "Supporting files"; + sourceTree = ""; + }; + 955E4FC521CBFB2800B4C3BB = { + isa = PBXGroup; + children = ( + 9518382221E4F08300BEA6EB /* CarLensCollectionViewLayoutDemo */, + 955E4FD121CBFB2800B4C3BB /* CarLensCollectionViewLayout */, + 955E4FD021CBFB2800B4C3BB /* Products */, + ); + sourceTree = ""; + }; + 955E4FD021CBFB2800B4C3BB /* Products */ = { + isa = PBXGroup; + children = ( + 955E4FCF21CBFB2800B4C3BB /* CarLensCollectionViewLayout.framework */, + 9518380B21E4F00000BEA6EB /* CarLensCollectionViewLayoutDemo.app */, + ); + name = Products; + sourceTree = ""; + }; + 955E4FD121CBFB2800B4C3BB /* CarLensCollectionViewLayout */ = { + isa = PBXGroup; + children = ( + 955E4FD221CBFB2800B4C3BB /* CarLensCollectionViewLayout.h */, + 9505725D21D4D8FB009EA422 /* CarLensCollectionViewLayout.swift */, + 958D17BF21D66DF00067BED6 /* CarLensCollectionViewCell.swift */, + 9505725F21D4D922009EA422 /* CarLensLayoutAttributes.swift */, + 955E4FD321CBFB2800B4C3BB /* Info.plist */, + ); + path = CarLensCollectionViewLayout; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + 955E4FCA21CBFB2800B4C3BB /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 955E4FD421CBFB2800B4C3BB /* CarLensCollectionViewLayout.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + 9518380A21E4F00000BEA6EB /* CarLensCollectionViewLayoutDemo */ = { + isa = PBXNativeTarget; + buildConfigurationList = 9518381A21E4F00200BEA6EB /* Build configuration list for PBXNativeTarget "CarLensCollectionViewLayoutDemo" */; + buildPhases = ( + 9518380721E4F00000BEA6EB /* Sources */, + 9518380821E4F00000BEA6EB /* Frameworks */, + 9518380921E4F00000BEA6EB /* Resources */, + 9518382121E4F04400BEA6EB /* Embed Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + 9518383621E4F16700BEA6EB /* PBXTargetDependency */, + ); + name = CarLensCollectionViewLayoutDemo; + productName = Example; + productReference = 9518380B21E4F00000BEA6EB /* CarLensCollectionViewLayoutDemo.app */; + productType = "com.apple.product-type.application"; + }; + 955E4FCE21CBFB2800B4C3BB /* CarLensCollectionViewLayout */ = { + isa = PBXNativeTarget; + buildConfigurationList = 955E4FD721CBFB2800B4C3BB /* Build configuration list for PBXNativeTarget "CarLensCollectionViewLayout" */; + buildPhases = ( + 955E4FCA21CBFB2800B4C3BB /* Headers */, + 955E4FCB21CBFB2800B4C3BB /* Sources */, + 955E4FCC21CBFB2800B4C3BB /* Frameworks */, + 955E4FCD21CBFB2800B4C3BB /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = CarLensCollectionViewLayout; + productName = CarlensCollectionViewLayout; + productReference = 955E4FCF21CBFB2800B4C3BB /* CarLensCollectionViewLayout.framework */; + productType = "com.apple.product-type.framework"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 955E4FC621CBFB2800B4C3BB /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 1010; + LastUpgradeCheck = 1010; + ORGANIZATIONNAME = Netguru; + TargetAttributes = { + 9518380A21E4F00000BEA6EB = { + CreatedOnToolsVersion = 10.1; + }; + 955E4FCE21CBFB2800B4C3BB = { + CreatedOnToolsVersion = 10.1; + }; + }; + }; + buildConfigurationList = 955E4FC921CBFB2800B4C3BB /* Build configuration list for PBXProject "CarLensCollectionViewLayout" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 955E4FC521CBFB2800B4C3BB; + productRefGroup = 955E4FD021CBFB2800B4C3BB /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 955E4FCE21CBFB2800B4C3BB /* CarLensCollectionViewLayout */, + 9518380A21E4F00000BEA6EB /* CarLensCollectionViewLayoutDemo */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 9518380921E4F00000BEA6EB /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 9518383321E4F0B500BEA6EB /* LaunchScreen.storyboard in Resources */, + 9518383821E4F31F00BEA6EB /* Assets.xcassets in Resources */, + 9518383121E4F09900BEA6EB /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 955E4FCD21CBFB2800B4C3BB /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 9518380721E4F00000BEA6EB /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 9518383921E4F32800BEA6EB /* AppDelegate.swift in Sources */, + 9518383721E4F31C00BEA6EB /* CollectionViewController.swift in Sources */, + 9518383C21E4FFCA00BEA6EB /* CollectionViewCell.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 955E4FCB21CBFB2800B4C3BB /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 9505725E21D4D8FB009EA422 /* CarLensCollectionViewLayout.swift in Sources */, + 958D17C021D66DF00067BED6 /* CarLensCollectionViewCell.swift in Sources */, + 9505726021D4D922009EA422 /* CarLensLayoutAttributes.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 9518383621E4F16700BEA6EB /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 955E4FCE21CBFB2800B4C3BB /* CarLensCollectionViewLayout */; + targetProxy = 9518383521E4F16700BEA6EB /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin PBXVariantGroup section */ + 9518382521E4F08300BEA6EB /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 9518382621E4F08300BEA6EB /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; + 9518382721E4F08300BEA6EB /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 9518382821E4F08300BEA6EB /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 9518381B21E4F00200BEA6EB /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Manual; + DEVELOPMENT_TEAM = ""; + INFOPLIST_FILE = "$(SRCROOT)/CarLensCollectionViewLayoutDemo/Supporting Files/Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = co.netguru.lib.CarLensCollectionViewLayoutDemo; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_VERSION = 4.2; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 9518381C21E4F00200BEA6EB /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Manual; + DEVELOPMENT_TEAM = ""; + INFOPLIST_FILE = "$(SRCROOT)/CarLensCollectionViewLayoutDemo/Supporting Files/Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = co.netguru.lib.CarLensCollectionViewLayoutDemo; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_VERSION = 4.2; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; + 955E4FD521CBFB2800B4C3BB /* 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; + CODE_SIGN_IDENTITY = "iPhone Developer"; + 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 = 9.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; + }; + 955E4FD621CBFB2800B4C3BB /* 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; + CODE_SIGN_IDENTITY = "iPhone Developer"; + 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 = 9.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; + }; + 955E4FD821CBFB2800B4C3BB /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_IDENTITY = ""; + CODE_SIGN_STYLE = Manual; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = ""; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = CarlensCollectionViewLayout/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = co.netguru.lib.CarLensCollectionViewLayout; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SKIP_INSTALL = YES; + SWIFT_VERSION = 4.2; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 955E4FD921CBFB2800B4C3BB /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_IDENTITY = ""; + CODE_SIGN_STYLE = Manual; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = ""; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = CarlensCollectionViewLayout/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = co.netguru.lib.CarLensCollectionViewLayout; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SKIP_INSTALL = YES; + SWIFT_VERSION = 4.2; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 9518381A21E4F00200BEA6EB /* Build configuration list for PBXNativeTarget "CarLensCollectionViewLayoutDemo" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 9518381B21E4F00200BEA6EB /* Debug */, + 9518381C21E4F00200BEA6EB /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 955E4FC921CBFB2800B4C3BB /* Build configuration list for PBXProject "CarLensCollectionViewLayout" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 955E4FD521CBFB2800B4C3BB /* Debug */, + 955E4FD621CBFB2800B4C3BB /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 955E4FD721CBFB2800B4C3BB /* Build configuration list for PBXNativeTarget "CarLensCollectionViewLayout" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 955E4FD821CBFB2800B4C3BB /* Debug */, + 955E4FD921CBFB2800B4C3BB /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 955E4FC621CBFB2800B4C3BB /* Project object */; +} diff --git a/CarLensCollectionViewLayout.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/CarLensCollectionViewLayout.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/CarLensCollectionViewLayout.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/CarLensCollectionViewLayout.xcodeproj/xcshareddata/xcschemes/CarLensCollectionViewLayout.xcscheme b/CarLensCollectionViewLayout.xcodeproj/xcshareddata/xcschemes/CarLensCollectionViewLayout.xcscheme new file mode 100644 index 0000000..5643a70 --- /dev/null +++ b/CarLensCollectionViewLayout.xcodeproj/xcshareddata/xcschemes/CarLensCollectionViewLayout.xcscheme @@ -0,0 +1,80 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/CarLensCollectionViewLayout.xcodeproj/xcshareddata/xcschemes/CarLensCollectionViewLayoutDemo.xcscheme b/CarLensCollectionViewLayout.xcodeproj/xcshareddata/xcschemes/CarLensCollectionViewLayoutDemo.xcscheme new file mode 100644 index 0000000..76b6a74 --- /dev/null +++ b/CarLensCollectionViewLayout.xcodeproj/xcshareddata/xcschemes/CarLensCollectionViewLayoutDemo.xcscheme @@ -0,0 +1,91 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/CarLensCollectionViewLayout/CarLensCollectionViewCell.swift b/CarLensCollectionViewLayout/CarLensCollectionViewCell.swift new file mode 100644 index 0000000..bdd86e0 --- /dev/null +++ b/CarLensCollectionViewLayout/CarLensCollectionViewCell.swift @@ -0,0 +1,61 @@ +// +// CarLensCollectionViewCell.swift +// CarLensCollectionViewCell +// +// Copyright © 2018 Netguru. All rights reserved. +// + + +import UIKit.UICollectionView + +open class CarLensCollectionViewCell: UICollectionViewCell { + + /// Indicates if the cell is currently displayed as primary cell. + public var isCurrentlyPrimary = false + + /// The upper view of the cell. + public var topView: UIView! + + /// The bottom view of the cell. + public var cardView: UIView! + + private let topViewHeight: CGFloat = UIScreen.main.bounds.height > 568 ? 200 : 170 + + /// Configuration of the cell. Must be called on a start. + /// + /// - Parameters: + /// - topView: The upper view of the cell. + /// - cardView: The bottom view of the cell. + open func configure(topView: UIView, cardView: UIView) { + self.topView = topView + self.cardView = cardView + setupView() + } + + private func animateViews(toProgress progress: Double) { + let offset = topViewHeight - (CGFloat(progress) * topViewHeight) + cardView.transform = .init(translationX: 0, y: -offset) + } + + private func setupView() { + [topView, cardView].forEach(contentView.addSubview) + NSLayoutConstraint.activate([ + topView.topAnchor.constraint(equalTo: topAnchor), + topView.leadingAnchor.constraint(equalTo: leadingAnchor), + topView.trailingAnchor.constraint(equalTo: trailingAnchor), + topView.heightAnchor.constraint(equalToConstant: topViewHeight), + cardView.bottomAnchor.constraint(equalTo: bottomAnchor), + cardView.leadingAnchor.constraint(equalTo: leadingAnchor), + cardView.trailingAnchor.constraint(equalTo: trailingAnchor), + cardView.topAnchor.constraint(equalTo: topView.bottomAnchor) + ]) + } + + /// - SeeAlso: UICollectionViewCell + open override func apply(_ layoutAttributes: UICollectionViewLayoutAttributes) { + super.apply(layoutAttributes) + guard let attributes = layoutAttributes as? CarLensLayoutAttributes else { return } + isCurrentlyPrimary = !(attributes.progress == 0) + animateViews(toProgress: attributes.progress) + } +} diff --git a/CarLensCollectionViewLayout/CarLensCollectionViewLayout.h b/CarLensCollectionViewLayout/CarLensCollectionViewLayout.h new file mode 100644 index 0000000..5bbe189 --- /dev/null +++ b/CarLensCollectionViewLayout/CarLensCollectionViewLayout.h @@ -0,0 +1,18 @@ +// +// CarLensCollectionViewLayout.h +// CarLensCollectionViewLayout +// +// Copyright © 2018 Netguru. All rights reserved. +// + +#import + +//! Project version number for CarlensCollectionViewLayout. +FOUNDATION_EXPORT double CarlensCollectionViewLayoutVersionNumber; + +//! Project version string for CarlensCollectionViewLayout. +FOUNDATION_EXPORT const unsigned char CarlensCollectionViewLayoutVersionString[]; + +// In this header, you should import all the public headers of your framework using statements like #import + + diff --git a/CarLensCollectionViewLayout/CarLensCollectionViewLayout.swift b/CarLensCollectionViewLayout/CarLensCollectionViewLayout.swift new file mode 100644 index 0000000..c8eb235 --- /dev/null +++ b/CarLensCollectionViewLayout/CarLensCollectionViewLayout.swift @@ -0,0 +1,74 @@ +// +// CarLensCollectionViewLayout.swift +// CarLensCollectionViewLayout +// +// Copyright © 2018 Netguru. All rights reserved. +// + +import UIKit + +public final class CarLensCollectionViewLayout: UICollectionViewFlowLayout { + + private var firstSetupDone = false + + /// SeeAlso: UICollectionViewFlowLayout + public override func prepare() { + super.prepare() + guard !firstSetupDone else { return } + setup() + firstSetupDone = true + } + + private func setup() { + guard let collectionView = collectionView else { return } + scrollDirection = .horizontal + minimumLineSpacing = 20 + itemSize = CGSize(width: collectionView.bounds.width - 80, height: collectionView.bounds.height) + let inset = (collectionView.bounds.width - itemSize.width) / 2 + collectionView.contentInset = .init(top: 0, left: inset, bottom: 0, right: inset) + collectionView.decelerationRate = UIScrollView.DecelerationRate.fast + } + + /// SeeAlso: UICollectionViewFlowLayout + public override func shouldInvalidateLayout(forBoundsChange newBounds: CGRect) -> Bool { + return true + } + + /// SeeAlso: UICollectionViewFlowLayout + public override class var layoutAttributesClass: AnyClass { + return CarLensLayoutAttributes.self + } + + /// SeeAlso: UICollectionViewFlowLayout + public override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? { + guard let collectionView = collectionView, let allAttributes = super.layoutAttributesForElements(in: rect) else { return nil } + for attributes in allAttributes { + let collectionCenter = collectionView.bounds.size.width / 2 + let offset = collectionView.contentOffset.x + let normalizedCenter = attributes.center.x - offset + + let maxDistance = itemSize.width + minimumLineSpacing + let distanceFromCenter = min(collectionCenter - normalizedCenter, maxDistance) + let ratio = (maxDistance - abs(distanceFromCenter)) / maxDistance + let normalizedRatio = min(1, max(0, ratio)) + + guard let attributes = attributes as? CarLensLayoutAttributes else { continue } + attributes.progress = Double(normalizedRatio) + } + return allAttributes + } + + /// SeeAlso: UICollectionViewFlowLayout + public override func targetContentOffset(forProposedContentOffset proposedContentOffset: CGPoint, withScrollingVelocity velocity: CGPoint) -> CGPoint { + guard let collectionView = collectionView, let layoutAttributes = layoutAttributesForElements(in: collectionView.bounds) else { + return .init(x: 0, y: 0) + } + // Snapping closest cell to the center + let centerOffset = collectionView.bounds.size.width / 2 + let offsetWithCenter = proposedContentOffset.x + (proposedContentOffset.x * velocity.x) + centerOffset + let closestAttribute = layoutAttributes + .sorted { abs($0.center.x - offsetWithCenter) < abs($1.center.x - offsetWithCenter) } + .first ?? UICollectionViewLayoutAttributes() + return CGPoint(x: closestAttribute.center.x - centerOffset, y: 0) + } +} diff --git a/CarLensCollectionViewLayout/CarLensLayoutAttributes.swift b/CarLensCollectionViewLayout/CarLensLayoutAttributes.swift new file mode 100644 index 0000000..4ef4a94 --- /dev/null +++ b/CarLensCollectionViewLayout/CarLensLayoutAttributes.swift @@ -0,0 +1,29 @@ +// +// CarLensLayoutAttributes.swift +// CarLensLayoutAttributes +// +// Copyright © 2018 Netguru. All rights reserved. +// + + +import UIKit + +final class CarLensLayoutAttributes: UICollectionViewLayoutAttributes { + + /// Progress towards the center of the screen, value between 0 and 1. + var progress = 0.0 + + /// SeeAlso: UICollectionViewLayoutAttributes + override func copy(with zone: NSZone?) -> Any { + let attributes = super.copy(with: zone) + (attributes as? CarLensLayoutAttributes)?.progress = progress + return attributes + } + + /// SeeAlso: UICollectionViewLayoutAttributes + override func isEqual(_ object: Any?) -> Bool { + guard let attributes = object as? CarLensLayoutAttributes, + attributes.progress == progress else { return false } + return super.isEqual(object) + } +} diff --git a/CarLensCollectionViewLayout/Info.plist b/CarLensCollectionViewLayout/Info.plist new file mode 100644 index 0000000..e1fe4cf --- /dev/null +++ b/CarLensCollectionViewLayout/Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleVersion + $(CURRENT_PROJECT_VERSION) + + diff --git a/CarLensCollectionViewLayoutDemo/AppDelegate.swift b/CarLensCollectionViewLayoutDemo/AppDelegate.swift new file mode 100644 index 0000000..3096be2 --- /dev/null +++ b/CarLensCollectionViewLayoutDemo/AppDelegate.swift @@ -0,0 +1,18 @@ +// +// AppDelegate.swift +// CarLensCollectionViewDemo +// +// Copyright © 2019 Netguru. All rights reserved. +// + +import UIKit + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + + var window: UIWindow? + + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { + return true + } +} diff --git a/CarLensCollectionViewLayoutDemo/CollectionViewCell.swift b/CarLensCollectionViewLayoutDemo/CollectionViewCell.swift new file mode 100644 index 0000000..57fad91 --- /dev/null +++ b/CarLensCollectionViewLayoutDemo/CollectionViewCell.swift @@ -0,0 +1,41 @@ +// +// CollectionViewCell.swift +// CarLensCollectionViewDemo +// +// Copyright © 2019 Netguru. All rights reserved. +// + +import UIKit +import CarLensCollectionViewLayout + +class CollectionViewCell: CarLensCollectionViewCell { + + static let identifier = "CollectionViewCell" + + private var upperView: UILabel = { + var label = UILabel() + label.translatesAutoresizingMaskIntoConstraints = false + label.font = .boldSystemFont(ofSize: 60) + label.textAlignment = .center + label.textColor = .white + label.text = "CarLens" + return label + }() + + private var bottomView: UIView = { + var view = UIView() + view.translatesAutoresizingMaskIntoConstraints = false + view.backgroundColor = .white + view.layer.cornerRadius = 10 + return view + }() + + override init(frame: CGRect) { + super.init(frame: frame) + configure(topView: upperView, cardView: bottomView) + } + + required init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } +} diff --git a/CarLensCollectionViewLayoutDemo/CollectionViewController.swift b/CarLensCollectionViewLayoutDemo/CollectionViewController.swift new file mode 100644 index 0000000..f6e4fd6 --- /dev/null +++ b/CarLensCollectionViewLayoutDemo/CollectionViewController.swift @@ -0,0 +1,36 @@ +// +// CollectionViewController.swift +// CarLensCollectionViewDemo +// +// Copyright © 2019 Netguru. All rights reserved. +// + +import UIKit +import CarLensCollectionViewLayout + +class CollectionViewController: UICollectionViewController { + + override func viewDidLoad() { + super.viewDidLoad() + setupView() + } + + private func setupView() { + collectionView.backgroundColor = .lightGray + collectionView.register(CollectionViewCell.self, forCellWithReuseIdentifier: CollectionViewCell.identifier) + collectionView.showsHorizontalScrollIndicator = false + collectionView.collectionViewLayout = CarLensCollectionViewLayout() + } + + override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { + return 5 + } + + override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { + guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: CollectionViewCell.identifier, for: indexPath) as? CollectionViewCell else { + return UICollectionViewCell() + } + return cell + } + +} diff --git a/CarLensCollectionViewLayoutDemo/Supporting files/Assets.xcassets/AppIcon.appiconset/Contents.json b/CarLensCollectionViewLayoutDemo/Supporting files/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..d8db8d6 --- /dev/null +++ b/CarLensCollectionViewLayoutDemo/Supporting files/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -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" + } +} \ No newline at end of file diff --git a/CarLensCollectionViewLayoutDemo/Supporting files/Assets.xcassets/Contents.json b/CarLensCollectionViewLayoutDemo/Supporting files/Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/CarLensCollectionViewLayoutDemo/Supporting files/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/CarLensCollectionViewLayoutDemo/Supporting files/Base.lproj/LaunchScreen.storyboard b/CarLensCollectionViewLayoutDemo/Supporting files/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000..bfa3612 --- /dev/null +++ b/CarLensCollectionViewLayoutDemo/Supporting files/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/CarLensCollectionViewLayoutDemo/Supporting files/Base.lproj/Main.storyboard b/CarLensCollectionViewLayoutDemo/Supporting files/Base.lproj/Main.storyboard new file mode 100644 index 0000000..03e55f6 --- /dev/null +++ b/CarLensCollectionViewLayoutDemo/Supporting files/Base.lproj/Main.storyboard @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/CarLensCollectionViewLayoutDemo/Supporting files/Info.plist b/CarLensCollectionViewLayoutDemo/Supporting files/Info.plist new file mode 100644 index 0000000..89d7858 --- /dev/null +++ b/CarLensCollectionViewLayoutDemo/Supporting files/Info.plist @@ -0,0 +1,43 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 0000000..35a2e8f --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,9 @@ +MIT License + +Copyright (c) 2019 Netguru S.A. + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/README.md b/README.md index 333404c..4abc13d 100644 --- a/README.md +++ b/README.md @@ -1 +1,81 @@ -# CarlensCollectionViewLayout \ No newline at end of file +# CarLensCollectionViewLayout + +![](https://img.shields.io/badge/swift-4.2-orange.svg) +![](https://img.shields.io/badge/cocoapods-compatible-green.svg) +![](https://img.shields.io/badge/carthage-compatible-green.svg) +![](https://app.bitrise.io/app/23a07b63b3f55f97/status.svg?token=Rt_2gKUavbR8LQ7PVuTbYg&branch=master) + +An easy to use Collection View Layout for card-like animation 🎉 + +

+ +

+ +*CarLensCollectionViewLayout* was created out of the implementation in [**CarLens** application 🚘](https://github.com/netguru/car-recognition-ios). The image above exactly shows the screen from the app! + +## Requirements + +*CarLensCollectionViewLayout* is written in **Swift 4.2** and supports **iOS 9.0+**. + + +## Usage + +The two main steps are needed for the configuration of *CarLensCollectionViewLayout*: + +### Step 1 +Assign `CarLensCollectionViewLayout` to yours collection view layout: +```swift +collectionView.collectionViewLayout = CarLensCollectionViewLayout() +``` +or initialize your collection view with `CarLensCollectionViewLayout`: +```swift +UICollectionView(frame: .zero, collectionViewLayout: CarLensCollectionViewLayout()) +``` + +### Step 2 +Subsclass `CarLensCollectionViewCell` and call `configure(topView: UIView, cardView: UIView)` right on the start! +```swift +class CollectionViewCell: CarLensCollectionViewCell { + override init(frame: CGRect) { + super.init(frame: frame) + configure(topView: upperView, cardView: bottomView) + } +} +``` +The sample implementation is available in [Demo](CarLensCollectionViewDemo) project. + +## Installation + +### CocoaPods + +If you're using [CocoaPods](http://cocoapods.org), add the following dependency to your `Podfile`: + +```none +use_frameworks! +pod 'CarLensCollectionViewLayout', '~> 1.0.0' +``` + +### Carthage + +If you're using [Carthage](https://github.com/Carthage/Carthage), add the following dependency to your `Cartfile`: + +```none +github "netguru/CarLensCollectionViewLayout" ~> 1.0.0 +``` + +## About + +This project is made with ❤️ by [Netguru](https://netguru.co). + +### License + +*CarLensCollectionViewLayout* is licensed under the MIT License. See [LICENSE.md](LICENSE.md) for more info. + +## Related links + +- [CarLens Page](https://www.netguru.com/carlens) +- [CarLens iOS](https://github.com/netguru/car-recognition-ios) +- [CarLens in App Store](https://itunes.apple.com/us/app/carlens/id1417168518?mt=8) +- [CarLens Android](https://github.com/netguru/car-recognition-android) +- [CarLens on Google Play](https://play.google.com/store/apps/details?id=co.netguru.android.carrecognition&hl=en) +- [CarLens Story on a Blog](https://www.netguru.com/blog/machine-learning-and-augmented-reality-combined-in-one-sleek-mobile-app-how-we-built-car-lens) diff --git a/bitrise.yml b/bitrise.yml new file mode 100644 index 0000000..5cebc3b --- /dev/null +++ b/bitrise.yml @@ -0,0 +1,74 @@ +# +# bitrise.yml +# +# Copyright © 2017 Netguru Sp. z o.o. All rights reserved. +# + +# CLI metadata + +format_version: 1.3.1 +default_step_lib_source: https://github.com/bitrise-io/bitrise-steplib.git + +# Workflow trigger map + +trigger_map: + + - pull_request_target_branch: develop + workflow: build + + - push_branch: develop + workflow: build + +# Environment configuration + +app: + envs: + - XCODEBUILD_PROJECT: ./CarLensCollectionViewLayout.xcodeproj + +# Workflow declarations + +workflows: + + # Top level build workflows + + build: + envs: + - XCODEBUILD_SCHEME: CarLensCollectionViewLayout + - XCODEBUILD_SCHEME_DEMO: CarLensCollectionViewLayoutDemo + before_run: + - build-lib + - build-demo + - cocoapods-test + after_run: + - deploy-artifacts + + build-lib: + steps: + - script: + title: build-lib + inputs: + - content: xcodebuild -project $XCODEBUILD_PROJECT -scheme $XCODEBUILD_SCHEME -destination 'platform=iOS Simulator,name=iPhone 7 Plus' + + build-demo: + steps: + - script: + title: build-demo + inputs: + - content: xcodebuild -project $XCODEBUILD_PROJECT -scheme $XCODEBUILD_SCHEME_DEMO -destination 'platform=iOS Simulator,name=iPhone 7 Plus' + + cocoapods-test: + steps: + - script: + title: cocoapods-lint + inputs: + # -- allow-warnings should be removed once repository is public + - content: pod lib lint --allow-warnings + + # Deploy workflows + + deploy-artifacts: + steps: + - deploy-to-bitrise-io: + inputs: + - notify_user_groups: none + - is_enable_public_page: false