自定义TabBar各个Item
制作如图的弹出菜单
首先将导航条的titleView换成一个UIButton
func configNavigationBar() {
navigationTitleBtn.setImage(UIImage.init(named: "navigationbar_arrow_down"), for: .normal)
navigationTitleBtn.setImage(UIImage.init(named: "navigationbar_arrow_up"), for: .selected)
navigationTitleBtn.setTitle("title", for: .normal)
navigationTitleBtn.setTitleColor(UIColor.black, for: .normal)
navigationTitleBtn.sizeToFit()
navigationItem.titleView = navigationTitleBtn
navigationTitleBtn.addTarget(self, action: #selector(navigationTitleClick), for: .touchUpInside)
}
func navigationTitleClick() {
let popoverVC : ZFPopMenuController = ZFPopMenuController()
popoverVC.modalPresentationStyle = .custom
popoverVC.transitioningDelegate = popOver
navigationTitleBtn.isSelected = popOver.isPresentedView
self.present(popoverVC, animated: true, completion: nil)
}
自定义弹出的控制器,并自定义控制器的尺寸
import UIKit
class ZFPresentationController: UIPresentationController {
lazy var coverView:UIView = UIView()
override func containerViewWillLayoutSubviews() {
super.containerViewWillLayoutSubviews()
let viewW:CGFloat = 180.0
presentedView?.frame = CGRect(x: (UIScreen.main.bounds.size.width - viewW) * 0.5, y: 55, width: viewW, height: 250)
configCover()
}
func configCover() {
containerView?.insertSubview(coverView, at: (containerView?.subviews.count)! - 1)
coverView.backgroundColor = UIColor(white: 0.8, alpha: 0.2)
coverView.frame = containerView!.bounds
let tap = UITapGestureRecognizer(target: self, action: #selector(coverViewClick))
coverView.addGestureRecognizer(tap)
}
func coverViewClick() {
print("coverViewClick")
presentedViewController.dismiss(animated: true, completion: nil)
}
}
在定义一个实现代理的类实现UIViewControllerTransitioningDelegate代理和UIViewControllerAnimatedTransitioning协议的方法,然后重置动画
import UIKit
class ZFPopOver: NSObject {
var isPresentedView:Bool = true
}
extension ZFPopOver : UIViewControllerTransitioningDelegate
{
func presentationController(forPresented presented: UIViewController, presenting: UIViewController?, source: UIViewController) -> UIPresentationController? {
//返回自定义的弹出控制器
return ZFPresentationController(presentedViewController: presented, presenting: presenting)
}
func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
isPresentedView = true
return self
}
func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
isPresentedView = false
return self
}
}
extension ZFPopOver : UIViewControllerAnimatedTransitioning
{
func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
return 0.2
}
func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
if isPresentedView == true
{
animationForPresented(transitionContext: transitionContext)
}
else
{
animationForDismiss(transitionContext: transitionContext)
}
}
func animationForPresented(transitionContext: UIViewControllerContextTransitioning){
//UITransitionContextViewKey.from 获取消失的view
//UITransitionContextViewKey.to 获取弹出的view
let presentedView = transitionContext.view(forKey: UITransitionContextViewKey.to)!
transitionContext.containerView.addSubview(presentedView)
presentedView.layer.anchorPoint = CGPoint(x:0.5,y:0)
presentedView.transform = CGAffineTransform(scaleX: 1.0,y: 0.0)
UIView.animate(withDuration: transitionDuration(using: transitionContext), animations: {
presentedView.transform = CGAffineTransform.identity
}) { (_) in
transitionContext.completeTransition(true)
}
}
func animationForDismiss(transitionContext: UIViewControllerContextTransitioning){
let dissmisView = transitionContext.view(forKey: UITransitionContextViewKey.from)!
transitionContext.containerView.addSubview(dissmisView)
dissmisView.layer.anchorPoint = CGPoint(x:0.5,y:0)
UIView.animate(withDuration: transitionDuration(using: transitionContext), animations: {
dissmisView.transform = CGAffineTransform(scaleX:1.0,y:0.00001)
}) { (_) in
transitionContext.completeTransition(true)
}
}
}