元のドキュメント: developer.apple.com/documentation/swiftui/landmarks-displaying-custom-activity-badges


サンプルコード


ランドマーク:カスタムアクティビティバッジの表示


アニメーション付きのカスタムアクティビティバッジを表示することで、人々が自分の冒険をする方法を提供します。



Download 註: ファイル等の再配布は Apple から禁じられているのでこのボタンは何も効果がない。「元のドキュメント」からダウンロードされたい。


iOS 26.0+ iPadOS 26.0+ Mac Catalyst 26.0+ macOS 26.0+ Xcode 26.0+

概観


Landmarks アプリを使えば、世界中の興味深い場所を探索できます。自宅近くの国立公園でも、遠く離れた大陸の僻地でも、このアプリを使えば、冒険の記録を残したり、旅の途中でオリジナルのアクティビティバッジを受け取ったりすることができます。



このサンプルでは、バッジを縦方向のビューに表示し、バッジの表示/非表示を切り替えるトグルボタンを備えています。ランドマークアプリには、他のビューでもバッジ表示を簡単に採用できるカスタム修飾子が含まれています。バッジがリキッドガラスを使用するように構成することで、バッジの表示/非表示時に変形アニメーションを使用できるという利点が得られます。



他のビューでバッジを表示する修飾子を追加


バッジを CollectionsView などの他のビューでも表示できるようにするため、サンプルでは ViewModifier としてカスタム修飾子 ShowBadgesViewModifier を使用しています。サンプルでは、ZStack を使用してバッジを別のビューの上に重ね、バッジビューを下隅に配置しています。


private struct ShowsBadgesViewModifier: ViewModifier {
    func body(content: Content) -> some View {
        ZStack {
            content
            HStack {
                Spacer()
                VStack {
                    Spacer()
                    BadgesView()
                        .padding()
                }
            }
        }
    }
}

このサンプルは、showBadges 修飾子を追加することで View を拡張しています。


extension View {
    func showsBadges() -> some View {
        modifier(ShowsBadgesViewModifier())
    }
}


トグルボタンにリキッドガラスを適用する


トグルボタンを作成するために、サンプルでは、表示状態と非表示状態に異なるシステム画像を持つ ToggleBadgesLabel を使用して Button を構成します。リキッドガラスを適用するには、glass 修飾子を使用してボタンをスタイル設定します。


Button {
    //...
} label: {
    //...
}
.buttonStyle(.glass)


バッジにリキッドガラスを追加する


各バッジにリキッドガラスを追加するには、サンプルでは glassEffect(_:in:) 修飾子を使用しています。カスタムのガラスビューの外観を作成するには、サンプルでは角の半径を指定した長方形オプションを指定しています。


BadgeLabel(badge: $0)
    .glassEffect(.regular, in: .rect(cornerRadius: Constants.badgeCornerRadius))


変形効果を使用してバッジをアニメーション化する


変形効果は、リキッドガラスビュー用のアニメーションです。このアニメーションでは、トグルボタンと各バッジが結合した状態で始まります。その後、ボタンとバッジは液体のように形状を変えながら分離し、ある場所から別の場所へと移動します。逆に、トグルボタンとバッジは形状を変え、再び結合して 1 つのビューに戻ります。


リキッドガラスの変形効果を実現するために、アプリは以下の処理を行います。


  • バッジとトグルボタンを GlassEffectContainer にまとめます。

  • 各バッジに glassEffectID(_:in:) を追加します。

  • トグルボタンに glassEffectID(_:in:) を追加します。

  • isExpanded プロパティをトグルするコマンドを withAnimation(_:_:) に包みます。

  • // Organizes the badges and toggle button to animate together.
    GlassEffectContainer(spacing: Constants.badgeGlassSpacing) {
        VStack(alignment: .center, spacing: Constants.badgeButtonTopSpacing) {
            if isExpanded {
                VStack(spacing: Constants.badgeSpacing) {
                    ForEach(modelData.earnedBadges) {
                        BadgeLabel(badge: $0)
                            // Adds Liquid Glass to the badge.
                            .glassEffect(.regular, in: .rect(cornerRadius: Constants.badgeCornerRadius))
                            // Adds an identifier to the badge for animation.
                            .glassEffectID($0.id, in: namespace)
                    }
                }
            }
    
            Button {
                // Animates this button and badges when `isExpanded` changes values.
                withAnimation {
                    isExpanded.toggle()
                }
            } label: {
                ToggleBadgesLabel(isExpanded: isExpanded)
                    .frame(width: Constants.badgeShowHideButtonWidth,
                           height: Constants.badgeShowHideButtonHeight)
            }
            // Adds Liquid Glass to the button.
            .buttonStyle(.glass)
            #if os(macOS)
            .tint(.clear)
            #endif
            // Adds an identifier to the button for animation.
            .glassEffectID("togglebutton", in: namespace)
        }
        .frame(width: Constants.badgeFrameWidth)
    }
    




    以下も見よ


    アプリの特色


    {} ランドマーク:背景拡張効果の適用

    画像をぼかしてサイドバーまたはインスペクタパネルの下に拡張表示するように構成します。


    {} ランドマーク:サイドバーまたはインスペクタの下で水平スクロールを拡張する

    サイドバーやインスペクタの下で水平スクロールバーを拡張することで、見た目を改善できます。


    {} ランドマーク:ツールバーにリキッドグラス効果を提供するシステムを改良しました。

    ツールバーを関連するグループに整理することで、見た目と使いやすさを向上させましょう。














    トップへ












    トップへ












    トップへ












    トップへ












    トップへ












    トップへ












    トップへ












    トップへ












    トップへ












    トップへ












    トップへ












    トップへ












    トップへ












    トップへ












    トップへ












    トップへ












    トップへ