diff --git a/Practice-YSB/StickyHeader/Podfile b/Practice-YSB/StickyHeader/Podfile new file mode 100644 index 0000000..2640c77 --- /dev/null +++ b/Practice-YSB/StickyHeader/Podfile @@ -0,0 +1,11 @@ +# Uncomment the next line to define a global platform for your project +# platform :ios, '9.0' + +target 'StickyHeader' do + # Comment the next line if you don't want to use dynamic frameworks + use_frameworks! + + # Pods for StickyHeader + pod 'SnapKit' + +end diff --git a/Practice-YSB/StickyHeader/Podfile.lock b/Practice-YSB/StickyHeader/Podfile.lock new file mode 100644 index 0000000..1ee8d01 --- /dev/null +++ b/Practice-YSB/StickyHeader/Podfile.lock @@ -0,0 +1,16 @@ +PODS: + - SnapKit (5.0.1) + +DEPENDENCIES: + - SnapKit + +SPEC REPOS: + trunk: + - SnapKit + +SPEC CHECKSUMS: + SnapKit: 97b92857e3df3a0c71833cce143274bf6ef8e5eb + +PODFILE CHECKSUM: 984ec16e67572a32e8bb28ae5cb764e733d0a406 + +COCOAPODS: 1.11.2 diff --git a/Practice-YSB/StickyHeader/StickyHeader.xcodeproj/project.pbxproj b/Practice-YSB/StickyHeader/StickyHeader.xcodeproj/project.pbxproj new file mode 100644 index 0000000..817a122 --- /dev/null +++ b/Practice-YSB/StickyHeader/StickyHeader.xcodeproj/project.pbxproj @@ -0,0 +1,443 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 55; + objects = { + +/* Begin PBXBuildFile section */ + 2B0237AC278B3E4000C87068 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2B0237AB278B3E4000C87068 /* AppDelegate.swift */; }; + 2B0237AE278B3E4000C87068 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2B0237AD278B3E4000C87068 /* SceneDelegate.swift */; }; + 2B0237B0278B3E4000C87068 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2B0237AF278B3E4000C87068 /* ViewController.swift */; }; + 2B0237B3278B3E4000C87068 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 2B0237B1278B3E4000C87068 /* Main.storyboard */; }; + 2B0237B5278B3E4100C87068 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 2B0237B4278B3E4100C87068 /* Assets.xcassets */; }; + 2B0237B8278B3E4100C87068 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 2B0237B6278B3E4100C87068 /* LaunchScreen.storyboard */; }; + 2B0237C0278B4DB600C87068 /* CustomCVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2B0237BF278B4DB600C87068 /* CustomCVC.swift */; }; + 2B0237C2278B574A00C87068 /* CustomHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2B0237C1278B574A00C87068 /* CustomHeaderView.swift */; }; + 61A7EF370059FF6E6FB8D4CB /* Pods_StickyHeader.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 12AAC2E36EA0BC4E05609729 /* Pods_StickyHeader.framework */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 1046633DFD7599C6119B3938 /* Pods-StickyHeader.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-StickyHeader.debug.xcconfig"; path = "Target Support Files/Pods-StickyHeader/Pods-StickyHeader.debug.xcconfig"; sourceTree = ""; }; + 12AAC2E36EA0BC4E05609729 /* Pods_StickyHeader.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_StickyHeader.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 2B0237A8278B3E4000C87068 /* StickyHeader.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = StickyHeader.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 2B0237AB278B3E4000C87068 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 2B0237AD278B3E4000C87068 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; + 2B0237AF278B3E4000C87068 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; + 2B0237B2278B3E4000C87068 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 2B0237B4278B3E4100C87068 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 2B0237B7278B3E4100C87068 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 2B0237B9278B3E4100C87068 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 2B0237BF278B4DB600C87068 /* CustomCVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomCVC.swift; sourceTree = ""; }; + 2B0237C1278B574A00C87068 /* CustomHeaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomHeaderView.swift; sourceTree = ""; }; + FC6368CF98714B7CAE5F14B8 /* Pods-StickyHeader.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-StickyHeader.release.xcconfig"; path = "Target Support Files/Pods-StickyHeader/Pods-StickyHeader.release.xcconfig"; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 2B0237A5278B3E4000C87068 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 61A7EF370059FF6E6FB8D4CB /* Pods_StickyHeader.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 093787318001865CDA20DE66 /* Pods */ = { + isa = PBXGroup; + children = ( + 1046633DFD7599C6119B3938 /* Pods-StickyHeader.debug.xcconfig */, + FC6368CF98714B7CAE5F14B8 /* Pods-StickyHeader.release.xcconfig */, + ); + path = Pods; + sourceTree = ""; + }; + 0CC9E824760A769DA872023E /* Frameworks */ = { + isa = PBXGroup; + children = ( + 12AAC2E36EA0BC4E05609729 /* Pods_StickyHeader.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + 2B02379F278B3E4000C87068 = { + isa = PBXGroup; + children = ( + 2B0237AA278B3E4000C87068 /* StickyHeader */, + 2B0237A9278B3E4000C87068 /* Products */, + 093787318001865CDA20DE66 /* Pods */, + 0CC9E824760A769DA872023E /* Frameworks */, + ); + sourceTree = ""; + }; + 2B0237A9278B3E4000C87068 /* Products */ = { + isa = PBXGroup; + children = ( + 2B0237A8278B3E4000C87068 /* StickyHeader.app */, + ); + name = Products; + sourceTree = ""; + }; + 2B0237AA278B3E4000C87068 /* StickyHeader */ = { + isa = PBXGroup; + children = ( + 2B0237AB278B3E4000C87068 /* AppDelegate.swift */, + 2B0237AD278B3E4000C87068 /* SceneDelegate.swift */, + 2B0237AF278B3E4000C87068 /* ViewController.swift */, + 2B0237C1278B574A00C87068 /* CustomHeaderView.swift */, + 2B0237BF278B4DB600C87068 /* CustomCVC.swift */, + 2B0237B1278B3E4000C87068 /* Main.storyboard */, + 2B0237B4278B3E4100C87068 /* Assets.xcassets */, + 2B0237B6278B3E4100C87068 /* LaunchScreen.storyboard */, + 2B0237B9278B3E4100C87068 /* Info.plist */, + ); + path = StickyHeader; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 2B0237A7278B3E4000C87068 /* StickyHeader */ = { + isa = PBXNativeTarget; + buildConfigurationList = 2B0237BC278B3E4100C87068 /* Build configuration list for PBXNativeTarget "StickyHeader" */; + buildPhases = ( + 58C51F864E8F1F4596BB7083 /* [CP] Check Pods Manifest.lock */, + 2B0237A4278B3E4000C87068 /* Sources */, + 2B0237A5278B3E4000C87068 /* Frameworks */, + 2B0237A6278B3E4000C87068 /* Resources */, + 5892F8C3789759579515301E /* [CP] Embed Pods Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = StickyHeader; + productName = StickyHeader; + productReference = 2B0237A8278B3E4000C87068 /* StickyHeader.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 2B0237A0278B3E4000C87068 /* Project object */ = { + isa = PBXProject; + attributes = { + BuildIndependentTargetsInParallel = 1; + LastSwiftUpdateCheck = 1300; + LastUpgradeCheck = 1300; + TargetAttributes = { + 2B0237A7278B3E4000C87068 = { + CreatedOnToolsVersion = 13.0; + }; + }; + }; + buildConfigurationList = 2B0237A3278B3E4000C87068 /* Build configuration list for PBXProject "StickyHeader" */; + compatibilityVersion = "Xcode 13.0"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 2B02379F278B3E4000C87068; + productRefGroup = 2B0237A9278B3E4000C87068 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 2B0237A7278B3E4000C87068 /* StickyHeader */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 2B0237A6278B3E4000C87068 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 2B0237B8278B3E4100C87068 /* LaunchScreen.storyboard in Resources */, + 2B0237B5278B3E4100C87068 /* Assets.xcassets in Resources */, + 2B0237B3278B3E4000C87068 /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 5892F8C3789759579515301E /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-StickyHeader/Pods-StickyHeader-frameworks-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Embed Pods Frameworks"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-StickyHeader/Pods-StickyHeader-frameworks-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-StickyHeader/Pods-StickyHeader-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; + 58C51F864E8F1F4596BB7083 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-StickyHeader-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + 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; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 2B0237A4278B3E4000C87068 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 2B0237C2278B574A00C87068 /* CustomHeaderView.swift in Sources */, + 2B0237B0278B3E4000C87068 /* ViewController.swift in Sources */, + 2B0237C0278B4DB600C87068 /* CustomCVC.swift in Sources */, + 2B0237AC278B3E4000C87068 /* AppDelegate.swift in Sources */, + 2B0237AE278B3E4000C87068 /* SceneDelegate.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 2B0237B1278B3E4000C87068 /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 2B0237B2278B3E4000C87068 /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 2B0237B6278B3E4100C87068 /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 2B0237B7278B3E4100C87068 /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 2B0237BA278B3E4100C87068 /* 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++17"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + 2B0237BB278B3E4100C87068 /* 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++17"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 2B0237BD278B3E4100C87068 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 1046633DFD7599C6119B3938 /* Pods-StickyHeader.debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = 4QG3GC35LA; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = StickyHeader/Info.plist; + INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; + INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen; + INFOPLIST_KEY_UIMainStoryboardFile = Main; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = subin.StickyHeader; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 2B0237BE278B3E4100C87068 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = FC6368CF98714B7CAE5F14B8 /* Pods-StickyHeader.release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = 4QG3GC35LA; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = StickyHeader/Info.plist; + INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; + INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen; + INFOPLIST_KEY_UIMainStoryboardFile = Main; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = subin.StickyHeader; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 2B0237A3278B3E4000C87068 /* Build configuration list for PBXProject "StickyHeader" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 2B0237BA278B3E4100C87068 /* Debug */, + 2B0237BB278B3E4100C87068 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 2B0237BC278B3E4100C87068 /* Build configuration list for PBXNativeTarget "StickyHeader" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 2B0237BD278B3E4100C87068 /* Debug */, + 2B0237BE278B3E4100C87068 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 2B0237A0278B3E4000C87068 /* Project object */; +} diff --git a/Practice-YSB/StickyHeader/StickyHeader.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/Practice-YSB/StickyHeader/StickyHeader.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..919434a --- /dev/null +++ b/Practice-YSB/StickyHeader/StickyHeader.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/Practice-YSB/StickyHeader/StickyHeader.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/Practice-YSB/StickyHeader/StickyHeader.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/Practice-YSB/StickyHeader/StickyHeader.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/Practice-YSB/StickyHeader/StickyHeader.xcworkspace/contents.xcworkspacedata b/Practice-YSB/StickyHeader/StickyHeader.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..53a0852 --- /dev/null +++ b/Practice-YSB/StickyHeader/StickyHeader.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,10 @@ + + + + + + + diff --git a/Practice-YSB/StickyHeader/StickyHeader.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/Practice-YSB/StickyHeader/StickyHeader.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/Practice-YSB/StickyHeader/StickyHeader.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/Practice-YSB/StickyHeader/StickyHeader/AppDelegate.swift b/Practice-YSB/StickyHeader/StickyHeader/AppDelegate.swift new file mode 100644 index 0000000..9bf64fa --- /dev/null +++ b/Practice-YSB/StickyHeader/StickyHeader/AppDelegate.swift @@ -0,0 +1,36 @@ +// +// AppDelegate.swift +// StickyHeader +// +// Created by 양수빈 on 2022/01/10. +// + +import UIKit + +@main +class AppDelegate: UIResponder, UIApplicationDelegate { + + + + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { + // Override point for customization after application launch. + return true + } + + // MARK: UISceneSession Lifecycle + + func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration { + // Called when a new scene session is being created. + // Use this method to select a configuration to create the new scene with. + return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role) + } + + func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) { + // Called when the user discards a scene session. + // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions. + // Use this method to release any resources that were specific to the discarded scenes, as they will not return. + } + + +} + diff --git a/Practice-YSB/StickyHeader/StickyHeader/Assets.xcassets/AccentColor.colorset/Contents.json b/Practice-YSB/StickyHeader/StickyHeader/Assets.xcassets/AccentColor.colorset/Contents.json new file mode 100644 index 0000000..eb87897 --- /dev/null +++ b/Practice-YSB/StickyHeader/StickyHeader/Assets.xcassets/AccentColor.colorset/Contents.json @@ -0,0 +1,11 @@ +{ + "colors" : [ + { + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Practice-YSB/StickyHeader/StickyHeader/Assets.xcassets/AppIcon.appiconset/Contents.json b/Practice-YSB/StickyHeader/StickyHeader/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..9221b9b --- /dev/null +++ b/Practice-YSB/StickyHeader/StickyHeader/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,98 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "scale" : "2x", + "size" : "20x20" + }, + { + "idiom" : "iphone", + "scale" : "3x", + "size" : "20x20" + }, + { + "idiom" : "iphone", + "scale" : "2x", + "size" : "29x29" + }, + { + "idiom" : "iphone", + "scale" : "3x", + "size" : "29x29" + }, + { + "idiom" : "iphone", + "scale" : "2x", + "size" : "40x40" + }, + { + "idiom" : "iphone", + "scale" : "3x", + "size" : "40x40" + }, + { + "idiom" : "iphone", + "scale" : "2x", + "size" : "60x60" + }, + { + "idiom" : "iphone", + "scale" : "3x", + "size" : "60x60" + }, + { + "idiom" : "ipad", + "scale" : "1x", + "size" : "20x20" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "size" : "20x20" + }, + { + "idiom" : "ipad", + "scale" : "1x", + "size" : "29x29" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "size" : "29x29" + }, + { + "idiom" : "ipad", + "scale" : "1x", + "size" : "40x40" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "size" : "40x40" + }, + { + "idiom" : "ipad", + "scale" : "1x", + "size" : "76x76" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "size" : "76x76" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "size" : "83.5x83.5" + }, + { + "idiom" : "ios-marketing", + "scale" : "1x", + "size" : "1024x1024" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Practice-YSB/StickyHeader/StickyHeader/Assets.xcassets/Contents.json b/Practice-YSB/StickyHeader/StickyHeader/Assets.xcassets/Contents.json new file mode 100644 index 0000000..73c0059 --- /dev/null +++ b/Practice-YSB/StickyHeader/StickyHeader/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Practice-YSB/StickyHeader/StickyHeader/Base.lproj/LaunchScreen.storyboard b/Practice-YSB/StickyHeader/StickyHeader/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000..865e932 --- /dev/null +++ b/Practice-YSB/StickyHeader/StickyHeader/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Practice-YSB/StickyHeader/StickyHeader/Base.lproj/Main.storyboard b/Practice-YSB/StickyHeader/StickyHeader/Base.lproj/Main.storyboard new file mode 100644 index 0000000..25a7638 --- /dev/null +++ b/Practice-YSB/StickyHeader/StickyHeader/Base.lproj/Main.storyboard @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Practice-YSB/StickyHeader/StickyHeader/CustomCVC.swift b/Practice-YSB/StickyHeader/StickyHeader/CustomCVC.swift new file mode 100644 index 0000000..a048d08 --- /dev/null +++ b/Practice-YSB/StickyHeader/StickyHeader/CustomCVC.swift @@ -0,0 +1,62 @@ +// +// CustomCVC.swift +// StickyHeader +// +// Created by 양수빈 on 2022/01/10. +// + +import UIKit + +import SnapKit + +class CustomCVC: UICollectionViewCell { + static let identifier = "CustomCVC" + + // MARK: - Properties + let titleLabel = UILabel() + let userNameLabel = UILabel() + + // MARK: - View Life Cycles + override init(frame: CGRect) { + super.init(frame: frame) + + setUI() + setLayout() + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + override func prepareForReuse() { + super.prepareForReuse() + + titleLabel.text = "---" + userNameLabel.text = "사용자이름" + } + + // MARK: - Methods + func setUI() { + titleLabel.text = "---" + userNameLabel.text = "사용자이름" + + titleLabel.font = .systemFont(ofSize: 20) + userNameLabel.font = .systemFont(ofSize: 14) + userNameLabel.textColor = .gray + } + + func setLayout() { + addSubview(titleLabel) + addSubview(userNameLabel) + + titleLabel.snp.makeConstraints { make in + make.leading.equalToSuperview().offset(16) + make.top.equalToSuperview().offset(16) + } + + userNameLabel.snp.makeConstraints { make in + make.leading.equalToSuperview().offset(16) + make.top.equalTo(titleLabel.snp.bottom).offset(10) + } + } +} diff --git a/Practice-YSB/StickyHeader/StickyHeader/CustomHeaderView.swift b/Practice-YSB/StickyHeader/StickyHeader/CustomHeaderView.swift new file mode 100644 index 0000000..89e3f34 --- /dev/null +++ b/Practice-YSB/StickyHeader/StickyHeader/CustomHeaderView.swift @@ -0,0 +1,51 @@ +// +// CustomHeaderView.swift +// StickyHeader +// +// Created by 양수빈 on 2022/01/10. +// + +import UIKit + +import SnapKit + +class CustomHeaderView: UICollectionReusableView { + static let identifier = "CustomHeaderView" + + // MARK: - Properties + let dateLabel = UILabel() + + // MARK: - View Life Cycles + override init(frame: CGRect) { + super.init(frame: frame) + + setUI() + setLayout() + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + override func prepareForReuse() { + super.prepareForReuse() + + dateLabel.text = "" + } + + // MARK: - Methods + func setUI() { + dateLabel.text = "Header" + dateLabel.font = .systemFont(ofSize: 30) + } + + func setLayout() { + addSubview(dateLabel) + + dateLabel.snp.makeConstraints { make in + make.leading.equalToSuperview().offset(16) + make.centerY.equalToSuperview() + } + } + +} diff --git a/Practice-YSB/StickyHeader/StickyHeader/Info.plist b/Practice-YSB/StickyHeader/StickyHeader/Info.plist new file mode 100644 index 0000000..dd3c9af --- /dev/null +++ b/Practice-YSB/StickyHeader/StickyHeader/Info.plist @@ -0,0 +1,25 @@ + + + + + UIApplicationSceneManifest + + UIApplicationSupportsMultipleScenes + + UISceneConfigurations + + UIWindowSceneSessionRoleApplication + + + UISceneConfigurationName + Default Configuration + UISceneDelegateClassName + $(PRODUCT_MODULE_NAME).SceneDelegate + UISceneStoryboardFile + Main + + + + + + diff --git a/Practice-YSB/StickyHeader/StickyHeader/SceneDelegate.swift b/Practice-YSB/StickyHeader/StickyHeader/SceneDelegate.swift new file mode 100644 index 0000000..cf0a69d --- /dev/null +++ b/Practice-YSB/StickyHeader/StickyHeader/SceneDelegate.swift @@ -0,0 +1,52 @@ +// +// SceneDelegate.swift +// StickyHeader +// +// Created by 양수빈 on 2022/01/10. +// + +import UIKit + +class SceneDelegate: UIResponder, UIWindowSceneDelegate { + + var window: UIWindow? + + + func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { + // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`. + // If using a storyboard, the `window` property will automatically be initialized and attached to the scene. + // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead). + guard let _ = (scene as? UIWindowScene) else { return } + } + + func sceneDidDisconnect(_ scene: UIScene) { + // Called as the scene is being released by the system. + // This occurs shortly after the scene enters the background, or when its session is discarded. + // Release any resources associated with this scene that can be re-created the next time the scene connects. + // The scene may re-connect later, as its session was not necessarily discarded (see `application:didDiscardSceneSessions` instead). + } + + func sceneDidBecomeActive(_ scene: UIScene) { + // Called when the scene has moved from an inactive state to an active state. + // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive. + } + + func sceneWillResignActive(_ scene: UIScene) { + // Called when the scene will move from an active state to an inactive state. + // This may occur due to temporary interruptions (ex. an incoming phone call). + } + + func sceneWillEnterForeground(_ scene: UIScene) { + // Called as the scene transitions from the background to the foreground. + // Use this method to undo the changes made on entering the background. + } + + func sceneDidEnterBackground(_ scene: UIScene) { + // Called as the scene transitions from the foreground to the background. + // Use this method to save data, release shared resources, and store enough scene-specific state information + // to restore the scene back to its current state. + } + + +} + diff --git a/Practice-YSB/StickyHeader/StickyHeader/ViewController.swift b/Practice-YSB/StickyHeader/StickyHeader/ViewController.swift new file mode 100644 index 0000000..f8a6606 --- /dev/null +++ b/Practice-YSB/StickyHeader/StickyHeader/ViewController.swift @@ -0,0 +1,256 @@ +// +// ViewController.swift +// StickyHeader +// +// Created by 양수빈 on 2022/01/10. +// + +import UIKit + +import SnapKit + +class ViewController: UIViewController { + + // MARK: - Dummy Data + var dummyDataList: Array = [ ["date": "2022-11-11", "userName": "양수빈", "sparkTitle": "간식먹기", "sparkCount": "1"], + ["date": "2022-11-11", "userName": "감자", "sparkTitle": "간식먹기222", "sparkCount": "2"], + ["date": "2022-11-11", "userName": "김", "sparkTitle": "아아아간식먹기", "sparkCount": "3"], + ["date": "2022-11-10", "userName": "옹", "sparkTitle": "아아 마셔", "sparkCount": "4"], + ["date": "2022-11-10", "userName": "우와", "sparkTitle": "커피 홀짝", "sparkCount": "5"], + ["date": "2022-11-9", "userName": "우와", "sparkTitle": "홀짝 커피", "sparkCount": "6"], + ["date": "2022-11-9", "userName": "뭐지", "sparkTitle": "하하하하", "sparkCount": "7"], + ["date": "2022-11-9", "userName": "하하", "sparkTitle": "쉽지않네", "sparkCount": "8"], + ["date": "2022-11-9", "userName": "호호", "sparkTitle": "덤이데잍어", "sparkCount": "9"], + ["date": "2022-11-7", "userName": "s", "sparkTitle": "덤이데sdfdfdfdf잍어", "sparkCount": "10"], + ["date": "2022-11-7", "userName": "호sgggg호", "sparkTitle": "덤이sddd데잍어", "sparkCount": "11"] ] + + var newDummyDataList: Array = [ ["date": "2022-11-7", "userName": "양수빈", "sparkTitle": "간식먹기", "sparkCount": "12"], + ["date": "2022-11-7", "userName": "감자", "sparkTitle": "간식먹기222", "sparkCount": "13"], + ["date": "2022-11-4", "userName": "김", "sparkTitle": "아아아간식먹기", "sparkCount": "14"], + ["date": "2022-11-4", "userName": "옹", "sparkTitle": "아아 마셔", "sparkCount": "15"], + ["date": "2022-11-3", "userName": "우와", "sparkTitle": "커피 홀짝", "sparkCount": "16"], + ["date": "2022-11-3", "userName": "우와", "sparkTitle": "홀짝 커피", "sparkCount": "17"], + ["date": "2022-11-3", "userName": "뭐지", "sparkTitle": "하하하하", "sparkCount": "18"], + ["date": "2022-11-3", "userName": "하하", "sparkTitle": "쉽지않네", "sparkCount": "19"], + ["date": "2022-11-3", "userName": "호호", "sparkTitle": "덤이데잍어", "sparkCount": "20"], + ["date": "2022-11-2", "userName": "s", "sparkTitle": "덤이데sdfdfdfdf잍어", "sparkCount": "21"], + ["date": "2022-11-2", "userName": "호sgggg호", "sparkTitle": "덤이sddd데잍어", "sparkCount": "22"] ] + + // MARK: - Properties + let collectionViewFlowlayout = UICollectionViewFlowLayout() + lazy var collectionView = UICollectionView(frame: .zero, collectionViewLayout: collectionViewFlowlayout) + var index = 0 + var dateList: [String] = [] + var firstList: [Any] = [] + var secondList: [Any] = [] + var thirdList: [Any] = [] + var fourthList: [Any] = [] + var fifthList: [Any] = [] + var sixthList: [Any] = [] + var seventhList: [Any] = [] + + // MARK: - View Life Cycles + override func viewDidLoad() { + super.viewDidLoad() + + setLayout() + setCollcetionView() + setData(datalist: dummyDataList) + } + + // MARK: - Methods + func setLayout() { + view.addSubview(collectionView) + + collectionView.snp.makeConstraints { make in + make.edges.equalTo(view.safeAreaLayoutGuide) + } + } + + func setData(datalist: Array>) { + var indexPath = 0 + var sectionCount = 0 /// section을 돌기 위한 변수 + +// print(dummyDataList[indexPath]["date"]) +// print(type(of: dummyDataList[indexPath]["date"])) +// print(dummyDataList[indexPath]) + +// print(datalist) +// print(type(of: datalist)) +// print(dummyDataList) +// print(type(of: dummyDataList)) + while indexPath < datalist.count { + if dateList.isEmpty { + dateList.append(datalist[indexPath]["date"] as! String) + indexPath += 1 + } else { + let day: String = datalist[indexPath]["date"] ?? "" + + if !(dateList.contains(day)) { + dateList.append(day) + } + + indexPath += 1 + } + } + + // TODO: - section별 리스트 생성 + while sectionCount < dateList.count { + var index = 0 + while index < datalist.count && !datalist.isEmpty && sectionCount != dateList.count { + + if dateList[sectionCount] == datalist[index]["date"] { + switch sectionCount { + case 0: + firstList.append(datalist[index]) + case 1: + secondList.append(datalist[index]) + case 2: + thirdList.append(datalist[index]) + case 3: + fourthList.append(datalist[index]) + case 4: + fifthList.append(datalist[index]) + case 5: + sixthList.append(datalist[index]) + case 6: + seventhList.append(datalist[index]) + default: + seventhList.append(datalist[index]) + } + + } + index += 1 + } + sectionCount += 1 + } + +// print("1: ", firstList) +// print("2: ", secondList) +// print("2: ", thirdList) +// print("4: ", fourthList) +// print("5: ", fifthList) +// print("6: ", sixthList) +// print("7: ", seventhList) +// print("-------------------------------------------------------") + } + + func setCollcetionView() { + collectionView.backgroundColor = .lightGray + collectionViewFlowlayout.scrollDirection = .vertical + collectionView.showsVerticalScrollIndicator = false + + /// cell register + collectionView.register(CustomCVC.self, forCellWithReuseIdentifier: CustomCVC.identifier) + collectionView.register(CustomHeaderView.self, forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader, withReuseIdentifier: CustomHeaderView.identifier) + + /// collectionView를 상단바 부분부터 시작하도록 하는 코드 +// collectionView.contentInset.top = -UIApplication.shared.statusBarFrame.height +// collectionView.contentInsetAdjustmentBehavior = .never + + /// delegate, datasource + collectionView.delegate = self + collectionView.dataSource = self + + /// sticky header을 가능하도록 하는 코드 + collectionViewFlowlayout.sectionHeadersPinToVisibleBounds = true + } +} + +// MARK: - extension +extension ViewController: UICollectionViewDelegate { + func numberOfSections(in collectionView: UICollectionView) -> Int { + return dateList.count + } +} + +extension ViewController: UICollectionViewDataSource { + func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { + var itemCount = 0 + var indexPath = 0 + + while indexPath < dummyDataList.count { + if dateList[section] == dummyDataList[indexPath]["date"] { + itemCount += 1 + indexPath += 1 + } else { + indexPath += 1 + } + } + + return itemCount + } + + func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { + guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: CustomCVC.identifier, for: indexPath) as? CustomCVC else { return UICollectionViewCell() } + + var alist: [String:String] = [:] + + // TODO: - section별 데이터 넣기 + switch indexPath.section { + case 0: + alist = firstList[indexPath.item] as! [String : String] + case 1: + alist = secondList[indexPath.item] as! [String : String] + case 2: + alist = thirdList[indexPath.item] as! [String : String] + case 3: + alist = fourthList[indexPath.item] as! [String : String] + case 4: + alist = fifthList[indexPath.item] as! [String : String] + case 5: + alist = sixthList[indexPath.item] as! [String : String] + case 6: + alist = seventhList[indexPath.item] as! [String : String] + default: + alist = firstList[indexPath.item] as! [String : String] + } + + cell.titleLabel.text = "\(String(describing: alist["sparkCount"]!))" + cell.userNameLabel.text = "\(String(describing: alist["userName"]!))" + cell.backgroundColor = .white + + return cell + } + + func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView { + guard let cell = collectionView.dequeueReusableSupplementaryView(ofKind: UICollectionView.elementKindSectionHeader, withReuseIdentifier: "CustomHeaderView", for: indexPath) as? CustomHeaderView else { return UICollectionReusableView() } + cell.dateLabel.text = "\(dateList[indexPath.section])" + cell.backgroundColor = .systemIndigo + + return cell + } + + func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize { + let width = UIScreen.main.bounds.width + + return CGSize(width: width, height: 60) + } + + func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) { + if (scrollView.contentOffset.y + 1) >= (scrollView.contentSize.height - scrollView.frame.size.height) { + if index < 1 { + dummyDataList.append(contentsOf: newDummyDataList) + setData(datalist: newDummyDataList) + collectionView.reloadData() + index += 1 + } else { + print("끝입니다") + } + } + } +} + +extension ViewController: UICollectionViewDelegateFlowLayout { + func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { + + let width = UIScreen.main.bounds.width + + return CGSize(width: width, height: 120) + } + + func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat { + + return 20 + } +} diff --git a/README.md b/README.md index 18783b1..9f61e15 100644 --- a/README.md +++ b/README.md @@ -7,5 +7,7 @@ Spark🎇 | 1 | 카카오 소셜로그인 구현 | [L-j-h-c](https://github.com/L-j-h-c) | [📎](https://github.com/TeamSparker/Spark-Practice-iOS/pull/9) | | 2 | 애플 소셜로그인 구현 | [yangsubinn](https://github.com/yangsubinn) | [📎](https://github.com/TeamSparker/Spark-Practice-iOS/pull/12) | | 3 | 플로팅버튼 구현(진행중) | [L-j-h-c](https://github.com/L-j-h-c) | | -| 4 | Carousel 구현 및 애니메이션 연습(진행중) | [L-j-h-c](https://github.com/L-j-h-c) | | -| 5 | 스톱워치 | [yangsubinn](https://github.com/yangsubinn) | [📎](https://github.com/TeamSparker/Spark-Practice-iOS/pull/15) | +| 4 | 플로팅버튼 구현 | [yangsubinn](https://github.com/yangsubinn) | [📎](https://github.com/TeamSparker/Spark-Practice-iOS/pull/18) | +| 5 | Carousel 구현 및 애니메이션 연습(진행중) | [L-j-h-c](https://github.com/L-j-h-c) | | +| 6 | 스톱워치 | [yangsubinn](https://github.com/yangsubinn) | [📎](https://github.com/TeamSparker/Spark-Practice-iOS/pull/15) | +| 7 | StickyHeader + 무한스크롤 | [yangsubinn](https://github.com/yangsubinn) | [📎](https://github.com/TeamSparker/Spark-Practice-iOS/pull/23) |