[英]How should I pass data between UIViewControllers in UIPageViewController and save variables
[英]UIPageViewController between two UIViewControllers
我剛剛開始用Swift進行編程,我想要完成的是一個非常簡單的應用程序,帶有一個初始UIViewController
,一個顯示一些書頁的UIPageViewController
和一個目標UIViewController
。
到目前為止,我的方法是:
UIViewController1
已加載並具有一個showPage按鈕,該按鈕僅顯示UIPageViewController
present(walkthroughViewController, animated: true, completion: nil)
當用戶到達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()
})
}
}
這是“算法”:
我假設您將所有這些視圖控制器都使用單個情節提要。
在OnBoardingViewController
聲明onDoneCallback
:
class OnBoardingViewController: ... { var onDoneCallback = {} ... }
在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 }) }
當您需要在OnboardingViewController
上調用onDoneCallback
關閉時
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) }) }
注意。 不要忘記在情節提要中設置OnboardingViewController
和AppContentViewController
的情節提要ID 。
這是示例項目
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.