Skip to content

Instantly share code, notes, and snippets.

@fatbobman
Last active April 12, 2023 02:22
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fatbobman/7f35764d753e351cc3189f6b2b7aa10b to your computer and use it in GitHub Desktop.
Save fatbobman/7f35764d753e351cc3189f6b2b7aa10b to your computer and use it in GitHub Desktop.
模态 Menu 用法演示
import Foundation
import SwiftUI
// https://discord.com/channels/967978112509935657/967978112509935663/1012284708685619253 原始问题
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.7) } // 可以用 Color.clear 显示为全透明
.zIndex(10) // 不显式设置 zIndex , 多次切换后可能会显示到 ScrollView 后面
}
}
.ignoresSafeArea(.all)
.onChange(of: menuIsShowing, perform: { _ in
print(menuIsShowing)
})
}
}
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
menuIsShowing = false
}
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{ // onAppear 有较高几率无法成功激发
print("on Appear")
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))
}
.padding(5)
.contentShape(Rectangle())
.simultaneousGesture( // 添加 tap 增加双保险
TapGesture().onEnded{ _ in
print("tap")
menuIsShowing = true
})
.controlSize(.large)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment