How to stop slide transition into Second VC before

2019-09-17 10:46发布

问题:

In my application I have a uiview at the top of the screen. When I tap that UIView I have a second View Controller slides up. What I would like to accomplish is that when the second View Controller slides into the screen it stops right before it covers up the UIView

What I am trying to accomplish is have a view slide up that contains store information such as hours open, address, phone number etc. So I was thinking that I could just have another view controller that holds all of this information. Only part is I want to stop it sliding up so it is flush with the uiview bar on top.

//tap to bring up the second view controller
@IBAction func showInfoVC(sender: AnyObject) {
    self.performSegueWithIdentifier("showSecondVC", sender: self)
}

回答1:

It sounds like your goals are:

  1. Have a base View
  2. Slide a second View part way up on the first

Assuming this is the case, there are multiple ways you could accomplish this, but Apple would probably recommend View Controller Containment. To accomplish this, you will have:

  1. A SlidingContainerViewController.
    • This is a custom container View Controller that will hold our other two View Controllers
  2. Some background View Controller
  3. Some foreground View Controller

Here is a basic implementation of a custom SlidingContainerViewController

// SlidingContainerViewController.swift

import UIKit

class SlidingContainerViewController: UIViewController {

    //MARK: - Init
    init(frontViewController: UIViewController, backViewController: UIViewController) {
        super.init(nibName: nil, bundle: nil)
        frontViewContoller = frontViewController
        backViewContoller = backViewController
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    //MARK: - Public
    var frontViewContoller: UIViewController = UIViewController()
    var backViewContoller: UIViewController = UIViewController()
    var splitOriginY: CGFloat = 160.0

    func toggleFrontView() {
        if frontIsVisible {
            UIView.animateWithDuration(0.4) {
                self.frontViewContoller.view.frame.origin.y = self.view.frame.height
                self.frontIsVisible = false
            }
        } else {
            UIView.animateWithDuration(0.4) {
                self.frontViewContoller.view.frame.origin.y = self.splitOriginY
                self.frontIsVisible = true
            }

        }
    }

    //MARK: - ViewLifecycle
    override func viewDidLoad() {
        super.viewDidLoad()
        addChild(backViewContoller)
        addChild(frontViewContoller)
        self.frontViewContoller.view.frame.origin.y = self.view.frame.height
    }

    //MARK: - Private
    var frontIsVisible = false

    private func addChild(viewController: UIViewController) {
        addChildViewController(viewController)
        view.addSubview(viewController.view)
        viewController.view.frame = view.bounds
        viewController.didMoveToParentViewController(self)
    }

}

You can then put any custom View Controllers that you want into this container View Controller. The bottom View Controller just needs to call toggleFrontView() on the container View Controller whenever it wants the slide to occur.

Below I've added two sample View Controllers for demonstrations purposes. You can view the whole project on github: SlidingVC

*Note: This solution is implemented programmatically without Interface Builder. I personally build all of my apps completely in code this way. If you desired to use Interface Builder, you could accomplish the same thing using a Storyboard and custom segues. Here is a related tutorial: A Beginner’s Guide to Animated Custom Segues in iOS 8