Swift・iOS

Swiftを中心に学んだことを記録に残すブログです。技術に関係ない記事もたまに書いています。

【SwiftUI】通知を画面上部からアニメーションして表示する

 

はじめに 

【SwiftUI】ポップアップ(オーバーレイ)を表示する - Swift・iOSの実装を修正して、UIPasteboardの通知やGame Centerのログイン通知、着信音オン/オフのような、画面上部からアニメーションして表示される通知を再現してみました。先に結論を言うと、再現度はいまいちです笑

 

本題

サンプルイメージ

f:id:hfoasi8fje3:20210825210401g:plain

 

開発環境

 

全体の実装

ContentView.swift

import SwiftUI

struct ContentView: View {
    @State private var selectedRating: Int = 0
    private var maximumRating = 5
    
    @State private var isOverlayPresented = false
    
    var body: some View {
        GeometryReader { geometry in
            ZStack {
                ratingView
                
                if isOverlayPresented {
                    overlayView
                        .position(x: geometry.size.width / 2, y: 20)
                }
            }
            .frame(width: geometry.size.width, height: geometry.size.height)
        }
    }
}

private extension ContentView {
    var ratingView: some View {
        HStack(spacing: 25) {
            ForEach(1 ..< maximumRating + 1) { ratingNumber in
                Image(systemName: ratingNumber > selectedRating ? "star" : "star.fill")
                    .foregroundColor(ratingNumber > selectedRating ? .gray : .yellow)
                    .onTapGesture {
                        selectedRating = ratingNumber

                        withAnimation(.easeOut(duration: 1.0)) {
                            isOverlayPresented = true
                        }
                        DispatchQueue.main.asyncAfter(deadline: .now() + 2.5) {
                            withAnimation(.easeIn(duration: 1.0)) {
                                isOverlayPresented = false
                            }
                        }
                    }
                    .font(.title)
            }
        }
    }
}

private extension ContentView {
    var overlayView: some View {
        Text("Submitted!")
            .font(.subheadline)
            .frame(width: 220, height: 50)
            .background(Color.white)
            .cornerRadius(100)
            .shadow(color: Color(red: 0.85, green: 0.85, blue: 0.85), radius: 20)
            .transition(.move(edge: .top))
    }
}

 

おわりに

遊びとしてやってみただけなので、「楽しかった」くらいの感想しかないのですが笑、せっかくなので記事に残しておきました。

 

参考