如何在 SwiftUI 中单击菜单项时隐藏浮动菜单
How to hide Floating Menu on Click of Menu Items in SwiftUI
我在 SwiftUI 中创建了浮动菜单,但我遇到了一个问题,当按下右下角的加号按钮时,我打开浮动菜单项,然后再次按下加号按钮隐藏浮动菜单项,但是当按下菜单项时它不会隐藏该菜单项。
下面是我的代码
MapContainerUIView.swift
struct MapContainerUIView: View {
let flotingMenuArray = [
MenuItemModel(title: "Camera", icon: "camera.fill"),
MenuItemModel(title: "Photo", icon: "photo.on.rectangle"),
MenuItemModel(title: "Share", icon: "square.and.arrow.up.fill")
]
var body: some View {
NavigationView{
ZStack {
FloatingMenu(dataSource: flotingMenuArray)
}
}
}
func floatingButtonAction(index: Int){
print("Floating item tap", index)
}
}
FloatingMenu.swift
struct FloatingMenu: View {
init() {
self.dataSource = []
}
init(dataSource: [MenuItemModel]) {
self.dataSource = dataSource
}
@State var isMenuShow = false
var dataSource: [MenuItemModel]
var body: some View {
ZStack(alignment: .trailing){
if isMenuShow{
Button(action: {
self.showMenu()
}) {
Text("")
.frame(maxWidth: .infinity, maxHeight: .infinity)
.background(Color.black)
.opacity(0.3)
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
.edgesIgnoringSafeArea(.all)
}
HStack{
Spacer()
VStack(alignment: .trailing, content: {
Spacer()
ForEach(0..<dataSource.count) { index in
if isMenuShow {
MenuItems(menuItemData: dataSource[index], index: index)
}
}
Button(action: {
self.showMenu()
}) {
Image(systemName: "plus.circle.fill")
.resizable()
.frame(width: 60, height: 60)
.foregroundColor(Color.white)
}
.background(Color.black)
.cornerRadius(35)
})
.shadow(color: .gray, radius: 4, x: 1, y: 1)
.padding(.init(top: 0, leading: 20, bottom: 20, trailing: 20))
}
}
}
func showMenu() {
self.isMenuShow.toggle()
}
}
MenuItems.swift
class MenuItemModel : Identifiable{
var id = UUID()
var title : String = ""
var icon : String = ""
init(title: String, icon: String) {
self.title = title
self.icon = icon
}
}
struct MenuItems: View {
var mapContainer = MapContainerUIView()
var menuItemData: MenuItemModel
var index : Int
var body: some View {
ZStack {
HStack{
Text(menuItemData.title)
.foregroundColor(.white)
.shadow(color: .gray, radius: 3, x: 1, y: 1)
Button(action: {
FloatingMenu().isMenuShow = false
print("button tap: ", menuItemData.title)
self.mapContainer.floatingButtonAction(index: index)
}) {
ZStack {
Circle()
.foregroundColor(Color.white)
.frame(width: 45, height: 45)
.shadow(color: .gray, radius: 3, x: 1, y: 1)
Image(systemName: menuItemData.icon)
.imageScale(.large)
.foregroundColor(.black)
}
.padding(EdgeInsets(top: 0, leading: 0, bottom: 0, trailing: 10))
}
}
}
}
}
我想在按下菜单项时隐藏浮动菜单,请有人指导我。
现在,您正在尝试在 FloatingMenu
的 新实例 上设置 isMenuShow
,这就是它不起作用的原因。
一个解决方案是从原始 FloatingMenu
实例传递一个 Binding
。
struct MenuItems: View {
@Binding var isMenuShow : Bool //<-- Here
var mapContainer = MapContainerUIView()
var menuItemData: MenuItemModel
var index : Int
var body: some View {
ZStack {
HStack{
Text(menuItemData.title)
.foregroundColor(.white)
.shadow(color: .gray, radius: 3, x: 1, y: 1)
Button(action: {
self.isMenuShow = false //<-- Here
print("button tap: ", menuItemData.title)
self.mapContainer.floatingButtonAction(index: index)
}) {
并且,在浮动菜单中:
if isMenuShow {
MenuItems(isMenuShow: $isMenuShow, //<-- Here
menuItemData: dataSource[index],
index: index)
}
另一个解决方案是提供一个闭包作为 MenuItems
的参数来关闭菜单:
struct MenuItems: View {
var closeMenu : () -> Void //<-- Here
var mapContainer = MapContainerUIView()
var menuItemData: MenuItemModel
var index : Int
var body: some View {
ZStack {
HStack{
Text(menuItemData.title)
.foregroundColor(.white)
.shadow(color: .gray, radius: 3, x: 1, y: 1)
Button(action: {
closeMenu() //<-- Here
print("button tap: ", menuItemData.title)
//self.mapContainer.floatingButtonAction(index: index)
}) {
if isMenuShow {
MenuItems(closeMenu: { self.isMenuShow = false },
menuItemData: dataSource[index],
index: index)
}
我在 SwiftUI 中创建了浮动菜单,但我遇到了一个问题,当按下右下角的加号按钮时,我打开浮动菜单项,然后再次按下加号按钮隐藏浮动菜单项,但是当按下菜单项时它不会隐藏该菜单项。
下面是我的代码
MapContainerUIView.swift
struct MapContainerUIView: View {
let flotingMenuArray = [
MenuItemModel(title: "Camera", icon: "camera.fill"),
MenuItemModel(title: "Photo", icon: "photo.on.rectangle"),
MenuItemModel(title: "Share", icon: "square.and.arrow.up.fill")
]
var body: some View {
NavigationView{
ZStack {
FloatingMenu(dataSource: flotingMenuArray)
}
}
}
func floatingButtonAction(index: Int){
print("Floating item tap", index)
}
}
FloatingMenu.swift
struct FloatingMenu: View {
init() {
self.dataSource = []
}
init(dataSource: [MenuItemModel]) {
self.dataSource = dataSource
}
@State var isMenuShow = false
var dataSource: [MenuItemModel]
var body: some View {
ZStack(alignment: .trailing){
if isMenuShow{
Button(action: {
self.showMenu()
}) {
Text("")
.frame(maxWidth: .infinity, maxHeight: .infinity)
.background(Color.black)
.opacity(0.3)
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
.edgesIgnoringSafeArea(.all)
}
HStack{
Spacer()
VStack(alignment: .trailing, content: {
Spacer()
ForEach(0..<dataSource.count) { index in
if isMenuShow {
MenuItems(menuItemData: dataSource[index], index: index)
}
}
Button(action: {
self.showMenu()
}) {
Image(systemName: "plus.circle.fill")
.resizable()
.frame(width: 60, height: 60)
.foregroundColor(Color.white)
}
.background(Color.black)
.cornerRadius(35)
})
.shadow(color: .gray, radius: 4, x: 1, y: 1)
.padding(.init(top: 0, leading: 20, bottom: 20, trailing: 20))
}
}
}
func showMenu() {
self.isMenuShow.toggle()
}
}
MenuItems.swift
class MenuItemModel : Identifiable{
var id = UUID()
var title : String = ""
var icon : String = ""
init(title: String, icon: String) {
self.title = title
self.icon = icon
}
}
struct MenuItems: View {
var mapContainer = MapContainerUIView()
var menuItemData: MenuItemModel
var index : Int
var body: some View {
ZStack {
HStack{
Text(menuItemData.title)
.foregroundColor(.white)
.shadow(color: .gray, radius: 3, x: 1, y: 1)
Button(action: {
FloatingMenu().isMenuShow = false
print("button tap: ", menuItemData.title)
self.mapContainer.floatingButtonAction(index: index)
}) {
ZStack {
Circle()
.foregroundColor(Color.white)
.frame(width: 45, height: 45)
.shadow(color: .gray, radius: 3, x: 1, y: 1)
Image(systemName: menuItemData.icon)
.imageScale(.large)
.foregroundColor(.black)
}
.padding(EdgeInsets(top: 0, leading: 0, bottom: 0, trailing: 10))
}
}
}
}
}
我想在按下菜单项时隐藏浮动菜单,请有人指导我。
现在,您正在尝试在 FloatingMenu
的 新实例 上设置 isMenuShow
,这就是它不起作用的原因。
一个解决方案是从原始 FloatingMenu
实例传递一个 Binding
。
struct MenuItems: View {
@Binding var isMenuShow : Bool //<-- Here
var mapContainer = MapContainerUIView()
var menuItemData: MenuItemModel
var index : Int
var body: some View {
ZStack {
HStack{
Text(menuItemData.title)
.foregroundColor(.white)
.shadow(color: .gray, radius: 3, x: 1, y: 1)
Button(action: {
self.isMenuShow = false //<-- Here
print("button tap: ", menuItemData.title)
self.mapContainer.floatingButtonAction(index: index)
}) {
并且,在浮动菜单中:
if isMenuShow {
MenuItems(isMenuShow: $isMenuShow, //<-- Here
menuItemData: dataSource[index],
index: index)
}
另一个解决方案是提供一个闭包作为 MenuItems
的参数来关闭菜单:
struct MenuItems: View {
var closeMenu : () -> Void //<-- Here
var mapContainer = MapContainerUIView()
var menuItemData: MenuItemModel
var index : Int
var body: some View {
ZStack {
HStack{
Text(menuItemData.title)
.foregroundColor(.white)
.shadow(color: .gray, radius: 3, x: 1, y: 1)
Button(action: {
closeMenu() //<-- Here
print("button tap: ", menuItemData.title)
//self.mapContainer.floatingButtonAction(index: index)
}) {
if isMenuShow {
MenuItems(closeMenu: { self.isMenuShow = false },
menuItemData: dataSource[index],
index: index)
}