两个 UIViewController 之间的 UIPageViewController
UIPageViewController between two UIViewControllers
我刚开始在 Swift 中编程,我想要完成的是一个非常简单的应用程序,它有一个初始 UIViewController
,一个显示一些书页的 UIPageViewController
和目的地 UIViewController
.
到目前为止我的方法是这样的:
UIViewController1
已加载并有一个仅显示 UIPageViewController
的 showPage 按钮
present(walkthroughViewController, animated: true, completion: nil)
当用户到达UIPageViewController
的最后一页时,我显示目的地UIViewController2
,从头开始解决segue UIViewController
override func onUIPageViewControllerRigthClosing(){
let pvc = self.presentingViewController as! StartPageController
dismiss(animated: true){
pvc.performSegue(withIdentifier: "startTest", sender: nil)
}
}
一切正常,但问题是当 UIPageViewController
被关闭时,开始 UIViewController
显示,然后显示第二个动画 segue。
我想要实现的是在 UIPageViewController
关闭时直接向用户显示目标 UiViewController
,而不显示从开始视图到目标视图的动画过渡。
我完全错了,或者有办法在关闭 UIPageViewController
?
之前进行转场
我在这里创建了一个显示问题的 gif,当我关闭 UIPageViewController
我看到之前的视图正在转换:GIF demo
我建议您使用这种方法:对于这些屏幕转换,使用 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()
})
}
}
这是"algorithm":
我假设您使用的是带有所有这些视图控制器的单个故事板。
在 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
闭包时
presentAppContentAfterOnboarding
RootViewController
上的方法可能如下所示:
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)
})
}
注意。不要忘记在故事板中设置 故事板 ID of OnboardingViewController
和 AppContentViewController
。
我刚开始在 Swift 中编程,我想要完成的是一个非常简单的应用程序,它有一个初始 UIViewController
,一个显示一些书页的 UIPageViewController
和目的地 UIViewController
.
到目前为止我的方法是这样的:
UIViewController1
已加载并有一个仅显示UIPageViewController
的 showPage 按钮
present(walkthroughViewController, animated: true, completion: nil)
当用户到达
UIPageViewController
的最后一页时,我显示目的地UIViewController2
,从头开始解决segueUIViewController
override func onUIPageViewControllerRigthClosing(){ let pvc = self.presentingViewController as! StartPageController dismiss(animated: true){ pvc.performSegue(withIdentifier: "startTest", sender: nil) } }
一切正常,但问题是当 UIPageViewController
被关闭时,开始 UIViewController
显示,然后显示第二个动画 segue。
我想要实现的是在 UIPageViewController
关闭时直接向用户显示目标 UiViewController
,而不显示从开始视图到目标视图的动画过渡。
我完全错了,或者有办法在关闭 UIPageViewController
?
我在这里创建了一个显示问题的 gif,当我关闭 UIPageViewController
我看到之前的视图正在转换:GIF demo
我建议您使用这种方法:对于这些屏幕转换,使用 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()
})
}
}
这是"algorithm":
我假设您使用的是带有所有这些视图控制器的单个故事板。
在
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
上调用 presentAppContentAfterOnboarding
RootViewController
上的方法可能如下所示: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) }) }
onDoneCallback
闭包时
注意。不要忘记在故事板中设置 故事板 ID of OnboardingViewController
和 AppContentViewController
。