【问题标题】:SwiftUI: popover to persist (not be dismissed when tapped outside)SwiftUI:弹出窗口持续存在(在外面点击时不会被关闭)
【发布时间】:2020-03-22 17:30:28
【问题描述】:

我创建了这个弹出框:

import SwiftUI

struct Popover : View {
  @State var showingPopover = false

  var body: some View {

    Button(action: {
      self.showingPopover = true
    }) {
      Image(systemName: "square.stack.3d.up")
    }
    .popover(isPresented: $showingPopover){

    Rectangle()

      .frame(width: 500, height: 500)

    }
  }
}

struct Popover_Previews: PreviewProvider {
    static var previews: some View {
        Popover()
        .colorScheme(.dark)
        .previewDevice("iPad Pro (12.9-inch) (3rd generation)")
    }
}

默认行为是关闭,一旦在外面点击。

问题: 如何将弹出框设置为: - 坚持(在外面点击时不会被解雇)? - 激活时不阻塞屏幕?

【问题讨论】:

    标签: swiftui popover


    【解决方案1】:

    我尝试使用.popover.sheet,但没有找到更接近的解决方案。 .sheet 可以为您呈现模态视图,但它会阻止父视图。所以我可以让你使用ZStack 并做出类似的行为(对于用户):

    import SwiftUI
    
    struct Popover: View {
        
        @State var showingPopover = false
        
        var body: some View {
            
            ZStack {
                
                // rectangles only for color control
                Rectangle()
                    .foregroundColor(.gray)
                
                Rectangle()
                    .foregroundColor(.white)
                    .opacity(showingPopover ? 0.75 : 1)
                
                Button(action: {
                    withAnimation {
                        self.showingPopover.toggle()
                    }
                }) {
                    Image(systemName: "square.stack.3d.up")
                }
                
                ModalView()
                    .opacity(showingPopover ? 1: 0)
                    .offset(y: self.showingPopover ? 0 : 3000)
            }
            
        }
    }
    
    // it can be whatever you need, but for arrow you should use Path() and draw it, for example
    struct ModalView: View {
        
        var body: some View {
            
            VStack {
                Spacer()
                
                ZStack {
                    Rectangle()
                        .frame(width: 520, height: 520)
                        .foregroundColor(.white)
                        .cornerRadius(10)
                    
                    Rectangle()
                        .frame(width: 500, height: 500)
                        .foregroundColor(.black)
                }
                
            }
        }
        
    }
    
    struct Popover_Previews: PreviewProvider {
        static var previews: some View {
            Popover()
            .colorScheme(.dark)
            .previewDevice("iPad Pro (12.9-inch) (3rd generation)")
        }
    }
    

    这里ModalView 从下方弹出,背景变得更暗。但您仍然可以触摸“父”视图上的所有内容

    更新:忘记显示结果:

    P.S.:从这里你可以走得更远。例如,您可以将所有内容放入GeometryReader 以计算ModalView 位置,添加最后一个.gesture(DragGesture()...) 以再次偏移底部下方的视图等等。

    【讨论】:

    • 非常感谢伙计!但这更像是一种模式
    【解决方案2】:

    您只需使用 .constant(showingPopover) 代替 $showingPopover。当您使用 $ 时,它会使用绑定并在您按下弹出框外部并关闭您的弹出框时更新您的 @State 变量。如果您使用 .constant(),它只会从您的 @State 变量中读取值,并且不会关闭弹出框。 您的代码应如下所示:

    struct Popover : View {
    
      @State var showingPopover = false
    
      var body: some View {
        Button(action: {
          self.showingPopover = true
        }) {
          Image(systemName: "square.stack.3d.up")
        }
        .popover(isPresented: .constant(showingPopover)) {
           Rectangle()
             .frame(width: 500, height: 500)
           }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-12-21
      • 1970-01-01
      • 2023-02-09
      • 1970-01-01
      • 1970-01-01
      • 2012-08-28
      • 2017-11-25
      相关资源
      最近更新 更多