使用UIPresentationController和Tab栏向上滑动菜单

时间:2017-08-03 08:09:12

标签: ios swift

我使用UIPresentationController来显示我的滑动菜单,我的应用程序中也有标签栏菜单。我的标签栏上显示了我的上拉菜单,但我希望它显示在我的标签栏上方?

所以现在它的行为如下:

enter image description here enter image description here

或对帧高进行一些操作:

enter image description here

但我需要它表现得像这样:

enter image description here

我的代码:

class SlideInPresentationController: UIPresentationController {
    private var direction: SlideDirection

    init(presentedViewController: UIViewController, presenting presentingViewController: UIViewController?,
         slideDirection: SlideDirection)
    {
        direction = slideDirection
        super.init(presentedViewController: presentedViewController, presenting: presentingViewController)
    }

    override func containerViewWillLayoutSubviews()
    {
        presentedView?.frame = frameOfPresentedViewInContainerView
    }

    override func size(forChildContentContainer container: UIContentContainer, withParentContainerSize parentSize: CGSize) -> CGSize {
        switch direction {
        case .slideLeft, .slideRight:
            return CGSize(width: parentSize.width*(2.0/3.0), height: parentSize.height)
        case .slideUp, .slideDown:
            return CGSize(width: parentSize.width, height: 88)
        }
    }

    override var frameOfPresentedViewInContainerView: CGRect {
        var frame: CGRect = .zero
        frame.size = size(forChildContentContainer: presentedViewController, withParentContainerSize: containerView!.bounds.size)
        switch direction {
        case .slideLeft:
            frame.origin.x = containerView!.frame.width - frame.size.width
        case .slideUp:
            frame.origin.y = containerView!.frame.height - 88-49 //slide up menu + tab bar
        default:
            frame.origin = .zero
        }
        return frame
    }

}

这里,动画类和SlideInPresentationAnimator的扩展

class SlideInPresentationAnimator: NSObject {
    let direction: SlideDirection

    enum AnimationType
    {
        case dismiss
        case show
    }

    let animationType: AnimationType
    var mainViewController: UIViewController?

    init(type: AnimationType, presentingSlideDirection slideDirection: SlideDirection, controller: UIViewController)
    {
        direction = slideDirection
        animationType = type
        mainViewController = controller
        super.init()
    }

    init(type: AnimationType, presentingSlideDirection slideDirection: SlideDirection)
    {
        direction = slideDirection
        animationType = type
        super.init()
    }
}


extension SlideInPresentationAnimator: UIViewControllerAnimatedTransitioning {
    func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval
    {
        return 0.3
    }

    func animateTransition(using transitionContext: UIViewControllerContextTransitioning)
    {
        let transitionKey: UITransitionContextViewControllerKey
        switch animationType {
        case .dismiss:
            transitionKey = .from
        case .show:
            transitionKey = .to
        }
        let controller = transitionContext.viewController(forKey: transitionKey)!
        if animationType == .show
        {

            transitionContext.containerView.addSubview(controller.view)
        }

        let inFrame = transitionContext.finalFrame(for: controller)
        var outFrame = inFrame
        switch direction {
        case .slideLeft:
            outFrame.origin.x = transitionContext.containerView.frame.size.width
        case .slideUp:
            outFrame.origin.y = transitionContext.containerView.frame.size.height - 88
        default: break
            // TODO
        }

        let startFrame: CGRect, endFrame: CGRect
        switch animationType {
        case .show:
            startFrame = outFrame
            endFrame = inFrame
        case .dismiss:
            startFrame = inFrame
            endFrame = outFrame
        }
        let animationDuration = transitionDuration(using: transitionContext)
        controller.view.frame = startFrame
        UIView.animate(withDuration: animationDuration, animations: {
            controller.view.frame = endFrame
        }) { (finished: Bool) in
            transitionContext.completeTransition(finished)
        }
    }
}

1 个答案:

答案 0 :(得分:1)

在这一行

outFrame.origin.y = transitionContext.containerView.frame.size.height - 88

您还应该减去标签栏的高度

outFrame.origin.y = transitionContext.containerView.frame.size.height - 88 - *height of tab bar*

我相信标签栏的高度曾经是49,但我有一段时间没有使用标签栏,所以最好通过使用

获得高度
tabBarController.tabBar.frame.size.height