Skip to content

Instantly share code, notes, and snippets.

@fatbobman
Created August 26, 2022 08:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fatbobman/f74d92ad31c6dfa591ff6daa4c4360a8 to your computer and use it in GitHub Desktop.
Save fatbobman/f74d92ad31c6dfa591ff6daa4c4360a8 to your computer and use it in GitHub Desktop.
通过状态显示遮盖层,让 Menu 具备模态视图的特征( 防止误触 )
struct ModalMenu: View {
@State private var menuIsShowing = false
@State private var selection: Int?
let colors: [Color] = [Color.red, .blue, .green, .orange, .pink, .cyan, .brown]
var body: some View {
VStack {
if let selection {
Text("CurrentID: \(selection)")
} else {
Text("No ID selected")
}
ZStack {
ScrollView {
ForEach(0..<20, id: \.self) { i in
cell(i: i)
}
}
// 添加遮罩
if menuIsShowing {
Button { menuIsShowing = false } label: { Color.secondary.opacity(0.2) } // 可以用 Color.clear 显示为全透明
.zIndex(10) // 不显式设置 zIndex , 多次切换后可能会显示到 ScrollView 后面
}
}
.ignoresSafeArea(.all)
}
}
func cell(i: Int) -> some View {
ZStack(alignment: .trailing) {
Rectangle()
.fill(colors[i % colors.count].opacity(0.3))
.overlay(Text("ID:\(i)").font(.title))
.onTapGesture {
selection = i
}
actionMenu(i: i)
.padding(.trailing, 20)
}
.frame(height: 80)
}
func actionMenu(i: Int) -> some View {
Menu {
Button("ID:\(i) Action1") {
// do action1
print("action1 \(i)")
menuIsShowing = false // 恢复状态
}
.onAppear {
menuIsShowing = true
}
Button("ID:\(i) Action2") {
// do action1
print("action2 \(i)")
menuIsShowing = false // 恢复状态
}
} label: {
Image(systemName: "ellipsis.circle.fill") // 􀍢
.font(.title)
.foregroundColor(.secondary.opacity(0.5))
}
.controlSize(.large)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment