フィードバックするための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アニメーションで完結してしまっているのか。などなど。