12 Commits

Author SHA1 Message Date
Yuriy Tolstoguzov 6357f86407 Added swift version to podspec file 2019-11-08 21:59:16 -08:00
Yuriy Tolstoguzov b9e3c2c985 Updated Swift podspec to use separate tag from ObjC releases 2019-11-08 21:54:31 -08:00
Yuriy Tolstoguzov 87cd6ab0a6 Updated README.md to include information about Swift version 2019-11-08 21:51:27 -08:00
Yuriy Tolstoguzov 57ee163f44 Prepared podspec for Swift version 2019-11-08 21:41:14 -08:00
Yuriy Tolstoguzov 2184ae7b2f Added pure Swift implementation of the carousel. Added an example for the Swift implementation 2019-11-04 21:54:00 -08:00
Yuriy Tolstoguzov 2d5798bd94 Updated travis configuration file 2019-10-19 15:37:05 -07:00
Yuriy Tolstoguzov 3626405815 Updated project files in Xcode 11.1 2019-10-19 14:48:22 -07:00
Yuriy Tolstoguzov 768feeb5e7 Added codebeat badge to README 2017-04-25 19:50:07 +03:00
Yuriy Tolstoguzov 973f63db6b Update README.md 2017-04-25 11:38:26 +03:00
Yuriy Tolstoguzov b3a8174e50 Added customization section to README 2017-04-25 11:34:43 +03:00
Yuriy Tolstoguzov 603200a174 Fixed Travis CI builds 2017-04-24 16:07:04 +03:00
Yuriy Tolstoguzov ebfa2361dd Updated README with Carthage installation instructions 2017-04-23 22:13:02 +03:00
46 changed files with 2703 additions and 765 deletions
+6 -3
View File
@@ -1,9 +1,12 @@
osx_image: xcode8.3
osx_image: xcode11.2
language: objective-c
cache: cocoapods
podfile: Example/Podfile
before_install:
- pod install --project-directory=Example
xcode_workspace: Example/ScaledCenterCarousel.xcworkspace
xcode_scheme: ScaledCenterCarousel-Example
xcode_destination: platform=iOS Simulator,OS=13.2,name=iPhone 11
xcode_sdk: iphonesimulator13.2
script:
- set -o pipefail && xcodebuild test -workspace Example/ScaledCenterCarousel.xcworkspace -scheme ScaledCenterCarousel-Example -sdk iphonesimulator10.3 ONLY_ACTIVE_ARCH=NO | xcpretty
- set -o pipefail && xcodebuild test -workspace Example/ScaledCenterCarousel.xcworkspace -scheme ScaledCenterCarousel-Example -sdk iphonesimulator13.2 ONLY_ACTIVE_ARCH=NO -destination 'platform=iOS Simulator,OS=13.2,name=iPhone 11' | xcpretty
- pod lib lint
+2
View File
@@ -1,5 +1,7 @@
use_frameworks!
platform :ios, '8.3'
target 'ScaledCenterCarousel_Example' do
pod 'ScaledCenterCarousel', :path => '../'
+10 -5
View File
@@ -1,6 +1,6 @@
PODS:
- Expecta (1.0.5)
- ScaledCenterCarousel (0.1.0)
- ScaledCenterCarousel (1.0.1)
- Specta (1.0.6)
DEPENDENCIES:
@@ -8,15 +8,20 @@ DEPENDENCIES:
- ScaledCenterCarousel (from `../`)
- Specta
SPEC REPOS:
https://github.com/cocoapods/specs.git:
- Expecta
- Specta
EXTERNAL SOURCES:
ScaledCenterCarousel:
:path: ../
:path: "../"
SPEC CHECKSUMS:
Expecta: e1c022fcd33910b6be89c291d2775b3fe27a89fe
ScaledCenterCarousel: 56f8aedda75dfeae260f5360c3e3ed27be67c58e
ScaledCenterCarousel: f55d4357dc086f64a39a6f6cc1a489d0ea310d55
Specta: f506f3a8361de16bc0dcf3b17b75e269072ba465
PODFILE CHECKSUM: 60029080b9aadec4da8c5b6712e2e396e9549830
PODFILE CHECKSUM: 32d7b0120b7156068dea7567c1a9aadd000320cb
COCOAPODS: 1.2.0
COCOAPODS: 1.5.3
@@ -1,9 +1,10 @@
{
"name": "ScaledCenterCarousel",
"version": "0.1.0",
"version": "1.0.1",
"summary": "A carousel-based layout for UICollectionView with scaled center item.",
"description": "A carousel-based layout for UICollectionView with scaled center item. \nIt also contains paginator to force user to select single item which will be presented exaclty at center of carousel.",
"homepage": "https://github.com/yuriy-tolstoguzov/ScaledCenterCarousel",
"screenshots": "https://raw.githubusercontent.com/yuriy-tolstoguzov/ScaledCenterCarousel/master/Example/Assets/ScaledCenterCarousel.gif",
"license": {
"type": "MIT",
"file": "LICENSE"
@@ -13,8 +14,9 @@
},
"source": {
"git": "https://github.com/yuriy-tolstoguzov/ScaledCenterCarousel.git",
"tag": "0.1.0"
"tag": "1.0.1"
},
"social_media_url": "https://twitter.com/ImOssir",
"platforms": {
"ios": "8.0"
},
+10 -5
View File
@@ -1,6 +1,6 @@
PODS:
- Expecta (1.0.5)
- ScaledCenterCarousel (0.1.0)
- ScaledCenterCarousel (1.0.1)
- Specta (1.0.6)
DEPENDENCIES:
@@ -8,15 +8,20 @@ DEPENDENCIES:
- ScaledCenterCarousel (from `../`)
- Specta
SPEC REPOS:
https://github.com/cocoapods/specs.git:
- Expecta
- Specta
EXTERNAL SOURCES:
ScaledCenterCarousel:
:path: ../
:path: "../"
SPEC CHECKSUMS:
Expecta: e1c022fcd33910b6be89c291d2775b3fe27a89fe
ScaledCenterCarousel: 56f8aedda75dfeae260f5360c3e3ed27be67c58e
ScaledCenterCarousel: f55d4357dc086f64a39a6f6cc1a489d0ea310d55
Specta: f506f3a8361de16bc0dcf3b17b75e269072ba465
PODFILE CHECKSUM: 60029080b9aadec4da8c5b6712e2e396e9549830
PODFILE CHECKSUM: 32d7b0120b7156068dea7567c1a9aadd000320cb
COCOAPODS: 1.2.0
COCOAPODS: 1.5.3
File diff suppressed because it is too large Load Diff
+3 -4
View File
@@ -1,11 +1,10 @@
CONFIGURATION_BUILD_DIR = $PODS_CONFIGURATION_BUILD_DIR/Expecta
CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/Expecta
ENABLE_BITCODE = NO
FRAMEWORK_SEARCH_PATHS = $(inherited) "$(PLATFORM_DIR)/Developer/Library/Frameworks"
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Public"
OTHER_LDFLAGS = -framework "Foundation" -framework "XCTest"
PODS_BUILD_DIR = $BUILD_DIR
PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
PODS_BUILD_DIR = ${BUILD_DIR}
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
PODS_ROOT = ${SRCROOT}
PODS_TARGET_SRCROOT = ${PODS_ROOT}/Expecta
PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}
@@ -1,11 +1,28 @@
#!/bin/sh
set -e
set -u
set -o pipefail
if [ -z ${FRAMEWORKS_FOLDER_PATH+x} ]; then
# If FRAMEWORKS_FOLDER_PATH is not set, then there's nowhere for us to copy
# frameworks to, so exit 0 (signalling the script phase was successful).
exit 0
fi
echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
COCOAPODS_PARALLEL_CODE_SIGN="${COCOAPODS_PARALLEL_CODE_SIGN:-false}"
SWIFT_STDLIB_PATH="${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}"
# Used as a return value for each invocation of `strip_invalid_archs` function.
STRIP_BINARY_RETVAL=0
# This protects against multiple targets copying the same framework dependency at the same time. The solution
# was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html
RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????")
# Copies and strips a vendored framework
install_framework()
{
if [ -r "${BUILT_PRODUCTS_DIR}/$1" ]; then
@@ -23,9 +40,9 @@ install_framework()
source="$(readlink "${source}")"
fi
# use filter instead of exclude so missing patterns dont' throw errors
echo "rsync -av --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\""
rsync -av --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}"
# Use filter instead of exclude so missing patterns don't throw errors.
echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\""
rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}"
local basename
basename="$(basename -s .framework "$1")"
@@ -54,12 +71,40 @@ install_framework()
fi
}
# Copies and strips a vendored dSYM
install_dsym() {
local source="$1"
if [ -r "$source" ]; then
# Copy the dSYM into a the targets temp dir.
echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${DERIVED_FILES_DIR}\""
rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${DERIVED_FILES_DIR}"
local basename
basename="$(basename -s .framework.dSYM "$source")"
binary="${DERIVED_FILES_DIR}/${basename}.framework.dSYM/Contents/Resources/DWARF/${basename}"
# Strip invalid architectures so "fat" simulator / device frameworks work on device
if [[ "$(file "$binary")" == *"Mach-O dSYM companion"* ]]; then
strip_invalid_archs "$binary"
fi
if [[ $STRIP_BINARY_RETVAL == 1 ]]; then
# Move the stripped file into its final destination.
echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${DERIVED_FILES_DIR}/${basename}.framework.dSYM\" \"${DWARF_DSYM_FOLDER_PATH}\""
rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${DERIVED_FILES_DIR}/${basename}.framework.dSYM" "${DWARF_DSYM_FOLDER_PATH}"
else
# The dSYM was not stripped at all, in this case touch a fake folder so the input/output paths from Xcode do not reexecute this script because the file is missing.
touch "${DWARF_DSYM_FOLDER_PATH}/${basename}.framework.dSYM"
fi
fi
}
# Signs a framework with the provided identity
code_sign_if_enabled() {
if [ -n "${EXPANDED_CODE_SIGN_IDENTITY}" -a "${CODE_SIGNING_REQUIRED}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then
if [ -n "${EXPANDED_CODE_SIGN_IDENTITY}" -a "${CODE_SIGNING_REQUIRED:-}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then
# Use the current code_sign_identitiy
echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}"
local code_sign_cmd="/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS} --preserve-metadata=identifier,entitlements '$1'"
local code_sign_cmd="/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS:-} --preserve-metadata=identifier,entitlements '$1'"
if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then
code_sign_cmd="$code_sign_cmd &"
@@ -72,11 +117,19 @@ code_sign_if_enabled() {
# Strip invalid architectures
strip_invalid_archs() {
binary="$1"
# Get architectures for current file
archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | rev)"
# Get architectures for current target binary
binary_archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | awk '{$1=$1;print}' | rev)"
# Intersect them with the architectures we are building for
intersected_archs="$(echo ${ARCHS[@]} ${binary_archs[@]} | tr ' ' '\n' | sort | uniq -d)"
# If there are no archs supported by this binary then warn the user
if [[ -z "$intersected_archs" ]]; then
echo "warning: [CP] Vendored binary '$binary' contains architectures ($binary_archs) none of which match the current build architectures ($ARCHS)."
STRIP_BINARY_RETVAL=0
return
fi
stripped=""
for arch in $archs; do
if ! [[ "${VALID_ARCHS}" == *"$arch"* ]]; then
for arch in $binary_archs; do
if ! [[ "${ARCHS}" == *"$arch"* ]]; then
# Strip non-valid architectures in-place
lipo -remove "$arch" -output "$binary" "$binary" || exit 1
stripped="$stripped $arch"
@@ -85,14 +138,15 @@ strip_invalid_archs() {
if [[ "$stripped" ]]; then
echo "Stripped $binary of architectures:$stripped"
fi
STRIP_BINARY_RETVAL=1
}
if [[ "$CONFIGURATION" == "Debug" ]]; then
install_framework "$BUILT_PRODUCTS_DIR/ScaledCenterCarousel/ScaledCenterCarousel.framework"
install_framework "${BUILT_PRODUCTS_DIR}/ScaledCenterCarousel/ScaledCenterCarousel.framework"
fi
if [[ "$CONFIGURATION" == "Release" ]]; then
install_framework "$BUILT_PRODUCTS_DIR/ScaledCenterCarousel/ScaledCenterCarousel.framework"
install_framework "${BUILT_PRODUCTS_DIR}/ScaledCenterCarousel/ScaledCenterCarousel.framework"
fi
if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then
wait
@@ -1,5 +1,13 @@
#!/bin/sh
set -e
set -u
set -o pipefail
if [ -z ${UNLOCALIZED_RESOURCES_FOLDER_PATH+x} ]; then
# If UNLOCALIZED_RESOURCES_FOLDER_PATH is not set, then there's nowhere for us to copy
# resources to, so exit 0 (signalling the script phase was successful).
exit 0
fi
mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
@@ -8,7 +16,11 @@ RESOURCES_TO_COPY=${PODS_ROOT}/resources-to-copy-${TARGETNAME}.txt
XCASSET_FILES=()
case "${TARGETED_DEVICE_FAMILY}" in
# This protects against multiple targets copying the same framework dependency at the same time. The solution
# was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html
RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????")
case "${TARGETED_DEVICE_FAMILY:-}" in
1,2)
TARGET_DEVICE_ARGS="--target-device ipad --target-device iphone"
;;
@@ -21,6 +33,9 @@ case "${TARGETED_DEVICE_FAMILY}" in
3)
TARGET_DEVICE_ARGS="--target-device tv"
;;
4)
TARGET_DEVICE_ARGS="--target-device watch"
;;
*)
TARGET_DEVICE_ARGS="--target-device mac"
;;
@@ -41,29 +56,29 @@ EOM
fi
case $RESOURCE_PATH in
*.storyboard)
echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}"
echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}" || true
ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS}
;;
*.xib)
echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}"
echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}" || true
ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS}
;;
*.framework)
echo "mkdir -p ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
echo "mkdir -p ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" || true
mkdir -p "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
echo "rsync -av $RESOURCE_PATH ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
rsync -av "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" $RESOURCE_PATH ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" || true
rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
;;
*.xcdatamodel)
echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH"`.mom\""
echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH"`.mom\"" || true
xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodel`.mom"
;;
*.xcdatamodeld)
echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd\""
echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd\"" || true
xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd"
;;
*.xcmappingmodel)
echo "xcrun mapc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm\""
echo "xcrun mapc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm\"" || true
xcrun mapc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm"
;;
*.xcassets)
@@ -71,7 +86,7 @@ EOM
XCASSET_FILES+=("$ABSOLUTE_XCASSET_FILE")
;;
*)
echo "$RESOURCE_PATH"
echo "$RESOURCE_PATH" || true
echo "$RESOURCE_PATH" >> "$RESOURCES_TO_COPY"
;;
esac
@@ -85,7 +100,7 @@ if [[ "${ACTION}" == "install" ]] && [[ "${SKIP_INSTALL}" == "NO" ]]; then
fi
rm -f "$RESOURCES_TO_COPY"
if [[ -n "${WRAPPER_EXTENSION}" ]] && [ "`xcrun --find actool`" ] && [ -n "$XCASSET_FILES" ]
if [[ -n "${WRAPPER_EXTENSION}" ]] && [ "`xcrun --find actool`" ] && [ -n "${XCASSET_FILES:-}" ]
then
# Find all other xcassets (this unfortunately includes those of path pods and other targets).
OTHER_XCASSETS=$(find "$PWD" -iname "*.xcassets" -type d)
@@ -95,5 +110,9 @@ then
fi
done <<<"$OTHER_XCASSETS"
printf "%s\0" "${XCASSET_FILES[@]}" | xargs -0 xcrun actool --output-format human-readable-text --notices --warnings --platform "${PLATFORM_NAME}" --minimum-deployment-target "${!DEPLOYMENT_TARGET_SETTING_NAME}" ${TARGET_DEVICE_ARGS} --compress-pngs --compile "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
if [ -z ${ASSETCATALOG_COMPILER_APPICON_NAME+x} ]; then
printf "%s\0" "${XCASSET_FILES[@]}" | xargs -0 xcrun actool --output-format human-readable-text --notices --warnings --platform "${PLATFORM_NAME}" --minimum-deployment-target "${!DEPLOYMENT_TARGET_SETTING_NAME}" ${TARGET_DEVICE_ARGS} --compress-pngs --compile "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
else
printf "%s\0" "${XCASSET_FILES[@]}" | xargs -0 xcrun actool --output-format human-readable-text --notices --warnings --platform "${PLATFORM_NAME}" --minimum-deployment-target "${!DEPLOYMENT_TARGET_SETTING_NAME}" ${TARGET_DEVICE_ARGS} --compress-pngs --compile "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" --app-icon "${ASSETCATALOG_COMPILER_APPICON_NAME}" --output-partial-info-plist "${TARGET_TEMP_DIR}/assetcatalog_generated_info_cocoapods.plist"
fi
fi
@@ -1,8 +1,9 @@
FRAMEWORK_SEARCH_PATHS = $(inherited) "$PODS_CONFIGURATION_BUILD_DIR/ScaledCenterCarousel"
FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/ScaledCenterCarousel"
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks'
OTHER_CFLAGS = $(inherited) -iquote "$PODS_CONFIGURATION_BUILD_DIR/ScaledCenterCarousel/ScaledCenterCarousel.framework/Headers"
OTHER_CFLAGS = $(inherited) -iquote "${PODS_CONFIGURATION_BUILD_DIR}/ScaledCenterCarousel/ScaledCenterCarousel.framework/Headers"
OTHER_LDFLAGS = $(inherited) -framework "ScaledCenterCarousel"
PODS_BUILD_DIR = $BUILD_DIR
PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
PODS_BUILD_DIR = ${BUILD_DIR}
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
PODS_PODFILE_DIR_PATH = ${SRCROOT}/.
PODS_ROOT = ${SRCROOT}/Pods
@@ -1,8 +1,9 @@
FRAMEWORK_SEARCH_PATHS = $(inherited) "$PODS_CONFIGURATION_BUILD_DIR/ScaledCenterCarousel"
FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/ScaledCenterCarousel"
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks'
OTHER_CFLAGS = $(inherited) -iquote "$PODS_CONFIGURATION_BUILD_DIR/ScaledCenterCarousel/ScaledCenterCarousel.framework/Headers"
OTHER_CFLAGS = $(inherited) -iquote "${PODS_CONFIGURATION_BUILD_DIR}/ScaledCenterCarousel/ScaledCenterCarousel.framework/Headers"
OTHER_LDFLAGS = $(inherited) -framework "ScaledCenterCarousel"
PODS_BUILD_DIR = $BUILD_DIR
PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
PODS_BUILD_DIR = ${BUILD_DIR}
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
PODS_PODFILE_DIR_PATH = ${SRCROOT}/.
PODS_ROOT = ${SRCROOT}/Pods
@@ -1,11 +1,28 @@
#!/bin/sh
set -e
set -u
set -o pipefail
if [ -z ${FRAMEWORKS_FOLDER_PATH+x} ]; then
# If FRAMEWORKS_FOLDER_PATH is not set, then there's nowhere for us to copy
# frameworks to, so exit 0 (signalling the script phase was successful).
exit 0
fi
echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
COCOAPODS_PARALLEL_CODE_SIGN="${COCOAPODS_PARALLEL_CODE_SIGN:-false}"
SWIFT_STDLIB_PATH="${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}"
# Used as a return value for each invocation of `strip_invalid_archs` function.
STRIP_BINARY_RETVAL=0
# This protects against multiple targets copying the same framework dependency at the same time. The solution
# was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html
RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????")
# Copies and strips a vendored framework
install_framework()
{
if [ -r "${BUILT_PRODUCTS_DIR}/$1" ]; then
@@ -23,9 +40,9 @@ install_framework()
source="$(readlink "${source}")"
fi
# use filter instead of exclude so missing patterns dont' throw errors
echo "rsync -av --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\""
rsync -av --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}"
# Use filter instead of exclude so missing patterns don't throw errors.
echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\""
rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}"
local basename
basename="$(basename -s .framework "$1")"
@@ -54,12 +71,40 @@ install_framework()
fi
}
# Copies and strips a vendored dSYM
install_dsym() {
local source="$1"
if [ -r "$source" ]; then
# Copy the dSYM into a the targets temp dir.
echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${DERIVED_FILES_DIR}\""
rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${DERIVED_FILES_DIR}"
local basename
basename="$(basename -s .framework.dSYM "$source")"
binary="${DERIVED_FILES_DIR}/${basename}.framework.dSYM/Contents/Resources/DWARF/${basename}"
# Strip invalid architectures so "fat" simulator / device frameworks work on device
if [[ "$(file "$binary")" == *"Mach-O dSYM companion"* ]]; then
strip_invalid_archs "$binary"
fi
if [[ $STRIP_BINARY_RETVAL == 1 ]]; then
# Move the stripped file into its final destination.
echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${DERIVED_FILES_DIR}/${basename}.framework.dSYM\" \"${DWARF_DSYM_FOLDER_PATH}\""
rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${DERIVED_FILES_DIR}/${basename}.framework.dSYM" "${DWARF_DSYM_FOLDER_PATH}"
else
# The dSYM was not stripped at all, in this case touch a fake folder so the input/output paths from Xcode do not reexecute this script because the file is missing.
touch "${DWARF_DSYM_FOLDER_PATH}/${basename}.framework.dSYM"
fi
fi
}
# Signs a framework with the provided identity
code_sign_if_enabled() {
if [ -n "${EXPANDED_CODE_SIGN_IDENTITY}" -a "${CODE_SIGNING_REQUIRED}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then
if [ -n "${EXPANDED_CODE_SIGN_IDENTITY}" -a "${CODE_SIGNING_REQUIRED:-}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then
# Use the current code_sign_identitiy
echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}"
local code_sign_cmd="/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS} --preserve-metadata=identifier,entitlements '$1'"
local code_sign_cmd="/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS:-} --preserve-metadata=identifier,entitlements '$1'"
if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then
code_sign_cmd="$code_sign_cmd &"
@@ -72,11 +117,19 @@ code_sign_if_enabled() {
# Strip invalid architectures
strip_invalid_archs() {
binary="$1"
# Get architectures for current file
archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | rev)"
# Get architectures for current target binary
binary_archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | awk '{$1=$1;print}' | rev)"
# Intersect them with the architectures we are building for
intersected_archs="$(echo ${ARCHS[@]} ${binary_archs[@]} | tr ' ' '\n' | sort | uniq -d)"
# If there are no archs supported by this binary then warn the user
if [[ -z "$intersected_archs" ]]; then
echo "warning: [CP] Vendored binary '$binary' contains architectures ($binary_archs) none of which match the current build architectures ($ARCHS)."
STRIP_BINARY_RETVAL=0
return
fi
stripped=""
for arch in $archs; do
if ! [[ "${VALID_ARCHS}" == *"$arch"* ]]; then
for arch in $binary_archs; do
if ! [[ "${ARCHS}" == *"$arch"* ]]; then
# Strip non-valid architectures in-place
lipo -remove "$arch" -output "$binary" "$binary" || exit 1
stripped="$stripped $arch"
@@ -85,16 +138,17 @@ strip_invalid_archs() {
if [[ "$stripped" ]]; then
echo "Stripped $binary of architectures:$stripped"
fi
STRIP_BINARY_RETVAL=1
}
if [[ "$CONFIGURATION" == "Debug" ]]; then
install_framework "$BUILT_PRODUCTS_DIR/Expecta/Expecta.framework"
install_framework "$BUILT_PRODUCTS_DIR/Specta/Specta.framework"
install_framework "${BUILT_PRODUCTS_DIR}/Expecta/Expecta.framework"
install_framework "${BUILT_PRODUCTS_DIR}/Specta/Specta.framework"
fi
if [[ "$CONFIGURATION" == "Release" ]]; then
install_framework "$BUILT_PRODUCTS_DIR/Expecta/Expecta.framework"
install_framework "$BUILT_PRODUCTS_DIR/Specta/Specta.framework"
install_framework "${BUILT_PRODUCTS_DIR}/Expecta/Expecta.framework"
install_framework "${BUILT_PRODUCTS_DIR}/Specta/Specta.framework"
fi
if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then
wait
@@ -1,5 +1,13 @@
#!/bin/sh
set -e
set -u
set -o pipefail
if [ -z ${UNLOCALIZED_RESOURCES_FOLDER_PATH+x} ]; then
# If UNLOCALIZED_RESOURCES_FOLDER_PATH is not set, then there's nowhere for us to copy
# resources to, so exit 0 (signalling the script phase was successful).
exit 0
fi
mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
@@ -8,7 +16,11 @@ RESOURCES_TO_COPY=${PODS_ROOT}/resources-to-copy-${TARGETNAME}.txt
XCASSET_FILES=()
case "${TARGETED_DEVICE_FAMILY}" in
# This protects against multiple targets copying the same framework dependency at the same time. The solution
# was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html
RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????")
case "${TARGETED_DEVICE_FAMILY:-}" in
1,2)
TARGET_DEVICE_ARGS="--target-device ipad --target-device iphone"
;;
@@ -21,6 +33,9 @@ case "${TARGETED_DEVICE_FAMILY}" in
3)
TARGET_DEVICE_ARGS="--target-device tv"
;;
4)
TARGET_DEVICE_ARGS="--target-device watch"
;;
*)
TARGET_DEVICE_ARGS="--target-device mac"
;;
@@ -41,29 +56,29 @@ EOM
fi
case $RESOURCE_PATH in
*.storyboard)
echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}"
echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}" || true
ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS}
;;
*.xib)
echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}"
echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}" || true
ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS}
;;
*.framework)
echo "mkdir -p ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
echo "mkdir -p ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" || true
mkdir -p "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
echo "rsync -av $RESOURCE_PATH ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
rsync -av "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" $RESOURCE_PATH ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" || true
rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
;;
*.xcdatamodel)
echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH"`.mom\""
echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH"`.mom\"" || true
xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodel`.mom"
;;
*.xcdatamodeld)
echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd\""
echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd\"" || true
xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd"
;;
*.xcmappingmodel)
echo "xcrun mapc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm\""
echo "xcrun mapc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm\"" || true
xcrun mapc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm"
;;
*.xcassets)
@@ -71,7 +86,7 @@ EOM
XCASSET_FILES+=("$ABSOLUTE_XCASSET_FILE")
;;
*)
echo "$RESOURCE_PATH"
echo "$RESOURCE_PATH" || true
echo "$RESOURCE_PATH" >> "$RESOURCES_TO_COPY"
;;
esac
@@ -85,7 +100,7 @@ if [[ "${ACTION}" == "install" ]] && [[ "${SKIP_INSTALL}" == "NO" ]]; then
fi
rm -f "$RESOURCES_TO_COPY"
if [[ -n "${WRAPPER_EXTENSION}" ]] && [ "`xcrun --find actool`" ] && [ -n "$XCASSET_FILES" ]
if [[ -n "${WRAPPER_EXTENSION}" ]] && [ "`xcrun --find actool`" ] && [ -n "${XCASSET_FILES:-}" ]
then
# Find all other xcassets (this unfortunately includes those of path pods and other targets).
OTHER_XCASSETS=$(find "$PWD" -iname "*.xcassets" -type d)
@@ -95,5 +110,9 @@ then
fi
done <<<"$OTHER_XCASSETS"
printf "%s\0" "${XCASSET_FILES[@]}" | xargs -0 xcrun actool --output-format human-readable-text --notices --warnings --platform "${PLATFORM_NAME}" --minimum-deployment-target "${!DEPLOYMENT_TARGET_SETTING_NAME}" ${TARGET_DEVICE_ARGS} --compress-pngs --compile "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
if [ -z ${ASSETCATALOG_COMPILER_APPICON_NAME+x} ]; then
printf "%s\0" "${XCASSET_FILES[@]}" | xargs -0 xcrun actool --output-format human-readable-text --notices --warnings --platform "${PLATFORM_NAME}" --minimum-deployment-target "${!DEPLOYMENT_TARGET_SETTING_NAME}" ${TARGET_DEVICE_ARGS} --compress-pngs --compile "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
else
printf "%s\0" "${XCASSET_FILES[@]}" | xargs -0 xcrun actool --output-format human-readable-text --notices --warnings --platform "${PLATFORM_NAME}" --minimum-deployment-target "${!DEPLOYMENT_TARGET_SETTING_NAME}" ${TARGET_DEVICE_ARGS} --compress-pngs --compile "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" --app-icon "${ASSETCATALOG_COMPILER_APPICON_NAME}" --output-partial-info-plist "${TARGET_TEMP_DIR}/assetcatalog_generated_info_cocoapods.plist"
fi
fi
@@ -1,8 +1,9 @@
FRAMEWORK_SEARCH_PATHS = $(inherited) $(PLATFORM_DIR)/Developer/Library/Frameworks "$PODS_CONFIGURATION_BUILD_DIR/Expecta" "$PODS_CONFIGURATION_BUILD_DIR/Specta" "$PODS_CONFIGURATION_BUILD_DIR/ScaledCenterCarousel"
FRAMEWORK_SEARCH_PATHS = $(inherited) $(PLATFORM_DIR)/Developer/Library/Frameworks "${PODS_CONFIGURATION_BUILD_DIR}/Expecta" "${PODS_CONFIGURATION_BUILD_DIR}/Specta" "${PODS_CONFIGURATION_BUILD_DIR}/ScaledCenterCarousel"
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks'
OTHER_CFLAGS = $(inherited) -iquote "$PODS_CONFIGURATION_BUILD_DIR/Expecta/Expecta.framework/Headers" -iquote "$PODS_CONFIGURATION_BUILD_DIR/Specta/Specta.framework/Headers" $(inherited) -iquote "$PODS_CONFIGURATION_BUILD_DIR/ScaledCenterCarousel/ScaledCenterCarousel.framework/Headers"
OTHER_CFLAGS = $(inherited) -iquote "${PODS_CONFIGURATION_BUILD_DIR}/Expecta/Expecta.framework/Headers" -iquote "${PODS_CONFIGURATION_BUILD_DIR}/Specta/Specta.framework/Headers" -iquote "${PODS_CONFIGURATION_BUILD_DIR}/ScaledCenterCarousel/ScaledCenterCarousel.framework/Headers"
OTHER_LDFLAGS = $(inherited) -framework "Expecta" -framework "Specta"
PODS_BUILD_DIR = $BUILD_DIR
PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
PODS_BUILD_DIR = ${BUILD_DIR}
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
PODS_PODFILE_DIR_PATH = ${SRCROOT}/.
PODS_ROOT = ${SRCROOT}/Pods
@@ -1,8 +1,9 @@
FRAMEWORK_SEARCH_PATHS = $(inherited) $(PLATFORM_DIR)/Developer/Library/Frameworks "$PODS_CONFIGURATION_BUILD_DIR/Expecta" "$PODS_CONFIGURATION_BUILD_DIR/Specta" "$PODS_CONFIGURATION_BUILD_DIR/ScaledCenterCarousel"
FRAMEWORK_SEARCH_PATHS = $(inherited) $(PLATFORM_DIR)/Developer/Library/Frameworks "${PODS_CONFIGURATION_BUILD_DIR}/Expecta" "${PODS_CONFIGURATION_BUILD_DIR}/Specta" "${PODS_CONFIGURATION_BUILD_DIR}/ScaledCenterCarousel"
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks'
OTHER_CFLAGS = $(inherited) -iquote "$PODS_CONFIGURATION_BUILD_DIR/Expecta/Expecta.framework/Headers" -iquote "$PODS_CONFIGURATION_BUILD_DIR/Specta/Specta.framework/Headers" $(inherited) -iquote "$PODS_CONFIGURATION_BUILD_DIR/ScaledCenterCarousel/ScaledCenterCarousel.framework/Headers"
OTHER_CFLAGS = $(inherited) -iquote "${PODS_CONFIGURATION_BUILD_DIR}/Expecta/Expecta.framework/Headers" -iquote "${PODS_CONFIGURATION_BUILD_DIR}/Specta/Specta.framework/Headers" -iquote "${PODS_CONFIGURATION_BUILD_DIR}/ScaledCenterCarousel/ScaledCenterCarousel.framework/Headers"
OTHER_LDFLAGS = $(inherited) -framework "Expecta" -framework "Specta"
PODS_BUILD_DIR = $BUILD_DIR
PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
PODS_BUILD_DIR = ${BUILD_DIR}
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
PODS_PODFILE_DIR_PATH = ${SRCROOT}/.
PODS_ROOT = ${SRCROOT}/Pods
@@ -15,7 +15,7 @@
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>0.1.0</string>
<string>1.0.1</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
@@ -1,9 +1,8 @@
CONFIGURATION_BUILD_DIR = $PODS_CONFIGURATION_BUILD_DIR/ScaledCenterCarousel
CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/ScaledCenterCarousel
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Public"
OTHER_LDFLAGS = -framework "UIKit"
PODS_BUILD_DIR = $BUILD_DIR
PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
PODS_BUILD_DIR = ${BUILD_DIR}
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
PODS_ROOT = ${SRCROOT}
PODS_TARGET_SRCROOT = ${PODS_ROOT}/../..
PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}
+3 -4
View File
@@ -1,11 +1,10 @@
CONFIGURATION_BUILD_DIR = $PODS_CONFIGURATION_BUILD_DIR/Specta
CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/Specta
ENABLE_BITCODE = NO
FRAMEWORK_SEARCH_PATHS = $(inherited) "$(PLATFORM_DIR)/Developer/Library/Frameworks"
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Public"
OTHER_LDFLAGS = -framework "Foundation" -framework "XCTest"
PODS_BUILD_DIR = $BUILD_DIR
PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
PODS_BUILD_DIR = ${BUILD_DIR}
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
PODS_ROOT = ${SRCROOT}
PODS_TARGET_SRCROOT = ${PODS_ROOT}/Specta
PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}
@@ -223,7 +223,6 @@
6003F587195388D20070C39A /* Frameworks */,
6003F588195388D20070C39A /* Resources */,
F76140CB44EF7563E9D7156A /* [CP] Embed Pods Frameworks */,
46B806111ED61FA76D428BF6 /* [CP] Copy Pods Resources */,
);
buildRules = (
);
@@ -243,7 +242,6 @@
6003F5AB195388D20070C39A /* Frameworks */,
6003F5AC195388D20070C39A /* Resources */,
41C005B6526ECF75FD91EC6A /* [CP] Embed Pods Frameworks */,
6901919B9AE8B00256C0EC2B /* [CP] Copy Pods Resources */,
);
buildRules = (
);
@@ -262,7 +260,7 @@
isa = PBXProject;
attributes = {
CLASSPREFIX = YT;
LastUpgradeCheck = 0820;
LastUpgradeCheck = 1110;
ORGANIZATIONNAME = "yuriy-tolstoguzov";
TargetAttributes = {
6003F589195388D20070C39A = {
@@ -279,6 +277,7 @@
developmentRegion = English;
hasScannedForEncodings = 0;
knownRegions = (
English,
en,
Base,
);
@@ -322,58 +321,36 @@
files = (
);
inputPaths = (
"${SRCROOT}/Pods/Target Support Files/Pods-ScaledCenterCarousel_Tests/Pods-ScaledCenterCarousel_Tests-frameworks.sh",
"${BUILT_PRODUCTS_DIR}/Expecta/Expecta.framework",
"${BUILT_PRODUCTS_DIR}/Specta/Specta.framework",
);
name = "[CP] Embed Pods Frameworks";
outputPaths = (
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Expecta.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Specta.framework",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-ScaledCenterCarousel_Tests/Pods-ScaledCenterCarousel_Tests-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
46B806111ED61FA76D428BF6 /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "[CP] Copy Pods Resources";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-ScaledCenterCarousel_Example/Pods-ScaledCenterCarousel_Example-resources.sh\"\n";
showEnvVarsInLog = 0;
};
6901919B9AE8B00256C0EC2B /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "[CP] Copy Pods Resources";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-ScaledCenterCarousel_Tests/Pods-ScaledCenterCarousel_Tests-resources.sh\"\n";
showEnvVarsInLog = 0;
};
972BD431F5D3934EFB6FF50A /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
"${PODS_ROOT}/Manifest.lock",
);
name = "[CP] Check Pods Manifest.lock";
outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-ScaledCenterCarousel_Example-checkManifestLockResult.txt",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n";
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
9EDB10FB4388792527478DBF /* [CP] Check Pods Manifest.lock */ = {
@@ -382,13 +359,16 @@
files = (
);
inputPaths = (
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
"${PODS_ROOT}/Manifest.lock",
);
name = "[CP] Check Pods Manifest.lock";
outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-ScaledCenterCarousel_Tests-checkManifestLockResult.txt",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n";
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
F76140CB44EF7563E9D7156A /* [CP] Embed Pods Frameworks */ = {
@@ -397,9 +377,12 @@
files = (
);
inputPaths = (
"${SRCROOT}/Pods/Target Support Files/Pods-ScaledCenterCarousel_Example/Pods-ScaledCenterCarousel_Example-frameworks.sh",
"${BUILT_PRODUCTS_DIR}/ScaledCenterCarousel/ScaledCenterCarousel.framework",
);
name = "[CP] Embed Pods Frameworks";
outputPaths = (
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/ScaledCenterCarousel.framework",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
@@ -472,18 +455,27 @@
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = 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_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_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
@@ -517,18 +509,27 @@
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = 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_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_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0820"
LastUpgradeVersion = "1110"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
@@ -27,6 +27,15 @@
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "6003F589195388D20070C39A"
BuildableName = "ScaledCenterCarousel_Example.app"
BlueprintName = "ScaledCenterCarousel_Example"
ReferencedContainer = "container:ScaledCenterCarousel.xcodeproj">
</BuildableReference>
</MacroExpansion>
<Testables>
<TestableReference
skipped = "NO">
@@ -39,17 +48,6 @@
</BuildableReference>
</TestableReference>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "6003F589195388D20070C39A"
BuildableName = "ScaledCenterCarousel_Example.app"
BlueprintName = "ScaledCenterCarousel_Example"
ReferencedContainer = "container:ScaledCenterCarousel.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
@@ -71,8 +69,6 @@
ReferencedContainer = "container:ScaledCenterCarousel.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>
+60 -3
View File
@@ -1,5 +1,6 @@
# ScaledCenterCarousel
[![codebeat badge](https://codebeat.co/badges/aeac52c6-2b7d-4039-a01b-e2ff9ca45803)](https://codebeat.co/projects/github-com-yuriy-tolstoguzov-scaledcentercarousel-master)
[![CI Status](http://img.shields.io/travis/yuriy-tolstoguzov/ScaledCenterCarousel.svg?style=flat)](https://travis-ci.org/yuriy-tolstoguzov/ScaledCenterCarousel)
[![Version](https://img.shields.io/cocoapods/v/ScaledCenterCarousel.svg?style=flat)](http://cocoapods.org/pods/ScaledCenterCarousel)
[![License](https://img.shields.io/cocoapods/l/ScaledCenterCarousel.svg?style=flat)](http://cocoapods.org/pods/ScaledCenterCarousel)
@@ -15,23 +16,79 @@ Before using library, make sure to have a look at Example project.
To run the example project, clone the repo, and run `pod install` from the Example directory first.
## Customization
The library is made purposely simple, but there are number of ways you can customize it. Most of properties could be set from IB via `IBInspectable`.
### Layout
- `centerCellHeight/centerCell.height` - The height of cell at the center position.
- `centerCellWidth/centerCell.width` - The width of cell at the center position.
- `normalCellHeight/normalCell.height` - The height of cells that far enough from the center position.
- `normalCellWidth/normalCell.width` - The width of cells that far enough from the center position.
- `proposedContentOffset` - The content offset that will be set once after next data source change. Think about adding items after you get them from web service and you want to pre-select one of them.
### Pagination (UICollectionViewDelegate)
If you want user to be able to select only one item at a time, you probably will use built-in `YTScaledCenterCarouselPaginator/ScaledCenterCarouselPaginator` and set it as your `UICollectionView` delegate.
It has next delegate methods:
- `-carousel:didSelectElementAtIndex: / carousel(_,didSelectElementAt)`
- `-carousel:didScrollToVisibleCells: / carousel(_,didScrollTo)`
If your data source will adopt `YTScaledCenterCarouselDataSource/ScaledCenterCarouselDataSource` protocol. It will always know what item is selected now and can use this knowledge to add some customization to selected cells. Also it encouraged to check cell selected state, because it's updated accordingly as well.
## Requirements
iOS 7+
## Installation
ScaledCenterCarousel is available through [CocoaPods](http://cocoapods.org). To install
it, simply add the following line to your Podfile:
### [CocoaPods](http://cocoapods.org)
To install
it through [CocoaPods](http://cocoapods.org), simply add the following line to your Podfile:
```ruby
pod "ScaledCenterCarousel"
pod "ScaledCenterCarousel" # ObjC version
pod "ScaledCenterCarouselSwift" # Swift version
```
Run update command in your terminal:
```bash
$ pod install
```
### [Carthage](https://github.com/Carthage/Carthage)
Add this line to your Cartfile:
```ruby
github "yuriy-tolstoguzov/ScaledCenterCarousel"
```
Run update command in your terminal:
```bash
$ carthage update
```
## Author
yuriy-tolstoguzov, Yuriy.Tolstoguzov@gmail.com
## Contribution
If you want to contribute, here is couple of topics I have in mind:
- [X] Swift migration
- [ ] Support for vertical layout
- [ ] Documentation improvements
Feel free to make a pull requests or contact me if you have questions.
## License
ScaledCenterCarousel is available under the MIT license. See the LICENSE file for more info.
+21 -2
View File
@@ -128,7 +128,7 @@
1114799B1EAD2BD100F6C7D5 /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 0820;
LastUpgradeCheck = 1110;
ORGANIZATIONNAME = "Yuriy Tolstoguzov";
TargetAttributes = {
111479A31EAD2BD100F6C7D5 = {
@@ -140,10 +140,11 @@
};
buildConfigurationList = 1114799E1EAD2BD100F6C7D5 /* Build configuration list for PBXProject "ScaledCenterCarousel" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = English;
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
en,
Base,
);
mainGroup = 1114799A1EAD2BD100F6C7D5;
productRefGroup = 111479A51EAD2BD100F6C7D5 /* Products */;
@@ -182,20 +183,29 @@
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = 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_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
@@ -233,20 +243,29 @@
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = 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_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0820"
LastUpgradeVersion = "1110"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
@@ -29,8 +29,6 @@
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
@@ -51,8 +49,6 @@
ReferencedContainer = "container:ScaledCenterCarousel.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>
+23
View File
@@ -0,0 +1,23 @@
Pod::Spec.new do |spec|
spec.name = "ScaledCenterCarouselSwift"
spec.version = "1.0.0"
spec.summary = "A carousel-based layout for UICollectionView with scaled center item."
spec.description = <<-DESC
A carousel-based layout for UICollectionView with scaled center item.
It also contains paginator to force user to select single item which will be presented exaclty at center of carousel.
DESC
spec.homepage = 'https://github.com/yuriy-tolstoguzov/ScaledCenterCarousel'
spec.screenshots = 'https://raw.githubusercontent.com/yuriy-tolstoguzov/ScaledCenterCarousel/master/Example/Assets/ScaledCenterCarousel.gif'
spec.license = { :type => "MIT", :file => "LICENSE" }
spec.author = { 'yuriy-tolstoguzov' => 'Yuriy.Tolstoguzov@gmail.com' }
spec.social_media_url = 'https://twitter.com/ImOssir'
spec.ios.deployment_target = "8.0"
spec.swift_version = "5.0"
spec.source = { :git => 'https://github.com/yuriy-tolstoguzov/ScaledCenterCarousel.git', :tag => "#{spec.version}-Swift" }
spec.source_files = 'Swift/ScaledCenterCarousel/Classes/**/*'
spec.frameworks = 'UIKit'
end
@@ -0,0 +1,421 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 50;
objects = {
/* Begin PBXBuildFile section */
F69B819C2376851F001ED129 /* ScaledCenterCarousel.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F69B8199237684FA001ED129 /* ScaledCenterCarousel.framework */; };
F6E29B91235D059900E10EA7 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = F6E29B90235D059900E10EA7 /* AppDelegate.swift */; };
F6E29B97235D059B00E10EA7 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = F6E29B96235D059B00E10EA7 /* Assets.xcassets */; };
F6E29B9D235D059B00E10EA7 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F6E29B9B235D059B00E10EA7 /* LaunchScreen.storyboard */; };
F6E29BA5235D171C00E10EA7 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F6E29BA4235D171C00E10EA7 /* Main.storyboard */; };
F6E29BA7235D17BD00E10EA7 /* CarouselCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = F6E29BA6235D17BD00E10EA7 /* CarouselCell.swift */; };
F6E29BA9235D18EC00E10EA7 /* CarouselDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = F6E29BA8235D18EC00E10EA7 /* CarouselDataSource.swift */; };
F6E29BAB235D192C00E10EA7 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F6E29BAA235D192C00E10EA7 /* ViewController.swift */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
F69B8198237684FA001ED129 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = F69B8194237684FA001ED129 /* ScaledCenterCarousel.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = F6CCE38A235BC826001CC2E5;
remoteInfo = ScaledCenterCarousel;
};
F69B819A23768518001ED129 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = F69B8194237684FA001ED129 /* ScaledCenterCarousel.xcodeproj */;
proxyType = 1;
remoteGlobalIDString = F6CCE389235BC826001CC2E5;
remoteInfo = ScaledCenterCarousel;
};
/* End PBXContainerItemProxy section */
/* Begin PBXCopyFilesBuildPhase section */
F6E29BB0235D1C4600E10EA7 /* Embed Frameworks */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "";
dstSubfolderSpec = 10;
files = (
);
name = "Embed Frameworks";
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
F69B8194237684FA001ED129 /* ScaledCenterCarousel.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = ScaledCenterCarousel.xcodeproj; path = ../../ScaledCenterCarousel.xcodeproj; sourceTree = "<group>"; };
F6E29B8D235D059900E10EA7 /* ScaledCenterCarouselSwiftExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ScaledCenterCarouselSwiftExample.app; sourceTree = BUILT_PRODUCTS_DIR; };
F6E29B90235D059900E10EA7 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
F6E29B96235D059B00E10EA7 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
F6E29B9C235D059B00E10EA7 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
F6E29B9E235D059B00E10EA7 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
F6E29BA4235D171C00E10EA7 /* Main.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = Main.storyboard; sourceTree = "<group>"; };
F6E29BA6235D17BD00E10EA7 /* CarouselCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CarouselCell.swift; sourceTree = "<group>"; };
F6E29BA8235D18EC00E10EA7 /* CarouselDataSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CarouselDataSource.swift; sourceTree = "<group>"; };
F6E29BAA235D192C00E10EA7 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
F6E29B8A235D059900E10EA7 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
F69B819C2376851F001ED129 /* ScaledCenterCarousel.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
F69B8195237684FA001ED129 /* Products */ = {
isa = PBXGroup;
children = (
F69B8199237684FA001ED129 /* ScaledCenterCarousel.framework */,
);
name = Products;
sourceTree = "<group>";
};
F6E29B84235D059900E10EA7 = {
isa = PBXGroup;
children = (
F6E29B8F235D059900E10EA7 /* ScaledCenterCarouselSwiftExample */,
F6E29B8E235D059900E10EA7 /* Products */,
F6E29BAC235D1C4500E10EA7 /* Frameworks */,
);
sourceTree = "<group>";
};
F6E29B8E235D059900E10EA7 /* Products */ = {
isa = PBXGroup;
children = (
F6E29B8D235D059900E10EA7 /* ScaledCenterCarouselSwiftExample.app */,
);
name = Products;
sourceTree = "<group>";
};
F6E29B8F235D059900E10EA7 /* ScaledCenterCarouselSwiftExample */ = {
isa = PBXGroup;
children = (
F6E29B90235D059900E10EA7 /* AppDelegate.swift */,
F6E29B96235D059B00E10EA7 /* Assets.xcassets */,
F6E29B9B235D059B00E10EA7 /* LaunchScreen.storyboard */,
F6E29B9E235D059B00E10EA7 /* Info.plist */,
F6E29BA4235D171C00E10EA7 /* Main.storyboard */,
F6E29BA6235D17BD00E10EA7 /* CarouselCell.swift */,
F6E29BA8235D18EC00E10EA7 /* CarouselDataSource.swift */,
F6E29BAA235D192C00E10EA7 /* ViewController.swift */,
);
path = ScaledCenterCarouselSwiftExample;
sourceTree = "<group>";
};
F6E29BAC235D1C4500E10EA7 /* Frameworks */ = {
isa = PBXGroup;
children = (
F69B8194237684FA001ED129 /* ScaledCenterCarousel.xcodeproj */,
);
name = Frameworks;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
F6E29B8C235D059900E10EA7 /* ScaledCenterCarouselSwiftExample */ = {
isa = PBXNativeTarget;
buildConfigurationList = F6E29BA1235D059B00E10EA7 /* Build configuration list for PBXNativeTarget "ScaledCenterCarouselSwiftExample" */;
buildPhases = (
F6E29B89235D059900E10EA7 /* Sources */,
F6E29B8A235D059900E10EA7 /* Frameworks */,
F6E29B8B235D059900E10EA7 /* Resources */,
F6E29BB0235D1C4600E10EA7 /* Embed Frameworks */,
);
buildRules = (
);
dependencies = (
F69B819B23768518001ED129 /* PBXTargetDependency */,
);
name = ScaledCenterCarouselSwiftExample;
productName = ScaledCenterCarouselSwiftExample;
productReference = F6E29B8D235D059900E10EA7 /* ScaledCenterCarouselSwiftExample.app */;
productType = "com.apple.product-type.application";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
F6E29B85235D059900E10EA7 /* Project object */ = {
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 1110;
LastUpgradeCheck = 1110;
ORGANIZATIONNAME = "Yuriy Tolstoguzov";
TargetAttributes = {
F6E29B8C235D059900E10EA7 = {
CreatedOnToolsVersion = 11.1;
};
};
};
buildConfigurationList = F6E29B88235D059900E10EA7 /* Build configuration list for PBXProject "ScaledCenterCarouselSwiftExample" */;
compatibilityVersion = "Xcode 9.3";
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
en,
Base,
);
mainGroup = F6E29B84235D059900E10EA7;
productRefGroup = F6E29B8E235D059900E10EA7 /* Products */;
projectDirPath = "";
projectReferences = (
{
ProductGroup = F69B8195237684FA001ED129 /* Products */;
ProjectRef = F69B8194237684FA001ED129 /* ScaledCenterCarousel.xcodeproj */;
},
);
projectRoot = "";
targets = (
F6E29B8C235D059900E10EA7 /* ScaledCenterCarouselSwiftExample */,
);
};
/* End PBXProject section */
/* Begin PBXReferenceProxy section */
F69B8199237684FA001ED129 /* ScaledCenterCarousel.framework */ = {
isa = PBXReferenceProxy;
fileType = wrapper.framework;
path = ScaledCenterCarousel.framework;
remoteRef = F69B8198237684FA001ED129 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
/* End PBXReferenceProxy section */
/* Begin PBXResourcesBuildPhase section */
F6E29B8B235D059900E10EA7 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
F6E29B9D235D059B00E10EA7 /* LaunchScreen.storyboard in Resources */,
F6E29BA5235D171C00E10EA7 /* Main.storyboard in Resources */,
F6E29B97235D059B00E10EA7 /* Assets.xcassets in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
F6E29B89235D059900E10EA7 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
F6E29B91235D059900E10EA7 /* AppDelegate.swift in Sources */,
F6E29BA9235D18EC00E10EA7 /* CarouselDataSource.swift in Sources */,
F6E29BAB235D192C00E10EA7 /* ViewController.swift in Sources */,
F6E29BA7235D17BD00E10EA7 /* CarouselCell.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */
F69B819B23768518001ED129 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
name = ScaledCenterCarousel;
targetProxy = F69B819A23768518001ED129 /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */
/* Begin PBXVariantGroup section */
F6E29B9B235D059B00E10EA7 /* LaunchScreen.storyboard */ = {
isa = PBXVariantGroup;
children = (
F6E29B9C235D059B00E10EA7 /* Base */,
);
name = LaunchScreen.storyboard;
sourceTree = "<group>";
};
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
F6E29B9F235D059B00E10EA7 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 13.1;
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;
};
F6E29BA0235D059B00E10EA7 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 13.1;
MTL_ENABLE_DEBUG_INFO = NO;
MTL_FAST_MATH = YES;
SDKROOT = iphoneos;
SWIFT_COMPILATION_MODE = wholemodule;
SWIFT_OPTIMIZATION_LEVEL = "-O";
VALIDATE_PRODUCT = YES;
};
name = Release;
};
F6E29BA2235D059B00E10EA7 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_STYLE = Automatic;
DEFINES_MODULE = YES;
DEVELOPMENT_ASSET_PATHS = "";
DEVELOPMENT_TEAM = 4L6G2L5WT7;
ENABLE_PREVIEWS = YES;
INFOPLIST_FILE = ScaledCenterCarouselSwiftExample/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = "yuriy-tolstoguzov.ScaledCenterCarouselSwiftExample";
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
};
F6E29BA3235D059B00E10EA7 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_STYLE = Automatic;
DEFINES_MODULE = YES;
DEVELOPMENT_ASSET_PATHS = "";
DEVELOPMENT_TEAM = 4L6G2L5WT7;
ENABLE_PREVIEWS = YES;
INFOPLIST_FILE = ScaledCenterCarouselSwiftExample/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = "yuriy-tolstoguzov.ScaledCenterCarouselSwiftExample";
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
F6E29B88235D059900E10EA7 /* Build configuration list for PBXProject "ScaledCenterCarouselSwiftExample" */ = {
isa = XCConfigurationList;
buildConfigurations = (
F6E29B9F235D059B00E10EA7 /* Debug */,
F6E29BA0235D059B00E10EA7 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
F6E29BA1235D059B00E10EA7 /* Build configuration list for PBXNativeTarget "ScaledCenterCarouselSwiftExample" */ = {
isa = XCConfigurationList;
buildConfigurations = (
F6E29BA2235D059B00E10EA7 /* Debug */,
F6E29BA3235D059B00E10EA7 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = F6E29B85235D059900E10EA7 /* Project object */;
}
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:ScaledCenterCarouselSwiftExample.xcodeproj">
</FileRef>
</Workspace>
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>
@@ -0,0 +1,78 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1110"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "F6E29B8C235D059900E10EA7"
BuildableName = "ScaledCenterCarouselSwiftExample.app"
BlueprintName = "ScaledCenterCarouselSwiftExample"
ReferencedContainer = "container:ScaledCenterCarouselSwiftExample.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "F6E29B8C235D059900E10EA7"
BuildableName = "ScaledCenterCarouselSwiftExample.app"
BlueprintName = "ScaledCenterCarouselSwiftExample"
ReferencedContainer = "container:ScaledCenterCarouselSwiftExample.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "F6E29B8C235D059900E10EA7"
BuildableName = "ScaledCenterCarouselSwiftExample.app"
BlueprintName = "ScaledCenterCarouselSwiftExample"
ReferencedContainer = "container:ScaledCenterCarouselSwiftExample.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
@@ -0,0 +1,18 @@
//
// AppDelegate.swift
// ScaledCenterCarouselSwiftExample
//
// Created by Yuriy Tolstoguzov on 10/20/19.
// Copyright © 2019 Yuriy Tolstoguzov. 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
}
}
@@ -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"
}
}
@@ -0,0 +1,6 @@
{
"info" : {
"version" : 1,
"author" : "xcode"
}
}
@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="13122.16" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13104.12"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--View Controller-->
<scene sceneID="EHf-IW-A2E">
<objects>
<viewController id="01J-lp-oVM" sceneMemberID="viewController">
<view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" xcode11CocoaTouchSystemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
<viewLayoutGuide key="safeArea" id="6Tk-OE-BBY"/>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="53" y="375"/>
</scene>
</scenes>
</document>
@@ -0,0 +1,29 @@
//
// CarouselCell.swift
// ScaledCenterCarouselSwiftExample
//
// Created by Yuriy Tolstoguzov on 10/20/19.
// Copyright © 2019 Yuriy Tolstoguzov. All rights reserved.
//
import UIKit
class CarouselCell: UICollectionViewCell {
@IBOutlet weak var label: UILabel?
var text: String? {
didSet {
label?.text = text
}
}
override var isSelected: Bool {
get {
super.isSelected
}
set {
super.isSelected = newValue
label?.textColor = isSelected ? .purple : .darkGray
}
}
}
@@ -0,0 +1,21 @@
import UIKit
class CarouselDataSource: NSObject, UICollectionViewDataSource {
var selectedIndex = Int(0)
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 100
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell",
for: indexPath) as? CarouselCell
else {
return UICollectionViewCell()
}
cell.text = String(indexPath.row)
cell.isSelected = selectedIndex == indexPath.row
return cell
}
}
@@ -0,0 +1,45 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIMainStoryboardFile</key>
<string>Main</string>
<key>UIRequiredDeviceCapabilities</key>
<array>
<string>armv7</string>
</array>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
</dict>
</plist>
@@ -0,0 +1,104 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="15400" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="o2x-hz-A4A">
<device id="retina6_1" orientation="portrait" appearance="light"/>
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="15404"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--View Controller-->
<scene sceneID="08G-ua-ApH">
<objects>
<viewController id="o2x-hz-A4A" customClass="ViewController" customModule="ScaledCenterCarouselSwiftExample" customModuleProvider="target" sceneMemberID="viewController">
<layoutGuides>
<viewControllerLayoutGuide type="top" id="AgR-AN-5BQ"/>
<viewControllerLayoutGuide type="bottom" id="FWG-vi-AFo"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="Rnw-yt-d7i">
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="t8s-G5-mcY" userLabel="Horizontal Center View">
<rect key="frame" x="206.5" y="398" width="1" height="100"/>
<color key="backgroundColor" red="0.5" green="0.0" blue="0.5" alpha="1" colorSpace="calibratedRGB"/>
<constraints>
<constraint firstAttribute="height" constant="100" id="DiL-Kg-xCw"/>
<constraint firstAttribute="width" constant="1" id="hpT-U1-Y9n"/>
</constraints>
</view>
<collectionView opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" alwaysBounceHorizontal="YES" showsHorizontalScrollIndicator="NO" showsVerticalScrollIndicator="NO" minimumZoomScale="0.0" maximumZoomScale="0.0" dataMode="prototypes" translatesAutoresizingMaskIntoConstraints="NO" id="hjk-H5-kzw">
<rect key="frame" x="0.0" y="408" width="414" height="80"/>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
<constraints>
<constraint firstAttribute="height" constant="80" id="tzh-fy-VZX"/>
</constraints>
<collectionViewLayout key="collectionViewLayout" id="i7U-1N-BZC" customClass="ScaledCenterCarouselLayout" customModule="ScaledCenterCarousel">
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="point" keyPath="proposedContentOffset">
<point key="value" x="100" y="0.0"/>
</userDefinedRuntimeAttribute>
<userDefinedRuntimeAttribute type="size" keyPath="centerCell">
<size key="value" width="90" height="65"/>
</userDefinedRuntimeAttribute>
<userDefinedRuntimeAttribute type="size" keyPath="normalCell">
<size key="value" width="53" height="60"/>
</userDefinedRuntimeAttribute>
</userDefinedRuntimeAttributes>
</collectionViewLayout>
<cells>
<collectionViewCell opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" reuseIdentifier="Cell" id="cIc-oH-4YW" customClass="CarouselCell" customModule="ScaledCenterCarouselSwiftExample" customModuleProvider="target">
<rect key="frame" x="0.0" y="0.0" width="50" height="50"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<view key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center">
<rect key="frame" x="0.0" y="0.0" width="50" height="50"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="T8S-bz-b8f">
<rect key="frame" x="1" y="1" width="48" height="48"/>
<color key="backgroundColor" white="0.88457761779999999" alpha="1" colorSpace="calibratedWhite"/>
</view>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="ZWw-gP-A5J">
<rect key="frame" x="4" y="14.5" width="42" height="21"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" white="0.33333333329999998" alpha="1" colorSpace="calibratedWhite"/>
<nil key="highlightedColor"/>
</label>
</subviews>
</view>
<color key="backgroundColor" white="0.8971585648" alpha="1" colorSpace="calibratedWhite"/>
<constraints>
<constraint firstItem="ZWw-gP-A5J" firstAttribute="centerX" secondItem="cIc-oH-4YW" secondAttribute="centerX" id="2l6-qx-97X"/>
<constraint firstAttribute="trailing" secondItem="T8S-bz-b8f" secondAttribute="trailing" constant="1" id="5QX-NS-OI3"/>
<constraint firstItem="T8S-bz-b8f" firstAttribute="top" secondItem="cIc-oH-4YW" secondAttribute="top" constant="1" id="JMX-Td-Woj"/>
<constraint firstItem="ZWw-gP-A5J" firstAttribute="centerY" secondItem="cIc-oH-4YW" secondAttribute="centerY" id="kod-NH-wjo"/>
<constraint firstItem="T8S-bz-b8f" firstAttribute="leading" secondItem="cIc-oH-4YW" secondAttribute="leading" constant="1" id="nDK-OJ-7NK"/>
<constraint firstAttribute="bottom" secondItem="T8S-bz-b8f" secondAttribute="bottom" constant="1" id="u4f-Bi-N8t"/>
</constraints>
<connections>
<outlet property="label" destination="ZWw-gP-A5J" id="6zO-wf-z82"/>
</connections>
</collectionViewCell>
</cells>
</collectionView>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstAttribute="centerY" secondItem="hjk-H5-kzw" secondAttribute="centerY" id="8l8-JK-zwP"/>
<constraint firstAttribute="centerY" secondItem="t8s-G5-mcY" secondAttribute="centerY" id="LKR-JY-c6k"/>
<constraint firstAttribute="trailing" secondItem="hjk-H5-kzw" secondAttribute="trailing" id="OQv-b5-VRJ"/>
<constraint firstAttribute="centerX" secondItem="t8s-G5-mcY" secondAttribute="centerX" id="XQ8-ac-y3O"/>
<constraint firstItem="hjk-H5-kzw" firstAttribute="leading" secondItem="Rnw-yt-d7i" secondAttribute="leading" id="jqb-IP-Gz2"/>
</constraints>
<viewLayoutGuide key="safeArea" id="LTf-zo-u7O"/>
</view>
<connections>
<outlet property="collectionView" destination="hjk-H5-kzw" id="mGN-7R-6GH"/>
</connections>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="fdL-0b-nur" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="33.5" y="35.5"/>
</scene>
</scenes>
</document>
@@ -0,0 +1,33 @@
//
// ViewController.swift
// ScaledCenterCarouselSwiftExample
//
// Created by Yuriy Tolstoguzov on 10/20/19.
// Copyright © 2019 Yuriy Tolstoguzov. All rights reserved.
//
import UIKit
import ScaledCenterCarousel
class ViewController: UIViewController, ScaledCenterCarouselPaginatorDelegate {
@IBOutlet weak var collectionView: UICollectionView?
let collectionViewDataSource = CarouselDataSource()
lazy var paginator = ScaledCenterCarouselPaginator(collectionView: collectionView!, delegate: self)
override func viewDidLoad() {
super.viewDidLoad()
guard let collectionView = collectionView else { return }
collectionView.dataSource = collectionViewDataSource
paginator = ScaledCenterCarouselPaginator(collectionView: collectionView,
delegate: self)
}
// MARK: - CarouselCenterPagerDelegate
func carousel(_ collectionView: UICollectionView, didSelectElementAt index: UInt) {
}
func carousel(_ collectionView: UICollectionView, didScrollTo visibleCells: [UICollectionViewCell]) {
}
}
@@ -0,0 +1,350 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 50;
objects = {
/* Begin PBXBuildFile section */
F6CCE397235BC9DA001CC2E5 /* ScaledCenterCarouselLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = F6CCE396235BC9DA001CC2E5 /* ScaledCenterCarouselLayout.swift */; };
F6E29B83235BDE0600E10EA7 /* ScaledCenterCarouselPaginator.swift in Sources */ = {isa = PBXBuildFile; fileRef = F6E29B82235BDE0600E10EA7 /* ScaledCenterCarouselPaginator.swift */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
F6CCE38A235BC826001CC2E5 /* ScaledCenterCarousel.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = ScaledCenterCarousel.framework; sourceTree = BUILT_PRODUCTS_DIR; };
F6CCE38E235BC826001CC2E5 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
F6CCE396235BC9DA001CC2E5 /* ScaledCenterCarouselLayout.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScaledCenterCarouselLayout.swift; sourceTree = "<group>"; };
F6E29B82235BDE0600E10EA7 /* ScaledCenterCarouselPaginator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScaledCenterCarouselPaginator.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
F6CCE387235BC826001CC2E5 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
F6CCE380235BC826001CC2E5 = {
isa = PBXGroup;
children = (
F6CCE38C235BC826001CC2E5 /* ScaledCenterCarousel */,
F6CCE38B235BC826001CC2E5 /* Products */,
);
sourceTree = "<group>";
};
F6CCE38B235BC826001CC2E5 /* Products */ = {
isa = PBXGroup;
children = (
F6CCE38A235BC826001CC2E5 /* ScaledCenterCarousel.framework */,
);
name = Products;
sourceTree = "<group>";
};
F6CCE38C235BC826001CC2E5 /* ScaledCenterCarousel */ = {
isa = PBXGroup;
children = (
F6CCE395235BC99F001CC2E5 /* Classes */,
F6CCE38E235BC826001CC2E5 /* Info.plist */,
);
path = ScaledCenterCarousel;
sourceTree = "<group>";
};
F6CCE395235BC99F001CC2E5 /* Classes */ = {
isa = PBXGroup;
children = (
F6CCE396235BC9DA001CC2E5 /* ScaledCenterCarouselLayout.swift */,
F6E29B82235BDE0600E10EA7 /* ScaledCenterCarouselPaginator.swift */,
);
path = Classes;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXHeadersBuildPhase section */
F6CCE385235BC826001CC2E5 /* Headers */ = {
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXHeadersBuildPhase section */
/* Begin PBXNativeTarget section */
F6CCE389235BC826001CC2E5 /* ScaledCenterCarousel */ = {
isa = PBXNativeTarget;
buildConfigurationList = F6CCE392235BC826001CC2E5 /* Build configuration list for PBXNativeTarget "ScaledCenterCarousel" */;
buildPhases = (
F6CCE385235BC826001CC2E5 /* Headers */,
F6CCE386235BC826001CC2E5 /* Sources */,
F6CCE387235BC826001CC2E5 /* Frameworks */,
F6CCE388235BC826001CC2E5 /* Resources */,
);
buildRules = (
);
dependencies = (
);
name = ScaledCenterCarousel;
productName = ScaledCenterCarousel;
productReference = F6CCE38A235BC826001CC2E5 /* ScaledCenterCarousel.framework */;
productType = "com.apple.product-type.framework";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
F6CCE381235BC826001CC2E5 /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 1110;
ORGANIZATIONNAME = "Yuriy Tolstoguzov";
TargetAttributes = {
F6CCE389235BC826001CC2E5 = {
CreatedOnToolsVersion = 11.1;
LastSwiftMigration = 1110;
};
};
};
buildConfigurationList = F6CCE384235BC826001CC2E5 /* Build configuration list for PBXProject "ScaledCenterCarousel" */;
compatibilityVersion = "Xcode 9.3";
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
en,
Base,
);
mainGroup = F6CCE380235BC826001CC2E5;
productRefGroup = F6CCE38B235BC826001CC2E5 /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
F6CCE389235BC826001CC2E5 /* ScaledCenterCarousel */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
F6CCE388235BC826001CC2E5 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
F6CCE386235BC826001CC2E5 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
F6E29B83235BDE0600E10EA7 /* ScaledCenterCarouselPaginator.swift in Sources */,
F6CCE397235BC9DA001CC2E5 /* ScaledCenterCarouselLayout.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin XCBuildConfiguration section */
F6CCE390235BC826001CC2E5 /* 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.1;
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;
};
F6CCE391235BC826001CC2E5 /* 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.1;
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;
};
F6CCE393235BC826001CC2E5 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_STYLE = Automatic;
DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = 4L6G2L5WT7;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
INFOPLIST_FILE = ScaledCenterCarousel/Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
"@loader_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = "yuriy-tolstoguzov.ScaledCenterCarousel";
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
SKIP_INSTALL = YES;
SUPPORTS_MACCATALYST = NO;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
};
F6CCE394235BC826001CC2E5 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_STYLE = Automatic;
DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = 4L6G2L5WT7;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
INFOPLIST_FILE = ScaledCenterCarousel/Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
"@loader_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = "yuriy-tolstoguzov.ScaledCenterCarousel";
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
SKIP_INSTALL = YES;
SUPPORTS_MACCATALYST = NO;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
F6CCE384235BC826001CC2E5 /* Build configuration list for PBXProject "ScaledCenterCarousel" */ = {
isa = XCConfigurationList;
buildConfigurations = (
F6CCE390235BC826001CC2E5 /* Debug */,
F6CCE391235BC826001CC2E5 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
F6CCE392235BC826001CC2E5 /* Build configuration list for PBXNativeTarget "ScaledCenterCarousel" */ = {
isa = XCConfigurationList;
buildConfigurations = (
F6CCE393235BC826001CC2E5 /* Debug */,
F6CCE394235BC826001CC2E5 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = F6CCE381235BC826001CC2E5 /* Project object */;
}
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:ScaledCenterCarousel.xcodeproj">
</FileRef>
</Workspace>
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>
@@ -0,0 +1,67 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1110"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "F6CCE389235BC826001CC2E5"
BuildableName = "ScaledCenterCarousel.framework"
BlueprintName = "ScaledCenterCarousel"
ReferencedContainer = "container:ScaledCenterCarousel.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "F6CCE389235BC826001CC2E5"
BuildableName = "ScaledCenterCarousel.framework"
BlueprintName = "ScaledCenterCarousel"
ReferencedContainer = "container:ScaledCenterCarousel.xcodeproj">
</BuildableReference>
</MacroExpansion>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
@@ -0,0 +1,117 @@
//
// ScaledCenterCarouselLayout.swift
// ScaledCenterCarousel
//
// Created by Yuriy Tolstoguzov on 10/19/19.
// Copyright © 2019 Yuriy Tolstoguzov. All rights reserved.
//
import UIKit
open class ScaledCenterCarouselLayout: UICollectionViewLayout {
@IBInspectable open var centerCell = CGSize.zero
@IBInspectable open var normalCell = CGSize.zero
@IBInspectable open var proposedContentOffset: CGPoint = CGPoint(x: NSNotFound, y: 0)
public let defaultProposedContentOffset = CGPoint(x: NSNotFound, y: 0)
@IBInspectable open var isIgnoringBoundsChange = false
private var layoutInformation: [UICollectionViewLayoutAttributes]?
private var currentVisibleRect = CGRect.zero
public init(centerCellSize: CGSize, normalCellSize: CGSize) {
self.centerCell = centerCellSize
self.normalCell = normalCellSize
super.init()
}
required public init?(coder: NSCoder) {
super.init(coder: coder)
}
open override var collectionViewContentSize: CGSize {
guard let collectionView = collectionView else { return .zero }
let numberOfItems = CGFloat(collectionView.numberOfItems(inSection: 0))
let sideSpace = (collectionView.bounds.size.width - centerCell.width) / 2
let width = normalCell.width * (numberOfItems - 1) + centerCell.width + sideSpace * 2
return CGSize(width: width, height: normalCell.height)
}
open override func prepare() {
super.prepare()
guard let collectionView = collectionView else { return }
let numberOfItems = collectionView.numberOfItems(inSection: 0)
currentVisibleRect = collectionView.bounds
self.layoutInformation = (0..<numberOfItems).map {
UICollectionViewLayoutAttributes(forCellWith: IndexPath(item: $0, section: 0))
}
updateLayout(for: currentVisibleRect)
}
open override func layoutAttributesForItem(at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? {
return layoutInformation?[indexPath.item]
}
open override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
return layoutInformation?.filter { $0.frame.intersects(rect) }
}
open override func shouldInvalidateLayout(forBoundsChange newBounds: CGRect) -> Bool {
currentVisibleRect = newBounds
return !self.isIgnoringBoundsChange
}
func updateLayout(for bounds: CGRect) {
let deltaX = centerCell.width - normalCell.width
let deltaY = centerCell.height - normalCell.height
let leftSideInset = (bounds.width - centerCell.width) / 2
for attribute in layoutInformation ?? [] {
let normalCellOffsetX = leftSideInset + CGFloat(attribute.indexPath.item) * normalCell.width
let normalCellOffsetY = (bounds.height - normalCell.height) / 2
let distanceBetweenCellAndBoundCenters = normalCellOffsetX - bounds.midX + centerCell.width / 2
// normalizedCenterScale has range (- 1 ... 1), 0 - cell placed at center of bounds
let normalizedCenterScale = distanceBetweenCellAndBoundCenters / normalCell.width
let isCenterCell = abs(normalizedCenterScale) < 1
let isNormalCellOnRightOfCenter = normalizedCenterScale > 0 && !isCenterCell
let isNormalCellOnLeftOfCenter = normalizedCenterScale < 0 && !isCenterCell
if isCenterCell {
let incrementX = (1 - abs(normalizedCenterScale)) * deltaX
let incrementY = (1 - abs(normalizedCenterScale)) * deltaY
let offsetX = normalizedCenterScale > 0 ? deltaX - incrementX : 0
let offsetY = -incrementY / 2
attribute.frame = CGRect(x: normalCellOffsetX + offsetX,
y: normalCellOffsetY + offsetY,
width: normalCell.width + incrementX,
height: normalCell.height + incrementY)
} else if isNormalCellOnRightOfCenter {
attribute.frame = CGRect(x: normalCellOffsetX + deltaX,
y: normalCellOffsetY,
width: normalCell.width,
height: normalCell.height)
} else if isNormalCellOnLeftOfCenter {
attribute.frame = CGRect(x: normalCellOffsetX,
y: normalCellOffsetY,
width: normalCell.width,
height: normalCell.height)
}
}
}
open override func targetContentOffset(forProposedContentOffset proposedContentOffset: CGPoint) -> CGPoint {
if self.proposedContentOffset.x != CGFloat(NSNotFound) {
let proposedContentOffset = self.proposedContentOffset
self.proposedContentOffset = defaultProposedContentOffset
return proposedContentOffset
} else {
return proposedContentOffset
}
}
}
@@ -0,0 +1,163 @@
//
// ScaledCenterCarouselPaginator.swift
// ScaledCenterCarousel
//
// Created by Yuriy Tolstoguzov on 10/19/19.
// Copyright © 2019 Yuriy Tolstoguzov. All rights reserved.
//
import UIKit
enum NearestPointDirection {
case any
case left
case right
}
public protocol ScaledCenterCarouselPaginatorDelegate {
func carousel(_ collectionView: UICollectionView, didSelectElementAt index: UInt)
func carousel(_ collectionView: UICollectionView, didScrollTo visibleCells: [UICollectionViewCell])
}
public protocol ScaledCenterCarouselDataSource: UICollectionViewDataSource {
var selectedIndex: UInt { get set }
}
open class ScaledCenterCarouselPaginator: NSObject, UICollectionViewDelegate {
public let delegate: ScaledCenterCarouselPaginatorDelegate
public var selectedIndex = UInt(0)
private var scrollVelocity = CGFloat(0)
private var collectionView: UICollectionView
private var collectionViewCenter: CGFloat {
return collectionView.bounds.width / 2
}
public init(collectionView: UICollectionView, delegate: ScaledCenterCarouselPaginatorDelegate) {
self.collectionView = collectionView
self.delegate = delegate
super.init()
self.collectionView.delegate = self
}
// MARK: - UICollectionViewDelegate
public func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
guard selectedIndex != UInt.max else { return }
let previousSelectedIndex = selectedIndex
if let dataSource = collectionView.dataSource as? ScaledCenterCarouselDataSource {
dataSource.selectedIndex = selectedIndex
}
selectedIndex = UInt.max
self.reloadCell(at: IndexPath(item: Int(previousSelectedIndex), section: 0),
withSelectedState: false)
}
public func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
if let dataSource = collectionView.dataSource as? ScaledCenterCarouselDataSource {
dataSource.selectedIndex = selectedIndex
}
self.reloadCell(at: IndexPath(item: Int(selectedIndex), section: 0), withSelectedState: false)
delegate.carousel(collectionView, didScrollTo: collectionView.visibleCells)
}
public func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
collectionView.deselectItem(at: indexPath, animated: true)
self.scrollViewWillBeginDragging(collectionView)
selectedIndex = UInt(indexPath.item)
delegate.carousel(collectionView, didSelectElementAt: selectedIndex)
if let layout = collectionView.collectionViewLayout as? ScaledCenterCarouselLayout {
let xPosition = CGFloat(selectedIndex) * layout.normalCell.width
layout.isIgnoringBoundsChange = true
collectionView.setContentOffset(CGPoint(x: xPosition, y: 0), animated: true)
layout.isIgnoringBoundsChange = false
DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) {
self.scrollViewDidEndDecelerating(collectionView)
}
}
}
// MARK: - Utility methods
private func offset(forCenterX centerX: CGFloat, withDirection direction: NearestPointDirection) -> CGPoint {
let leftNearestCenter = nearestLeftCenter(forCenterX: centerX)
let leftCenterIndex = leftNearestCenter.index
let leftCenter = leftNearestCenter.distance
let rightNearestCenter = nearestRightCenter(forCenterX: centerX)
let rightCenterIndex = rightNearestCenter.index
let rightCenter = rightNearestCenter.distance
var nearestItemIndex = UInt(NSNotFound)
switch direction {
case .any:
if (leftCenter > rightCenter) {
nearestItemIndex = rightCenterIndex
}
else {
nearestItemIndex = leftCenterIndex
}
case .left:
nearestItemIndex = leftCenterIndex
case .right:
nearestItemIndex = rightCenterIndex
}
selectedIndex = nearestItemIndex
if selectedIndex != NSNotFound {
delegate.carousel(collectionView, didSelectElementAt: selectedIndex)
}
if let layout = collectionView.collectionViewLayout as? ScaledCenterCarouselLayout {
return CGPoint(x: CGFloat(nearestItemIndex) * layout.normalCell.width, y: 0)
} else {
return .zero
}
}
public func scrollViewWillEndDragging(_ scrollView: UIScrollView,
withVelocity velocity: CGPoint,
targetContentOffset: UnsafeMutablePointer<CGPoint>) {
scrollVelocity = velocity.x
var direction: NearestPointDirection
if scrollVelocity == 0 {
direction = .any
} else if scrollVelocity < 0 {
direction = .left
} else {
direction = .right
}
targetContentOffset.pointee = offset(forCenterX: targetContentOffset.pointee.x + collectionViewCenter,
withDirection: direction)
}
func nearestLeftCenter(forCenterX centerX: CGFloat) -> (index: UInt, distance: CGFloat) {
guard let layout = collectionView.collectionViewLayout as? ScaledCenterCarouselLayout else { return (0, 0) }
let nearestLeftElementIndex = (centerX - collectionViewCenter - layout.centerCell.width
+ layout.normalCell.width) / layout.normalCell.width
let minimumLeftDistance = centerX - nearestLeftElementIndex * layout.normalCell.width - collectionView.bounds.width / 2 - layout.centerCell.width + layout.normalCell.width
return (UInt(nearestLeftElementIndex), minimumLeftDistance)
}
func nearestRightCenter(forCenterX centerX: CGFloat) -> (index: UInt, distance: CGFloat) {
guard let layout = collectionView.collectionViewLayout as? ScaledCenterCarouselLayout else { return (0, 0) }
let nearestRightElementIndex = ceil(centerX - collectionViewCenter - layout.centerCell.width
+ layout.normalCell.width) / layout.normalCell.width
let minimumRightDistance = nearestRightElementIndex * layout.normalCell.width + collectionViewCenter
- centerX - layout.centerCell.width + layout.normalCell.width
return (UInt(nearestRightElementIndex), minimumRightDistance)
}
func reloadCell(at indexPath: IndexPath, withSelectedState isSelected: Bool) {
let cell = collectionView.cellForItem(at: indexPath)
cell?.isSelected = isSelected
}
}
+22
View File
@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>$(CURRENT_PROJECT_VERSION)</string>
</dict>
</plist>