Reputation: 85
I am implementing a UIPageViewController to my app to try to build a UI like Tinder, in which you can swipe left and right to not only like or dislike a person, but to navigate different screens, i.e. chat screen, profile screen, matches screen etc.
In my case, after signing in, a UIPageViewController that contains 4 other UIViewControllers will pop up.
However, the UIPageViewController is modal and doesn't cover the whole screen(as there is a small gap at the top which allows the user to swipe the modal down and away). I tried using code like this:
self.window = UIWindow(frame: UIScreen.main.bounds)
if let window = self.window {
window.rootViewController = PageViewController()
window.makeKeyAndVisible()
}
at my AppDelegate, or setting Full Screen at the storyboard, but did't work.
I wonder how I should do this? Or maybe UIPageViewController is not the right choice to achieve this swipe from screen to screen navigation style Tinder has?
Anyway, here is the code of my PageViewController:
import UIKit
class PageViewController: UIPageViewController, UIPageViewControllerDataSource, UIPageViewControllerDelegate {
var controllers = [UIViewController]()
override func viewDidLoad() {
super.viewDidLoad()
let vc = TodayPicksViewController()
controllers.append(vc)
let vc1 = TopPicksViewController()
vc1.view.backgroundColor = .yellow
controllers.append(vc1)
let vc2 = ChatViewController()
vc2.view.backgroundColor = .gray
controllers.append(vc2)
let vc3 = (storyboard?.instantiateViewController(withIdentifier: String(describing: ProfileViewController.self)) as? ProfileViewController)!
controllers.append(vc3)
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
DispatchQueue.main.asyncAfter(deadline: .now()+2, execute: {
self.presentPageVC()
})
}
func presentPageVC() {
guard let first = controllers.first else {
return
}
let vc = UIPageViewController(transitionStyle: .scroll,
navigationOrientation: .horizontal,
options: nil)
vc.delegate = self
vc.dataSource = self
vc.setViewControllers([first],
direction: .forward,
animated: true,
completion: nil)
present(vc, animated: true)
}
func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
guard let index = controllers.firstIndex(of: viewController), index > 0 else {
return nil
}
let before = index - 1
return controllers[before]
}
func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
guard let index = controllers.firstIndex(of: viewController), index < (controllers.count - 1) else {
return nil
}
let after = index + 1
return controllers[after]
}
}
Upvotes: 0
Views: 979
Reputation: 28539
By default when you present a ViewController in Swift it doesn't cover the fullscreen. To make it cover the fullscreen you need to set the modalPresentationStyle
on the ViewController.
So in your presentPageVC
method you need to add the following line :
vc.modalPresentationStyle = .fullScreen
So your method will now look like this:
func presentPageVC() {
guard let first = controllers.first else {
return
}
let vc = UIPageViewController(transitionStyle: .scroll,
navigationOrientation: .horizontal,
options: nil)
vc.delegate = self
vc.dataSource = self
vc.setViewControllers([first],
direction: .forward,
animated: true,
completion: nil)
vc.modalPresentationStyle = .fullScreen // <- add this before presenting your ViewController
present(vc, animated: true)
}
To read more about the different presentation styles that you can have check out the documentation here.
Upvotes: 2