【问题标题】:UIPageViewController between two UIViewControllers两个 UIViewController 之间的 UIPageViewController
【发布时间】:2018-05-26 08:53:58
【问题描述】:

我刚刚开始使用 Swift 编程,我想要完成的是一个非常简单的应用程序,它具有初始 UIViewController、一个显示一些书页的 UIPageViewController 和一个目标 UIViewController

到目前为止,我的方法是这样的:

  1. UIViewController1 已加载,并有一个 showPage 按钮,仅显示 UIPageViewController

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

  1. 当用户到达UIPageViewController 的最后一页时,我会显示目的地UIViewController2,从开始UIViewController 开始寻址

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

一切正常,但问题是当UIPageViewController 被关闭时,会显示Starting UIViewController,然后用动画segue 显示第二个。 我想要实现的是在关闭UIPageViewController 时直接向用户显示目标UiViewController,而不显示从开始视图到目标视图的动画过渡。

我完全错了,或者在解雇UIPageViewController之前有办法做segue?

在这里我创建了一个显示问题的 gif,当我关闭 UIPageViewController 时,我看到之前的视图正在转换:GIF demo

【问题讨论】:

  • 可以分享示例代码吗?
  • 你的意思是完整的项目吗?因为代码已经在应用程序中,实际上第一步是点击一个按钮,第二个方法在 UiPageViewController 的页面完成时调用
  • @AntonBelousov 我通过添加 Gif 修改了问题,我希望现在问题比以前更清楚

标签: ios swift uiviewcontroller segue uipageviewcontroller


【解决方案1】:

我建议您使用这种方法:对于这些屏幕转换使用 childViewControllers 而不是模态显示它们并使用默认的 UIKit 函数关闭。

你有命名的问题,所以让我重命名视图控制器。 说,你有:

  • RootViewController(第一屏,用户看后 应用程序启动)。
  • OnboardingViewController(您的 pageViewController 或其他容器)
  • AppContentViewController(其实是应用主屏)

我建议您使用这种方法:对于RootViewController 上的屏幕转换,使用 childViewControllers 而不是模态显示它们并使用默认的 UIKit 函数关闭。

这是与 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()
        })
    }
}

这里是“算法”:

我假设您将单个故事板与所有这些视图控制器一起使用。

  1. OnBoardingViewController 上声明onDoneCallback

    class OnBoardingViewController: ... {
        var onDoneCallback = {}
        ...
    }
    
  2. 当你需要出席OnboardingViewController时打开RootViewController

    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. 当您需要调用 onDoneCallback 关闭 OnboardingViewController

  4. 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)
        })
    }
    

注意。不要忘记在您的故事板中设置OnboardingViewControllerAppContentViewController故事板ID

这里是sample project

【讨论】:

  • 谢谢你很有用!我希望有一种方法可以让我使用 segue,但我认为这是不可能的
  • 好吧,看起来好像没有方便的方法来做到这一点,只使用 segues
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多