CNUpSlideDetailViewController.swift 6.4 KB
//
//  CNUpSlideDetailViewController.swift
//  metaCode
//
//  Created by zx on 2023/10/16.
//  下滑页原生页--大图点击详情页

import Foundation

class CNUpSlideDetailViewController: CNLiveBaseViewController {
    
    //slideModel
    var _slideModel : CNLiveDownSlideModel?
    var slideModel : CNLiveDownSlideModel? {
        get{
            _slideModel
        }
        set{
            _slideModel = newValue!
        }
    }
    
    var dismissClosure: (()->())?
    //the point when start to interactive
    var interactiveStartingPoint: CGPoint? = nil

    var draggingDownToDismiss = false
    
    let cell: CNDownSlideSingleCourseCell!
    
    private lazy var dismissPanGesture: UIPanGestureRecognizer = {
        let ges = UIPanGestureRecognizer()
        ges.maximumNumberOfTouches = 1
        ges.addTarget(self, action: #selector(handleDismissPan(gesture:)))
        ges.delegate = self
        return ges
    }()
    
    lazy var scrollView: CNUpSlideDetailScrollView = {
        let frame = self.view.bounds
        let view = CNUpSlideDetailScrollView(frame: frame)
        view.callBack = {(contentMdl:CNLiveDownSlideContentsModel)->Void in
            CNLiveDownSlideTool.detailPushWebVCWithContentsMdl(contentMdl: contentMdl, viewController: self)
        }
        view.delegate = self
        return view
    }()
    
    lazy var closeBtn: UIButton = {
        let btn = UIButton()
        btn.frame = CGRect(x: KSreenWidth - 20 - 30, y: KStatusBarHeight+20, width: 30, height: 30)
        btn.setImage(#imageLiteral(resourceName: "close_button"), for: .normal)
        btn.addTarget(self, action: #selector(closeAction), for: .touchUpInside)
        return btn
    }()
    
    init(cell: CNDownSlideSingleCourseCell,slideModel:CNLiveDownSlideModel) {
        self.cell = cell
        super.init(nibName: nil, bundle: nil)
        self.slideModel = slideModel
        self.setupTranstion()
        setNeedsStatusBarAppearanceUpdate()
    }
    
    private func setupTranstion() {
        modalPresentationStyle = .custom
        transitioningDelegate = self
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        setupUI()
        getImageFromCell()
    }
    
    private func setupUI() {
        self.view.layer.masksToBounds = true
        view.addSubview(scrollView)
        scrollView.slideModel = _slideModel
        view.addSubview(closeBtn)
        view.addGestureRecognizer(dismissPanGesture)
        
        if #available(iOS 11.0, *) {
            scrollView.contentInsetAdjustmentBehavior = .never
        } else {
            automaticallyAdjustsScrollViewInsets = false
        }
    }
    
    private func getImageFromCell() {
        scrollView.imageView.image = cell.bgImageView.image
    }
    
    @objc private func closeAction() {
        dismiss(animated: true, completion: nil)
        let nav = self.navigationController as! CNSlideBaseNavigationController
        nav.dismissClosure?()
    }
    
    @objc private func handleDismissPan(gesture: UIPanGestureRecognizer) {
        if !draggingDownToDismiss {
            return
        }
        
        let startingPoint: CGPoint
        
        if let p = interactiveStartingPoint {
            startingPoint = p
        } else {
            startingPoint = gesture.location(in: nil)
            interactiveStartingPoint = startingPoint
        }

        let currentLocation = gesture.location(in: nil)
        
        var progress = (currentLocation.y - startingPoint.y) / 100
        
        //prevent viewController bigger when scrolling up
        if currentLocation.y <= startingPoint.y {
            progress = 0
        }
        
        if progress >= 1.0 {
            dismiss(animated: true, completion: nil)
            let nav = self.navigationController as! CNSlideBaseNavigationController
            nav.dismissClosure?()
//            dismissClosure?()
            stopDismissPanGesture(gesture)
            return
        }

        let targetShrinkScale: CGFloat = 0.86
        let currentScale: CGFloat = 1 - (1 - targetShrinkScale) * progress
        
        switch gesture.state {
        case .began,.changed:
            scrollView.isScrollEnabled = false
            gesture.view?.transform = CGAffineTransform(scaleX: currentScale, y: currentScale)
            gesture.view?.layer.cornerRadius = GlobalConstants.toDayCardCornerRadius * (progress)
            scrollView.showsVerticalScrollIndicator = false
        case .cancelled,.ended:
            scrollView.isScrollEnabled = true
            stopDismissPanGesture(gesture)
        default:
            break
        }
    }
    
    //当下拉Offset超过100或取消下拉手势时,执行此方法
    private func stopDismissPanGesture(_ gesture: UIPanGestureRecognizer) {
        draggingDownToDismiss = false
        interactiveStartingPoint = nil
        scrollView.showsVerticalScrollIndicator = true
        
        UIView.animate(withDuration: 0.2) {
            gesture.view?.transform = CGAffineTransform.identity
        }
    }

}

extension CNUpSlideDetailViewController: UIViewControllerTransitioningDelegate {
    
    func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
        return CNUpSlideAnimationTransition(animationType: .present)
    }
    
    func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
        return CNUpSlideAnimationTransition(animationType: .dismiss)
    }
    
    func presentationController(forPresented presented: UIViewController, presenting: UIViewController?, source: UIViewController) -> UIPresentationController? {
        return CNUpSlideCardPresentationController(presentedViewController: presented, presenting: presenting)
    }
}

extension CNUpSlideDetailViewController: UIScrollViewDelegate {
    func scrollViewDidScroll(_ scrollView: UIScrollView) {
        
        if scrollView.contentOffset.y < 0 {
            scrollView.contentOffset = .zero
            draggingDownToDismiss = true
        }
    }
}

extension CNUpSlideDetailViewController: UIGestureRecognizerDelegate {
    func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
        return true
    }
}