Использование очереди для всплывающих окон в SwiftUI

#swift #swiftui #notifications #popup #queue

Вопрос:

Я пытаюсь реализовать пользовательские уведомления внутри приложения. Например, пользователь нажимает на кнопку, и может быть ограничение, и он получает всплывающее окно о том, что нужно сделать.

Ниже вы можете увидеть мой код, с которым отображается всплывающее окно при нажатии на кнопку

Параметры всплывающего окна:

 public struct TopPopupOptions {  public var yOffset: CGFloat  public var hideAfter: TimeInterval?  public var animation: Animation?   public init(  yOffset: CGFloat = 60,  hideAfter: TimeInterval? = nil,  animation: Animation? = nil,  ) {  self.yOffset = yOffset  self.hideAfter = hideAfter  self.animation = animation  } }  

Визуальный вид всплывающего окна, анимация:

 protocol TopPopupModifierProtocol: ViewModifier {  var shouldShowPopup: Bool { get set }  var options: TopPopupOptions? { get } }  struct TopPopupFade: TopPopupModifierProtocol {  @Binding var shouldShowPopup: Bool  let options: TopPopupOptions?    func body(content: Content) -gt; some View {  content  .transition(AnyTransition.opacity.animation(options?.animation ?? .linear))  .opacity(shouldShowPopup ? 1 : 0)  .zIndex(1)  } }  

Модификатор и расширение:

 struct TopPopupModifierlt;TopPopupContent: Viewgt;: ViewModifier {  @Binding var isPresented: Bool    let options: TopPopupOptions  let onDismiss: (() -gt; Void)?  let content: () -gt; TopPopupContent    func body(content: Content) -gt; some View {  content  .frame(maxWidth: .infinity, maxHeight: .infinity)  .overlay (  VStack {  if isPresented {  self.content()  .modifier(TopPopupSlide(shouldShowPopup: $isPresented, options: options))  .offset(x: 0, y: options.yOffset)  }  }  )  } }  
 extension View {  func topPopuplt;TopPopupContent: Viewgt;(  isShowing: Bindinglt;Boolgt;, options: TopPopupOptions,  onDismiss: (() -gt; Void)? = nil,  @ViewBuilder content: @escaping () -gt; TopPopupContent) -gt; some View  {  self.modifier(  TopPopupModifier(isPresented: isShowing, options: options, onDismiss: onDismiss, content: content)  )  } }  

Popup View:

 struct TopPopupView: View {  let title: String  let onCloseTap: () -gt; Void    var body: some View {    GeometryReader { proxy in  ZStack {  Color.blue    HStack(alignment: .center) {  Image(systemName: "paperplane.fill")  .foregroundColor(.white)  .padding()    Text(title)  .font(.system(size: 16))  .foregroundColor(.white)    Spacer()    Image(systemName: "xmark")  .frame(width: 14, height: 14)  .foregroundColor(.white)  .padding()  .onTapGesture {  onCloseTap()  }  }  }  .frame(height: 70)  .padding(.horizontal, 15)  }  } }  

Usage:

 struct ContentView: View {  @State var shouldShowPopup: Bool = false    private let popupOptions = TopPopupOptions(  hideAfter: .infinity  )    var body: some View {  VStack {  Button("Show popup") {  withAnimation {  shouldShowPopup = true  }  }  }  .topPopup(isShowing: $shouldShowPopup, options: popupOptions) {  TopPopupView(title: "Popup", onCloseTap: {  withAnimation {  shouldShowPopup = false  }  })  }  } }  

Ну что ж, еще раз. Я хотел бы добавить возможность добавлять всплывающие окна в очередь. Я нажимаю на кнопку, в результате у меня отображается одно всплывающее окно, с другой стороны, может появиться всплывающее окно другого типа, и оно встанет в очередь. После минимизации текущего всплывающего окна отображается то, которое было следующим в очереди. Заранее благодарю вас!