简体   繁体   English

两个UIViewController之间的UIPageViewController

[英]UIPageViewController between two UIViewControllers

I've just started programming in Swift, what I'm trying to accomplish is a very simple app with an initial UIViewController , a UIPageViewController that shows some book pages and a destination UIViewController . 我刚刚开始用Swift进行编程,我想要完成的是一个非常简单的应用程序,带有一个初始UIViewController ,一个显示一些书页的UIPageViewController和一个目标UIViewController

My approach so far is this: 到目前为止,我的方法是:

  1. The UIViewController1 is loaded and has a showPage button that simply shows UIPageViewController UIViewController1已加载并具有一个showPage按钮,该按钮仅显示UIPageViewController

present(walkthroughViewController, animated: true, completion: nil)

  1. When the user reaches the last page of the UIPageViewController , I show the destination UIViewController2 , addressing the segue from the start UIViewController 当用户到达UIPageViewController的最后一页时,我将显示目标UIViewController2 ,从开始的UIViewController处理UIPageViewController

     override func onUIPageViewControllerRigthClosing(){ let pvc = self.presentingViewController as! StartPageController dismiss(animated: true){ pvc.performSegue(withIdentifier: "startTest", sender: nil) } } 

Everything works correctly, but the problem is that when UIPageViewController is dismissed, the Starting UIViewController is showed and then is showed the second with the animated segue. 一切正常,但是问题在于,当UIPageViewController时,将显示“启动UIViewController ,然后显示第二个带有动画的序列。 What I am trying to achieve is to directly display the target UiViewController to the user on the dismiss of the UIPageViewController , without showing the transition with animation from start View to the destination View. 我想要实现的是在关闭UiViewController直接向用户显示目标UIPageViewController ,而不显示从开始View到目标View的动画过渡。

I'm completely wrong approaching or there is a way to do the segue before dismissing the UIPageViewController ? 我的做法完全错误,或者有办法在关闭UIPageViewController之前执行segue吗?

Here I created a gif that shows the problem, when I close the UIPageViewController I see the previous view in transition: GIF demo 在这里,我创建了一个gif来显示问题,当我关闭UIPageViewController我看到了转换中的前一个视图: GIF演示

I suggest you using this approach: for these screens transitions use childViewControllers instead of presenting them modally and dismissing with default UIKit functions. 我建议您使用这种方法:对于这些屏幕过渡,请使用childViewControllers而不是以模态方式呈现它们并使用默认的UIKit函数关闭。

You have problems with naming, so let me rename view controllers. 您在命名时遇到问题,所以让我重命名视图控制器。 Say, you have: 说,您有:

  • RootViewController (the first screen, user see after app launch). RootViewController (第一个屏幕,用户在应用启动后查看)。
  • OnboardingViewController (your pageViewController or other container) OnboardingViewController (您的pageViewController或其他容器)
  • AppContentViewController (actually app main screen) AppContentViewController (实际上是应用程序主屏幕)

I suggest you using this approach: for screens transitions on RootViewController use childViewControllers instead of presenting them modally and dismissing with default UIKit functions. 我建议您使用这种方法:对于RootViewController上的屏幕过渡,请使用childViewControllers而不是以模态方式呈现它们并使用默认的UIKit函数关闭。

Here is sample code that works with childViewControllers 这是与childViewControllers一起使用的示例代码

extension UIViewController {
    func displayChildController(_ content: UIViewController, duration: TimeInterval = 0.4, animation: (() -> ())? = nil, completion: @escaping () -> () = {}) {
        content.view.frame = CGRect(x: 0, y: 0, width: self.view.frame.size.width, height: self.view.frame.size.height)
        view.addSubview(content.view)
        addChildViewController(content)
        UIView.animate(withDuration: animation != nil ? duration : 0, animations: {() -> Void in
            animation?()
        }, completion: {(_ finished: Bool) -> Void in
            content.didMove(toParentViewController: self)
            completion()
        })
    }

    func hideChildController(_ content: UIViewController, duration: TimeInterval = 0.4, animation: (() -> ())? = nil, completion: @escaping () -> () = {}) {

        UIView.animate(withDuration: animation != nil ? duration : 0, animations: {() -> Void in
            animation?()
        }, completion: {(_ finished: Bool) -> Void in
            content.willMove(toParentViewController: nil)
            content.view.removeFromSuperview()
            content.removeFromParentViewController()
            completion()
        })
    }
}

Here is "algorithm": 这是“算法”:

I assuming that you are using single storyboard with all these view controllers. 我假设您将所有这些视图控制器都使用单个情节提要。

  1. On OnBoardingViewController declare onDoneCallback : OnBoardingViewController声明onDoneCallback

     class OnBoardingViewController: ... { var onDoneCallback = {} ... } 
  2. On RootViewController when you need present OnboardingViewController : RootViewController ,需要显示OnboardingViewController

     func presentOnboardingScreen() { let onboardingVC = self.storyboard?.instantiateViewController(withIdentifier: "OnboardingViewController") as! OnboardingViewController onboardingVC.transform = .init(translationX: 0, y: self.view.frame.height) onboardingVC.onDoneCallback = { self.presentAppContentAfterOnboarding() // see below } displayChildController(onboardingVC, duration: 0.3, animation: { vc.view.transform = .identity }) } 
  3. When you need call onDoneCallback closure on OnboardingViewController 当您需要在OnboardingViewController上调用onDoneCallback关闭时

  4. presentAppContentAfterOnboarding method on RootViewController could look like: RootViewController上的presentAppContentAfterOnboarding方法可能类似于:

     func presentAppContentAfterOnboarding() { let onboardingVC = self.childViewControllers.last as! OnboardingViewController let appContentVC = self.storyboard?.instantiateViewController(withIdentifier: "AppContentViewController") as! AppContentViewController displayChildController(appContentVC) view.insertSubview(appContentVC.view, belowSubview: onboardingVC.view) hideChildController(childVC, duration: duration, animation: { onboardingVC.view.transform = .init(translationX: 0, y: self.view.frame.height) }) } 

Note. 注意。 Don't forget to set Storyboard ID of OnboardingViewController and AppContentViewController in your storyboard. 不要忘记在情节提要中设置OnboardingViewControllerAppContentViewController的情节提要ID

Here is the sample project 这是示例项目

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM