4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

iOS強化月間 - iOSアプリ開発の知見を共有しよう -

SwiftUIでToastっぽいバナーっぽいやつを実装してみる

Last updated at Posted at 2023-09-11

こんな感じにしたい

PowerplayToastKit: A Simple Toast Library for iOS

とか
image.png

翻訳のポップアップ

とか
image.png

実装-Success

こんな感じで3秒経つと消える感じです
image.png

ToastBanner.swift
import SwiftUI

struct ToastBanner: View {
    
    @Binding var showFlag: Bool
    
    var body: some View {
        ZStack {
            VStack {
                HStack {
                    Image(systemName: "checkmark.circle.fill")
                        .resizable()
                        .scaledToFit()
                        .frame(height: 30)
                        .foregroundColor(Color.green)
                    VStack(alignment: .leading) {
                        Text("ダウンロード完了")
                            .font(.custom("RoundedMplus1c-Bold", size: 16))
                            .foregroundColor(Color.black)
                        Text("ファイルを写真アプリに保存しました")
                            .font(.custom("RoundedMplus1c-Regular", size: 14))
                            .foregroundColor(Color.black)
                    }
                }
                .padding(.all, 10)
                // PaleGreenっぽいやつ #D0E2BE
                .background(Color(red: 232/255, green: 242/255, blue: 228/255))
                .clipShape(RoundedRectangle(cornerRadius: 10))
                Spacer()
            }
        }
        .padding(.top, 50)
        .onAppear {
            DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
                withAnimation {
                    showFlag = false
                }
            }
        }
    }
}

struct ToastBanner_Previews: PreviewProvider {
    static var flag = State(initialValue: true)
    
    static var previews: some View {
        ToastBanner(showFlag: flag.projectedValue)
    }
}

実装-Failure

image.png

ちょっと使いまわしてフラグで成否切り替えするようにしてみる。

ToastBanner.swift
struct ToastBanner: View {
    /// バナー表示フラグ
    @Binding var showFlag: Bool
    /// ダウンロード成否表示切替フラグ
    @State var shouldShowDownloadSuccess: Bool
    
    var body: some View {
        Group {
            if shouldShowDownloadSuccess {
                SuccessBanner()
            } else {
                FailureBanner()
            }
        }
        .padding(.top, 50)
        .onAppear {
            DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
                withAnimation {
                    showFlag = false
                }
            }
        }
    }
}

private struct SuccessBanner: View {
    var body: some View {
        ZStack {
            VStack {
                HStack {
                    Image(systemName: "checkmark.circle.fill")
                        .resizable()
                        .scaledToFit()
                        .frame(height: 30)
                        .foregroundColor(Color.green)
                    VStack(alignment: .leading) {
                        Text("ダウンロード完了")
                            .font(.custom("RoundedMplus1c-Bold", size: 16))
                            .foregroundColor(Color.black)
                        Text("ファイルを写真アプリに保存しました")
                            .font(.custom("RoundedMplus1c-Regular", size: 14))
                            .foregroundColor(Color.black)
                    }
                }
                .padding(.all, 10)
                // PaleGreenっぽいやつ #D0E2BE
                .background(Color(red: 232/255, green: 242/255, blue: 228/255))
                .clipShape(RoundedRectangle(cornerRadius: 10))
                Spacer()
            }
        }
    }
}

private struct FailureBanner: View {
    var body: some View {
        ZStack {
            VStack {
                HStack {
                    Image(systemName: "xmark.circle.fill")
                        .resizable()
                        .scaledToFit()
                        .frame(height: 30)
                        .foregroundColor(Color.red)
                    VStack(alignment: .leading) {
                        Text("ダウンロード失敗")
                            .font(.custom("RoundedMplus1c-Bold", size: 16))
                            .foregroundColor(Color.black)
                        Text("ファイルの保存に失敗しました")
                            .font(.custom("RoundedMplus1c-Regular", size: 14))
                            .foregroundColor(Color.black)
                    }
                }
                .padding(.all, 10)
                // Light Red #F4E4DE
                .background(Color(red: 244/255, green: 228/255, blue: 222/255))
                .clipShape(RoundedRectangle(cornerRadius: 10))
                Spacer()
            }
        }
    }
}

struct ToastBanner_Previews: PreviewProvider {
    static var flag = State(initialValue: true)
    
    static var previews: some View {
        ToastBanner(showFlag: flag.projectedValue, shouldShowDownloadSuccess: false)
    }
}

参考

PowerplayToastKit: A Simple Toast Library for iOS
薄緑(うすみどり)の色見本・カラーコード
カラーコード変換ツール
SwiftUI でトースト・バナーを表示する方法

4
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?