আমরা দেখাই Safe Area কী — স্ক্রিনের নিরাপদ অঞ্চল যা নিশ্চিত করে যে কন্টেন্ট সিস্টেম এলিমেন্ট: notch, Dynamic Island, StatusBar, Home ইন্ডিকেটর এবং গোলাকার কোণ দ্বারা আচ্ছাদিত না হয়। Safe Area iOS এবং Android-এ অ্যাডাপ্টিভ লেআউটের একটি বাধ্যতামূলক উপাদান, যা ছাড়া কাটআউটযুক্ত ডিভাইসে ইন্টারফেস ভুল দেখাতে পারে। Apple HIG (2025) অনুসারে, 2017 সালে iPhone X চালুর পর থেকে, সমস্ত অ্যাপ্লিকেশনকে Safe Area Layout Guide ব্যবহার করতে হবে।
মূল পয়েন্ট
Safe Area হল স্ক্রিনের একটি আয়তাকার এলাকা যেখানে কন্টেন্ট হার্ডওয়্যার এবং সফ্টওয়্যার সিস্টেম এলিমেন্ট: ক্যামেরা কাটআউট (notch), Dynamic Island, স্ট্যাটাস বার (StatusBar), জেসচার নেভিগেশন ইন্ডিকেটর (Home Indicator), গোলাকার ডিসপ্লে কোণ এবং নেভিগেশন বার দ্বারা আচ্ছাদিত না হওয়ার নিশ্চয়তা দেওয়া হয়। ডিভাইস ঘুরালে, কীবোর্ড খুললে বা Split View চালু করলে Safe Area-এর সীমানা গতিশীলভাবে পরিবর্তিত হয়। Apple Human Interface Guidelines (2025) অনুসারে, Safe Area উপেক্ষা করাকে ডিজাইন ত্রুটি হিসেবে বিবেচনা করা হয় এবং পর্যালোচনার সময় অ্যাপ্লিকেশন প্রত্যাখ্যানের কারণ হতে পারে।
Safe Area মোবাইল ইকোসিস্টেমে স্ক্রিন বিভাজনের সমস্যা সমাধান করে। iPhone X-এর আগে, সমস্ত iPhone-এর একই অনুপাতের আয়তাকার ডিসপ্লে ছিল। notch আসার পর, স্ক্রিন ভেরিয়েন্টের সংখ্যা 20+ এ পৌঁছেছে — বিভিন্ন notch আকার, Dynamic Island, গোলাকার কোণ, ইন্ডিকেটর। Safe Area ডেভেলপারকে এই পার্থক্যগুলো থেকে বিমূর্ত করে, অ্যাডাপ্টিভ মার্জিনের জন্য একটি ইউনিফায়েড API প্রদান করে। Apple Developer (2025) অনুসারে, iOS রুট ভিউতে স্বয়ংক্রিয়ভাবে Safe Area প্রয়োগ করে, কিন্তু UICollectionView এবং UIScrollView-এর জন্য ম্যানুয়াল কনফিগারেশন প্রয়োজন।
| ডিভাইস | কাটআউটের ধরন | উপরের মার্জিন | নিচের মার্জিন | StatusBar |
|---|---|---|---|---|
| iPhone SE (3rd gen) | কোনোটি নয় | 20px | 0px | হ্যাঁ |
| iPhone 13 Pro | Notch | 47px | 34px | Notch-এর ভিতরে |
| iPhone 14 Pro | Dynamic Island | 59px | 34px | DI-এর ভিতরে |
| iPhone 16 Pro | Dynamic Island | 59px | 34px | DI-এর ভিতরে |
| Android Pixel 8 | Punch-hole (ক্যামেরা) | 24px | 24px | স্ট্যাটাস বার |
iOS-এ, Safe Area বাস্তবায়িত হয় UIKit-এ SafeAreaLayoutGuide এবং SwiftUI-তে safeAreaInset মডিফায়ারের মাধ্যমে। SafeAreaLayoutGuide হল একটি লেআউট গাইড যা প্রতিটি UIView-এ যোগ করা হয় এবং সিস্টেম এলিমেন্ট থেকে মুক্ত আয়তক্ষেত্র নির্ধারণ করে। Interface Builder-এ, Safe Area নীল এলাকা হিসেবে প্রদর্শিত হয়। SwiftUI অধিকাংশ কন্টেইনারের জন্য স্বয়ংক্রিয়ভাবে Safe Area প্রয়োগ করে কিন্তু .ignoresSafeArea()-এর মাধ্যমে এটি উপেক্ষা করার অনুমতি দেয়।
// UIKit: SafeAreaLayoutGuide
let safeGuide = view.safeAreaLayoutGuide
button.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
button.topAnchor.constraint(
equalTo: safeGuide.topAnchor),
button.leadingAnchor.constraint(
equalTo: safeGuide.leadingAnchor),
button.trailingAnchor.constraint(
equalTo: safeGuide.trailingAnchor),
])
UIKit-এ SafeAreaLayoutGuide চারটি অ্যাঙ্কর — শীর্ষ, নিচ, শুরু, শেষ — নির্ধারণ করে যা স্বয়ংক্রিয়ভাবে notch, StatusBar এবং Home Indicator বিবেচনায় নেয়। এই পদ্ধতি iOS 11 থেকে সমস্ত iOS ডিভাইসে কাজ করে। SwiftUI-তে, একই প্রভাব NavigationStack বা VStack-এর ভিতরে কন্টেন্ট মডিফায়ারের মাধ্যমে অর্জিত হয় — SwiftUI স্বয়ংক্রিয়ভাবে Safe Area Insets প্রয়োগ করে।
// SwiftUI: safeAreaInset এবং ignoresSafeArea
ZStack {
Color.blue
.ignoresSafeArea()
VStack {
Text("Safe Area-এ কন্টেন্ট")
.foregroundColor(.white)
Spacer()
}
}
.safeAreaInset(edge: .bottom) {
Text("স্ক্রিনের নিচের বার")
.padding()
.background(.thinMaterial)
}
SwiftUI-তে, .ignoresSafeArea() ব্যাকগ্রাউন্ডকে Safe Area-এর বাইরে প্রসারিত করার অনুমতি দেয়, যেখানে .safeAreaInset(edge:) একটি কাস্টম প্যানেল যোগ করে যা নির্দিষ্ট দিকে Safe Area হ্রাস করে। এটি নেভিগেশন বার, টুলবার এবং বিজ্ঞাপন ব্যানারের জন্য একটি স্ট্যান্ডার্ড প্যাটার্ন।
Android-এ, Safe Area বাস্তবায়িত হয় WindowInsets (API 30+) এবং WindowInsetsCompat (AndroidX লাইব্রেরি) এর মাধ্যমে। WindowInsets Status Bar, Navigation Bar, IME (কীবোর্ড) এবং সিস্টেম জেসচারের জন্য মার্জিন প্রদান করে। Android 10 (API 29) থেকে শুরু করে, Google সকল সিস্টেম এলিমেন্টের জন্য একীভূত মার্জিন সেট পেতে WindowInsetsCompat.getInsets() ব্যবহার করার পরামর্শ দেয় WindowInsetsCompat.Type.systemBars() এর সাথে।
// Android: WindowInsets (Kotlin)
class MainActivity : AppCompatActivity() {
override fun onCreate(
savedInstanceState: Bundle?
) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
ViewCompat.setOnApplyWindowInsetsListener(
findViewById(R.id.main_content)
) { view, insets ->
val systemBars = insets.getInsets(
WindowInsetsCompat.Type.systemBars()
)
view.setPadding(
systemBars.left,
systemBars.top,
systemBars.right,
systemBars.bottom
)
ViewCompat.ON_APPLY_WINDOW_INSETS_LISTENER
}
}
}
এই উদাহরণে, WindowInsets সকল সিস্টেম বারের জন্য মার্জিন ফেরত দেয় — উপরে Status Bar, নিচে Navigation Bar। setOnApplyWindowInsetsListener প্রতিবার মার্জিন পরিবর্তনের সময় কল করা হয় (ঘূর্ণন, কীবোর্ড আহ্বান)। systemBars() পদ্ধতি স্ট্যাটাস বার, নেভিগেশন বার এবং কাস্টমাইজেশন বারকে একটি সেটে একত্রিত করে, কোড সহজ করে।
Android 15 থেকে শুরু করে, Google নতুন API লক্ষ্য করে সমস্ত অ্যাপ্লিকেশনের জন্য edge-to-edge ডিসপ্লে প্রয়োজন। এর মানে হল অ্যাপ্লিকেশন সিস্টেম বারের নিচে আঁকে, এবং Safe Area প্রয়োগ করা হয় handleWindowInsets বা WindowInsetController-এর মাধ্যমে। Android Developer Blog (2025) অনুসারে, 68% অ্যাপ্লিকেশন ইতিমধ্যে edge-to-edge-এ স্থানান্তরিত হয়েছে, যা বড় স্ক্রিনযুক্ত ডিভাইসে ভিজ্যুয়াল ধারণা উন্নত করে।
Safe Area, Padding এবং Insets সম্পর্কিত কিন্তু ভিন্ন ধারণা। Safe Area হল স্ক্রিনের এলাকা যা সিস্টেম এলিমেন্ট থেকে মুক্ত থাকার নিশ্চয়তা দেওয়া হয়। Padding হল একটি এলিমেন্টের তার সীমানা থেকে অভ্যন্তরীণ মার্জিন। Insets হল নির্দিষ্ট সংখ্যাসূচক অফসেট মান যা Safe Area API ফেরত দেয়। Apple Tech Notes (2025) অনুসারে, Safe Area এবং Padding-এর মধ্যে বিভ্রান্তি অ্যাপ স্টোরগুলিতে 40% অভিযোজনযোগ্যতা সমস্যার কারণ।
| ধারণা | সংজ্ঞা | প্ল্যাটফর্ম | পরিবর্তনযোগ্যতা |
|---|---|---|---|
| Safe Area | সিস্টেম এলিমেন্ট ছাড়া এলাকা | iOS, Android | গতিশীল |
| Padding | ভিউ-এর ভিতরে অভ্যন্তরীণ মার্জিন | সব প্ল্যাটফর্ম | স্থির |
| Layout Margins | লেআউটের প্রান্ত থেকে মার্জিন | iOS (UIKit) | স্থির/গতিশীল |
| WindowInsets | Android-এ সিস্টেম মার্জিন | Android | গতিশীল |
আসুন সাধারণ পরিস্থিতি বিবেচনা করি: notch সহ ল্যান্ডস্কেপ ওরিয়েন্টেশনের জন্য UIKit-এ Safe Area, কাস্টম প্যানেল সহ SwiftUI-তে Safe Area, Android Compose-এ Safe Area৷ iOS UIKit-এর জন্য উদাহরণ — Dynamic Island সহ iPhone-এ Safe Area-এর ভিতরে কালেকশন স্থাপন। Jetpack Compose-এর জন্য উদাহরণ — Material 3-এ WindowInsets ব্যবহার।
// Jetpack Compose: Safe Area মার্জিন
@OptIn(ExperimentalMaterial3Api::class)
fun SafeAreaScreen() {
val systemBars = with(
LocalDensity.current
) {
val insets = WindowInsets
.systemBars
.getAsPaddingValues()
PaddingValues(
top = insets.calculateTopPadding(),
bottom = insets.calculateBottomPadding()
)
}
Scaffold(
contentWindowInsets = WindowInsets(
top = systemBars.computeTopPadding(),
bottom = systemBars.computeBottomPadding()
)
) { innerPadding ->
Column(
modifier = Modifier
.padding(innerPadding)
) {
Text("Safe Area-এ কন্টেন্ট")
}
}
}
Jetpack Compose-এ, Scaffold contentWindowInsets প্যারামিটারের মাধ্যমে স্বয়ংক্রিয়ভাবে WindowInsets বিবেচনায় নেয়। InnerPadding content-এ পাস করা হয় এবং অভ্যন্তরীণ উপাদানগুলিতে প্রয়োগ করা হয়। padding(innerPadding) মডিফায়ার সহ Column নিশ্চিত করে যে টেক্সট সিস্টেম বারের নিচে না যায়।
Apple (2025) দ্বারা App Store Review বিশ্লেষণ অনুসারে, পাঁচটি সবচেয়ে সাধারণ ভুল হল: ল্যান্ডস্কেপ ওরিয়েন্টেশনে Safe Area উপেক্ষা করা, SafeAreaLayoutGuide-এর পরিবর্তে হার্ডকোডেড মার্জিন ব্যবহার, UIScrollView-এ Safe Area-এর ভুল হ্যান্ডলিং, মোডাল প্রেজেন্টেশনে ভুলে যাওয়া মার্জিন এবং Dynamic Island-এর জন্য অভিযোজনের অভাব। হার্ডকোডেড মার্জিন (উপরে 20px হার্ডকোডেড) সবচেয়ে সাধারণ ভুল: iPhone 14 Pro-তে, সেই 20px 59px হয়ে যায় এবং কন্টেন্ট কেটে যায়।
প্রায়শই জিজ্ঞাসিত প্রশ্ন
SwiftUI-তে, Safe Area অধিকাংশ কন্টেইনারে স্বয়ংক্রিয়ভাবে প্রয়োগ হয়। মার্জিন পড়তে, EnvironmentValues ব্যবহার করুন: @Environment(\.safeAreaInsets) var safeAreaInsets। কাস্টম প্যানেলের জন্য, .safeAreaInset(edge:content:) ব্যবহার করুন। ব্যাকগ্রাউন্ডের জন্য যা সিস্টেম এলিমেন্টের নিচে প্রসারিত হওয়া উচিত, .ignoresSafeArea() প্রয়োগ করুন।
Edge-to-edge হল একটি ডিসপ্লে মোড যেখানে অ্যাপ্লিকেশন সিস্টেম বার (Status Bar, Navigation Bar) এর নিচে আঁকে, এবং Safe Area WindowInsets-এর মাধ্যমে প্রয়োগ করা হয়। Android 15 থেকে শুরু করে, Google targetSdk 35 সহ সমস্ত অ্যাপ্লিকেশনের জন্য edge-to-edge প্রয়োজন। এটি Jetpack Compose-এ WindowInsetsCompat বা handleWindowInsets-এর মাধ্যমে বাস্তবায়িত হয়।
হ্যাঁ, WebView-কেও Safe Area বিবেচনায় নিতে হবে। iOS-এ, webView.scrollView.contentInsetAdjustmentBehavior = .always ব্যবহার করুন। Android-এ, XML-এ android:fitsSystemWindows="true" যোগ করুন অথবা ViewCompat.setOnApplyWindowInsetsListener-এর মাধ্যমে প্রোগ্রামেটিক padding করুন। CSS পরিবেশ (env(safe-area-inset-top)) Safari-এ কাজ করে কিন্তু Android সিস্টেম WebViews-এ নয়।
সারাংশ
আমরা একটি মোবাইল অ্যাপ্লিকেশন টার্নকি তৈরি করব
IT Sectr 2017 সাল থেকে স্টার্টআপ এবং ব্যবসার জন্য iOS এবং Android অ্যাপ্লিকেশন তৈরি করে। আমরা আপনাকে পরামর্শ দেব এবং সেরা সমাধান প্রস্তাব করব।
আরও পড়ুন