Commit 0008e4629946c3885e689b1ef71c0dc33b540b04

Authored by 张旭
1 parent d2a651c3

下滑动画的效果

metaCode.xcodeproj/project.pbxproj
... ... @@ -9,6 +9,14 @@
9 9 /* Begin PBXBuildFile section */
10 10 0D39E93D7229931C86EB1161 /* Pods_metaCode_metaCodeUITests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D879B49B1E42F1584DD75E /* Pods_metaCode_metaCodeUITests.framework */; };
11 11 19123FC12ABC11170075C883 /* CNWebViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19123FC02ABC11170075C883 /* CNWebViewController.swift */; };
  12 + 192336EB2AD9224300D47CD4 /* CNUpSlideViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 192336EA2AD9224300D47CD4 /* CNUpSlideViewController.swift */; };
  13 + 19CC4D472ADD006600308E2A /* CNDownSlideCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19CC4D462ADD006600308E2A /* CNDownSlideCell.swift */; };
  14 + 19CC4D492ADD06C500308E2A /* UITableView+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19CC4D482ADD06C500308E2A /* UITableView+Extension.swift */; };
  15 + 19CC4D4B2ADD086F00308E2A /* CNUpSlideDetailViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19CC4D4A2ADD086F00308E2A /* CNUpSlideDetailViewController.swift */; };
  16 + 19CC4D4F2ADD0FC200308E2A /* CNUpSlideDetailScrollView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19CC4D4E2ADD0FC200308E2A /* CNUpSlideDetailScrollView.swift */; };
  17 + 19CC4D522ADD129800308E2A /* CNUpSlideAnimationTransition.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19CC4D512ADD129800308E2A /* CNUpSlideAnimationTransition.swift */; };
  18 + 19CC4D542ADD163D00308E2A /* CNUpSlideCardPresentationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19CC4D532ADD163D00308E2A /* CNUpSlideCardPresentationController.swift */; };
  19 + 19CC4D562ADD19C200308E2A /* String+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19CC4D552ADD19C200308E2A /* String+Extension.swift */; };
12 20 19F1C2332AB5728B0083D06C /* CNIDCardView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19F1C2322AB5728B0083D06C /* CNIDCardView.swift */; };
13 21 1DD2808DF02C120276F99F4D /* Pods_metaCode.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F1C55A719CFEE073C06D37CE /* Pods_metaCode.framework */; };
14 22 7905BB492AB0588B0089BC50 /* CNLiveMineAuthResultViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7905BB482AB0588B0089BC50 /* CNLiveMineAuthResultViewController.swift */; };
... ... @@ -116,6 +124,14 @@
116 124 0EC910AB9EBD717B04432BC4 /* Pods-metaCode-metaCodeUITests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-metaCode-metaCodeUITests.debug.xcconfig"; path = "Target Support Files/Pods-metaCode-metaCodeUITests/Pods-metaCode-metaCodeUITests.debug.xcconfig"; sourceTree = "<group>"; };
117 125 170BC5D0622EA2969D110A3B /* Pods-metaCode.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-metaCode.release.xcconfig"; path = "Target Support Files/Pods-metaCode/Pods-metaCode.release.xcconfig"; sourceTree = "<group>"; };
118 126 19123FC02ABC11170075C883 /* CNWebViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CNWebViewController.swift; sourceTree = "<group>"; };
  127 + 192336EA2AD9224300D47CD4 /* CNUpSlideViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CNUpSlideViewController.swift; sourceTree = "<group>"; };
  128 + 19CC4D462ADD006600308E2A /* CNDownSlideCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CNDownSlideCell.swift; sourceTree = "<group>"; };
  129 + 19CC4D482ADD06C500308E2A /* UITableView+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UITableView+Extension.swift"; sourceTree = "<group>"; };
  130 + 19CC4D4A2ADD086F00308E2A /* CNUpSlideDetailViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CNUpSlideDetailViewController.swift; sourceTree = "<group>"; };
  131 + 19CC4D4E2ADD0FC200308E2A /* CNUpSlideDetailScrollView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CNUpSlideDetailScrollView.swift; sourceTree = "<group>"; };
  132 + 19CC4D512ADD129800308E2A /* CNUpSlideAnimationTransition.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CNUpSlideAnimationTransition.swift; sourceTree = "<group>"; };
  133 + 19CC4D532ADD163D00308E2A /* CNUpSlideCardPresentationController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CNUpSlideCardPresentationController.swift; sourceTree = "<group>"; };
  134 + 19CC4D552ADD19C200308E2A /* String+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "String+Extension.swift"; sourceTree = "<group>"; };
119 135 19F1C2322AB5728B0083D06C /* CNIDCardView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CNIDCardView.swift; sourceTree = "<group>"; };
120 136 54E09C540E13D78166D71395 /* Pods_metaCodeTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_metaCodeTests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
121 137 63D879B49B1E42F1584DD75E /* Pods_metaCode_metaCodeUITests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_metaCode_metaCodeUITests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
... ... @@ -241,6 +257,14 @@
241 257 /* End PBXFrameworksBuildPhase section */
242 258  
243 259 /* Begin PBXGroup section */
  260 + 19CC4D502ADD126D00308E2A /* Util */ = {
  261 + isa = PBXGroup;
  262 + children = (
  263 + 19CC4D512ADD129800308E2A /* CNUpSlideAnimationTransition.swift */,
  264 + );
  265 + path = Util;
  266 + sourceTree = "<group>";
  267 + };
244 268 20238A324E444EF8C813D9FA /* Pods */ = {
245 269 isa = PBXGroup;
246 270 children = (
... ... @@ -268,6 +292,8 @@
268 292 7C83B4432A541F36004BF4A4 /* NSDate+CNLiveExtensions.swift */,
269 293 79E496E22AB9357000127BF8 /* UITableViewCell+CNLiveExtension.swift */,
270 294 79E496E72AB9674300127BF8 /* NSMutableAttributedString+CNLiveExtensions.swift */,
  295 + 19CC4D482ADD06C500308E2A /* UITableView+Extension.swift */,
  296 + 19CC4D552ADD19C200308E2A /* String+Extension.swift */,
271 297 );
272 298 path = Extensions;
273 299 sourceTree = "<group>";
... ... @@ -534,6 +560,7 @@
534 560 7CD675212A26F844008354C1 /* HomePage */ = {
535 561 isa = PBXGroup;
536 562 children = (
  563 + 19CC4D502ADD126D00308E2A /* Util */,
537 564 7C83B43C2A52B899004BF4A4 /* ViewModel */,
538 565 7CD6754D2A2840B9008354C1 /* Controller */,
539 566 7CD675232A26F8F8008354C1 /* View */,
... ... @@ -554,6 +581,8 @@
554 581 7C4931372A307BDB000E44B4 /* CNHomePageGuideView.swift */,
555 582 7C27032F2A36CBE30061EC50 /* CNCertificationView.swift */,
556 583 19F1C2322AB5728B0083D06C /* CNIDCardView.swift */,
  584 + 19CC4D462ADD006600308E2A /* CNDownSlideCell.swift */,
  585 + 19CC4D4E2ADD0FC200308E2A /* CNUpSlideDetailScrollView.swift */,
557 586 );
558 587 name = View;
559 588 path = HomePage/View;
... ... @@ -564,6 +593,9 @@
564 593 children = (
565 594 7CD6754E2A2840B9008354C1 /* CNMetaCodeHomePageController.swift */,
566 595 19123FC02ABC11170075C883 /* CNWebViewController.swift */,
  596 + 192336EA2AD9224300D47CD4 /* CNUpSlideViewController.swift */,
  597 + 19CC4D4A2ADD086F00308E2A /* CNUpSlideDetailViewController.swift */,
  598 + 19CC4D532ADD163D00308E2A /* CNUpSlideCardPresentationController.swift */,
567 599 );
568 600 name = Controller;
569 601 path = HomePage/Controller;
... ... @@ -877,6 +909,7 @@
877 909 796398942A260C0100D045EB /* AppDelegate.swift in Sources */,
878 910 7989B5C72A4BDC7200A19B10 /* CNLiveMineEarnListViewController.swift in Sources */,
879 911 79396EF12A31C21B0053E1AF /* CNLiveInfoShowViewController.swift in Sources */,
  912 + 192336EB2AD9224300D47CD4 /* CNUpSlideViewController.swift in Sources */,
880 913 7963989D2A260E6200D045EB /* CNLiveBaseViewController.swift in Sources */,
881 914 798A44FB2A30999900815935 /* CNLiveAlertTool.swift in Sources */,
882 915 790D01A52A2DF65E00C5978D /* CNLiveLoginPickerView.swift in Sources */,
... ... @@ -885,11 +918,13 @@
885 918 790B1FB82A41B6A60074CF00 /* CNLiveMineMessageViewController.swift in Sources */,
886 919 798A44F22A30674200815935 /* CNLiveMineSubBodyListView.swift in Sources */,
887 920 790D01822A2D88FC00C5978D /* CNLiveConfigMacro.swift in Sources */,
  921 + 19CC4D4B2ADD086F00308E2A /* CNUpSlideDetailViewController.swift in Sources */,
888 922 7C83B4402A52BB2B004BF4A4 /* CNGlobalEnum.swift in Sources */,
889 923 7C83B4442A541F36004BF4A4 /* NSDate+CNLiveExtensions.swift in Sources */,
890 924 7CD675482A274167008354C1 /* PGIndexBannerSubiew.m in Sources */,
891 925 790D019F2A2DD66E00C5978D /* CNLiveLoginViewModel.swift in Sources */,
892 926 7C7C62F62A4D72E9007A912E /* CNLiveIdentityDB.swift in Sources */,
  927 + 19CC4D4F2ADD0FC200308E2A /* CNUpSlideDetailScrollView.swift in Sources */,
893 928 79EABB892AB4497700F3A4E2 /* CNLiveSaveStandDB.swift in Sources */,
894 929 790B1FB62A41938F0074CF00 /* UIImage+CNLiveExtensions.swift in Sources */,
895 930 790D019D2A2DCBD000C5978D /* UIView+CNLiveExtensions.swift in Sources */,
... ... @@ -900,6 +935,7 @@
900 935 790B1FB62A41938F0074CF00 /* UIImage+CNLiveExtensions.swift in Sources */,
901 936 790D019D2A2DCBD000C5978D /* UIView+CNLiveExtensions.swift in Sources */,
902 937 79E496E82AB9674300127BF8 /* NSMutableAttributedString+CNLiveExtensions.swift in Sources */,
  938 + 19CC4D472ADD006600308E2A /* CNDownSlideCell.swift in Sources */,
903 939 79E496E32AB9357000127BF8 /* UITableViewCell+CNLiveExtension.swift in Sources */,
904 940 7C83B4422A541EBF004BF4A4 /* CALayer+CNLiveExtensions.swift in Sources */,
905 941 798A44F72A3077ED00815935 /* CNLiveHotButton.swift in Sources */,
... ... @@ -917,6 +953,7 @@
917 953 7C2703362A3AFD3A0061EC50 /* CNLiveEnvironment.swift in Sources */,
918 954 798A44FD2A309EBA00815935 /* CNLiveTypeFeedBackViewController.swift in Sources */,
919 955 79656E382AAEBA8E00119A61 /* CNLiveMineInputViewController.swift in Sources */,
  956 + 19CC4D522ADD129800308E2A /* CNUpSlideAnimationTransition.swift in Sources */,
920 957 7CD6754F2A2840B9008354C1 /* CNMetaCodeHomePageController.swift in Sources */,
921 958 7989B5C52A4BDC6000A19B10 /* CNLiveMineEarnViewController.swift in Sources */,
922 959 792E57DB2A3AE9F4005834DB /* CNLiveCommonQiniuTool.swift in Sources */,
... ... @@ -925,7 +962,9 @@
925 962 798A44FF2A30A0A800815935 /* CNLiveInputFeedBackViewController.swift in Sources */,
926 963 79282A442A2F1C1E00B5F8CF /* CNLiveLoginAuthView.swift in Sources */,
927 964 7C2703302A36CBE30061EC50 /* CNCertificationView.swift in Sources */,
  965 + 19CC4D542ADD163D00308E2A /* CNUpSlideCardPresentationController.swift in Sources */,
928 966 790D01A32A2DDBA300C5978D /* CNLiveConfigManager.swift in Sources */,
  967 + 19CC4D492ADD06C500308E2A /* UITableView+Extension.swift in Sources */,
929 968 7C2703332A36CC660061EC50 /* CNLiveGlobalBlock.swift in Sources */,
930 969 7987BF3D2A497644000A1ABC /* CNLiveMineQuestViewController.swift in Sources */,
931 970 798A44EA2A30135D00815935 /* CNLiveMineBodyListView.swift in Sources */,
... ... @@ -935,6 +974,7 @@
935 974 79396EED2A319F220053E1AF /* NSObject+CNLiveExtensions.swift in Sources */,
936 975 7C4931312A2F142F000E44B4 /* CNHomePageBackgroupView.swift in Sources */,
937 976 790D018B2A2D8B3300C5978D /* CNLiveLoginViewController.swift in Sources */,
  977 + 19CC4D562ADD19C200308E2A /* String+Extension.swift in Sources */,
938 978 7905BB492AB0588B0089BC50 /* CNLiveMineAuthResultViewController.swift in Sources */,
939 979 798A44EC2A302DBE00815935 /* CNLiveMineAddInfoViewController.swift in Sources */,
940 980 7CD675422A2740F8008354C1 /* CNCustomIndexView.swift in Sources */,
... ...
metaCode/Classes/Extensions/String+Extension.swift 0 → 100644
  1 +//
  2 +// String+Extension.swift
  3 +// metaCode
  4 +//
  5 +// Created by zx on 2023/10/16.
  6 +//
  7 +
  8 +
  9 +import UIKit
  10 +
  11 +
  12 +extension String {
  13 + /// Calculate text's height from `width` and `front`.
  14 + func calculateHeightWith(width: CGFloat, font: UIFont)-> CGFloat {
  15 + let attr = [NSAttributedString.Key.font: font]
  16 + let maxSize: CGSize = CGSize(width: width, height: CGFloat(MAXFLOAT))
  17 + let option = NSStringDrawingOptions.usesLineFragmentOrigin
  18 + return self.boundingRect(with: (maxSize), options: option, attributes: attr, context: nil).size.height
  19 + }
  20 +}
... ...
metaCode/Classes/Extensions/UITableView+Extension.swift 0 → 100644
  1 +//
  2 +// UITableView+Extension.swift
  3 +// metaCode
  4 +//
  5 +// Created by zx on 2023/10/16.
  6 +//
  7 +
  8 +
  9 +import UIKit
  10 +
  11 +extension UITableView {
  12 + // 注册有nib的cell
  13 + func ut_registerNibCell<T>(_ cellType: T.Type) where T: UITableViewCell {
  14 + let nib = UINib(nibName: "\(cellType)", bundle: nil)
  15 + let identifier = "\(cellType)"
  16 + register(nib, forCellReuseIdentifier: identifier)
  17 + }
  18 + // 注册无nib的cell
  19 + func ut_registerClassCell<T>(_ cellType: T.Type) where T: UITableViewCell {
  20 + let identifier = "\(cellType)"
  21 + register(cellType, forCellReuseIdentifier: identifier)
  22 + }
  23 + // 从缓存池池出队已经存在的 cell
  24 + func ut_dequeueReusable<T: UITableViewCell>(_ cell: T.Type, for indexPath: IndexPath) -> T {
  25 + let cell = dequeueReusableCell(withIdentifier: "\(T.self)", for: indexPath) as! T
  26 + return cell
  27 + }
  28 +
  29 + // 注册有nib的headerFooterView
  30 + func ut_registerNibHeaderFooterView<T>(_ viewType: T.Type) where T: UITableViewHeaderFooterView {
  31 + let nib = UINib(nibName: "\(viewType)", bundle: nil)
  32 + let identifier = "\(viewType)"
  33 + register(nib, forHeaderFooterViewReuseIdentifier: identifier)
  34 + }
  35 +
  36 + // 注册无nib的headerFooterView
  37 + func ut_registerClassHeaderFooterView<T>(_ viewType: T.Type) where T: UITableViewHeaderFooterView {
  38 + let identifier = "\(viewType)"
  39 + register(viewType, forHeaderFooterViewReuseIdentifier: identifier)
  40 + }
  41 +
  42 + // 从缓存池里取出已注册的headerFooterView
  43 + func ut_dequeueReusableHeaderFooterView<T: UITableViewHeaderFooterView>(_ view: T.Type) -> T {
  44 + let headerFooterView = dequeueReusableHeaderFooterView(withIdentifier: "\(T.self)") as! T
  45 + return headerFooterView
  46 + }
  47 +}
  48 +
  49 +extension UICollectionView {
  50 + // 注册有nib的cell
  51 + func ut_registerNibCell<T>(_ cellType: T.Type) where T: UICollectionViewCell {
  52 + let nib = UINib(nibName: "\(cellType)", bundle: nil)
  53 + let identifier = "\(cellType)"
  54 + register(nib, forCellWithReuseIdentifier: identifier)
  55 + }
  56 + // 注册无nib的cell
  57 + func ut_registerClassCell<T>(_ cellType: T.Type) where T: UICollectionViewCell {
  58 + let identifier = "\(cellType)"
  59 + register(cellType, forCellWithReuseIdentifier: identifier)
  60 + }
  61 + // 从缓存池池出队已经存在的 cell
  62 + func ut_dequeueReusable<T: UICollectionViewCell>(_ cell: T.Type, for indexPath: IndexPath) -> T {
  63 + let cell = dequeueReusableCell(withReuseIdentifier: "\(T.self)", for: indexPath) as! T
  64 + return cell
  65 + }
  66 +}
... ...
metaCode/Classes/Extensions/UIView+CNLiveExtensions.swift
... ... @@ -235,4 +235,14 @@ extension UIView {
235 235 return self.frame.size
236 236 }
237 237 }
  238 +
  239 + // Constrain 4 edges of `self` to specified `view`.
  240 + func edges(to view: UIView, top: CGFloat=0, left: CGFloat=0, bottom: CGFloat=0, right: CGFloat=0) {
  241 + NSLayoutConstraint.activate([
  242 + self.leftAnchor.constraint(equalTo: view.leftAnchor, constant: left),
  243 + self.rightAnchor.constraint(equalTo: view.rightAnchor, constant: right),
  244 + self.topAnchor.constraint(equalTo: view.topAnchor, constant: top),
  245 + self.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: bottom)
  246 + ])
  247 + }
238 248 }
... ...
metaCode/Classes/Main/HomePage/Controller/CNMetaCodeHomePageController.swift
... ... @@ -18,6 +18,8 @@ let LeftGap: CGFloat = UIScreen.main.bounds.size.width &lt;= 375 ? 23 : 40
18 18  
19 19 ///主窗口宽度
20 20 let MainViewW: CGFloat = Width-LeftGap*2//Width-50
  21 +///下滑页底部工具条高度
  22 +let DownSllideBottomViewHeight: CGFloat = 74
21 23  
22 24 ///存储是否第一次显示首页上滑引导
23 25 let CNKeyIsFirstAppearUpSlideHomeGuide: String = "isFirstAppearUpSlideHomeGuideKey"
... ...
metaCode/Classes/Main/HomePage/Controller/CNUpSlideCardPresentationController.swift 0 → 100644
  1 +//
  2 +// CNUpSlideCardPresentationController.swift
  3 +// metaCode
  4 +//
  5 +// Created by zx on 2023/10/16.
  6 +//
  7 +
  8 +import UIKit
  9 +
  10 +class CNUpSlideCardPresentationController: UIPresentationController {
  11 +
  12 + private lazy var blurView = UIVisualEffectView(effect: nil)
  13 +
  14 + override var shouldRemovePresentersView: Bool {
  15 + return false
  16 + }
  17 +
  18 + override func presentationTransitionWillBegin() {
  19 + let container = containerView!
  20 + blurView.translatesAutoresizingMaskIntoConstraints = false
  21 + container.addSubview(blurView)
  22 + blurView.edges(to: container)
  23 + blurView.alpha = 0.0
  24 +
  25 + presentingViewController.beginAppearanceTransition(false, animated: false)
  26 + presentedViewController.transitionCoordinator!.animate(alongsideTransition: { (ctx) in
  27 + self.blurView.effect = UIBlurEffect(style: .light)
  28 + self.blurView.alpha = 1
  29 + }) { (ctx) in }
  30 + }
  31 +
  32 + override func presentationTransitionDidEnd(_ completed: Bool) {
  33 + presentingViewController.endAppearanceTransition()
  34 + }
  35 +
  36 + override func dismissalTransitionWillBegin() {
  37 + presentingViewController.beginAppearanceTransition(true, animated: true)
  38 + presentedViewController.transitionCoordinator!.animate(alongsideTransition: { (ctx) in
  39 + self.blurView.alpha = 0.0
  40 + }, completion: nil)
  41 + }
  42 +
  43 + override func dismissalTransitionDidEnd(_ completed: Bool) {
  44 + presentingViewController.endAppearanceTransition()
  45 + if completed {
  46 + blurView.removeFromSuperview()
  47 + }
  48 + }
  49 +}
... ...
metaCode/Classes/Main/HomePage/Controller/CNUpSlideDetailViewController.swift 0 → 100644
  1 +//
  2 +// CNUpSlideDetailViewController.swift
  3 +// metaCode
  4 +//
  5 +// Created by zx on 2023/10/16.
  6 +//
  7 +
  8 +import Foundation
  9 +
  10 +class CNUpSlideDetailViewController: UIViewController {
  11 +
  12 + override var prefersStatusBarHidden: Bool {
  13 + return true
  14 + }
  15 +
  16 + var dismissClosure: (()->())?
  17 + //the point when start to interactive
  18 + var interactiveStartingPoint: CGPoint? = nil
  19 +
  20 + var draggingDownToDismiss = false
  21 +
  22 + let cell: CNDownSlideCell!
  23 +
  24 + private lazy var dismissPanGesture: UIPanGestureRecognizer = {
  25 + let ges = UIPanGestureRecognizer()
  26 + ges.maximumNumberOfTouches = 1
  27 + ges.addTarget(self, action: #selector(handleDismissPan(gesture:)))
  28 + ges.delegate = self
  29 + return ges
  30 + }()
  31 +
  32 + lazy var scrollView: CNUpSlideDetailScrollView = {
  33 + let frame = self.view.bounds
  34 + let view = CNUpSlideDetailScrollView(frame: frame)
  35 + view.delegate = self
  36 + return view
  37 + }()
  38 +
  39 + lazy var closeBtn: UIButton = {
  40 + let btn = UIButton()
  41 + btn.frame = CGRect(x: KSreenWidth - 20 - 30, y: 20, width: 30, height: 30)
  42 + btn.setImage(#imageLiteral(resourceName: "close_button"), for: .normal)
  43 + btn.addTarget(self, action: #selector(closeAction), for: .touchUpInside)
  44 + return btn
  45 + }()
  46 +
  47 + init(cell: CNDownSlideCell) {
  48 + self.cell = cell
  49 + super.init(nibName: nil, bundle: nil)
  50 + self.setupTranstion()
  51 + }
  52 +
  53 + override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
  54 + print("DetailtouchesBegan")
  55 + }
  56 +
  57 + private func setupTranstion() {
  58 + modalPresentationStyle = .custom
  59 + transitioningDelegate = self
  60 + }
  61 +
  62 + required init?(coder aDecoder: NSCoder) {
  63 + fatalError("init(coder:) has not been implemented")
  64 + }
  65 +
  66 + override func viewDidLoad() {
  67 + super.viewDidLoad()
  68 + setupUI()
  69 + getImageFromCell()
  70 + }
  71 +
  72 + private func setupUI() {
  73 + self.view.backgroundColor = .white
  74 + self.view.layer.masksToBounds = true
  75 + view.addSubview(scrollView)
  76 + view.addSubview(closeBtn)
  77 + view.addGestureRecognizer(dismissPanGesture)
  78 +
  79 + if #available(iOS 11.0, *) {
  80 + scrollView.contentInsetAdjustmentBehavior = .never
  81 + } else {
  82 + automaticallyAdjustsScrollViewInsets = false
  83 + }
  84 + }
  85 +
  86 + private func getImageFromCell() {
  87 + scrollView.imageView.image = cell.bgImageView.image
  88 + }
  89 +
  90 + @objc private func closeAction() {
  91 + dismiss(animated: true, completion: nil)
  92 + dismissClosure?()
  93 + }
  94 +
  95 + @objc private func handleDismissPan(gesture: UIPanGestureRecognizer) {
  96 + if !draggingDownToDismiss {
  97 + return
  98 + }
  99 +
  100 + let startingPoint: CGPoint
  101 +
  102 + if let p = interactiveStartingPoint {
  103 + startingPoint = p
  104 + } else {
  105 + startingPoint = gesture.location(in: nil)
  106 + interactiveStartingPoint = startingPoint
  107 + }
  108 +
  109 + let currentLocation = gesture.location(in: nil)
  110 +
  111 + var progress = (currentLocation.y - startingPoint.y) / 100
  112 +
  113 + //prevent viewController bigger when scrolling up
  114 + if currentLocation.y <= startingPoint.y {
  115 + progress = 0
  116 + }
  117 +
  118 + if progress >= 1.0 {
  119 + dismiss(animated: true, completion: nil)
  120 + dismissClosure?()
  121 + stopDismissPanGesture(gesture)
  122 + return
  123 + }
  124 +
  125 + let targetShrinkScale: CGFloat = 0.86
  126 + let currentScale: CGFloat = 1 - (1 - targetShrinkScale) * progress
  127 +
  128 + switch gesture.state {
  129 + case .began,.changed:
  130 + scrollView.isScrollEnabled = false
  131 + gesture.view?.transform = CGAffineTransform(scaleX: currentScale, y: currentScale)
  132 + gesture.view?.layer.cornerRadius = GlobalConstants.toDayCardCornerRadius * (progress)
  133 + scrollView.showsVerticalScrollIndicator = false
  134 + case .cancelled,.ended:
  135 + scrollView.isScrollEnabled = true
  136 + stopDismissPanGesture(gesture)
  137 + default:
  138 + break
  139 + }
  140 + }
  141 +
  142 + //当下拉Offset超过100或取消下拉手势时,执行此方法
  143 + private func stopDismissPanGesture(_ gesture: UIPanGestureRecognizer) {
  144 + draggingDownToDismiss = false
  145 + interactiveStartingPoint = nil
  146 + scrollView.showsVerticalScrollIndicator = true
  147 +
  148 + UIView.animate(withDuration: 0.2) {
  149 + gesture.view?.transform = CGAffineTransform.identity
  150 + }
  151 + }
  152 +
  153 +}
  154 +
  155 +extension CNUpSlideDetailViewController: UIViewControllerTransitioningDelegate {
  156 +
  157 + func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
  158 + return CNUpSlideAnimationTransition(animationType: .present)
  159 + }
  160 +
  161 + func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
  162 + return CNUpSlideAnimationTransition(animationType: .dismiss)
  163 + }
  164 +
  165 + func presentationController(forPresented presented: UIViewController, presenting: UIViewController?, source: UIViewController) -> UIPresentationController? {
  166 + return CNUpSlideCardPresentationController(presentedViewController: presented, presenting: presenting)
  167 + }
  168 +}
  169 +
  170 +extension CNUpSlideDetailViewController: UIScrollViewDelegate {
  171 + func scrollViewDidScroll(_ scrollView: UIScrollView) {
  172 +
  173 + if scrollView.contentOffset.y < 0 {
  174 + scrollView.contentOffset = .zero
  175 + draggingDownToDismiss = true
  176 + }
  177 + }
  178 +}
  179 +
  180 +extension CNUpSlideDetailViewController: UIGestureRecognizerDelegate {
  181 + func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
  182 + return true
  183 + }
  184 +}
... ...
metaCode/Classes/Main/HomePage/Controller/CNUpSlideViewController.swift 0 → 100644
  1 +//
  2 +// CNUpSlideViewController.swift
  3 +// metaCode
  4 +//
  5 +// Created by zx on 2023/10/13.
  6 +//
  7 +
  8 +import Foundation
  9 +import UIKit
  10 +
  11 +class CNUpSlideViewController: CNLiveBaseViewController,UITableViewDelegate,UITableViewDataSource{//UITableViewController {
  12 +
  13 + let kCNLiveDownSlideCellIdentifier = "kCNLiveDownSlideCellIdentifier"
  14 +
  15 + var selectedCell: CNDownSlideCell?
  16 +
  17 + var statusBarShouldBeHidden = false
  18 + //we need to set `View controller-based status bar appearance = YES` in info.plist.
  19 + //so we can be able to hide statusBar.
  20 + override var prefersStatusBarHidden: Bool {
  21 + return statusBarShouldBeHidden
  22 + }
  23 +
  24 + override var preferredStatusBarUpdateAnimation: UIStatusBarAnimation {
  25 + return .slide
  26 + }
  27 +
  28 + override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
  29 + print("slidetouchesBegan")
  30 + }
  31 +
  32 +
  33 + override func viewDidLoad() {
  34 + super.viewDidLoad()
  35 +
  36 + view.addSubview(tableView)
  37 + tableView.snp.makeConstraints { make in
  38 + make.edges.equalToSuperview()
  39 + }
  40 + }
  41 +
  42 + lazy var tableView : UITableView = {
  43 + let tableView = UITableView(frame: .zero, style: .grouped)
  44 + tableView.dataSource = self
  45 + tableView.delegate = self
  46 + tableView.separatorStyle = .none
  47 + tableView.register(CNDownSlideCell.self, forCellReuseIdentifier: kCNLiveDownSlideCellIdentifier)
  48 + tableView.rowHeight = GlobalConstants.toDayCardRowH
  49 + return tableView
  50 + }()
  51 +
  52 + private func updateStatusBarAndTabbarFrame(visible: Bool) {
  53 + statusBarShouldBeHidden = !visible
  54 + UIView.animate(withDuration: 0.25) {
  55 + self.setNeedsStatusBarAppearanceUpdate()
  56 + }
  57 + }
  58 +
  59 + func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
  60 + return 2
  61 + }
  62 +
  63 + func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
  64 + let cell = tableView.dequeueReusableCell(withIdentifier: kCNLiveDownSlideCellIdentifier) as! CNDownSlideCell
  65 + cell.selectionStyle = .none
  66 + cell.bgImageView.backgroundColor = .red
  67 + cell.bgImageView.kf.setImage(with: URL(string: "https://wjj.ys2.cnliveimg.com/769/img_new/1697162534497.jpg"))
  68 +
  69 + return cell
  70 + }
  71 +
  72 +
  73 + func tableView(_ tableView: UITableView, didHighlightRowAt indexPath: IndexPath) {
  74 + guard let row = tableView.cellForRow(at: indexPath) as? CNDownSlideCell else { return }
  75 + UIView.animate(withDuration: 0.1) {
  76 + row.bgBackView.transform = CGAffineTransform(scaleX: 0.95, y: 0.95)
  77 + }
  78 + }
  79 +
  80 + func tableView(_ tableView: UITableView, didUnhighlightRowAt indexPath: IndexPath) {
  81 + guard let row = tableView.cellForRow(at: indexPath) as? CNDownSlideCell else { return }
  82 + UIView.animate(withDuration: 0.3) {
  83 + row.bgBackView.transform = CGAffineTransform(scaleX: 1.0, y: 1.0)
  84 + }
  85 + }
  86 +
  87 + func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
  88 + print("点击了cell")
  89 + guard let cell = tableView.cellForRow(at: indexPath) as? CNDownSlideCell else { return }
  90 + selectedCell = cell
  91 +
  92 + let detailVC = CNUpSlideDetailViewController(cell: cell)
  93 +
  94 + detailVC.dismissClosure = { [weak self] in
  95 + guard let StrongSelf = self else { return }
  96 + StrongSelf.updateStatusBarAndTabbarFrame(visible: true)
  97 + }
  98 +
  99 + updateStatusBarAndTabbarFrame(visible: false)
  100 +
  101 + present(detailVC, animated: true, completion: nil)
  102 +
  103 + }
  104 +}
... ...
metaCode/Classes/Main/HomePage/View/CNCustomIndexView.swift
... ... @@ -118,11 +118,11 @@ class CNCustomIndexView:PGIndexBannerSubiew, UIScrollViewDelegate, WJColorChange
118 118 set{
119 119 self.mainView.idModel = newValue!
120 120 _idModel = newValue
121   - self.upSlideView.type = _idModel?.downType
122   - self.upSlideView.url = _idModel?.downPath
  121 + self.upSlideView.type = _idModel?.upType
  122 + self.upSlideView.url = _idModel?.upPath
123 123  
124   - self.downSlideView.type = _idModel?.upType
125   - self.downSlideView.url = _idModel?.upPath
  124 + self.downSlideView.type = _idModel?.downType
  125 + self.downSlideView.url = _idModel?.downPath
126 126  
127 127 self.topNavView.setTitleString(title:(_idModel?.name)!)
128 128 }
... ... @@ -184,7 +184,7 @@ class CNCustomIndexView:PGIndexBannerSubiew, UIScrollViewDelegate, WJColorChange
184 184  
185 185 ///下滑显示的VIew
186 186 lazy var downSlideView: CNDownSlideView = {
187   - let collectionView = CNDownSlideView.init(frame: CGRectMake(-25, 0, self.frame.size.width + 50, self.frame.size.height))
  187 + let collectionView = CNDownSlideView.init(frame: CGRectMake(-LeftGap, 0, self.frame.size.width+LeftGap*2, self.frame.size.height))
188 188 collectionView.backgroundColor = .clear
189 189 collectionView.backAction = {[weak self] in
190 190 self?.baseScrollView.setContentOffset(CGPoint(x: 0, y: (self!.baseScrollView.height)), animated: true)
... ...
metaCode/Classes/Main/HomePage/View/CNDownSlideCell.swift 0 → 100644
  1 +//
  2 +// CNDownSlideCell.swift
  3 +// metaCode
  4 +//
  5 +// Created by zx on 2023/10/16.
  6 +//
  7 +
  8 +import Foundation
  9 +import UIKit
  10 +
  11 +enum GlobalConstants {
  12 + static let leftMargin: CGFloat = 20
  13 +
  14 + static let toDayCardRowH: CGFloat = 440
  15 + static let toDayCardCornerRadius: CGFloat = 15.0
  16 + static let todayCardSize: CGSize = CGSize(width: KSreenWidth - 2 * 20, height: 410)
  17 + static let cardDetailTopImageH: CGFloat = 500
  18 +
  19 + static let iconBorderColor: CGColor = UIColor(red: 239/255.0, green: 240/255.0, blue: 241/255.0, alpha: 1).cgColor
  20 + static let iconBorderWidth: CGFloat = 0.8
  21 + static let iconCornerRadius: CGFloat = 17.5
  22 +
  23 + static let textBlueColor = UIColor(red: 0/255.0, green: 122/255.0, blue: 255/255.0, alpha: 1.0) //007AFF
  24 + static let speratorLineColor = UIColor(red: 224/255.0, green: 224/255.0, blue: 224/255.0, alpha: 1)
  25 +
  26 +}
  27 +
  28 +class CNDownSlideCell: UITableViewCell {
  29 +
  30 + let bgBackView = UIView()
  31 + let bgImageView = UIImageView()
  32 + let emptyView = UIView()
  33 +
  34 + override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
  35 + super.init(style: style, reuseIdentifier: reuseIdentifier)
  36 + setupUI()
  37 + }
  38 +
  39 + required init?(coder aDecoder: NSCoder) {
  40 + fatalError("init(coder:) has not been implemented")
  41 + }
  42 +
  43 + private func setupUI() {
  44 +
  45 + contentView.addSubview(bgBackView)
  46 + bgBackView.addSubview(bgImageView)
  47 + contentView.addSubview(emptyView)
  48 +
  49 + bgBackView.frame = CGRect(x: GlobalConstants.leftMargin, y: 0, width: GlobalConstants.todayCardSize.width, height: GlobalConstants.todayCardSize.height)
  50 + bgBackView.layer.shadowColor = UIColor.black.cgColor
  51 + bgBackView.layer.shadowOpacity = 0.4
  52 + bgBackView.layer.shadowOffset = CGSize(width: 0, height: 1)
  53 +
  54 + bgImageView.frame = bgBackView.bounds
  55 + bgImageView.contentMode = .scaleAspectFill
  56 + bgImageView.layer.cornerRadius = GlobalConstants.toDayCardCornerRadius
  57 + bgImageView.layer.masksToBounds = true
  58 +
  59 + emptyView.backgroundColor = UIColor.white.withAlphaComponent(0)
  60 + emptyView.frame = CGRect(x: 0, y: bgImageView.frame.size.height, width: GlobalConstants.todayCardSize.width, height: GlobalConstants.toDayCardRowH - GlobalConstants.todayCardSize.height)
  61 + }
  62 +
  63 +}
... ...
metaCode/Classes/Main/HomePage/View/CNDownSlideView.swift
... ... @@ -16,6 +16,7 @@ class CNDownSlideView:UIView{
16 16 //返回首页
17 17 var backAction:backBlock?
18 18  
  19 +
19 20 //MARK: - 懒加载
20 21 lazy var contentView:UIView = {
21 22  
... ... @@ -47,6 +48,34 @@ class CNDownSlideView:UIView{
47 48 return webView
48 49 }()
49 50  
  51 +// var upSlideVCView:UIView = {
  52 +//// let upSlideVCView = CNUpSlideViewController.init().view
  53 +// let upSlideVCView:UIView = UIView.init(frame: CGRect(x: 0, y: 0, width: KSreenWidth/2.0, height: KSreenHeight/2.0))
  54 +// upSlideVCView.backgroundColor = .red
  55 +//// upSlideVCView?.width = KSreenWidth
  56 +//// upSlideVCView?.height = KSreenHeight
  57 +// return upSlideVCView
  58 +// }()
  59 +
  60 + override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
  61 + let view = super.hitTest(point, with: event)
  62 + guard view == self else {
  63 + return view
  64 + }
  65 + guard let superView = view?.superview else {
  66 + return view
  67 + }
  68 + print(String(format: "self:%p, view:%p", self, view!))
  69 + return view
  70 + }
  71 +
  72 + var upSlideVCView:CNUpSlideViewController = {
  73 + let upSlideVCView = CNUpSlideViewController.init()
  74 + upSlideVCView.view.width = KSreenWidth
  75 + upSlideVCView.view.height = KSreenHeight-DownSllideBottomViewHeight
  76 + return upSlideVCView
  77 + }()
  78 +
50 79 var type:Int?
51 80  
52 81 var _url:String?
... ... @@ -56,9 +85,21 @@ class CNDownSlideView:UIView{
56 85 }
57 86 set{
58 87 _url = newValue!
59   - if (_url != ""){
60   - let webUrl: URL! = URL.init(string: _url!)
61   - webView.load(URLRequest.init(url:webUrl))
  88 +
  89 + if(type == UpDownTypeH5){
  90 + if (_url != ""){
  91 + let webUrl: URL! = URL.init(string: _url!)
  92 + webView.load(URLRequest.init(url:webUrl))
  93 + }
  94 + }else if(type == UpDownTypePage){
  95 + print("UpDownTypePage")
  96 + self.webView.isHidden = true
  97 +// self.upSlideVC.isHidden = false
  98 +
  99 + }else if(type == UpDownTypeShopDetail){
  100 +
  101 + }else if(type == UpDownTypeShopControlConsole){
  102 +
62 103 }
63 104 }
64 105 }
... ... @@ -100,9 +141,15 @@ class CNDownSlideView:UIView{
100 141  
101 142 override init(frame: CGRect) {
102 143 super.init(frame: frame)
  144 +
  145 + let tap = UITapGestureRecognizer.init(target: self, action: #selector(slideViewTap))
  146 + tap.cancelsTouchesInView = false
  147 + self.addGestureRecognizer(tap)
103 148 self.initUI()
104 149 }
105   -
  150 + @objc func slideViewTap() {
  151 + print("slideViewTap")
  152 + }
106 153 required init?(coder: NSCoder) {
107 154 fatalError("init(coder:) has not been implemented")
108 155 }
... ... @@ -110,10 +157,12 @@ class CNDownSlideView:UIView{
110 157  
111 158 ///初始化UI
112 159 func initUI(){
  160 + self.isUserInteractionEnabled = true
113 161 self.addSubview(self.contentView)
114 162 self.contentView.addSubview(self.webView)
115 163 // self.addSubview(self.topView)
116 164 self.addSubview(self.bottomView)
  165 + self.addSubview(self.upSlideVCView.view)
117 166  
118 167 }
119 168  
... ...
metaCode/Classes/Main/HomePage/View/CNUpSlideDetailScrollView.swift 0 → 100644
  1 +//
  2 +// CNUpSlideDetailScrollView.swift
  3 +// metaCode
  4 +//
  5 +// Created by zx on 2023/10/16.
  6 +//
  7 +
  8 +import UIKit
  9 +
  10 +class CNUpSlideDetailScrollView: UIScrollView {
  11 +
  12 + let bgBackView = UIView()
  13 + let imageView = UIImageView()
  14 + let textView = UITextView()
  15 +
  16 + override init(frame: CGRect) {
  17 + super.init(frame: frame)
  18 + setupUI()
  19 + }
  20 +
  21 + required init?(coder aDecoder: NSCoder) {
  22 + fatalError("init(coder:) has not been implemented")
  23 + }
  24 +
  25 + private func setupUI() {
  26 + bgBackView.frame = CGRect(x: 0, y: 0, width: KSreenWidth, height: GlobalConstants.cardDetailTopImageH)
  27 + bgBackView.layer.masksToBounds = true
  28 +
  29 + imageView.frame = bgBackView.bounds
  30 + imageView.isUserInteractionEnabled = true
  31 + imageView.contentMode = .scaleAspectFill
  32 +
  33 + let textViewWidth = KSreenWidth - 2 * textViewLeftMargin
  34 + let font = UIFont.boldSystemFont(ofSize: 15)
  35 + let textHeight = textViewText.calculateHeightWith(width: textViewWidth, font: font)
  36 + textView.frame = CGRect(x: textViewLeftMargin, y: bgBackView.frame.height + textViewTopMargin, width: textViewWidth, height: textHeight + textViewBottomMargin)
  37 + textView.text = textViewText
  38 + textView.font = font
  39 + textView.textColor = .gray
  40 +
  41 + bgBackView.addSubview(imageView)
  42 + addSubview(bgBackView)
  43 + addSubview(textView)
  44 +
  45 + contentSize = CGSize(width: KSreenWidth, height: bgBackView.frame.height + textViewTopMargin + textView.frame.height + textViewBottomMargin)
  46 + }
  47 +
  48 +}
  49 +
  50 +
  51 +fileprivate let textViewLeftMargin: CGFloat = 20
  52 +fileprivate let textViewTopMargin: CGFloat = 40
  53 +fileprivate let textViewBottomMargin: CGFloat = 50
  54 +fileprivate let textViewText = "Thank you. I'm honored to be with you today for your commencement from one of the finest universities in the world. Truth be told, i never graduated from college and this is the closest I've ever gotten to a college gradution. \n\nToday i want to tell you three stories from my life. That's it. No big deal. Just three stories. The first story is about connecting the dots. \n\ndropped out of Reed College after the first 6 months, but then stayed around as a drop-in for another 18 months or so before I really quit. So why did I drop out? \n\nIt started before I was born. My biological mother was a young,unwed college graduate student, and she decided to put me up for adoption. She felt very strongly that I should be adopted by college graduates, so everything was all set for me to be adopted at birth by a lawyer and his wife. Except that when I popped out they decided at the last minute that they really wanted a girl. So my parents, who were on a waiting list, got a call in the middle of the night asking: 'We got an unexpected baby boy; do you want him?' They said: 'Of course.' My biological mother found out later that my mother had never graduated from college and my father had never graduated from high school. She refused to sign the final adoption papers. She only relented a few months later when my parents promised that I would go to college."
... ...
metaCode/Classes/Main/HomePage/View/CNUpSlideView.swift
... ... @@ -24,6 +24,11 @@ class CNUpSlideView:UIView{
24 24 return webView
25 25 }()
26 26  
  27 + var upSlideVC: CNUpSlideViewController = {
  28 + let upSlideVC = CNUpSlideViewController.init()
  29 + return upSlideVC
  30 + }()
  31 +
27 32 var type:Int?
28 33  
29 34 var _url:String?
... ... @@ -38,8 +43,11 @@ class CNUpSlideView:UIView{
38 43 let webUrl: URL! = URL.init(string: _url!)
39 44 webView.load(URLRequest.init(url:webUrl))
40 45 }
41   - }else if(type == UpDownTypePage){
  46 + }
  47 + else if(type == UpDownTypePage){
42 48 print("UpDownTypePage")
  49 + self.webView.isHidden = true
  50 + self.upSlideVC.view.isHidden = false
43 51 }else if(type == UpDownTypeShopDetail){
44 52  
45 53 }else if(type == UpDownTypeShopControlConsole){
... ... @@ -64,6 +72,7 @@ class CNUpSlideView:UIView{
64 72 self.clipsToBounds = true;
65 73 self.layer.cornerRadius = 20;
66 74 self.addSubview(self.webView)
  75 +// self.addSubview(self.upSlideVC.view)
67 76  
68 77  
69 78 // let imageview : UIImageView = UIImageView.init(frame: CGRect(x: 20, y: 10, width: self.width - 40, height: self.height - 20))
... ...
metaCode/Classes/Main/Util/CNUpSlideAnimationTransition.swift 0 → 100644
  1 +//
  2 +// CNUpSlideAnimationTransition.swift
  3 +// metaCode
  4 +//
  5 +// Created by zx on 2023/10/16.
  6 +//
  7 +
  8 +import UIKit
  9 +
  10 +fileprivate let transitonDuration: TimeInterval = 1.0
  11 +
  12 +
  13 +enum AnimationType {
  14 + case present
  15 + case dismiss
  16 +}
  17 +
  18 +class CNUpSlideAnimationTransition: NSObject {
  19 + let animationType: AnimationType!
  20 +
  21 + init(animationType: AnimationType) {
  22 + self.animationType = animationType
  23 + super.init()
  24 + }
  25 +}
  26 +
  27 +extension CNUpSlideAnimationTransition: UIViewControllerAnimatedTransitioning {
  28 + func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
  29 + return transitonDuration
  30 + }
  31 +
  32 + func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
  33 + if animationType == .present {
  34 + animationForPresent(using: transitionContext)
  35 + } else {
  36 + animationForDismiss(using: transitionContext)
  37 + }
  38 + }
  39 +
  40 + func animationForPresent(using transitionContext: UIViewControllerContextTransitioning) {
  41 + let containerView = transitionContext.containerView
  42 + //1.Get fromVC and toVC
  43 + guard let fromVC = transitionContext.viewController(forKey: .from) as? CNUpSlideViewController else { return }
  44 + guard let toVC = transitionContext.viewController(forKey: .to) as? CNUpSlideDetailViewController else { return }
  45 + guard let selectedCell = fromVC.selectedCell else { return }
  46 +
  47 + let frame = selectedCell.convert(selectedCell.bgBackView.frame, to: fromVC.view)
  48 + //2.Set presentation original size.
  49 + toVC.view.frame = frame
  50 + toVC.scrollView.imageView.frame.size.width = GlobalConstants.todayCardSize.width
  51 + toVC.scrollView.imageView.frame.size.height = GlobalConstants.todayCardSize.height
  52 +
  53 + containerView.addSubview(toVC.view)
  54 +
  55 + //3.Change original size to final size with animation.
  56 + UIView.animate(withDuration: transitonDuration, delay: 0, usingSpringWithDamping: 0.5, initialSpringVelocity: 0, options: [], animations: {
  57 + toVC.view.frame = UIScreen.main.bounds
  58 + toVC.scrollView.imageView.frame.size.width = KSreenWidth
  59 + toVC.scrollView.imageView.frame.size.height = GlobalConstants.cardDetailTopImageH
  60 + toVC.closeBtn.alpha = 1
  61 +
  62 + }) { (completed) in
  63 + transitionContext.completeTransition(completed)
  64 + }
  65 + }
  66 +
  67 + func animationForDismiss(using transitionContext: UIViewControllerContextTransitioning) {
  68 + guard let fromVC = transitionContext.viewController(forKey: .from) as? CNUpSlideDetailViewController else { return }
  69 + guard let toVC = transitionContext.viewController(forKey: .to) as? CNUpSlideViewController else { return }
  70 + guard let selectedCell = toVC.selectedCell else { return }
  71 +
  72 + UIView.animate(withDuration: transitonDuration - 0.3, delay: 0, usingSpringWithDamping: 0.8, initialSpringVelocity: 0, options: [], animations: {
  73 + let frame = selectedCell.convert(selectedCell.bgBackView.frame, to: toVC.view)
  74 + fromVC.view.frame = frame
  75 + fromVC.view.layer.cornerRadius = GlobalConstants.toDayCardCornerRadius
  76 + fromVC.scrollView.imageView.frame.size.width = GlobalConstants.todayCardSize.width
  77 + fromVC.scrollView.imageView.frame.size.height = GlobalConstants.todayCardSize.height
  78 + fromVC.closeBtn.alpha = 0
  79 +
  80 + }) { (completed) in
  81 + transitionContext.completeTransition(completed)
  82 + }
  83 + }
  84 +
  85 +}
... ...
metaCode/Supporting Files/Assets.xcassets/Home/close_button.imageset/Contents.json 0 → 100644
  1 +{
  2 + "images" : [
  3 + {
  4 + "idiom" : "universal",
  5 + "scale" : "1x"
  6 + },
  7 + {
  8 + "filename" : "close_button@2x.png",
  9 + "idiom" : "universal",
  10 + "scale" : "2x"
  11 + },
  12 + {
  13 + "idiom" : "universal",
  14 + "scale" : "3x"
  15 + }
  16 + ],
  17 + "info" : {
  18 + "author" : "xcode",
  19 + "version" : 1
  20 + }
  21 +}
... ...
metaCode/Supporting Files/Assets.xcassets/Home/close_button.imageset/close_button@2x.png 0 → 100644

1.14 KB