Skip to content

Position content around the iPhone's notch or Dynamic Island.

License

Notifications You must be signed in to change notification settings

Aeastr/NotchMyProblem

NotchMyProblem Icon

NotchMyProblem

Swift package that handles positioning UI elements around the iPhone's notch or Dynamic Island.

Swift 6.0+ iOS 13+ License: MIT

iPhone with notch iPhone with Dynamic Island iPhone without notch
Notch Devices Dynamic Island Standard Devices
iPhone X → 14/Plus, 16e iPhone 14 Pro+, 15/16/17 series, Air Home button iPhones, iPads, Mac

Overview

NotchMyProblem automatically detects the device's top cutout and provides tools to create adaptive layouts without manual positioning.

  • Automatically positions buttons around the notch or Dynamic Island
  • Adapts to device-specific dimensions with built-in overrides
  • Supports all modern iPhones: notch (iPhone X → 14/Plus, 16e), Dynamic Island (14 Pro+, 15/16/17 series, Air), and standard devices
  • Intelligent padding system that scales with cutout size

Installation

dependencies: [
    .package(url: "https://github.com/Aeastr/NotchMyProblem.git", from: "2.0.0")
]
import NotchMyProblem

Or in Xcode: File > Add Packages… and enter https://github.com/Aeastr/NotchMyProblem

Usage

CutoutAccessoryView

The simplest way to position UI elements around the notch/island:

struct MyView: View {
    var body: some View {
        ZStack {
            // Your main content here

            CutoutAccessoryView(
                padding: .auto,
                leadingContent: {
                    Button(action: { print("Left tapped") }) {
                        Image(systemName: "gear")
                    }
                },
                trailingContent: {
                    Button(action: { print("Right tapped") }) {
                        Text("Save")
                    }
                }
            )
        }
    }
}

Manual Access

Access cutout dimensions directly when needed:

let rawRect    = NotchMyProblem.exclusionRect                   // raw API result
let adjusted   = NotchMyProblem.shared.adjustedExclusionRect    // with overrides applied
let customRect = NotchMyProblem.shared.adjustedExclusionRect(using: myOverrides)

Customization

Padding

Without proper padding, UI elements can appear cramped against the cutout, get clipped by curved screen edges, or look inconsistent across devices. NotchMyProblem's padding scales with actual cutout dimensions to keep content at a safe, polished distance.

Three padding types:

  • Cutout padding – space around the display cutout
  • Content padding – space on either side of your HStack content
  • Vertical padding – space above and below your content

Available modes:

Mode Description
.auto Adaptive padding using an inverse relationship—narrow cutouts (Dynamic Island) get more breathing room, wide cutouts (notch) get less since they already create natural spacing.
.none No extra padding; views hug the safe-area edges exactly.
.custom(cutout:content:vertical:) Supply closures to compute each padding dynamically.
CutoutAccessoryView(
    padding: .custom(
        cutout:   { cutoutW in cutoutW / 12 },
        content:  { cutoutW in cutoutW / 6  },
        vertical: { cutoutH in cutoutH * 0.2 }
    ),
    leadingContent: { /* … */ },
    trailingContent: { /* … */ }
)

Device Overrides

Some devices report incorrect notch dimensions through the API, causing misaligned UI:

Misaligned buttons on iPhone 16e without overrides

NotchMyProblem includes built-in overrides (e.g., iPhone 16e), but you can configure your own:

Global overrides (app-wide):

NotchMyProblem.globalOverrides = [
    .series(prefix: "iPhone13", scale: 0.95, heightFactor: 1.0, radius: 27),
    DeviceOverride(modelIdentifier: "iPhone14,3", scale: 0.8, heightFactor: 0.7)
]

Instance overrides:

NotchMyProblem.shared.overrides = [
    DeviceOverride(modelIdentifier: "iPhone14,3", scale: 0.8, heightFactor: 0.7)
]

View-specific overrides:

CutoutAccessoryView(/* … */)
    .notchOverride(.series(prefix: "iPhone14", scale: 0.6, heightFactor: 0.6))

Override precedence: View-specific → Instance exact → Instance series → Global exact → Global series

How It Works

NotchMyProblem uses private APIs to detect the device's display cutout dimensions. Filter Console with subsystem com.notchmyproblem for debug logs.

Built on concepts from TopNotch. Uses private APIs—use at your own risk.

Device Testing

Model Dynamic Island Tested
iPhone 17 Yes Yes
iPhone 17 Pro Yes Yes
iPhone 17 Pro Max Yes Yes
iPhone Air Yes Yes

Contributing

Contributions welcome. Please feel free to submit a Pull Request.

License

MIT. See LICENSE for details.

About

Position content around the iPhone's notch or Dynamic Island.

Resources

License

Code of conduct

Contributing

Stars

Watchers

Forks

Packages

No packages published

Languages