Horizo​​ntal ScrollView 中的 NavigationLink 和 Menu

NavigationLink and Menu inside Horizontal ScrollView

我正在尝试创建一个应用程序,列表中有一个水平滚动视图。点击那个水平滚动视图,每个项目都应该导航到另一个屏幕,每个项目上都有一个按钮,显示上下文菜单。但是,这两个功能不能一起工作。如果 navigatiionlink 有效,则点击时不会弹出菜单(不过长按会弹出)。

代码如下:

    
    var categoryName: String
    
    var items: [Post]
    
    var body: some View {
        
        VStack(alignment: .leading) {
            
            Text(categoryName)
                
                .font(.headline)
                
                .padding(.leading, 15)
            
            ScrollView(.horizontal, showsIndicators: false) {
                
                HStack(alignment: .top, spacing: 0) {
                    
                    ForEach(items) { post in
                        
                        VStack {
                            
                            NavigationLink(
                                destination: PostView(post: post)) {
                                EmptyView()
                            }
                        
//                            NavigationLink(
//                                destination: PostView(post: post)) {
                                
                                CategoryItem(categoryName: "Featured", post: post)
                                    
                                    .frame(width: (UIScreen.main.bounds.width - 90), height: 155)
                                    
                                    .padding(.leading, 10)
                                    
                                    .onAppear {
                                        if (self.items.last?.id == post.id) {
                                            print("Last Featured")
                                        }
                                    }
//                            }
                        }
                        
                    }
                    
                }
                
            }
            
            .frame(height: 185)
            
            .padding(.top, 0)
            
        }
        
    }
    
}

这是类别项目:

VStack(alignment: .trailing, spacing: nil, content: {
                
                Menu {
                    
                    VStack {
                        
                        Button(action: {
                            print("Hello")
                            if (!checkIfAlreadySaved(post: post, viewContext: viewContext)) {
                                self.bookmarkPost(post: post, viewContext: viewContext) {
//                                    self.isBookmarked = true
                                }
                            } else {
                                self.unBookmarkPost(post: post, viewContext: viewContext) {
//                                    self.isBookmarked = false
                                }
                            }
                        }) {
                            Text(!checkIfAlreadySaved(post: post, viewContext: viewContext) ? "Add to Favourites" : "Remove from Favourites")
                        }
                        Button(action: {
                            print("Hello")
                            self.actionSheet(urlString: post.link)
                        }) {
                            Text("Share")
                        }
                        
                    }

                }  label: {
                    Image(systemName: "ellipsis")
                        
                        .font(.subheadline)
                        
                        .foregroundColor(.white)
                        
//                        .rotationEffect(.degrees(-90))
                        
                        //                        .position(CGPoint(x: 0.0, y: 20.0))
                        
//                        .frame(width: 30, height: 30, alignment: .trailing)
                        
                        .padding(8)
                    
//                        .zIndex(2.0)
                        
                }
            })

CategoryItem 中也有更多代码,但是,只有其他视图,所有这些都在 ZStack 中。

使用上面的代码,弹出菜单,但导航link不起作用。 如您所见,我还尝试将 CategoryItem 放入 NavigationLink(注释掉的代码)中,这会导致导航link 正常工作, 但菜单只会在长按时弹出。

有人可以帮忙吗? 谢谢

P.S。整个视图是从另一个视图导航的,该视图嵌入 List,进一步嵌入 NavigationView。此外,问题出在滚动视图中,它适用于列表,但我需要水平滚动视图,所以不能使用它。

这可能是您组织视图的方式,也许 ZStack 您没有显示的内容存在冲突。

在您的代码中,NavigationLink 可能不会弹出,因为您已将其设为 EmptyView

如果您明确区分了可点击区域,您应该不会有问题。

第一个例子将省略号的可点击区域变成了一个小方块

import SwiftUI

struct NavLinkMenuView: View {
    var body: some View {
        GeometryReader{geo in
            NavigationView{
                List{
                    ForEach(0..<3){ count in
                        VStack{
                            Text("category \(count)")
                            NavLinkRowView(geo: geo)
                        }
                    }
                }.listStyle(PlainListStyle())
            }
        }
    }
}
struct NavLinkRowView: View {
    let geo: GeometryProxy
    var body: some View {
        ScrollView(.horizontal){
            HStack{
                ForEach(0..<15){ count in
                    ZStack{
                        //The the user to the next page
                        NavigationLink(destination: Text(count.description), label: {
                            Text(count.description)
                            //Make the NavigationLink take all the available space
                                .frame(maxWidth: .infinity, maxHeight: .infinity)
                            //Just to make a visible marke of the view
                                .border(Color.green, width: 2)
                        })
                        HStack{
                            Spacer()
                            //CategoryItem
                            VStack(alignment: .trailing, spacing: nil){
                                Menu(content: {
                                    Text("context menu")
                                }, label: {
                                    
                                    Image(systemName: "ellipsis")
                                    //stretch the tappable area to the ellipsis column
                                        .frame(maxWidth: .infinity, maxHeight: .infinity)
                                    
                                        .font(.subheadline)
                                        .foregroundColor(.gray)
                                        .padding(8)
                                }
                                )
                            }
                            .aspectRatio(1, contentMode: .fit)
                            //Limit the size of the ellipsis column
                            .frame(maxWidth: geo.size.width * 0.08)
                            
                            //Just to make a visible marke of the view
                            .border(Color.red)
                        }
                    }
                    //Just to make a visible marke of the view
                    .border(Color.orange)
                    //Size of the overall view
                    .frame(width: (geo.size.width - 90), height: 155)
                    //Just to make a visible marke of the view
                    .border(Color.blue)
                    .padding(.leading, 10)
                }
            }
        }
    }
}

第二个示例为省略号创建了一个可点击的列

import SwiftUI

struct NavLinkMenuView: View {
    var body: some View {
        GeometryReader{geo in
            NavigationView{
                List{
                    ForEach(0..<3){ count in
                        VStack{
                            Text("category \(count)")
                            NavLinkRowView(geo: geo)
                        }
                    }
                }.listStyle(PlainListStyle())
            }
        }
    }
}
struct NavLinkRowView: View {
    let geo: GeometryProxy
    var body: some View {
        ScrollView(.horizontal){
            HStack{
                ForEach(0..<15){ count in
                    HStack(spacing: 0){
                        //The the user to the next page
                        NavigationLink(destination: Text(count.description), label: {
                            Text(count.description)
                            //Make the NavigationLink take all the available space
                                .frame(maxWidth: .infinity, maxHeight: .infinity)
                            //Just to make a visible marke of the view
                                .border(Color.green, width: 2)
                        })
                        
                        //CategoryItem
                        VStack(alignment: .trailing, spacing: nil){
                            Menu(content: {
                                Text("context menu")
                            }, label: {
                                
                                Image(systemName: "ellipsis")
                                //stretch the tappable area to the ellipsis column
                                    .frame(maxWidth: .infinity, maxHeight: .infinity)
                                
                                    .font(.subheadline)
                                    .foregroundColor(.gray)
                                    .padding(8)
                            }
                            )
                        }
                        //Limit the size of the ellipsis column
                        .frame(maxWidth: geo.size.width * 0.08, maxHeight: .infinity)
                        
                        //Just to make a visible marke of the view
                        .border(Color.red)
                        
                    }
                    //Just to make a visible marke of the view
                    .border(Color.orange)
                    //Size of the overall view
                    .frame(width: (geo.size.width - 90), height: 155)
                    //Just to make a visible marke of the view
                    .border(Color.blue)
                    .padding(.leading, 10)
                }
            }
        }
    }
}