Skip to content

Feature: per-idiom splash image (image_ipad / image_iphone) for iPad vs iPhone #830

@avive

Description

@avive

Use case

iPad apps that lock to landscape-only and iPhone apps that lock to portrait-only typically need different splash images — iPad benefits from a 16:9 / 4:3 landscape composition, iPhone needs a tall portrait composition. The current pipeline collapses both into a single image (or image_ios) which makes one of the two device classes look wrong at startup.

Today's behavior

flutter_native_splash 2.4.7 writes a single LaunchImage.imageset with idiom: universal entries generated from the single configured image (or image_ios). iPadOS picks the universal asset, the storyboard renders it at scaleAspectFill, and a portrait source ends up massively cropped on iPad landscape (or vice versa).

Native iOS asset catalogs already support per-idiom renditions — idiom: iphone, idiom: ipad, idiom: universal — which UIKit picks automatically per device. The plugin just doesn't surface a config for it.

Proposed config

flutter_native_splash:
  # Universal source — used as `iphone` rendition (and `universal` fallback) when the per-idiom keys below aren't set.
  image: assets/branding/splash_portrait.png

  # New: per-idiom override. When set, writes the matching idiom entries
  # into LaunchImage.imageset/Contents.json and generates the scale variants.
  image_ipad: assets/branding/splash_landscape.png
  # Optional dark variants matching the existing dark-mode story:
  image_dark_ipad: assets/branding/splash_landscape_dark.png

  # Runtime splash (Dart-side) also reads the per-idiom variant via
  # MediaQuery.platformBrightness + a new check on shortestSide, so the
  # transition from native → runtime splash uses the same image per device.

Manually patching LaunchImage.imageset/Contents.json after flutter_native_splash:create works (asset catalog idiom resolution is the iOS-canonical mechanism, confirmed via assetutil --info), but the patch gets clobbered every time :create runs.

Why it matters

  • Apps that lock orientation per device (portrait on iPhone, landscape on iPad) currently can't ship a consistent native splash.
  • The Dart-side runtime splash also flashes the wrong-aspect image on the "other" device class for a few hundred ms.
  • Workarounds either fork the plugin or post-process the generated assets — both painful for projects on auto-regen workflows.

Notes

Happy to take a stab at the implementation if there's interest — _createiOSSplash in lib/cli_commands.dart is the natural place to fan out into per-idiom paths. The Contents.json writer is the only structural change needed; image scale generation can reuse the existing pipeline twice.

Tested on iOS 26.5 (iPad Pro 11" M5 simulator) — confirms that asset catalog idiom variants ARE honored for LaunchImage references in launch storyboards when the Contents.json is set up correctly. The plugin just needs to emit the right Contents.json.

Polymyth's hand-edited Contents.json for reference:

```json
{
"images": [
{ "filename": "LaunchImage.png", "idiom": "universal", "scale": "1x" },
{ "filename": "LaunchImage@2x.png", "idiom": "universal", "scale": "2x" },
{ "filename": "LaunchImage@3x.png", "idiom": "universal", "scale": "3x" },
{ "filename": "LaunchImage-ipad.png", "idiom": "ipad", "scale": "1x" },
{ "filename": "LaunchImage-ipad@2x.png", "idiom": "ipad", "scale": "2x" }
],
"info": { "author": "xcode", "version": 1 }
}
```

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions