はじめに
2026-08-16、さんすうおじさん の一時停止ボタンが、iPhone 16e の実機で押せないことが分かった。
画面最上部の中央に置いたボタンが、カメラの裏に隠れる。指で触れる場所に無い。
シミュレータでは見えている。撮ったスクリーンショットにも、はっきり写る。
撮れる範囲と、見える範囲が違う
xcrun simctl io ... screenshot はフレームバッファ全体を書き出す。ノッチやダイナミックアイランドの黒は、実機ではハードウェアが物理的に覆っている領域であって、描画データの一部ではない。
だから画像には出ない。
実機では隠れている要素が、スクリーンショットには「見えて」しまう。
上端・下端に置いた要素だけは、画像で確認したことにならない。実機で指で触るしかない。
固定値は必ずどこかの端末で外れる
直接の原因は、ボタンを top: 8 で絶対配置していたこと。もうひとつ、上端の余白に 36pt の固定値を置いていたことが根にある。
セーフエリアの上端は端末ごとに違う。Web で調べても 47 / 54 / 59pt と情報が割れていて、どれが正しいとも決まらない。手で決めた値は、必ずどこかの端末で外れる。
実測すると、iPhone 16e は 47pt だった。固定していた 36pt はこれより 11pt 浅い。ボタンの当たり判定の上部が、ちょうどノッチの内側へ入り込む。
見えているのに押せない、という状態の正体はこの 11pt だった。
ライブラリを足さずに OS の値を取る
react-native-safe-area-context を入れる手もあるが、Expo のプロジェクトには expo-constants が既に依存に入っていることが多い。追加ゼロで実測値が取れる。
import Constants from 'expo-constants';
const TOP = Constants.statusBarHeight; // iPhone 16e = 47
これを固定値の代わりに使う。SafeAreaView を使う場合でも、絶対配置の要素は自分で余白を持つ必要があるので、値そのものが要る場面は残る。
上端・下端の確認手順
# 実機に入れて、上端と下端の要素を実際に指で押す
npx expo run:ios --device
画像で済ませてよいのは、上下の端から離れた場所だけ。端に置いたものは、シミュレータのスクリーンショットが嘘をつく側に倒れる。見えないものが見えるように写るので、間違いに気づけない。
セーフエリアの値は、調べるものではなく取るもの。
押せないボタンのスクリーンショットを撮って、問題なしと報告した。
画像は撮った範囲のことしか教えてくれない。
記事に登場したアプリ: