LoginSignup
7

More than 3 years have passed since last update.

[SwiftUI] フィードバックのUIに使うポップアップを作ってみる

Posted at

Untitled.gif

フィードバックするためのUIであるポップアップはSwiftUIでどのように作るのが良いのでしょうか?
作るだけ作れたので共有します。

まずは表示するポップアップ自体のコンポーネントを作成

struct MyPopup: View {

  var body: some View {
    Text("Hello!")
      .foregroundColor(.white)
      .padding(16)
      .background(Color.pink)
      .cornerRadius(8)
  }
}

extensionを作る

次にポップアップを表示させたい画面から表示処理を呼び出せるようにView protocolにExtensionを作ります。

extension View {

  func popup<Content: View>(isPresented: Binding<Bool>, content: () -> Content) -> some View {

    if isPresented.wrappedValue {
      DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
        isPresented.wrappedValue = false
      }
    }

    return ZStack {
      self

      content()
        .opacity(isPresented.wrappedValue ? 1 : 0)
        .scaleEffect(isPresented.wrappedValue ? 1 : 0)
        .animation(.spring(response: 0.2, dampingFraction: 0.6, blendDuration: 0))
    }
  }
}

画面の上に表示したいので、ZStackで包みます。

自動で閉じるようにするために isPresentedがtrueになったらDispatchQueueを使って1秒後にBinding経由でisPresentedをfalseに戻します。


最後に表示する画面の作成

struct ContentView: View {

  @State var isPresented = false

  var body: some View {
    VStack {

      ...

      Button(action: {
        self.isPresented = true
      }) {
        Text("Show")
      }
    }
    .popup(isPresented: $isPresented) {
      MyPopup()
    }
  }
}

感想

こんな感じでいいんだっけ?という印象
n秒後に閉じるという処理はStateをどうやって制御していくのが良いのでしょうか?

React,Vueの世界ではどうやっているのかがヒントになりそう。
同様にStateなのか、CSSアニメーションで完結してしまっているのか。などなど。

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
7