项目中会经常使用一些弹出的View如果直接在控制器的View中写会照成里面的代码太多了,所以我们要自定义一个弹出的控制器。一些逻辑处理在我们自定义的控制器里面做, 要自定义大小
我们自定义一个控制器, 名字叫做PopoverViewController
//2.设置弹出控制器
let popoverView = PopoverViewController()
//3.设置弹出动画 防止x底下的控制器的vView被移除
popoverView.modalPresentationStyle = .custom
popoverView.transitioningDelegate = self
present(popoverView, animated: true, completion: nil)
现在他可以弹出来,但是大小是占据整个屏幕的额
我们要控制它的大小,
首先,modal出的控制器,都有一个父控制器来暂时存放UIPresentationController
extension HomeTVC : UIViewControllerTransitioningDelegate
{
func presentationController(forPresented presented: UIViewController, presenting: UIViewController?, source: UIViewController) -> UIPresentationController?
{
return WBPresentationController(presentedViewController: presented, presenting: presenting)
}
}
自定义一个UIPresentationController,手动调整里面的被弹出的控制器,和弹出的控制器
import UIKit
class WBPresentationController: UIPresentationController
{
//从新布局
override func containerViewWillLayoutSubviews()
{
//设置弹出试图的尺寸
presentedView?.frame = CGRect(x: 100, y: 55, width: 180, height: 200)
addCoverView()
}
}
//MARK: - 设置UI相关 -
extension WBPresentationController
{
private func addCoverView()
{
let coverView = UIView();
coverView.backgroundColor = UIColor(white: 0.5, alpha: 0.6)
coverView.frame = containerView!.bounds
containerView?.insertSubview(coverView, at: 0)
//添加手势
let tap = UITapGestureRecognizer(target: self, action: #selector(coverViewClick))
coverView.addGestureRecognizer(tap)
}
}
//MARK: - 事件监听 -
extension WBPresentationController
{
@objc private func coverViewClick()
{
presentedViewController.dismiss(animated: true, completion: nil)
}
}
自定义弹出动画。逐渐变大
要遵守UIViewControllerAnimatedTransitioning协议
extension PopoverAnimator : UIViewControllerTransitioningDelegate
{
func presentationController(forPresented presented: UIViewController, presenting: UIViewController?, source: UIViewController) -> UIPresentationController?
{
return WBPresentationController(presentedViewController: presented, presenting: presenting)
}
// 目的:自定义弹出的动画
func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning?
{
isPresented = true
return self
}
func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning?
{
isPresented = false
return self
}
}
extension PopoverAnimator : UIViewControllerAnimatedTransitioning
{
/// 动画执行的时间
func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval
{
return 0.3
}
/// 获取`转场的上下文`:可以通过转场上下文获取弹出的View和消失的View
// UITransitionContextFromViewKey : 获取消失的View
// UITransitionContextToViewKey : 获取弹出的View
func animateTransition(using transitionContext: UIViewControllerContextTransitioning)
{
isPresented ? animatForPresentedView(transitionContext: transitionContext) : animatForDismissedView(transitionContext: transitionContext)
}
/// 自定义弹出动画
private func animatForPresentedView(transitionContext: UIViewControllerContextTransitioning)
{
// 1.获取弹出的View
let presentView = transitionContext.view(forKey: UITransitionContextViewKey.to)!
// 2.将弹出的View添加到containerView中
transitionContext.containerView.addSubview(presentView)
//3.知行动画
presentView.transform = CGAffineTransform(scaleX: 1.0, y: 0)
presentView.layer.anchorPoint = CGPoint(x: 0.5, y: 0)
UIView.animate(withDuration: transitionDuration(using: transitionContext), animations:
{
presentView.transform = CGAffineTransform(scaleX: 1.0, y: 1.0)
})
{ (_) in
//告诉上下文 完成动画
transitionContext.completeTransition(true)
}
}
/// 自定义消失动画
private func animatForDismissedView(transitionContext: UIViewControllerContextTransitioning)
{
// 1.获取弹出的View
let presentView = transitionContext.view(forKey: UITransitionContextViewKey.from)!
// 2.将弹出的View添加到containerView中
transitionContext.containerView.addSubview(presentView)
//3.知行动画
UIView.animate(withDuration: transitionDuration(using: transitionContext), animations:
{
presentView.transform = CGAffineTransform(scaleX: 1.0, y: 0.00001)
})
{ (_) in
//告诉上下文 完成动画
transitionContext.completeTransition(true)
}
}
}
网友评论