If you are an iOS developer, you should have heard about parallax header and page tabbar controller. There are many tutorials and libraries on these feature, but just implementing individually. What about combine these 2 features together? In this post I’ll guide how to combine parallax header with page tabbar controller easily.
Set up page tabbar controller
First, download source code in this link.
Open Xcode Workspace in path: start/ParallaxHeaderPagingViewControllerDemo.xcworkspace
The source code in this project is pretty simple. It contains a screen with a UITableView display an ascending ordered number list. Run the project to see for yourself.
Now we’ll integrate page tabbar controller by using library Parchment. Open Podfile
and insert the following code after line use_frameworks!
:
pod 'Parchment'
Open terminal, cd to the path [root]/start, then run the following command:
pod install
In Xcode, create a new UIViewController with name as ParchmentExampleViewController
with the following code:
import UIKit
import Parchment
class ParchmentExampleViewController: UIViewController {
@IBOutlet weak var pagingContainer: UIView!
var viewControllers: [TableViewController] = []
var pagingViewController: PagingViewController!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
// 1
viewControllers = [
TableViewController(count: 20),
TableViewController(count: 1),
TableViewController(count: 10),
TableViewController(count: 100),
]
// 2
for (index, viewController) in viewControllers.enumerated() {
viewController.title = String(index)
}
// 3
let pagingViewController = PagingViewController(viewControllers: viewControllers)
pagingContainer.addSubview(pagingViewController.view)
pagingViewController.view.translatesAutoresizingMaskIntoConstraints = false
pagingViewController.view.topAnchor.constraint(equalTo: pagingContainer.topAnchor).isActive = true
pagingViewController.view.bottomAnchor.constraint(equalTo: pagingContainer.bottomAnchor).isActive = true
pagingViewController.view.leftAnchor.constraint(equalTo: pagingContainer.leftAnchor).isActive = true
pagingViewController.view.rightAnchor.constraint(equalTo: pagingContainer.rightAnchor).isActive = true
pagingViewController.didMove(toParent: self)
self.pagingViewController = pagingViewController
}
}
What you just did:
- Create an array of
TableViewController
with different number of items. - Config title for each item in array
viewControllers
. - Set up
PagingViewController
and add it as subview ofpagingContainer
.
Open Main.storyboard, delete Table View Controller Scene. Then add a new UIViewController and subclass it as ParchmentExampleViewController.
Next, add a UIView into ParchmentExampleViewController. This view will be used as container for page tabbar controller. Config its contraints as follow:
- Top space to safe area top with 0 px.
- Leading, Trailing, Bottom space to parent view’s edges with 0 px.
If you config correctly, Xcode should show like this:
Select the view, connect its IBOutlet to variable pagingContainer:
Select ParchmentExampleViewController, on the right sidebar open attributes inspector and tick on Is Initial View Controller.
Now run the project, you can see the screen is displaying a page tabbar controller:
We have finished set up page tabbar controller. Next we’ll integrate parallax header into our demo.
Integrate parallax header
In this tutorial we’ll use HPParallaxHeader to implement parallax header. First, open Podfile and add the following code after line pod 'Parchment'
:
pod 'HPParallaxHeader'
Then, run command in terminal:
pod install
Open Main.storyboard, add a UIScrollView
with top, bottom, leading and trailing constraint to super view’s corresponding edges. This scroll view will be used to display parallax header. In Size Inspector, deselect option Content Layout Guides. If you config correctly, Xcode should display as follow:
Next, move Paging Container view into Scroll View and add the following constaint:
- Top, bottom, leading and trailing equal to super view’s edges.
- Width and height equal to super view’s width and height.
Xcode should show as follow:
Switch to file ParchmentExampleViewController.swift, add the following line below var pagingViewController: PagingViewController!
:
@IBOutlet weak var scrollView: HPScrollView!
In method viewDidLoad
, add the following code:
// 1
scrollView.parallaxHeader.load(nibName: "StarshipHeader", bundle: nil, options: [:])
// 2
scrollView.parallaxHeader.height = 300
// 3
scrollView.parallaxHeader.mode = .fill
Switch to Main.storyboard, select scroll view, subclass it as HPParallaxHeader.
Connect its IBOutlet to variable scrollView
of ParchmentExampleViewController
.
Now, you can run the project. The parallax header is now working properly with page tabbar view controller. But there is some wrong: the tab bar is overlap with safe area which makes you cannot tap on it.
We’ll fix this problem by adding the following code after viewDidLoad
:
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
scrollView.parallaxHeader.minimumHeight = view.safeAreaInsets.top
}
In the above block code we set minimum height of parallax header equal to safe area insets top to make the tab bar avoid safe area. Run the project and you can see the tab bar position is now below safe area top which is good.
Now try to scroll the list to end and … Oops! The bottom of the list is now beyond the bottom of the screen which is kind of weird.
It turns out since we previously set up pagingContainer
’s height equal super view height, when we set parallax header minimum height the pagingContainer
’s bottom is push below super view’s bottom. We’ll fix this by subtracting pagingContainer
’s height with parallax header’s minium height.
In ParchmentExampleViewController.swift, add the following code below @IBOutlet weak var pagingContainer: UIView!
:
@IBOutlet weak var pagingContainerHeightConstraint: NSLayoutConstraint!
Swich to Main.storyboard, select Parchment Example Scene, connect IBOutlet from pagingContainer
’s height contraint with variablepagingContainerHeightConstraint
just created above.
Back to ParchmentExampleViewController.swift, add the following code at the end of viewDidAppear
:
pagingContainerHeightConstraint.constant = -(scrollView.parallaxHeader.minimumHeight)
Run the project, now everything works perfectly!
Wraps Up
So we finally finish integrate parallax header with page tab bar controller into our application. It is pretty easy right? With the combination of HPParallaxHeader and Parchment it takes you only 5 – 10 minutes to complete a task that may cost you 1 – 2 day if do it yourself. Hope this article helps. If you have any questions please let me know in the comment section below.