From 244b093ccc351da8c4c75018fc2655b50ded93d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=80=E1=85=B5=E1=86=B7=E1=84=90=E1=85=A2=E1=84=92?= =?UTF-8?q?=E1=85=A7=E1=86=BC=5BLINE=20MUSIC=20iOS=5D?= Date: Mon, 1 Jul 2024 11:19:14 +0900 Subject: [PATCH 1/4] =?UTF-8?q?sheetGradientView=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Sheet.xcodeproj/project.pbxproj | 23 +++++---- .../SheetContentsViewController.swift | 48 ++++++++++++++++++- Sources/SheetGradientView.swift | 15 ++++++ 3 files changed, 76 insertions(+), 10 deletions(-) create mode 100644 Sources/SheetGradientView.swift diff --git a/Sheet.xcodeproj/project.pbxproj b/Sheet.xcodeproj/project.pbxproj index 7e4080a..bd4f646 100644 --- a/Sheet.xcodeproj/project.pbxproj +++ b/Sheet.xcodeproj/project.pbxproj @@ -41,6 +41,7 @@ 4AEF0F4B2162441200FF034E /* UIEdgeInsets+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4AEF0F49216243C000FF034E /* UIEdgeInsets+Extension.swift */; }; 4AEF0F4E216244A100FF034E /* Optional+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4AEF0F4C2162449F00FF034E /* Optional+Extension.swift */; }; 4AEF0F5121624BF400FF034E /* MoveItemViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4AEF0F5021624BF400FF034E /* MoveItemViewController.swift */; }; + 8381AA602C3246F5004D10DD /* SheetGradientView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8381AA5F2C3246F5004D10DD /* SheetGradientView.swift */; }; 8933C7851EB5B820000D00A4 /* Sheet.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8933C7841EB5B820000D00A4 /* Sheet.swift */; }; CE4924A3226FFD9C00033244 /* FullViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE4924A2226FFD9C00033244 /* FullViewController.swift */; }; /* End PBXBuildFile section */ @@ -105,6 +106,7 @@ 4AEF0F4C2162449F00FF034E /* Optional+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Optional+Extension.swift"; sourceTree = ""; }; 4AEF0F5021624BF400FF034E /* MoveItemViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MoveItemViewController.swift; sourceTree = ""; }; 52D6D97C1BEFF229002C0205 /* Sheet.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Sheet.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 8381AA5F2C3246F5004D10DD /* SheetGradientView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SheetGradientView.swift; sourceTree = ""; }; 8933C7841EB5B820000D00A4 /* Sheet.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Sheet.swift; sourceTree = ""; }; 8933C7891EB5B82A000D00A4 /* SheetTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SheetTests.swift; sourceTree = ""; }; AD2FAA261CD0B6D800659CF4 /* Sheet.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Sheet.plist; sourceTree = ""; }; @@ -253,6 +255,7 @@ 4AEF0EEA216235F100FF034E /* Animator */, 4AEF0F4F216244CD00FF034E /* Extensions */, 8933C7841EB5B820000D00A4 /* Sheet.swift */, + 8381AA5F2C3246F5004D10DD /* SheetGradientView.swift */, ); path = Sources; sourceTree = ""; @@ -344,11 +347,12 @@ TargetAttributes = { 4AEF0F05216236A600FF034E = { CreatedOnToolsVersion = 9.3; - DevelopmentTeam = SV5LTS7ED5; + DevelopmentTeam = LJV6HBLFS3; ProvisioningStyle = Automatic; }; 52D6D97B1BEFF229002C0205 = { CreatedOnToolsVersion = 7.1; + DevelopmentTeam = LJV6HBLFS3; LastSwiftMigration = 0800; }; }; @@ -421,6 +425,7 @@ buildActionMask = 2147483647; files = ( 4AEF0EFE216235F200FF034E /* SheetDecorationView.swift in Sources */, + 8381AA602C3246F5004D10DD /* SheetGradientView.swift in Sources */, 4AEF0F4E216244A100FF034E /* Optional+Extension.swift in Sources */, 4AEF0F4521623FDD00FF034E /* SheetLayoutElement.swift in Sources */, 4AEF0F4221623F4600FF034E /* SheetManager.swift in Sources */, @@ -465,10 +470,10 @@ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_IDENTITY = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; - DEVELOPMENT_TEAM = SV5LTS7ED5; + DEVELOPMENT_TEAM = LJV6HBLFS3; GCC_C_LANGUAGE_STANDARD = gnu11; INFOPLIST_FILE = Example/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 10.0; + IPHONEOS_DEPLOYMENT_TARGET = 14.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.Gwangbeom.Example; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -494,10 +499,10 @@ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_IDENTITY = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; - DEVELOPMENT_TEAM = SV5LTS7ED5; + DEVELOPMENT_TEAM = LJV6HBLFS3; GCC_C_LANGUAGE_STANDARD = gnu11; INFOPLIST_FILE = Example/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 10.0; + IPHONEOS_DEPLOYMENT_TARGET = 14.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.Gwangbeom.Example; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -626,9 +631,9 @@ buildSettings = { APPLICATION_EXTENSION_API_ONLY = NO; CLANG_ENABLE_MODULES = YES; - CODE_SIGN_IDENTITY = "iPhone Developer"; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + CODE_SIGN_IDENTITY = "Apple Development"; DEFINES_MODULE = YES; + "DEVELOPMENT_TEAM[sdk=iphoneos*]" = LJV6HBLFS3; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; @@ -652,9 +657,9 @@ buildSettings = { APPLICATION_EXTENSION_API_ONLY = NO; CLANG_ENABLE_MODULES = YES; - CODE_SIGN_IDENTITY = "iPhone Developer"; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + CODE_SIGN_IDENTITY = "Apple Development"; DEFINES_MODULE = YES; + "DEVELOPMENT_TEAM[sdk=iphoneos*]" = LJV6HBLFS3; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; diff --git a/Sources/Controller/SheetContentsViewController.swift b/Sources/Controller/SheetContentsViewController.swift index b6d0568..9f86f13 100644 --- a/Sources/Controller/SheetContentsViewController.swift +++ b/Sources/Controller/SheetContentsViewController.swift @@ -9,15 +9,29 @@ import UIKit open class SheetContentsViewController: UICollectionViewController, SheetContent { + private var sheetTopGradientView: SheetGradientView? private var options: SheetOptions { return SheetManager.shared.options } private var layout = SheetContentsLayout() + private var isSheetTopGradientViewAnimating = false public var topMargin: CGFloat = 0 + public var sheetTopGradientViewHeight: CGFloat { + return 56.0 + statusBarHeight + } + + private var statusBarHeight: CGFloat { + if #available(iOS 13.0, *) { + return UIApplication.shared.windows.first { $0.isKeyWindow }?.windowScene?.statusBarManager?.statusBarFrame.height ?? 0 + } else { + return UIApplication.shared.statusBarFrame.height + } + } + public var contentScrollView: UIScrollView { return collectionView } @@ -72,7 +86,27 @@ open class SheetContentsViewController: UICollectionViewController, SheetContent } open override func scrollViewDidScroll(_ scrollView: UIScrollView) { - topMargin = max(layout.settings.topMargin - scrollView.contentOffset.y, 0) + let yOffset = scrollView.contentOffset.y + topMargin = max(layout.settings.topMargin - yOffset, 0) + + guard !isSheetTopGradientViewAnimating, let sheetTopGradientView else { return } + if yOffset > statusBarHeight && sheetTopGradientView.isHidden == true { + isSheetTopGradientViewAnimating = true + UIView.animate(withDuration: 0.3, animations: { [weak self] in + guard let self else { return } + sheetTopGradientView.isHidden = false + self.view.bringSubviewToFront(sheetTopGradientView) + }, completion: { [weak self] _ in + self?.isSheetTopGradientViewAnimating = false + }) + } else if yOffset <= statusBarHeight && sheetTopGradientView.isHidden == false { + isSheetTopGradientViewAnimating = true + UIView.animate(withDuration: 0.3, animations: { + sheetTopGradientView.isHidden = true + }, completion: { [weak self] _ in + self?.isSheetTopGradientViewAnimating = false + }) + } } open override func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer) { @@ -128,6 +162,18 @@ private extension SheetContentsViewController { view.backgroundColor = .clear setupContainerView() setupDimmingView() + setupTopGradientView() + } + + func setupTopGradientView() { + guard sheetTopGradientViewHeight > 0 else { return } + sheetTopGradientView = SheetGradientView(frame: CGRect(x: 0, y: 0, width: view.bounds.width, height: sheetTopGradientViewHeight)) + guard let sheetTopGradientView else { return } + let backgroundColor = options.dimmingViewBackgroundColor + sheetTopGradientView.isHidden = true + view.addSubview(sheetTopGradientView) + let topGradientLayer = sheetTopGradientView.layer as? CAGradientLayer + topGradientLayer?.colors = [backgroundColor.cgColor, backgroundColor.cgColor, backgroundColor.withAlphaComponent(0).cgColor] } func setupContainerView() { diff --git a/Sources/SheetGradientView.swift b/Sources/SheetGradientView.swift new file mode 100644 index 0000000..c6a558c --- /dev/null +++ b/Sources/SheetGradientView.swift @@ -0,0 +1,15 @@ +// +// SheetGradientView.swift +// Sheet-iOS +// +// Created by taeHyeongKim on 7/1/24. +// Copyright © 2024 Interactive. All rights reserved. +// + +import UIKit + +class SheetGradientView: UIView { + override final class var layerClass: AnyClass { + return CAGradientLayer.self + } +} From eb1280706d02266bb9412725016c5948e074e893 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=80=E1=85=B5=E1=86=B7=E1=84=90=E1=85=A2=E1=84=92?= =?UTF-8?q?=E1=85=A7=E1=86=BC=5BLINE=20MUSIC=20iOS=5D?= Date: Mon, 1 Jul 2024 12:00:38 +0900 Subject: [PATCH 2/4] =?UTF-8?q?=EC=B6=94=EA=B0=80=20=EB=94=94=ED=85=8C?= =?UTF-8?q?=EC=9D=BC=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../SheetContentsViewController.swift | 21 +++++++++++-------- Sources/Manager/SheetOptions.swift | 3 +++ 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/Sources/Controller/SheetContentsViewController.swift b/Sources/Controller/SheetContentsViewController.swift index 9f86f13..2687d6d 100644 --- a/Sources/Controller/SheetContentsViewController.swift +++ b/Sources/Controller/SheetContentsViewController.swift @@ -21,6 +21,7 @@ open class SheetContentsViewController: UICollectionViewController, SheetContent public var topMargin: CGFloat = 0 public var sheetTopGradientViewHeight: CGFloat { + guard options.useSheetTopGradientView else { return 0 } return 56.0 + statusBarHeight } @@ -89,21 +90,23 @@ open class SheetContentsViewController: UICollectionViewController, SheetContent let yOffset = scrollView.contentOffset.y topMargin = max(layout.settings.topMargin - yOffset, 0) - guard !isSheetTopGradientViewAnimating, let sheetTopGradientView else { return } - if yOffset > statusBarHeight && sheetTopGradientView.isHidden == true { + guard !isSheetTopGradientViewAnimating, let sheetTopGradientView = sheetTopGradientView else { return } + if topMargin < statusBarHeight && sheetTopGradientView.isHidden == true { isSheetTopGradientViewAnimating = true - UIView.animate(withDuration: 0.3, animations: { [weak self] in - guard let self else { return } - sheetTopGradientView.isHidden = false - self.view.bringSubviewToFront(sheetTopGradientView) + sheetTopGradientView.alpha = 0.0 + sheetTopGradientView.isHidden = false + UIView.animate(withDuration: 0.2, animations: { [weak self] in + sheetTopGradientView.alpha = 1.0 + self?.view.bringSubviewToFront(sheetTopGradientView) }, completion: { [weak self] _ in self?.isSheetTopGradientViewAnimating = false }) - } else if yOffset <= statusBarHeight && sheetTopGradientView.isHidden == false { + } else if topMargin >= statusBarHeight && sheetTopGradientView.isHidden == false { isSheetTopGradientViewAnimating = true - UIView.animate(withDuration: 0.3, animations: { - sheetTopGradientView.isHidden = true + UIView.animate(withDuration: 0.2, animations: { + sheetTopGradientView.alpha = 0.0 }, completion: { [weak self] _ in + sheetTopGradientView.isHidden = true self?.isSheetTopGradientViewAnimating = false }) } diff --git a/Sources/Manager/SheetOptions.swift b/Sources/Manager/SheetOptions.swift index c50e87a..c197eb5 100644 --- a/Sources/Manager/SheetOptions.swift +++ b/Sources/Manager/SheetOptions.swift @@ -78,6 +78,9 @@ public struct SheetOptions { /// sheet background color public var sheetBackgroundColor: UIColor = .white + + /// sheet top area gradient background view + public var useSheetTopGradientView = true } public struct SheetAnimationOption { From b3eff09069ae6163ba6f53312704611125b7b0cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=80=E1=85=B5=E1=86=B7=E1=84=90=E1=85=A2=E1=84=92?= =?UTF-8?q?=E1=85=A7=E1=86=BC=5BLINE=20MUSIC=20iOS=5D?= Date: Mon, 1 Jul 2024 12:11:20 +0900 Subject: [PATCH 3/4] =?UTF-8?q?=EC=B6=94=EA=B0=80=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Sources/Controller/SheetContentsViewController.swift | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/Sources/Controller/SheetContentsViewController.swift b/Sources/Controller/SheetContentsViewController.swift index 2687d6d..90af352 100644 --- a/Sources/Controller/SheetContentsViewController.swift +++ b/Sources/Controller/SheetContentsViewController.swift @@ -26,11 +26,7 @@ open class SheetContentsViewController: UICollectionViewController, SheetContent } private var statusBarHeight: CGFloat { - if #available(iOS 13.0, *) { - return UIApplication.shared.windows.first { $0.isKeyWindow }?.windowScene?.statusBarManager?.statusBarFrame.height ?? 0 - } else { - return UIApplication.shared.statusBarFrame.height - } + return UIApplication.shared.windows.first { $0.isKeyWindow }?.windowScene?.statusBarManager?.statusBarFrame.height ?? 0 } public var contentScrollView: UIScrollView { From 8aeb7a11b01ebce21819947b46783b3ec08a3037 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=80=E1=85=B5=E1=86=B7=E1=84=90=E1=85=A2=E1=84=92?= =?UTF-8?q?=E1=85=A7=E1=86=BC=5BLINE=20MUSIC=20iOS=5D?= Date: Tue, 2 Jul 2024 10:44:45 +0900 Subject: [PATCH 4/4] =?UTF-8?q?=EB=A6=AC=EB=B7=B0=20=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Sources/Controller/SheetContentsViewController.swift | 7 +++---- Sources/Manager/SheetOptions.swift | 3 --- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/Sources/Controller/SheetContentsViewController.swift b/Sources/Controller/SheetContentsViewController.swift index 90af352..bb8c762 100644 --- a/Sources/Controller/SheetContentsViewController.swift +++ b/Sources/Controller/SheetContentsViewController.swift @@ -20,9 +20,8 @@ open class SheetContentsViewController: UICollectionViewController, SheetContent public var topMargin: CGFloat = 0 - public var sheetTopGradientViewHeight: CGFloat { - guard options.useSheetTopGradientView else { return 0 } - return 56.0 + statusBarHeight + open var sheetTopGradientViewHeight: CGFloat? { + return nil } private var statusBarHeight: CGFloat { @@ -165,7 +164,7 @@ private extension SheetContentsViewController { } func setupTopGradientView() { - guard sheetTopGradientViewHeight > 0 else { return } + guard let sheetTopGradientViewHeight else { return } sheetTopGradientView = SheetGradientView(frame: CGRect(x: 0, y: 0, width: view.bounds.width, height: sheetTopGradientViewHeight)) guard let sheetTopGradientView else { return } let backgroundColor = options.dimmingViewBackgroundColor diff --git a/Sources/Manager/SheetOptions.swift b/Sources/Manager/SheetOptions.swift index c197eb5..c50e87a 100644 --- a/Sources/Manager/SheetOptions.swift +++ b/Sources/Manager/SheetOptions.swift @@ -78,9 +78,6 @@ public struct SheetOptions { /// sheet background color public var sheetBackgroundColor: UIColor = .white - - /// sheet top area gradient background view - public var useSheetTopGradientView = true } public struct SheetAnimationOption {