Safe Areaとは — システム要素(ノッチ、Dynamic Island、StatusBar、Homeインジケーター、角丸)によってコンテンツが隠されないことを保証する画面の安全領域です。Safe AreaはiOSとAndroidのアダプティブレイアウトに必須の要素であり、これがないと切り欠きのあるデバイスでインターフェースが正しく表示されない可能性があります。Apple HIG(2025)によると、2017年のiPhone X登場以来、すべてのアプリケーションはSafe Area Layout Guideを使用する必要があります。
重要なポイント
Safe Areaとは、ハードウェアおよびソフトウェアのシステム要素(カメラの切り欠き(ノッチ)、Dynamic Island、ステータスバー(StatusBar)、ジェスチャーナビゲーションインジケーター(Home Indicator)、画面の角丸、ナビゲーションバー)によってコンテンツが隠されないことが保証される画面の長方形領域です。Safe Areaの境界は、デバイスの回転、キーボードの呼び出し、Split Viewの起動時に動的に変化します。Apple Human Interface Guidelines(2025)によると、Safe Areaを無視することは設計上の欠陥と見なされ、レビュー中にアプリが却下される原因となる可能性があります。
Safe Areaは、モバイルエコシステムにおける画面の断片化の問題を解決します。iPhone X以前は、すべてのiPhoneが同じ比率の長方形ディスプレイを備えていました。ノッチの登場により、画面の種類は20以上に増加しました — さまざまなノッチサイズ、Dynamic Island、角丸、インジケーター。Safe Areaは、アダプティブマージンのための統一APIを提供することで、開発者をこれらの違いから抽象化します。Apple Developer(2025)によると、iOSはルートビューに自動的にSafe Areaを適用しますが、UICollectionViewとUIScrollViewでは手動設定が必要です。
| デバイス | 切り欠きの種類 | 上部マージン | 下部マージン | StatusBar |
|---|---|---|---|---|
| iPhone SE(第3世代) | なし | 20px | 0px | あり |
| iPhone 13 Pro | ノッチ | 47px | 34px | ノッチ内 |
| iPhone 14 Pro | Dynamic Island | 59px | 34px | DI内 |
| iPhone 16 Pro | Dynamic Island | 59px | 34px | DI内 |
| Android Pixel 8 | パンチホール(カメラ) | 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は、4つのアンカー(上、下、先頭、末尾)を定義し、ノッチ、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()メソッドは、ステータスバー、ナビゲーションバー、カスタマイゼーションバーを1つのセットに結合し、コードを簡素化します。
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 | 動的 |
典型的なシナリオを見てみましょう:ノッチ付き横向きの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分析によると、最も一般的な5つの間違いは:横向きでの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システムのWebViewでは機能しません。
まとめ
ターンキー方式のモバイルアプリケーションを開発します
IT Sectrは2017年からスタートアップや企業向けにiOS・Androidアプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。