欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

iOS 模态弹出全屏且带下拉dismiss

程序员文章站 2022-03-03 19:18:55
iOS 模态弹出全屏且带下拉dismiss当前iOS模态弹出时全屏和下拉返回互不兼容,如果要做到兼容可以通过拓展或自定义控制器。我选择的是自定义一个控制器的类,下面是代码。class PullViewController: UIViewController, UIScrollViewDelegate { var isPull: Bool = false var nextVC: PullViewController? = nil lazy var mainSc...

iOS 模态弹出全屏且带下拉dismiss

当前iOS模态弹出时全屏和下拉返回互不兼容,如果要做到兼容可以通过拓展或自定义控制器。
我选择的是自定义一个控制器的类,下面是代码。

class PullViewController: UIViewController, UIScrollViewDelegate {
    
    var isPull: Bool = false
    var nextVC: PullViewController? = nil
    
    lazy var mainScroll: UIScrollView = {
        let bounds = view.bounds
        let scroll = UIScrollView(frame: bounds)
        scroll.showsVerticalScrollIndicator = false
        scroll.showsHorizontalScrollIndicator = false
        scroll.isPagingEnabled = true
        scroll.backgroundColor = .clear
        scroll.contentSize = CGSize(width: bounds.width, height: bounds.height+0.1)
        return scroll
    }()

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
    }
    
    override func present(_ viewControllerToPresent: UIViewController, animated flag: Bool, completion: (() -> Void)? = nil) {
        if viewControllerToPresent.isKind(of: PullViewController.self) {
            nextVC = (viewControllerToPresent as! PullViewController)
            self.addChild(viewControllerToPresent)
            mainScroll.delegate = self
            view.addSubview(mainScroll)
            mainScroll.addSubview(viewControllerToPresent.view)
            let bounds = view.bounds
            viewControllerToPresent.view.frame = CGRect(x: 0, y: bounds.height, width: bounds.width, height: bounds.height)
            UIView.animate(withDuration: 0.25) {
                viewControllerToPresent.view.frame = bounds
            } completion: { (finish) in
                self.mainScroll.setContentOffset(CGPoint.zero, animated: false)
                self.isPull = false
                if (completion != nil) {
                    completion!()
                }
            }
        }else {
            super.present(viewControllerToPresent, animated: flag, completion: completion)
        }
    }
    
    override func dismiss(animated flag: Bool, completion: (() -> Void)? = nil) {
        if ((self.parent?.isKind(of: PullViewController.self)) != nil) {
            let parent: PullViewController = self.parent as! PullViewController
            if parent.isPull == false {
                parent.isPull = true
                let bounds = view.bounds
                UIView.animate(withDuration: 0.25) {
                    self.view.frame = CGRect(x: 0, y: bounds.height, width: bounds.width, height: bounds.height)
                } completion: { (finish) in
                    parent.mainScroll.removeFromSuperview()
                    self.view.removeFromSuperview()
                    if (completion != nil) {
                        completion!()
                    }
                }
            }
        }else {
            super.dismiss(animated: flag, completion: completion)
        }
    }
    
    func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
        if scrollView.contentOffset.y < -view.bounds.height/5 {
            if nextVC != nil {
                nextVC!.dismiss(animated: true, completion: nil)
            }
        }else {
            scrollView.setContentOffset(CGPoint.zero, animated: true)
        }
    }
    
    func scrollViewDidEndScrollingAnimation(_ scrollView: UIScrollView) {
        if scrollView.contentOffset.y < -view.bounds.height/5 {
            if nextVC != nil {
                nextVC!.dismiss(animated: true, completion: nil)
            }
        }else {
            scrollView.setContentOffset(CGPoint.zero, animated: true)
        }
    }
    
    func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {
        if scrollView.contentOffset.y < -view.bounds.height/5 {
            if nextVC != nil {
                nextVC!.dismiss(animated: true, completion: nil)
            }
        }else {
            scrollView.setContentOffset(CGPoint.zero, animated: true)
        }
    }
}

然后我通过测试验证效果成功

class ParentController: PullViewController {
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        view.backgroundColor = .black
        
        let button = UIButton(type: .custom)
        button.frame = CGRect(x: 100, y: 200, width: view.bounds.width-200, height: 50)
        button.setTitle("跳转", for: .normal)
        button.setTitleColor(.red, for: .normal)
        button.layer.borderWidth = 1
        button.layer.borderColor = UIColor.red.cgColor
        button.addTarget(self, action: #selector(presentNext), for: .touchUpInside)
        view.addSubview(button)
    }
    
    @objc func presentNext() {
        let vc = NextController()
        self.present(vc, animated: true, completion: nil)
    }
    
}

class NextController: PullViewController {
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        view.backgroundColor = .white
        
        let button = UIButton(type: .custom)
        button.frame = CGRect(x: 100, y: 200, width: view.bounds.width-200, height: 50)
        button.setTitle("收起", for: .normal)
        button.setTitleColor(.red, for: .normal)
        button.layer.borderWidth = 1
        button.layer.borderColor = UIColor.red.cgColor
        button.addTarget(self, action: #selector(backParent), for: .touchUpInside)
        view.addSubview(button)
    }
    
    @objc func backParent() {
        self.dismiss(animated: true, completion: nil)
    }
}

demo
希望能和志同道合者多多交流。

本文地址:https://blog.csdn.net/weixin_42979360/article/details/111936244

相关标签: ios