簡體   English   中英

兩個UIViewController之間的UIPageViewController

[英]UIPageViewController between two UIViewControllers

我剛剛開始用Swift進行編程,我想要完成的是一個非常簡單的應用程序,帶有一個初始UIViewController ,一個顯示一些書頁的UIPageViewController和一個目標UIViewController

到目前為止,我的方法是:

  1. UIViewController1已加載並具有一個showPage按鈕,該按鈕僅顯示UIPageViewController

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

  1. 當用戶到達UIPageViewController的最后一頁時,我將顯示目標UIViewController2 ,從開始的UIViewController處理UIPageViewController

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

一切正常,但是問題在於,當UIPageViewController時,將顯示“啟動UIViewController ,然后顯示第二個帶有動畫的序列。 我想要實現的是在關閉UiViewController直接向用戶顯示目標UIPageViewController ,而不顯示從開始View到目標View的動畫過渡。

我的做法完全錯誤,或者有辦法在關閉UIPageViewController之前執行segue嗎?

在這里,我創建了一個gif來顯示問題,當我關閉UIPageViewController我看到了轉換中的前一個視圖: GIF演示

我建議您使用這種方法:對於這些屏幕過渡,請使用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. 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. 當您需要在OnboardingViewController上調用onDoneCallback關閉時

  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

這是示例項目

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM