9ura00

iPhone のウィジェットのタップで、実機でだけ起きた3つの落とし穴

Sheet Widget2026年10月4日

Sheet Widget のウィジェットには、タップで動く機能がいくつかあります。

  • ウィジェットをタップすると、スプレッドシートやアプリが開く
  • (Pro)セルをタップすると、その値をコピーできる
  • (Pro)ウィジェットの更新ボタンで、すぐに最新の内容にする

iOS 17 からウィジェットにボタンを置けるようになり、こうした機能が作りやすくなりました。ただ、作ってみると、シミュレータや自動テストでは再現せず、実機のホーム画面でだけ起きる問題が3つありました。同じところでつまずく人がいるかもしれないので、まとめておきます。

1. ウィジェットから、クリップボードに書き込めない

「セルをタップしてコピー」は、最初、ウィジェットのボタン(App Intent)の処理の中で、そのままクリップボードに書き込む形で作りました。

UIPasteboard.general.string = value

ところが、実機ではこれがエラーも出さずに失敗します。処理は最後まで走るのに、クリップボードには何も入りません。調べたところ、ウィジェットの拡張機能からクリップボードに書き込めないのは、Apple にも報告されている既知の問題でした(Feedback ID: FB13636156)。

直し方:アプリを一瞬前に出してコピーする

ウィジェットの側では、どのセルが押されたか(行と列)だけをアプリに渡し、実際のコピーは、前面に出たアプリが行う形に変えました。

  1. ウィジェットのセルを、行と列を含んだ URL へのリンクにする
  2. タップすると Sheet Widget のアプリが開く
  3. アプリは、保存してあるシートの内容からその値を取り出してコピーする
  4. コピーしたあと、利用者が選んだ行き先(スプレッドシートを開く、など)に移る

アプリが前面に出ていれば、クリップボードには普通に書き込めます。

2. ボタンが、ウィジェットの長押しメニューを奪う

ウィジェット全体をタップできるようにするため、最初はウィジェット全体を、App Intent のボタンで包んでいました。

Button(intent: OpenAction()) {
    GridView(...)
}

これを実機のホーム画面に置くと、ウィジェットを長押ししても「ウィジェットを編集」のメニューが出ず、先にボタンが反応してしまうようになりました。SwiftUI のボタンが長押しの操作まで受け取ってしまうためです。ウィジェットの設定(表示するシートの切り替えなど)ができなくなるので、致命的でした。

ウィジェットのタップには、次のように使い分けるのが正解でした。

タップしたい場所 使うもの
ウィジェット全体 .widgetURL(...)
ウィジェットの一部(セルなど) Link(destination:)
小さなボタン(更新ボタンなど) Button(intent:) のままで大丈夫

更新ボタンのように小さな領域なら、長押しのメニューとぶつからないので、ボタンのままにしています。

3. 一部の設定でだけ、タップしても反応しない場所ができた

「セルをタップしてコピー」をオンにしているときは、ウィジェット全体のタップ先(.widgetURL)を nil にしていました。セルのリンクを優先させたかったからです。

ところが、.widgetURL はウィジェット全体に効く1つの設定です。nil にすると、セル以外の場所(ヘッダー、フッター、空のセル)まで巻き添えで、タップしても何も起きなくなりました。

直し方:widgetURL は常に「行き先」を返す

.widgetURL は常に、利用者が選んだ行き先(スプレッドシートを開く、など)を返すようにしました。コピーするかどうかの判断は、URL を受け取ったアプリの側でまとめて行います。ウィジェットの側で分岐させないほうが、反応しない場所ができません。

教訓:タップまわりを触ったら、実機で全部押す

3つとも、XCTest やシミュレータでは見つけられず、実機のホーム画面に置いて、実際に指で押して初めて分かった問題でした。

それ以来、ウィジェットのタップまわりを変えたときは、次のことを実機で確認するようにしています。

  • ウィジェットの全部の場所(ヘッダー、フッター、空のセル、値のあるセル、ボタン)をタップする
  • 長押しで「ウィジェットを編集」が出るか
  • 設定(コピーのオン・オフなど)を切り替えて、同じことを繰り返す

ウィジェットは「見るもの」から「触れるもの」になってきていますが、触れる部分には、アプリ本体とは違う制約がまだ多くあります。


Sheet Widget は App Store で公開しています。

← ブログの一覧へ