開発者向け
SwiftUI のスクロールエッジ効果:soft と hard、iOS 27 での変更
iPhone と iPhone Duo での SwiftUI のスクロールエッジ効果を解説。.soft と .hard の違い、iOS 27 でバーが不透明に見える理由、iOS 26 のフェードの戻し方、UIKit の API まで。
AppleDuo 編集部公開 13分で読めます
このページの内容
アプリを Xcode 27 でリビルドすると、ナビゲーションバーの見た目が突然変わることがあります。以前はツールバーの下でコンテンツが柔らかくフェードしていたのに、くっきりした線と、より不透明な帯が現れるのです。コードは何も変えていません。変わったのは、スクロールするコンテンツとバーが接する部分に iOS が適用する処理、SwiftUI の スクロールエッジ効果のデフォルトです。
このガイドでは、スクロールエッジ効果とは何か、.soft と .hard の違い、iOS 26 と iOS 27 の間で何が変わったか、そして SwiftUI と UIKit で望みの見た目を選ぶ方法を解説します。内容は Apple のドキュメントと WWDC25 のセッション、デベロッパフォーラムでの Apple のエンジニアの回答、@sarunw をはじめとするデベロッパの報告に基づいています。iOS 27 での変更は Apple のリリースノートに記載されていないため、リリース間で変わる可能性のある観察された動作として扱ってください。
SwiftUI のスクロールエッジ効果とは?
スクロールエッジ効果は、iOS 26 で Liquid Glass の一部として登場しました。ツールバーは不透明な背景の上に置かれるのではなく、そのアイテムがコンテンツの上に浮かぶようになりました。それらのアイテムを読みやすく保つために、システムはその下にスクロールするコンテンツに処理を施します。Apple の WWDC25 のセッション「Build a SwiftUI app with the new design」では、これを「システムのツールバーの下のコンテンツに適用される、控えめなぼかしとフェードの効果」と呼んでいます。
この効果はシステムのバーの下で自動的に適用されます。Apple は、バーのアイテムの背後に置いた余分な背景や暗くするレイヤーは効果の妨げになるので削除するよう求めています。カスタムのバーも対象にできます。iOS 26 の新機能である SwiftUI の safeAreaBar(edge:alignment:spacing:content:) は、ビューの横にコンテンツをカスタムバーとして表示し、その下のスクロールビューにはシステムのバーの下と同様のエッジ効果が付きます。
効果は、同じく iOS 26 の新機能である scrollEdgeEffectStyle(_:for:) で制御します。これは変更対象のビュー内にあるすべてのスクロールビューに適用されるので、スクロールビューごとではなくコンテナに設定できます。
.soft と .hard の違いは?
ScrollEdgeEffectStyle には 3 つの値があります。Apple はそれぞれを次のように定義しています。
| スタイル | Apple の定義 | 主な用途 |
|---|---|---|
.automatic | 固定されたコンテンツがスクロールするコンテンツに重なるときにシステムが適用 | デフォルト。iOS に任せる |
.soft | 固定されたコントロールとスクロールするコンテンツの間の、控えめでぼかした境界 | iOS 26 で多くのアプリの上端にあったフェード |
.hard | 固定されたコントロールとスクロールするコンテンツの間の、直線的でほぼ不透明な境界 | 浮遊する要素が多い、密度の高いインターフェイス |
Apple 自身が挙げる密度の高いインターフェイスの例は、カレンダーアプリです。UIKit 版のセッションでは、hard スタイルは iOS 18 の標準的なバーの背景に似ていると説明されています。SwiftUI のセッションのサンプルは次のとおりです。
ScrollView {
// コンテンツ
}
.scrollEdgeEffectStyle(.hard, for: .top)
iOS 27 でスクロールエッジ効果の見た目が変わったのはなぜ?
変わった点は 2 つあり、混同しやすいので注意が必要です。
デフォルトが変わりました。 @sarunw のまとめでは、「iOS 26 ではスクロールエッジ効果のデフォルトは .soft、iOS 27 では .hard」です。デベロッパも自分のアプリで同じことを確認しています。Shellbee プロジェクトでは iOS 27 でビルドした後にアプリ全体のバーが平板になったとしてバグが報告され、DevelopersIO もカスタムの safeAreaBar で同じ現象を確認しました。厳密には、デフォルトは今も .automatic で、変わったのはそれが何に解決されるかです。DevelopersIO によると、Xcode 26.6 でビルドして iOS 27 で実行したアプリは以前の見た目のままだったため、この変更はビルドに使う SDK に従います。筆者は iOS 27 と Xcode 27 のリリースノートに記載を見つけられなかったとしています。
スタイル自体も変わりました。 @sarunw は、.hard が両バージョンで同じではないと指摘しています。iOS 26 ではほぼ不透明なバーで、背後のテキストは読めません。iOS 27 では境界線は残るものの、コンテンツが透けて見えます。ダークモードでも同じ違いがあると述べており、.soft はフェードし、.hard は区切り、iOS 27 のスタイルのほうがバランスが取れているとしています。Apple は .soft も変更しました。デベロッパフォーラムで Apple のエンジニアは、「.soft スタイルは iOS 27 で大幅に変更された」と書いています。
| iOS 26 | iOS 27 | |
|---|---|---|
上端の .automatic(デベロッパの報告による) | soft に解決 | hard に解決 |
.hard の見た目(@sarunw による) | ほぼ不透明。背後のテキストは読めない | 境界線があり、コンテンツが透ける |
.soft の見た目 | ぼかしとフェード | 再設計(Apple のエンジニアによる) |
なぜ切り替えたのでしょうか。Apple は公には説明していません。同じフォーラムの回答では、.automatic のほうが適切な場面で多くのアプリが .soft を明示的に選んでいたこと、そして .soft は「OS のデフォルトではない」ことが指摘されています。
iOS 27 で iOS 26 のスクロールエッジのフェードを戻すには?
デザインがフェードに依存しているなら、明示的に指定しましょう。@sarunw の解決策はモディファイア 1 つです。
List(items) { item in
ItemRow(item: item)
}
.scrollEdgeEffectStyle(.soft, for: .top)
iOS 26 より前のリリースもサポートしている場合は、可用性チェックで包めば、1 回の呼び出しでどこにでも適用できます。
extension View {
@ViewBuilder
func softTopScrollEdge() -> some View {
if #available(iOS 26.0, *) {
scrollEdgeEffectStyle(.soft, for: .top)
} else {
self
}
}
}
注意点が 3 つあります。1 つ目に、Shellbee の修正メモによると、アプリのルートで設定したスタイルは、シートやフルスクリーンカバーとして表示した NavigationStack には届かなかったため、それぞれの中で適用してください。2 つ目に、「戻す」といっても完全には一致しません。.soft は iOS 27 で再設計されたので、得られるのは iOS 27 の soft の見た目で、iOS 26 とピクセル単位で同じではありません。3 つ目に、Apple のエンジニアは、デザイン上の要件を満たす場面では .automatic を使うよう勧めており、.soft がすべてのデザインに合うわけではないと指摘しています。
互換性のバグもありました。デベロッパフォーラムのスレッドでは、iOS 27 ベータで safeAreaBar の上の .soft が完全に透明に描画されると報告されました。ただし、iOS 26 SDK でビルドしたアプリに限った問題です。Apple は iOS 27.2 でそうしたアプリでも新しい .soft が使えるようになると述べ、スレッドの後の投稿では iOS 27.2 beta 4 で修正されたと報告されています。iOS 26 でリンクしたビルドを出荷している場合は、iOS 27.2 で確認してください。
1 つの端だけスクロールエッジ効果を設定または非表示にするには?
scrollEdgeEffectStyle(_:for:) の 2 つ目のパラメータは Edge.Set なので、スタイルを適用する端を選べます。1 つの端、複数の端、または .all です。DevelopersIO によるカスタムのボトムバーの修正では、その端だけを対象にしています。
ScrollView {
DayList()
}
.scrollEdgeEffectStyle(.soft, for: .bottom)
.safeAreaBar(edge: .bottom) {
DayPicker()
}
筆者によると、この例のように、モディファイアはスクロールビューを包む外側のビューに付けてもかまいません。
効果を削除するには、iOS 26 の新機能である scrollEdgeEffectHidden(_:for:) を使います。どちらのパラメータにもデフォルト値があるので、引数なしのモディファイアはすべての端を非表示にします。
ScrollView {
PhotoGrid()
}
.scrollEdgeEffectHidden(true, for: .bottom)
非表示にするのは、その端の上に固定された要素が何もない場合か、独自のデザインですでにコントロールの読みやすさを確保している場合に限りましょう。そうでないと、ガラスのボタンが処理されていないコンテンツの上に乗ってしまいます。
UIKit でスクロールエッジ効果を変更するには?
UIKit にも同じモデルがあり、こちらも iOS 26 の新機能です。各 UIScrollView は topEdgeEffect、bottomEdgeEffect、leftEdgeEffect、rightEdgeEffect を公開しています。それぞれが UIScrollEdgeEffect で、.automatic、.soft、.hard のいずれかの style と、デフォルトが false の isHidden フラグを持ちます。
tableView.topEdgeEffect.style = .soft
collectionView.bottomEdgeEffect.isHidden = true
ボタンの列など、スクロールビューの端に重ねる独自のビューについては、Apple のセッション「Build a UIKit app with the new design」で UIScrollEdgeElementContainerInteraction が使われています。コンテナの子孫であるラベル、画像、コントロールなどが、エッジ効果の形を決めるようになります。
let interaction = UIScrollEdgeElementContainerInteraction()
interaction.scrollView = scrollView
interaction.edge = .bottom
buttonContainer.addInteraction(interaction)
iOS 27 でのデフォルト変更の報告の多くは SwiftUI のプロジェクトからのものですが、前述のフォーラムのスレッドには .soft のバグに遭遇した UIKit のデベロッパもいます。UIKit の画面も影響を受けないと決めつけず、iOS 27 で確認してください。
iPhone Duo の縦向きバーではスクロールエッジ効果はどう働く?
iPhone Duo では、iOS 27.1 SDK でビルドしたアプリのナビゲーションとツールバーのアイテムが、片側の端に沿った縦向きバーに移動します。Apple の Tech Talk「Raise the bar with iPhone Duo」によると、縦向きバーには横向きのバーと同じく「デフォルトではスクロールエッジ効果がない」一方、「透明度を下げる」がオンのときは背景が付きます。Apple は、どちらの場合でもバー内のカスタムビューを読みやすく保つよう求めています。バーが縦向きになる条件は iPhone Duo の縦向きツールバーのガイドで解説しています。
.leading や .trailing を指定した scrollEdgeEffectStyle が縦向きバーとどう関係するかは Apple のドキュメントに記載がないので、推測に頼った実装は避けてください。内側ディスプレイの縦向きでは横向きのバーのままなので、.top に設定したスタイルは、横向きでは縦向きバーを表示する同じデバイスでも意味を持ちます。両方の向きで確認し、適切なセーフエリアとコンテンツマージンでコンテンツがバーにかからないようにしましょう。
まとめ
- iOS 26 で追加されたスクロールエッジ効果は、スクロールするコンテンツの上で Liquid Glass のバーを読みやすく保ちます。
scrollEdgeEffectStyle(_:for:)で設定し、scrollEdgeEffectHidden(_:for:)で非表示にします。 .softはぼかした境界、.hardはほぼ不透明な境界です。Apple は密度の高いインターフェイスに.hardを勧めています。- デベロッパの報告によると、iOS 27 でビルドすると上端の自動の効果は
.hardに解決され、どちらのスタイルも iOS 27 では見た目が異なります。 - フェードを保つには、モーダルの
NavigationStackの中も含めて.scrollEdgeEffectStyle(.soft, for: .top)を適用しましょう。 - UIKit では、各
UIScrollViewの端のtopEdgeEffect.styleとisHiddenを使います。 - iPhone Duo の縦向きバーにはデフォルトでスクロールエッジ効果がないので、両方の向きで確認しましょう。
iOS 26 のツールバーがアイテムをどうグループ化し、スタイルを付けるかについては、Liquid Glass 時代の SwiftUI ツールバーのガイドをお読みください。このデバイスを最大限に活かしているアプリやゲームは Built for the fold でご覧いただけます。
よくある質問
SwiftUI のスクロールエッジ効果とは?
ツールバーなどの固定されたコントロールの下にスクロールするコンテンツに iOS 26 が適用する処理で、コントロールを読みやすく保つためのものです。SwiftUI が自動的に適用し、scrollEdgeEffectStyle(_:for:) で変更、scrollEdgeEffectHidden(_:for:) で削除できます。
.soft と .hard の違いは?
Apple は .soft を、固定されたコントロールとスクロールするコンテンツの間の控えめでぼかした境界、.hard を、直線的でほぼ不透明な境界と説明しています。Apple は、浮遊する要素が多い密度の高いインターフェイスに .hard を勧めています。
iOS 27 でツールバーが不透明に見えるのはなぜ?
デベロッパの報告によると、iOS 27 SDK でアプリをビルドすると、上端の自動のスクロールエッジ効果が iOS 26 の .soft のフェードではなく .hard になります。Apple のリリースノートには記載がないので、特定の見た目に依存している場合はスタイルを明示的に設定してください。
iOS 27 で iOS 26 のスクロールエッジのフェードを戻すには?
スクロールビュー、またはそれを囲むコンテナに .scrollEdgeEffectStyle(.soft, for: .top) を適用します。モーダルのスタックはルートから設定を引き継がないとデベロッパが報告しているので、シートやフルスクリーンカバーとして表示する NavigationStack の中にもそれぞれ適用してください。
UIKit でスクロールエッジ効果を変更するには?
各 UIScrollView には topEdgeEffect、bottomEdgeEffect、leftEdgeEffect、rightEdgeEffect のプロパティがあります。端の style を .soft、.hard、.automatic のいずれかに設定するか、isHidden を true にして削除します。
出典
- scrollEdgeEffectStyle(_:for:) · Apple Developer Documentation
- ScrollEdgeEffectStyle · Apple Developer Documentation
- scrollEdgeEffectHidden(_:for:) · Apple Developer Documentation
- safeAreaBar(edge:alignment:spacing:content:) · Apple Developer Documentation
- UIScrollEdgeEffect · Apple Developer Documentation
- UIScrollEdgeElementContainerInteraction · Apple Developer Documentation
- Build a SwiftUI app with the new design · Apple Developer (WWDC25)
- Build a UIKit app with the new design · Apple Developer (WWDC25)
- Raise the bar with iPhone Duo · Apple Developer
- iOS 27 beta 1: .scrollEdgeEffectStyle(.soft) renders fully transparent above safeAreaBar · Apple Developer Forums
- Xcode 27: safeAreaBar's effect changed to the equivalent of hard · DevelopersIO (Classmethod)
- iOS 27 changes scroll-edge toolbar default from soft to hard · Shellbee on GitHub
- In iOS 26, the scroll edge effect default is .soft. In iOS 27, it is .hard · @sarunw on X
- .hard is not the same on iOS 26 and iOS 27 · @sarunw on X
- Same scroll edge styles in Dark Mode · @sarunw on X
- Want the iOS 26 scroll edge fade back on iOS 27? · @sarunw on X
折りたたみを、アプリの一部に。
AppleDuo は iPhone Duo を本当に活かしたアプリとゲームを紹介しています。App Store へのリンクを添えて送ってください。ほかの開発者の作品も見られます。