美文网首页
自定义model出来的控制器

自定义model出来的控制器

作者: 落夏简叶 | 来源:发表于2018-08-29 20:54 被阅读17次

    本文代码基于swift4.0
    实现效果如下:


    A30DC7C074D43F762DF1AE00D5C96755.png

    这个提示框,是一个自定义的控制器。类似系统的UIAlertController。present出来的时候动画效果可自定义,弹框大小可自定义。

    其步骤大致可分为3步:
    1. 定义一个自定义的XXPresentationController负责管理弹出控制器的大小,模式
    import UIKit
    
    class XXPresentationController: UIPresentationController {
        
        let dimmingView = UIView()
        
        override var shouldPresentInFullscreen: Bool {
            return false
        }
        
        override var adaptivePresentationStyle: UIModalPresentationStyle {
            return .overCurrentContext
        }
        
        override func size(forChildContentContainer container: UIContentContainer, withParentContainerSize parentSize: CGSize) -> CGSize {
            return container.preferredContentSize
        }
        
        override var frameOfPresentedViewInContainerView: CGRect {
            guard let containerView = containerView else {
                return CGRect()
            }
            let containerBounds = containerView.bounds
            var presentedViewFrame = containerBounds
            
            presentedViewFrame.size = size(forChildContentContainer: presentedViewController, withParentContainerSize: containerBounds.size)
            presentedViewFrame.origin.x = containerBounds.size.width / 2 - presentedViewFrame.size.width / 2
            presentedViewFrame.origin.y = containerBounds.size.height / 2 - presentedViewFrame.size.height / 2
    
            return presentedViewFrame
        }
        
        override func presentationTransitionWillBegin() {
            dimmingView.backgroundColor = UIColor.black
            dimmingView.alpha = 0.0
            containerView?.insertSubview(dimmingView, at: 0)
            
            guard let coordinator = presentedViewController.transitionCoordinator else {
                return
            }
            coordinator.animate(alongsideTransition: { (_) in
                self.dimmingView.alpha = 0.4
            }, completion: nil)
         
        }
        
        override func dismissalTransitionWillBegin() {
            guard let coordinator = presentedViewController.transitionCoordinator else {
                return
            }
            coordinator.animate(alongsideTransition: { (_) in
                self.dimmingView.alpha = 0.0
            }) { (_) in
                self.dimmingView.removeFromSuperview()
            }
            
        }
        
        override func containerViewWillLayoutSubviews() {
            super.containerViewWillLayoutSubviews()
            guard let containerView = containerView else {
                return
            }
            //不能写dimmingView.bounds
            dimmingView.frame = containerView.bounds
            presentedView?.frame = frameOfPresentedViewInContainerView
        }
    }
    
    
    1. 定义一个自定义的class,服从UIViewControllerTransitioningDelegate协议。然后实现代理方法
    import UIKit
    
    class XXCustomTransitionDelegate: NSObject, UIViewControllerTransitioningDelegate {
        
        func presentationController(forPresented presented: UIViewController, presenting: UIViewController?, source: UIViewController) -> UIPresentationController? {
            return XXPresentationController(presentedViewController: presented, presenting: presenting)
        }
        
    //负责present时的动画效果
        func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
            let animator = XXCustomAnimator()
            animator.isPresentation = true
            return animator
        }
        
    //负责dismiss时的动画效果
        func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
            let animator = XXCustomAnimator()
            animator.isPresentation = false
            return animator
        }
    }
    
    
    1. 设置弹出控制器的transitioningDelegate 为自定义的类(这一步就类似于设置UITableView的代理)
    import UIKit
    
    class ViewController: UIViewController {
        private var customTransitionDelegate: UIViewControllerTransitioningDelegate? //这个很重要,要是全局的。
    
        override func viewDidLoad() {
            super.viewDidLoad()
            // Do any additional setup after loading the view, typically from a nib.
        }
    
        @IBAction func customAlertButtonDidClicked(_ sender: UIButton) {
            let alertVC = UIStoryboard.init(name: "XXAlert", bundle: nil).instantiateViewController(withIdentifier: "XXTipAlertVC") as! XXTipAlertVC
            alertVC.titles = ("success", "yes", "no")
            alertVC.notNowCallback = {
                self.dismiss(animated: true, completion: nil)
            }
            alertVC.actionCallback = {
                self.dismiss(animated: true, completion: nil)
            }
            alertVC.view.backgroundColor = UIColor.yellow
            //不能写成alertVC.transitioningDelegate = XXCustomTransitionDelegate()
            //注意customTransitionDelegate 不能在局部函数调用。要是全局的。
            customTransitionDelegate = XXCustomTransitionDelegate()
            alertVC.transitioningDelegate = customTransitionDelegate
            present(alertVC, animated: true, completion: nil)
        }
    
    }
    
    • 这里为了让弹出控制器有圆角,写了一个子类处理圆角,以及设置modalPresentationStyle = .custom
    import UIKit
    
    class CustomPopupVC: UIViewController {
    
        override func viewDidLoad() {
            super.viewDidLoad()
            view.backgroundColor = UIColor.white
            view.layer.cornerRadius = 12
            view.layer.masksToBounds = true
        }
    
        override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
            super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
            initialization()
        }
    
        required init?(coder aDecoder: NSCoder) {
            super.init(coder: aDecoder)
            initialization()
        }
    
        func initialization() {
            modalPresentationStyle = .custom
        }
    }
    
    
    • alertVC是在storyBoard中绘制的简单的弹框


      image.png
    • 不过要注意一点,在storyBoard中记得设置ViewController的preferredContentSize。(XXPresentationController中是根据这个值来设置弹出控制器的大小)


      控制器的contentSize

    相关文章

      网友评论

          本文标题:自定义model出来的控制器

          本文链接:https://www.haomeiwen.com/subject/cttlwftx.html