🚀 UIKit Roadmap (Beginner → Project Level)
We will go step-by-step like this:
🥇 PHASE 1 – UIKit Fundamentals (Most Important)
1️⃣UIView & ViewController (START HERE ✅)
What is UIView?
What is UIViewController?
viewDidLoad()
Background color change
Adding subviews
👉 This is the FIRST topic we will start.
2️⃣UI Elements (Basic Components)
UIButton
UILabel
UITextField
UIImageView
UISwitch
You must master these.
3️⃣AutoLayout (Very Important ⚠️)
Constraints
Leading, Trailing, Top, Bottom
Width & Height
StackView
Safe Area
Without this → UI will break on different screen sizes.
🥈 PHASE 2 – User Interaction & Navigation
4️⃣Target-Action Pattern
@IBAction
addTarget()
Button click handling
5️⃣Navigation
UINavigationController
Push & Pop
Passing data between screens
6️⃣Tab Bar Controller
UITabBarController
Multiple screens
🥉 PHASE 3 – Table & Collection View (Real App Level)
7️⃣UITableView (VERY IMPORTANT 🔥)
UITableViewDataSource
UITableViewDelegate
Custom cells
Dynamic data
8️⃣UICollectionView
Grid layout
Custom cells
Color grid project
🏆 PHASE 4 – Real App Features
9️⃣Networking (API)
URLSession
JSON parsing
Codable
🔟 MVC Architecture
Model
View
Controller
🥇 PHASE 1 – UIKit Fundamentals
We will cover:
1. What is UIKit?
2. What is UIView?
3. What is UIViewController?
4. How screen is created
5. viewDidLoad()
6. Background color change
7. Adding subviews
1️⃣ What is UIKit? (Very Simple)
UIKit is a framework provided by Apple to build iOS app UI.
It gives you:
Buttons
Labels
TextFields
Images
Navigation
Animations
Touch handling
Without UIKit → you cannot build iPhone UI.
Think like this:
UIKit = Toolbox
UIView = One tool
UIButton = One tool
UILabel = One tool
2️⃣ What is UIView? (MOST IMPORTANT 🔥)
Definition:
UIView is the base class for everything you see on screen.
Everything visible on screen is a UIView.
Examples:
Screen background → UIView
Button → subclass of UIView
Label → subclass of UIView
ImageView → subclass of UIView
🧠 Visual Understanding
Imagine your screen like this:
Main View (UIView)
|
|-- Button (UIView)
|-- Label (UIView)
|-- ImageView (UIView)
Everything is inside a big main view.
That main view belongs to ViewController.
Example Code
let myView = UIView()
[Link] = .red
This creates a red view.
3️⃣ What is UIViewController?
Now this is VERY IMPORTANT.
Definition:
UIViewController manages a screen.
Each screen = one ViewController.
If your app has:
Login Screen
Home Screen
Profile Screen
That means you have:
LoginViewController
HomeViewController
ProfileViewController
Relationship Between ViewController & View
Every ViewController has one main view:
[Link]
This is the root view of the screen.
Think like this:
ViewController = Brain
View = Body
Brain controls the body.
4️⃣ How Screen is Created?
When app launches:
1. AppDelegate starts
2. SceneDelegate loads
3. Root ViewController loads
4. ViewController loads its view
5. viewDidLoad() is called
Then screen appears.
5️⃣ viewDidLoad() (Very Important 🔥🔥🔥)
What is it?
It is a lifecycle method.
It runs ONLY ONCE when the screen is loaded into memory.
Why we use it?
We use it for:
Initial setup
UI customization
Setting background color
Creating views programmatically
API call (initial)
Example:
override func viewDidLoad() {
[Link]()
print("Screen Loaded")
}
This runs once.
6️⃣ Background Color Change
Every ViewController has:
[Link]
To change background:
[Link] = .yellow
Example:
override func viewDidLoad() {
[Link]()
[Link] = .lightGray
}
That changes full screen color.
7️⃣ Adding Subviews (Very Important)
Subview means:
A view inside another view.
Example:
Button inside screen
Label inside screen
Small view inside big view
Syntax:
[Link](myView)
Full Example (Programmatic UI)
override func viewDidLoad() {
[Link]()
// Change background
[Link] = .white
// Create a new view
let redBox = UIView()
[Link] = .red
[Link] = CGRect(x: 100, y: 200, width: 150, height: 150)
// Add to screen
[Link](redBox)
}
Now a red box appears on screen.
🧠 Important Concept: View Hierarchy
ViewController
|
Main View ([Link])
|
|-- redBox
|-- button
|-- label
Everything is layered like this.
🎯 Super Important Things to Remember
✔ Every screen = UIViewController
✔ Every visible thing = UIView
✔ viewDidLoad() runs once
✔ [Link] is main screen
✔ addSubview() adds UI to screen
2️⃣ UI Elements (Basic Components)
UIButton
UILabel
UITextField
UIImageView
UISwitch
You must master these.
🥇 1️⃣ UILabel
✅ What is UILabel?
UILabel is used to display text on screen.
It is read-only text (user cannot edit it).
🧠 Real Example
App title
"Welcome"
Error message
Price text
Description text
All these are UILabel.
🛠 Important Properties
Property What it does
text Sets text
textColor Text color
font Font style & size
textAlignment Left / Center / Right
numberOfLines Single or multiple lines
📌 Example (Programmatically)
override func viewDidLoad() {
[Link]()
let label = UILabel()
[Link] = "Hello UIKit"
[Link] = .black
[Link] = [Link](ofSize: 24)
[Link] = .center
[Link] = CGRect(x: 50, y: 200, width: 300, height: 50)
[Link](label)
}
🥈 2️⃣ UIButton
✅ What is UIButton?
UIButton is used to perform an action when tapped.
It is clickable.
🧠 Real Example
Login button
Submit button
Next button
Delete button
🛠 Important Properties
Property What it does
setTitle() Set button text
backgroundColor Background color
setTitleColor() Text color
[Link] Make rounded
addTarget() Add action
📌 Example
let button = UIButton(type: .system)
[Link]("Tap Me", for: .normal)
[Link] = .blue
[Link](.white, for: .normal)
[Link] = CGRect(x: 100, y: 300, width: 200, height: 50)
[Link] = 10
[Link](self, action: #selector(buttonTapped), for: .touchUpInside)
[Link](button)
Action method:
@objc func buttonTapped() {
print("Button Clicked")
}
🥉 3️⃣ UITextField
✅ What is UITextField?
UITextField is used to take input from user.
User can type text.
🧠 Real Example
Email field
Password field
Search bar
Name input
🛠 Important Properties
Property What it does
text Gets entered text
placeholder Light gray hint text
isSecureTextEntry For password
keyboardType Number pad / email keyboard
delegate For advanced control
📌 Example
let textField = UITextField()
[Link] = "Enter your name"
[Link] = .roundedRect
[Link] = CGRect(x: 50, y: 150, width: 300, height: 40)
[Link](textField)
For password:
[Link] = true
🏅 4️⃣ UIImageView
✅ What is UIImageView?
UIImageView is used to display images.
🧠 Real Example
Profile photo
Product image
App logo
Banner image
🛠 Important Properties
Property What it does
image Sets image
contentMode How image fits
clipsToBounds Cuts overflow
[Link] Rounded image
📌 Example
let imageView = UIImageView()
[Link] = UIImage(named: "logo")
[Link] = .scaleAspectFit
[Link] = CGRect(x: 100, y: 100, width: 150, height: 150)
[Link](imageView)
🏆 5️⃣ UISwitch
✅ What is UISwitch?
UISwitch is a toggle button (ON / OFF).
🧠 Real Example
Dark Mode switch
Notification enable/disable
WiFi on/off
🛠 Important Properties
Property What it does
isOn True / False
onTintColor Color when ON
addTarget Detect change
📌 Example
let toggle = UISwitch()
[Link] = true
[Link] = .green
[Link] = CGRect(x: 150, y: 400, width: 50, height: 30)
[Link](self, action: #selector(switchChanged), for: .valueChanged)
[Link](toggle)
Action:
@objc func switchChanged(_ sender: UISwitch) {
print([Link])
}
🧠 Big Picture Understanding
All of these are:
UIView subclasses
Hierarchy looks like this:
UIView
|
|-- UILabel
|-- UIButton
|-- UITextField
|-- UIImageView
|-- UISwitch
That means:
All have frame
All have backgroundColor
All can be added using addSubview()
🎯 What You Must Master
Before moving ahead:
✅ Creating them programmatically
✅ Changing properties
✅ Adding to view
✅ Handling actions
✅ Styling them
3️⃣ AutoLayout (Very Important ⚠️)
Constraints
Leading, Trailing, Top, Bottom
Width & Height
StackView
Safe Area
Without this → UI will break on different screen sizes.
🥇 AutoLayout (Very Very Important ⚠️)
If you don’t understand AutoLayout:
UI will break on different iPhones
Layout will look wrong on iPad
Things will overlap
Interviewers will reject you
So let’s understand this very deeply but very simply.
📱 First Understand the Problem
There are many iPhone sizes:
If you set position like this:
[Link] = CGRect(x: 50, y: 200, width: 200, height: 50)
It may look good on one device
But on bigger screen → it will look small
On smaller screen → it may go outside
❌ That is why we don’t rely on frames.
🧠 What is AutoLayout?
AutoLayout means:
Instead of telling the exact position,
we tell RELATIONSHIPS using rules called constraints.
🧱 What is a Constraint?
A constraint is a rule.
Example rules:
This button should be 20 points from left
This label should be below button
This view should fill entire screen
This image should be centered
These rules adjust automatically for any screen size.
🎯 Core Constraint Types
We mainly use:
1. Leading
2. Trailing
3. Top
4. Bottom
5. Width
6. Height
7. CenterX
8. CenterY
Now I’ll explain each.
1️⃣ Leading & Trailing
Think like this:
Leading = Left side (in left-to-right language)
Trailing = Right side
Example:
|----20----[ Button ]----20----|
Means:
Button leading = 20 from left
Button trailing = 20 from right
So width becomes automatic.
2️⃣ Top & Bottom
Top = Distance from top
Bottom = Distance from bottom
Example:
Top Safe Area
|
| 50
V
[ Label ]
Constraint:
Top = 50 from safe area
3️⃣ Width & Height
You can fix:
[Link](equalToConstant: 200)
[Link](equalToConstant: 50)
But better practice:
Avoid fixed width when possible.
4️⃣ CenterX & CenterY
If you want something in center:
[Link](equalTo: [Link])
[Link](equalTo: [Link])
That keeps it perfectly centered on all screens.
🛡 What is Safe Area?
Very important.
Look at this:
Phones have:
Notch (top)
Home indicator (bottom)
Dynamic island
Safe Area ensures your content does NOT go under these areas.
So instead of:
[Link]
We use:
[Link]
🏗 How To Use AutoLayout Programmatically
Step 1: Disable autoresizing
[Link] = false
Step 2: Add constraints
[Link]([
[Link](equalTo: [Link], constant: 50),
[Link](equalTo: [Link], constant: 20),
[Link](equalTo: [Link], constant: -20),
[Link](equalToConstant: 50)
])
Now:
Button will stretch full width
20 from left
20 from right
50 from top
Height 50
Works on ALL devices ✅
📦 What is UIStackView?
UIStackView is a layout helper.
It arranges views automatically:
Vertical
Horizontal
Instead of manually adding constraints between views.
Example:
Without StackView:
You must manually:
Add top constraint
Add spacing
Add width
Add height
With StackView:
Just do:
let stack = UIStackView()
[Link] = .vertical
[Link] = 20
[Link] = .fillEqually
Then add arranged subviews:
[Link](button1)
[Link](button2)
[Link](button3)
Stack handles spacing automatically.
🧠 Why AutoLayout is Powerful
Because it handles:
Small screens
Big screens
Landscape
iPad
Dynamic type
Rotation
Automatically.
🎓 Real Understanding Example
If you say:
20 from left
20 from right
Then width is calculated automatically.
If screen width is:
375 → button width = 335
430 → button width = 390
That’s smart layout.
🚨 Common Beginner Mistakes
❌ Using frame instead of constraints
❌ Forgetting translatesAutoresizingMaskIntoConstraints = false
❌ Not using safe area
❌ Adding incomplete constraints (Xcode will show red warnings)
🏆 Golden Rule
For vertical layout:
Usually you need:
Top
Leading
Trailing
Height
That’s enough.
🧠 Summary
AutoLayout = Rule-based layout system
Constraints = Rules
Safe Area = Protected area of screen
StackView = Automatic layout manager
Without AutoLayout → Your app is not professional.
🥈 PHASE 2 – User Interaction & Navigation
4️⃣ Target-Action Pattern
@IBAction
addTarget()
Button click handling
🥈 Target-Action Pattern (Very Important in UIKit)
We will understand:
1. What is Target-Action?
2. What is @IBAction?
3. What is addTarget()?
4. How button click works internally
5. Proper real examples
6. When to use which method
🧠 1️⃣ What is Target-Action Pattern?
In simple words:
Target-Action is the system UIKit uses to respond when a user interacts with a control (like a
button).
When user taps a button:
Button = sends message
Target = who should handle it
Action = what function should run
Real Life Example
Imagine:
You press a doorbell 🔔
Button = Doorbell
Target = Person inside house
Action = Open the door
Same in UIKit:
UIButton = Doorbell
ViewController = Person inside
Function = Open the door
🧱 2️⃣ How It Works Internally
When button is tapped:
1. Button detects touch
2. It sends message to target
3. Target runs action method
Structure looks like:
Button → Target → Action Method
🎯 3️⃣ @IBAction (Storyboard Method)
This is used when working with Storyboard.
Example
In storyboard:
1. Add button
2. Control + Drag to ViewController
3. Create:
@IBAction func buttonTapped(_ sender: UIButton) {
print("Button Clicked")
}
Now when tapped → function runs.
What is @IBAction?
@IBAction is just a special keyword.
It tells Interface Builder:
"This function is connected to a UI element"
Without @IBAction → storyboard cannot connect.
🛠 4️⃣ addTarget() (Programmatic Method)
This is used when you create UI in code.
Example (Programmatic Button)
let button = UIButton(type: .system)
[Link]("Tap Me", for: .normal)
[Link] = .blue
[Link](.white, for: .normal)
[Link] = false
Now connect target:
[Link](self, action: #selector(buttonTapped), for: .touchUpInside)
Action method:
@objc func buttonTapped() {
print("Tapped")
}
Then add to view:
[Link](button)
🧠 Understanding addTarget Parameters
[Link](self,
action: #selector(buttonTapped),
for: .touchUpInside)
Let’s break it:
Parameter Meaning
self Who handles it (Target)
Parameter Meaning
#selector(buttonTapped) Which function (Action)
.touchUpInside When to trigger
🎯 What is .touchUpInside?
It means:
When finger touches and releases inside button.
Other events:
.touchDown → when finger touches
.valueChanged → for switch
.editingChanged → for textfield
But mostly we use:
.touchUpInside
🔥 5️⃣ Full Working Example
Let’s build small app:
When button tapped → background color changes.
override func viewDidLoad() {
[Link]()
[Link] = .white
let button = UIButton(type: .system)
[Link]("Change Color", for: .normal)
[Link] = .systemBlue
[Link](.white, for: .normal)
[Link] = 10
[Link] = false
[Link](self, action: #selector(changeColor), for: .touchUpInside)
[Link](button)
[Link]([
[Link](equalTo: [Link]),
[Link](equalTo: [Link]),
[Link](equalToConstant: 200),
[Link](equalToConstant: 50)
])
}
@objc func changeColor() {
[Link] = .systemGreen
}
Now:
Tap button → background changes.
That is Target-Action.
🧠 6️⃣ Passing Sender Parameter
Sometimes we need to know which button was tapped.
Example:
@objc func buttonTapped(_ sender: UIButton) {
[Link] = .red
}
This changes the tapped button’s color.
🏆 7️⃣ Multiple Buttons One Action (Professional Way)
Instead of writing 4 functions:
Use tags.
[Link] = 1
[Link] = 2
[Link] = 3
Then:
@objc func buttonTapped(_ sender: UIButton) {
switch [Link] {
case 1:
[Link] = .red
case 2:
[Link] = .green
case 3:
[Link] = .blue
default:
break
}
}
This is cleaner.
🧠 Why @objc Is Required?
UIKit is built on Objective-C.
When using #selector, Swift needs Objective-C runtime.
So we must write:
@objc func buttonTapped()
Without @objc → error.
🎓 Interview Level Understanding
Target-Action is:
Loosely coupled design
UIControl sends event
Target responds
Action is selector method
It’s part of UIKit’s event handling system.
🧩 Summary
Target = Who handles
Action = What runs
Event = When it runs
Storyboard → @IBAction
Programmatic → addTarget()
🧠 1️⃣ What is Target-Action Pattern?
In simple words:
Target-Action is the system UIKit uses to respond when a user interacts with a control (like a
button).
When user taps a button:
Button = sends message
Target = who should handle it
Action = what function should run
Real Life Example
Imagine:
You press a doorbell 🔔
Button = Doorbell
Target = Person inside house
Action = Open the door
Same in UIKit:
UIButton = Doorbell
ViewController = Person inside
Function = Open the door
🧱 2️⃣ How It Works Internally
When button is tapped:
1. Button detects touch
2. It sends message to target
3. Target runs action method
Structure looks like:
Button → Target → Action Method
🎯 3️⃣ @IBAction (Storyboard Method)
This is used when working with Storyboard.
Example
In storyboard:
1. Add button
2. Control + Drag to ViewController
3. Create:
@IBAction func buttonTapped(_ sender: UIButton) {
print("Button Clicked")
}
Now when tapped → function runs.
What is @IBAction?
@IBAction is just a special keyword.
It tells Interface Builder:
"This function is connected to a UI element"
Without @IBAction → storyboard cannot connect.
🛠 4️⃣ addTarget() (Programmatic Method)
This is used when you create UI in code.
Example (Programmatic Button)
let button = UIButton(type: .system)
[Link]("Tap Me", for: .normal)
[Link] = .blue
[Link](.white, for: .normal)
[Link] = false
Now connect target:
[Link](self, action: #selector(buttonTapped), for: .touchUpInside)
Action method:
@objc func buttonTapped() {
print("Tapped")
}
Then add to view:
[Link](button)
🧠 Understanding addTarget Parameters
[Link](self,
action: #selector(buttonTapped),
for: .touchUpInside)
Let’s break it:
Parameter Meaning
self Who handles it (Target)
#selector(buttonTapped) Which function (Action)
.touchUpInside When to trigger
🎯 What is .touchUpInside?
It means:
When finger touches and releases inside button.
Other events:
.touchDown → when finger touches
.valueChanged → for switch
.editingChanged → for textfield
But mostly we use:
.touchUpInside
🔥 5️⃣ Full Working Example
Let’s build small app:
When button tapped → background color changes.
override func viewDidLoad() {
[Link]()
[Link] = .white
let button = UIButton(type: .system)
[Link]("Change Color", for: .normal)
[Link] = .systemBlue
[Link](.white, for: .normal)
[Link] = 10
[Link] = false
[Link](self, action: #selector(changeColor), for: .touchUpInside)
[Link](button)
[Link]([
[Link](equalTo: [Link]),
[Link](equalTo: [Link]),
[Link](equalToConstant: 200),
[Link](equalToConstant: 50)
])
}
@objc func changeColor() {
[Link] = .systemGreen
}
Now:
Tap button → background changes.
That is Target-Action.
🧠 6️⃣ Passing Sender Parameter
Sometimes we need to know which button was tapped.
Example:
@objc func buttonTapped(_ sender: UIButton) {
[Link] = .red
}
This changes the tapped button’s color.
🏆 7️⃣ Multiple Buttons One Action (Professional Way)
Instead of writing 4 functions:
Use tags.
[Link] = 1
[Link] = 2
[Link] = 3
Then:
@objc func buttonTapped(_ sender: UIButton) {
switch [Link] {
case 1:
[Link] = .red
case 2:
[Link] = .green
case 3:
[Link] = .blue
default:
break
}
}
This is cleaner.
🧠 Why @objc Is Required?
UIKit is built on Objective-C.
When using #selector, Swift needs Objective-C runtime.
So we must write:
@objc func buttonTapped()
Without @objc → error.
🎓 Interview Level Understanding
Target-Action is:
Loosely coupled design
UIControl sends event
Target responds
Action is selector method
It’s part of UIKit’s event handling system.
🧩 Summary
Target = Who handles
Action = What runs
Event = When it runs
Storyboard → @IBAction
Programmatic → addTarget()
🚀 Next Step
Now tell me:
1️⃣ Do you want deep explanation of Navigation (Push & Pop)?
2️⃣ Or how data passing works between screens?
3️⃣ Or build small 2-screen project using Target-Action?
We move step by step like real iOS engineer 👨💻🔥
### 5️⃣ Navigation * UINavigationController * Push & Pop * Passing data between screens
now explain this in simple way and detail with example
Perfect 🔥🔥🔥
Now we are entering Navigation in UIKit — this is how apps move from one screen to
another.
We will learn:
1. What is UINavigationController
2. What is Push
3. What is Pop
4. How navigation stack works
5. Passing data between screens
6. Full working example
Everything in simple language + detailed.
🥇 1️⃣ What is UINavigationController?
Simple Definition:
UINavigationController manages multiple screens in a stack format.
Think like this:
It controls screen movement like pages in a book.
Visual Understanding
4
Stack Concept
Navigation works like a stack (LIFO).
Example:
Home Screen
↓ Push
Details Screen
↓ Push
Profile Screen
Stack looks like:
[Home, Details, Profile]
If you press back:
Profile removed → Details shown
This is called Pop.
🥈 2️⃣ Push (Move Forward)
Push means:
Add new screen on top of stack.
Code:
navigationController?.pushViewController(secondVC, animated: true)
🥉 3️⃣ Pop (Go Back)
Pop means:
Remove top screen from stack.
Code:
navigationController?.popViewController(animated: true)
🧠 4️⃣ How Navigation Stack Works
Let’s understand properly.
Suppose:
FirstViewController
SecondViewController
When app starts:
Stack = [FirstVC]
After push:
Stack = [FirstVC, SecondVC]
When pop:
Stack = [FirstVC]
UINavigationController manages this automatically.
🛠 5️⃣ Full Example (Programmatic)
We will create:
First screen with button
Button → goes to Second screen
Second screen has back button
Step 1: Set Root as NavigationController
In SceneDelegate:
window?.rootViewController = UINavigationController(rootViewController:
FirstViewController())
Now your app supports navigation.
Step 2: FirstViewController
class FirstViewController: UIViewController {
override func viewDidLoad() {
[Link]()
[Link] = .white
title = "Home"
let button = UIButton(type: .system)
[Link]("Go To Second", for: .normal)
[Link] = false
[Link](self, action: #selector(goToSecond), for: .touchUpInside)
[Link](button)
[Link]([
[Link](equalTo: [Link]),
[Link](equalTo: [Link])
])
}
@objc func goToSecond() {
let secondVC = SecondViewController()
navigationController?.pushViewController(secondVC, animated: true)
}
}
Step 3: SecondViewController
class SecondViewController: UIViewController {
override func viewDidLoad() {
[Link]()
[Link] = .systemGreen
title = "Second Screen"
}
}
Now:
Tap button → new screen slides in.
Tap back → previous screen comes back.
That is Push & Pop.
🏆 6️⃣ Passing Data Between Screens
Now important part.
Suppose you want to pass a string.
Example:
First screen has text
Second screen displays it
Step 1: Create Property in SecondVC
class SecondViewController: UIViewController {
var receivedText: String?
override func viewDidLoad() {
[Link]()
[Link] = .white
let label = UILabel()
[Link] = receivedText
[Link] = false
[Link](label)
[Link]([
[Link](equalTo: [Link]),
[Link](equalTo: [Link])
])
}
}
Step 2: Set Value Before Push
Inside FirstVC:
@objc func goToSecond() {
let secondVC = SecondViewController()
[Link] = "Hello from First Screen"
navigationController?.pushViewController(secondVC, animated: true)
}
Now:
When pushed → second screen shows text.
🧠 Important Concept
Why this works?
Because:
We create secondVC object
Set property
Then push
So data is already set before view loads.
🎓 Interview-Level Understanding
UINavigationController:
Manages stack of view controllers
Uses push & pop
Automatically provides back button
Maintains navigation bar
Data Passing:
Simple → Use property
Complex → Use Delegate pattern
Advanced → Use Closures
🚨 Common Beginner Mistakes
❌ Forgetting to embed in NavigationController
❌ Using present() instead of push()
❌ Setting data after pushing
❌ Not marking property as var
🆚 Push vs Present (Important Difference)
Push:
Needs UINavigationController
Has back button automatically
Stack-based
Present:
Modal
Covers full screen
No stack concept
🧩 Summary
Push → Go forward
Pop → Go back
NavigationController → Manages stack
Passing data → Set property before pushing
🚀 Next Step
Now tell me:
1️⃣ Should I explain Present vs Push in depth?
2️⃣ Or how to pass data backward (Second → First)?
3️⃣ Or build a 3-screen mini project?
We continue step-by-step like real iOS engineer 👨💻🔥
now explain me with example how to send data back to previous view controller
Perfect 🔥🔥🔥
Now you’re asking real iOS developer level question 👏
Today we learn:
🥇 How To Send Data Back (Second → First ViewController)
This is called:
Reverse Data Passing
Very important in real apps.
Example situations:
Edit profile → send updated name back
Settings screen → send selected theme back
Color picker → send selected color back
🧠 First Understand the Problem
Forward data passing is easy:
[Link] = "John"
But backward?
SecondVC cannot directly access FirstVC safely.
Why?
Because:
It should not tightly depend on previous screen
That creates bad architecture
So we use:
✅ Delegate Pattern (Most Common & Professional Way)
🎯 What is Delegate?
Simple meaning:
Delegate = Give responsibility to someone else.
Real life example:
You order food 🍕
Restaurant cooks
Delivery boy delivers
Delivery boy = Delegate
🏗 How Delegate Works in iOS
Structure:
FirstVC ← (delegate) ← SecondVC
SecondVC says:
"Hey FirstVC, I have new data"
FirstVC responds.
🚀 Step-by-Step Example
We build:
First Screen → Button → Go to Second
Second Screen → Button → Send text back
🥇 Step 1: Create Protocol
In SecondViewController:
protocol SecondViewControllerDelegate: AnyObject {
func didSendData(_ text: String)
}
Explanation:
protocol = rule
AnyObject = only class can adopt
didSendData = function to send data
🥈 Step 2: Create Delegate Property
Inside SecondViewController:
weak var delegate: SecondViewControllerDelegate?
⚠️Why weak?
To avoid retain cycle (memory issue).
🥉 Step 3: Call Delegate When Button Tapped
Inside SecondVC:
@objc func sendDataBack() {
delegate?.didSendData("Hello from Second VC")
navigationController?.popViewController(animated: true)
}
This means:
If delegate exists → call function → then go back.
🏆 Full SecondViewController Code
class SecondViewController: UIViewController {
weak var delegate: SecondViewControllerDelegate?
override func viewDidLoad() {
[Link]()
[Link] = .systemGreen
let button = UIButton(type: .system)
[Link]("Send Data Back", for: .normal)
[Link] = false
[Link](self, action: #selector(sendDataBack), for: .touchUpInside)
[Link](button)
[Link]([
[Link](equalTo: [Link]),
[Link](equalTo: [Link])
])
}
@objc func sendDataBack() {
delegate?.didSendData("Hello from Second VC")
navigationController?.popViewController(animated: true)
}
}
🥇 Step 4: Conform to Protocol in FirstVC
In FirstViewController:
class FirstViewController: UIViewController, SecondViewControllerDelegate {
Now implement method:
func didSendData(_ text: String) {
print("Received:", text)
}
🥈 Step 5: Assign Delegate Before Push
Inside FirstVC:
@objc func goToSecond() {
let secondVC = SecondViewController()
[Link] = self
navigationController?.pushViewController(secondVC, animated: true)
}
Important:
[Link] = self
This connects both screens.
🧠 Flow Understanding
Step-by-step what happens:
1. FirstVC pushes SecondVC
2. FirstVC sets itself as delegate
3. User taps button in SecondVC
4. SecondVC calls:
delegate?.didSendData("Hello")
5. FirstVC receives data
6. SecondVC pops
7. FirstVC updates UI
🎯 Real Example (Update Label)
Let’s improve example.
In FirstVC:
let label = UILabel()
Inside didSendData:
func didSendData(_ text: String) {
[Link] = text
}
Now label updates when returning.
🧠 Why Use Protocol?
Because:
Loose coupling
Cleaner architecture
Interview friendly
Industry standard
🚨 Common Mistakes
❌ Forgetting weak
❌ Forgetting delegate = self
❌ Forgetting protocol conformance
❌ Not marking protocol class-only
🆚 Other Ways (Briefly)
There are 3 main ways:
1️⃣ Delegate (Most Common)
2️⃣ Closure
3️⃣ NotificationCenter
Delegate = Best for interviews.
🏆 Summary
Protocol = Rule
Delegate property = Communication channel
FirstVC adopts protocol
SecondVC calls delegate method
Data sent back successfully
🚀 Next Step
Now tell me:
1️⃣ Do you want to learn Closure method for sending data back?
2️⃣ Or deep explanation of retain cycle & why weak is needed?
3️⃣ Or build mini project using forward + backward data passing?
Now you are thinking like real iOS developer 👨💻🔥
SecondViewControllerDelegate?
but where it is written
Ahhh 🔥 very good question.
You are asking:
Where is SecondViewControllerDelegate written?
Where is it defined?
Why can we use SecondViewControllerDelegate??
Let’s clear this completely.
🥇 Where is SecondViewControllerDelegate Written?
It is written by YOU.
It is a protocol that you create manually.
It does NOT come from UIKit.
✅ Step 1 — You Must Create the Protocol
At the top of [Link] (outside the class), you write:
protocol SecondViewControllerDelegate: AnyObject {
func didSendData(_ text: String)
}
That line creates a new type called:
SecondViewControllerDelegate
Now Swift knows this type exists.
🥈 Then Inside SecondViewController
You write:
weak var delegate: SecondViewControllerDelegate?
Now it makes sense.
Because:
SecondViewControllerDelegate is a protocol (a type)
delegate is a variable
It must follow that protocol
🧠 Think Like This
Protocol = Rule Book 📘
Delegate Variable = Person who follows that rule
So:
weak var delegate: SecondViewControllerDelegate?
Means:
"delegate can be any object that follows this protocol"
🏗 Full Structure Example (Very Clear)
// 1️⃣ CREATE PROTOCOL (Outside class)
protocol SecondViewControllerDelegate: AnyObject {
func didSendData(_ text: String)
}
// 2️⃣ SECOND VIEW CONTROLLER
class SecondViewController: UIViewController {
weak var delegate: SecondViewControllerDelegate?
@objc func sendDataBack() {
delegate?.didSendData("Hello")
navigationController?.popViewController(animated: true)
}
}
🥉 Now FirstViewController Must Follow The Protocol
class FirstViewController: UIViewController, SecondViewControllerDelegate {
func didSendData(_ text: String) {
print("Received:", text)
}
@objc func goToSecond() {
let secondVC = SecondViewController()
[Link] = self
navigationController?.pushViewController(secondVC, animated: true)
}
}
🎯 Important Understanding
This line:
weak var delegate: SecondViewControllerDelegate?
Means:
delegate is optional (?)
delegate must follow that protocol
delegate will usually be FirstViewController
🔥 Why Is It Optional ( ? )
Because:
When SecondViewController is created,
delegate is initially:
nil
Later we assign:
[Link] = self
So we must use optional.
🧠 Why AnyObject Is Written?
protocol SecondViewControllerDelegate: AnyObject
This means:
Only classes can adopt this protocol.
Why?
Because delegate must be weak.
And weak only works with class types.
💡 If You Forget to Create Protocol
If you only write:
weak var delegate: SecondViewControllerDelegate?
Without defining protocol first,
You will get error:
Cannot find type 'SecondViewControllerDelegate' in scope
Because Swift doesn’t know what it is.
🎯 Final Mental Model
Step 1 → You create protocol
Step 2 → SecondVC has delegate property
Step 3 → FirstVC adopts protocol
Step 4 → FirstVC sets itself as delegate
Step 5 → SecondVC calls delegate method
That’s it.
Now tell me:
Do you want me to explain visually with diagram how delegate works in memory?
Or do you want closure method next? 👨💻🔥
### 6️⃣ Tab Bar Controller * UITabBarController * Multiple screens
now explain me this topic in simple way and in detail with examples
Perfect 🔥🔥🔥
Now we are starting:
🥇 UITabBarController (Tab Bar in iOS)
This is used when your app has multiple main sections.
Examples:
Instagram → Home, Search, Reels, Profile
WhatsApp → Chats, Updates, Calls
App Store → Today, Games, Apps
All these use Tab Bar Controller.
🧠 1️⃣ What is UITabBarController?
Simple Definition:
UITabBarController manages multiple screens using tabs at the bottom.
Each tab = one ViewController.
📱 Visual Understanding
4
At bottom you see icons.
When you tap different tab → different screen opens.
🏗 2️⃣ How It Works Internally
Structure looks like this:
UITabBarController
|
|-- FirstViewController
|-- SecondViewController
|-- ThirdViewController
TabBarController is the parent.
Each tab contains a ViewController.
🥇 3️⃣ Creating Tab Bar (Programmatic Way)
We will create:
Home Screen
Profile Screen
Step 1️⃣ Create ViewControllers
class HomeViewController: UIViewController {
override func viewDidLoad() {
[Link]()
[Link] = .systemBlue
title = "Home"
}
}
class ProfileViewController: UIViewController {
override func viewDidLoad() {
[Link]()
[Link] = .systemGreen
title = "Profile"
}
}
Step 2️⃣ Create TabBarController
In SceneDelegate:
let homeVC = HomeViewController()
let profileVC = ProfileViewController()
let tabBarController = UITabBarController()
[Link] = [homeVC, profileVC]
window?.rootViewController = tabBarController
window?.makeKeyAndVisible()
Now you have tabs.
🥈 4️⃣ Adding Icons & Titles to Tabs
Each tab needs:
Title
Image
Add this:
[Link] = UITabBarItem(
title: "Home",
image: UIImage(systemName: "house"),
tag: 0
)
[Link] = UITabBarItem(
title: "Profile",
image: UIImage(systemName: "person"),
tag: 1
)
Now bottom tab shows icons.
🧠 5️⃣ Real App Structure (Professional Way)
Usually each tab has its own NavigationController.
Structure becomes:
UITabBarController
|
|-- UINavigationController
| |
| |-- HomeViewController
|
|-- UINavigationController
|
|-- ProfileViewController
Why?
Because inside each tab you may push new screens.
Example:
let homeNav = UINavigationController(rootViewController: homeVC)
let profileNav = UINavigationController(rootViewController: profileVC)
[Link] = [homeNav, profileNav]
Now inside Home tab you can push screens.
🎯 6️⃣ How Switching Tabs Works
When user taps tab:
TabBarController switches active ViewController
It does NOT push or pop
It just changes selectedIndex
You can switch manually:
[Link] = 1
This switches to second tab.
🧠 7️⃣ Important Properties
Property Meaning
viewControllers Array of tabs
selectedIndex Current selected tab
tabBar Access tab bar
tabBarItem Item for each VC
🧩 8️⃣ Example With 3 Tabs
let homeVC = HomeViewController()
let searchVC = UIViewController()
let settingsVC = UIViewController()
[Link] = .systemOrange
[Link] = .systemGray
[Link] = UITabBarItem(title: "Home", image: UIImage(systemName: "house"),
tag: 0)
[Link] = UITabBarItem(title: "Search", image: UIImage(systemName:
"magnifyingglass"), tag: 1)
[Link] = UITabBarItem(title: "Settings", image: UIImage(systemName:
"gear"), tag: 2)
let tabBarController = UITabBarController()
[Link] = [homeVC, searchVC, settingsVC]
window?.rootViewController = tabBarController
🧠 Difference Between NavigationController & TabBarController
Navigation Tab Bar
Push & Pop Switch tabs
Stack-based Parallel screens
Back button No back button
Used for flow Used for main sections
🏆 When To Use Tab Bar?
Use TabBar when:
App has 3–5 main sections
Sections are independent
User needs quick switching
Do NOT use when:
You need step-by-step flow
Login → Dashboard → Profile (Use navigation)
🚨 Common Beginner Mistakes
❌ Not embedding in NavigationController
❌ Adding too many tabs (max 5 recommended)
❌ Not setting tabBarItem
🎓 Interview-Level Explanation
UITabBarController:
Container ViewController
Manages multiple child view controllers
Displays tab bar at bottom
Allows switching between root controllers
🏁 Final Understanding
TabBarController = Parent
Each Tab = Child ViewController
Optional: Each tab has NavigationController
🚀 Next Step
Now tell me:
1️⃣ Do you want to build mini real app using TabBar + Navigation together?
2️⃣ Or should I explain lifecycle when switching tabs?
3️⃣ Or how to customize tab bar color & appearance?
You are progressing like real iOS developer 👨💻🔥