# [HowTo] Custom Tabs Fully Programmatic Approach
Custom Tabs without using any 3rd party library and fully programmatic approach.
The view for the tabs (TabsView) will be a UICollectionView, and each cell (TabCell) has an UIImageView for the icon (optional) and an UILabel for the title.
# Code
Refresh CollectionView Layout when you rotate the device
//ViewController.swift
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
tabsView.collectionView.collectionViewLayout.invalidateLayout()
}
Set TabMode to '.fixed' for stretched tabs in full width of screen or '.scrollable' for scrolling to see all tabs
//ViewController.swift
private func setupTabs() {
tabsView.tabs = [
Tab(icon: UIImage(systemName: "music.note.list"), title: "Music"),
Tab(icon: UIImage(systemName: "film"), title: "Movie"),
Tab(icon: UIImage(systemName: "book"), title: "Book")
]
tabsView.tabMode = .fixed
tabsView.titleColor = .black
tabsView.iconColor = .black
tabsView.indicatorColor = .black
tabsView.titleFont = UIFont.systemFont(ofSize: 20, weight: .semibold)
tabsView.collectionView.backgroundColor = .white
tabsView.delegate = self
tabsView.collectionView.selectItem(at: IndexPath(item: 0, section: 0), animated: true, scrollPosition: .centeredVertically)
}
Select transitionStyle to '.scroll' for cool animation and set the selected ViewController in the PageViewController when the app starts.
private func setupPageViewController() {
// PageViewController
self.pageController = TabsPageViewController(transitionStyle: .scroll, navigationOrientation: .horizontal, options: nil)
self.addChild(self.pageController)
self.view.addSubview(self.pageController.view)
// Set PageViewController Delegate & DataSource
pageController.delegate = self
pageController.dataSource = self
// Set the selected ViewController in the PageViewController when the app starts
pageController.setViewControllers([showViewController(0)!], direction: .forward, animated: true, completion: nil)
// PageViewController Constraints
self.pageController.view.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
self.pageController.view.topAnchor.constraint(equalTo: self.tabsView.bottomAnchor),
self.pageController.view.leadingAnchor.constraint(equalTo: self.view.leadingAnchor),
self.pageController.view.trailingAnchor.constraint(equalTo: self.view.trailingAnchor),
self.pageController.view.bottomAnchor.constraint(equalTo: self.view.bottomAnchor)
])
self.pageController.didMove(toParent: self)
}