Resolving the Issue: SwiftUI TabView Support for iOS 13
Fix Issue for iOS 13
Resolving the Issue: SwiftUI TabView Support for iOS 13
Fix Issue for iOS 13

If you’re facing the same issue as I did, here’s the solution:
In my iOS project, I needed to support iOS 13. Unfortunately, many newer SwiftUI components, including the updated TabView, require iOS 14 or later, creating compatibility issues with my work. One such issue was implementing a card slider with an indicator, which TabView typically handles but isn't available for iOS 13.
To work around this, I created a custom ScrollablePageView that replicates the functionality of TabView as closely as possible. This custom view allows my project to maintain compatibility with iOS 13 while achieving the desired sliding indicator effect.
This Available only on iOS 14 and above.
//#available(iOS 14.0, *)
TabView(selection: $currentPage) {
ForEach(0 ..< viewModel.investingSelections.count, id: \.self) { index in
// put yout view here
InvestingSelectionContentView(model: viewModel.investingSelections)
.tag(index)
}
}
.tabViewStyle(PageTabViewStyle(indexDisplayMode: .never))
.frame(height: 320)
Result error look like this, it caanot use in if minimum deployment still iOS 13.

Here’s the complete code for a custom TabView that works with iOS 13. Feel free to copy this, and then simply call it wherever you need to use it.
This solution for TabView for iOS 13 like this
import SwiftUI
// Custom UIScrollView wrapper for iOS 13
struct ScrollablePageView<Content: View>: UIViewControllerRepresentable {
@Binding var currentPage: Int
let pages: Int
let content: (Int) -> Content
func makeCoordinator() -> Coordinator {
Coordinator(self)
}
func makeUIViewController(context: Context) -> UIPageViewController {
let pageViewController = UIPageViewController(
transitionStyle: .scroll,
navigationOrientation: .horizontal,
options: nil
)
pageViewController.dataSource = context.coordinator
pageViewController.delegate = context.coordinator
// Create initial view controller
let initialVC = UIHostingController(rootView: content(currentPage))
pageViewController.setViewControllers(
[initialVC],
direction: .forward,
animated: true
)
return pageViewController
}
func updateUIViewController(_ pageViewController: UIPageViewController, context: Context) {
context.coordinator.parent = self
if let currentVC = pageViewController.viewControllers?.first,
let currentIndex = context.coordinator.indexForViewController(currentVC),
currentIndex != currentPage
{
let newVC = context.coordinator.createViewController(for: currentPage)
let direction: UIPageViewController.NavigationDirection = currentIndex < currentPage ? .forward : .reverse
pageViewController.setViewControllers(
[newVC],
direction: direction,
animated: true
)
}
}
class Coordinator: NSObject, UIPageViewControllerDataSource, UIPageViewControllerDelegate {
var parent: ScrollablePageView
private var controllers: [UIHostingController<Content>] = []
init(_ pageViewController: ScrollablePageView) {
self.parent = pageViewController
super.init()
}
// MARK: - UIPageViewControllerDataSource
func pageViewController(
_ pageViewController: UIPageViewController,
viewControllerBefore viewController: UIViewController
) -> UIViewController? {
guard let index = indexForViewController(viewController) else { return nil }
if index == 0 { return nil }
return createViewController(for: index - 1)
}
func pageViewController(
_ pageViewController: UIPageViewController,
viewControllerAfter viewController: UIViewController
) -> UIViewController? {
guard let index = indexForViewController(viewController) else { return nil }
if index + 1 >= parent.pages { return nil }
return createViewController(for: index + 1)
}
// MARK: - UIPageViewControllerDelegate
func pageViewController(
_ pageViewController: UIPageViewController,
didFinishAnimating finished: Bool,
previousViewControllers: [UIViewController],
transitionCompleted completed: Bool
) {
if finished,
completed,
let visibleVC = pageViewController.viewControllers?.first,
let index = indexForViewController(visibleVC)
{
DispatchQueue.main.async {
self.parent.currentPage = index
}
}
}
// MARK: - Helper methods
func createViewController(for index: Int) -> UIViewController {
let hostingController = UIHostingController(rootView: parent.content(index))
hostingController.view.tag = index // Use tag to store index
return hostingController
}
func indexForViewController(_ viewController: UIViewController) -> Int? {
if let hostingController = viewController as? UIHostingController<Content> {
return hostingController.view.tag
}
return nil
}
}
}
How to use the custom TabView
if #available(iOS 14.0, *) {
TabView(selection: $currentPage) {
ForEach(0 ..< viewModel.investingSelections.count, id: \.self) { index in
InvestingSelectionContentView(model: viewModel.investingSelections)
.tag(index)
}
}
.tabViewStyle(PageTabViewStyle(indexDisplayMode: .never))
.frame(height: 320)
} else {
// for iOS 13
ScrollablePageView(
currentPage: $currentPage,
pages: viewModel.investingSelections.count
) { index in
// put yout view here
InvestingSelectionContentView(model: viewModel.investingSelections)
}
.frame(height: 320)
}
This Preview using Custom TabView

Result
Using this solution alone will work smoothly on the latest iOS versions as well, so there’s no need to create two separate versions.
Thank you for reading! If you enjoyed it, please consider clapping and following for more updates! 👏
Stackademic 🎓
Thank you for reading until the end. Before you go:
- Please consider clapping and following the writer! 👏
- Follow us **X | [LinkedIn](https://www.linkedin.com/company/stackademic) | [YouTube](https://www.youtube.com/c/stackademic) | [Discord](https://discord.gg/in-plain-english-709094664682340443) | [Newsletter](https://newsletter.plainenglish.io/) | [Podcast](https://open.spotify.com/show/7qxylRWKhvZwMz2WuEoua0)**
- **Create a free AI-powered blog on Differ.**
- More content at **Stackademic.com**
메타데이터
- post_id
- 18e5ced57ddd
- slug
- resolving-the-issue-swiftui-tabview-support-for-ios-13-18e5ced57ddd
- url
- https://blog.stackademic.com/resolving-the-issue-swiftui-tabview-support-for-ios-13-18e5ced57ddd
- canonical_url
- https://blog.stackademic.com/resolving-the-issue-swiftui-tabview-support-for-ios-13-18e5ced57ddd
- author_url
- https://medium.com/@21zerixpm
- status
- ok
- fetched_at
- 2026-07-22 05:00:42