This content originally appeared on DEV Community and was authored by ArshTechPro
Introduction
Ever wondered what's really happening when you use a SwiftUI List
or TextField
? While SwiftUI presents a modern, declarative API, many of its components are actually powered by battle-tested UIKit views under the hood.
In this article, we'll explore which SwiftUI components use UIKit as their foundation in iOS 16+, and how you can verify this yourself using Xcode's tools.
Why Does This Matter?
Understanding the UIKit foundation helps you:
- Debug issues more effectively using familiar UIKit knowledge
- Set realistic expectations for customization capabilities
- Optimize performance by understanding underlying mechanisms
- Make better architectural decisions when choosing between SwiftUI and UIKit
How to Verify UIKit Components
Before we dive in, here's how you can see the UIKit layer yourself:
- Run your SwiftUI app in Xcode
- Navigate to Debug → View Debugging → Capture View Hierarchy
- Examine the view hierarchy to see the underlying UIKit components
Key Examples
1. List → UICollectionView
The most significant change in iOS 16: List
now uses UICollectionView
instead of UITableView
.
import SwiftUI
struct ListExample: View {
var body: some View {
List {
Text("Row 1")
Text("Row 2")
Text("Row 3")
}
.listStyle(.insetGrouped)
}
}
What you'll see in View Debugger:
├── List
│ └── CollectionViewListRoot
│ └── UICollectionView
This change brings better performance and modern collection view features, but requires different customization approaches than the old UITableView.
2. NavigationStack → UINavigationController
Navigation in SwiftUI is powered by UIKit's navigation infrastructure:
struct NavigationExample: View {
var body: some View {
NavigationStack {
List {
NavigationLink("Go to Detail") {
Text("Detail View")
.navigationTitle("Detail")
}
}
.navigationTitle("Main")
}
}
}
This gives you the familiar navigation bar, animations, and gesture-based navigation from UIKit.
3. TextField & TextEditor → UITextField & UITextView
Text input components wrap their UIKit equivalents:
struct TextInputExample: View {
@State private var shortText = ""
@State private var longText = ""
var body: some View {
VStack(spacing: 20) {
// Uses UITextField internally
TextField("Enter text", text: $shortText)
.textFieldStyle(.roundedBorder)
// Uses UITextView internally
TextEditor(text: $longText)
.frame(height: 100)
.border(Color.gray, width: 1)
}
.padding()
}
}
Complete Component Mapping
Here's a comprehensive list of SwiftUI components and their UIKit foundations:
SwiftUI Component | UIKit Foundation | Notes |
---|---|---|
List | UICollectionView | Changed from UITableView in iOS 16 |
LazyVGrid/LazyHGrid | UICollectionView | Since iOS 14 |
NavigationStack | UINavigationController | NavigationView in iOS 15 and earlier |
TabView | UITabBarController | Standard tab style |
TabView (page style) | UIPageViewController | When using .tabViewStyle(.page)
|
TextField | UITextField | Single line text input |
TextEditor | UITextView | Multi-line text input |
ScrollView | UIScrollView | Basic scrolling container |
Sheet | UIViewController presentation | Modal presentation |
Alert | UIAlertController | System alerts |
Menu/ContextMenu | UIMenu & UIContextMenuInteraction | Since iOS 14 |
DatePicker | UIDatePicker | Date and time selection |
ColorPicker | UIColorWell | Since iOS 14 |
Slider | UISlider | Value selection |
Toggle | UISwitch | On/off states |
ProgressView | UIProgressView/UIActivityIndicatorView | Progress indicators |
Pure SwiftUI Components
Not everything uses UIKit! These are implemented purely in SwiftUI:
-
Stack Views:
VStack
,HStack
,ZStack
-
Shapes:
Rectangle
,Circle
,RoundedRectangle
,Ellipse
-
Layout Containers:
GeometryReader
,Group
,ForEach
- Canvas: Direct drawing API
- View Modifiers: Most modifiers are pure SwiftUI transformations
- Layout Protocol Views: Custom layouts using the Layout protocol (iOS 16+)
Performance Considerations
Understanding the UIKit layer helps optimize performance:
- List/LazyVGrid: Leverage UICollectionView's cell reuse - only visible items are in memory
- ScrollView with VStack: Creates all views immediately - use LazyVStack for large datasets
- TextField vs TextEditor: UITextField is lighter for single-line input
Debugging Tips
When debugging in Xcode's View Debugger, look for these telltale signs:
- CollectionViewListRoot: Indicates a List (iOS 16+)
- UIHostingController: SwiftUI content wrapped for UIKit
- _UIHostingView: SwiftUI views inside UIKit containers
- UIViewRepresentable: Custom UIKit integrations
Conclusion
SwiftUI's use of UIKit components isn't a weakness—it's a pragmatic approach that leverages decades of optimization while providing a modern API. As SwiftUI evolves, Apple continues to optimize these foundations, but UIKit's maturity ensures stability and performance for years to come.
Have you discovered other interesting UIKit foundations in SwiftUI? Share your findings in the comments!
This content originally appeared on DEV Community and was authored by ArshTechPro

ArshTechPro | Sciencx (2025-08-25T21:23:46+00:00) The Hidden UIKit: SwiftUI Components Under the Hood in iOS 16+. Retrieved from https://www.scien.cx/2025/08/25/the-hidden-uikit-swiftui-components-under-the-hood-in-ios-16/
Please log in to upload a file.
There are no updates yet.
Click the Upload button above to add an update.