自定义model出来的控制器

2018-08-29  本文已影响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)
    }

}
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
    }
}

上一篇下一篇

猜你喜欢

热点阅读