如何在 SwiftUI 中删除列表选择指示器和分隔符?

Posted

技术标签:

【中文标题】如何在 SwiftUI 中删除列表选择指示器和分隔符?【英文标题】:How to remove List selection indicator and separator in SwiftUI? 【发布时间】:2019-08-20 07:46:53 【问题描述】:

我在 ScrollView 中编写了一个 List,当我选择一个 List 单元格以转换到另一个视图并返回时,单元格选定指示器在选择后没有消失。 我希望在选择列表单元格后,选择的指示器应该消失。

我调试了一下,发现ScrollView在和List配合的时候出现了一些问题。如果没有ScrollView,列表选择行为是可以的,如果加上列表外的ScrollView,问题就变成了。

另一个问题是如何删除列表分隔符。

感谢您的帮助!!!

@State var valueData: [String] = ["Apple", "Pear", "Orange", "Cake"]
var body: some View 
    NavigationView 
        ScrollView(.vertical) 
            VStack(spacing: 10) 
                DietListView(valueData: self.$valueData)
                DietListView(valueData: self.$valueData)
                .padding()


            

        
        .frame(width: 352)
    



struct DietListView: View 
    @Binding var valueData: [String]

    var body: some View 
        VStack 
            List 
                ForEach(self.valueData, id: \.self)  item in
                    NavigationLink(destination: DietItemDetailView()) 
                        HStack 
                            Text(item)
                            Spacer()
                            Text("100")
                        
                    

                
                .onDelete  index in
                    self.valueData.remove(at: index.first!)
                
            
            .frame(height: 300)

        
        .frame(width: 352, height: 350)
        .background(Color.white)
        .cornerRadius(16)
        .shadow(radius: 10)
    

问题是这样的:

【问题讨论】:

【参考方案1】:

目前(SwiftUI Beta 5)您无法自定义List 的变化很大,例如分隔线样式。根据您的需要,您可以做的是将ScrollViewForEach 一起使用,并为单元格提供您想要的样式。例如:

struct ContentView: View 
    @State var valueData: [String] = ["Apple", "Pear", "Orange", "Cake"]
    var body: some View 
        NavigationView 
            ScrollView(.vertical) 
                VStack(spacing: 10) 
                    DietListView(valueData: self.$valueData)
                    DietListView(valueData: self.$valueData)
                    .padding()


                

            
            .frame(width: 352)
        

    


struct DietListView: View 
    @Binding var valueData: [String]

    var body: some View 
        VStack 
            ScrollView 
                ForEach(self.valueData, id: \.self)  item in
                    NavigationLink(destination: Text("ciao")) 
                        HStack 
                            Text(item)
                            Spacer()
                            Text("100")
                        
                        .foregroundColor(.primary)
                        .padding(10)
                    

                
            
            .frame(height: 300)
        
        .frame(width: 352, height: 350)
        .background(Color.white)
        .cornerRadius(16)
        .shadow(radius: 10)
    


#if DEBUG
struct ContentView_Previews: PreviewProvider 
    static var previews: some View 
        ContentView()
    

#endif

另外,看看这个:https://***.com/a/56498261/1291872

编辑:您只能在List 中使用onDeleteonMoveonInsert。如果你想让用户删除ScrollView 中的一行,你必须自己实现一些东西。看看下面的代码,看一个简单(相当丑陋)的例子:

struct ContentView: View 
    @State var valueData: [String] = ["Apple", "Pear", "Orange", "Cake"]
    var body: some View 
        NavigationView 
            ScrollView(.vertical) 
                VStack(spacing: 10) 
                    DietListView(valueData: self.$valueData)
                    DietListView(valueData: self.$valueData)
                    .padding()
                
            
            .frame(width: 352)
        
    

struct DietListView: View 
    @Binding var valueData: [String]
    var body: some View 
        VStack 
            ScrollView 
                ForEach(self.valueData.indices, id: \.self)  idx in
                    NavigationLink(destination: Text("ciao")) 
                        HStack 
                            Text(self.valueData[idx])
                            Spacer()
                            Text("100")
                                .padding(.trailing, 20)
                            Button(action: 
                                self.valueData.remove(at: idx)
                            ) 
                                Image(systemName: "xmark.circle")
                                    .resizable()
                                    .frame(width: 25, height: 25)
                                    .foregroundColor(Color.red)
                            
                        
                        .foregroundColor(.primary)
                        .padding([.leading, .trailing], 20)
                        .padding([.top, .bottom], 10)
                    
                
            
            .frame(height: 300)
        
        .frame(width: 352, height: 350)
        .background(Color.white)
        .cornerRadius(16)
        .shadow(radius: 10)
    


#if DEBUG
struct ContentView_Previews: PreviewProvider 
    static var previews: some View 
        ContentView()
    

#endif

【讨论】:

首先,非常感谢。那么如何使用像“onDelete”这样的修饰符来处理ScrollView。我试过了,但它不像 List 行为那样工作。这是我必须使用 List 的主要原因。 @Alexweng 看看我的编辑。我想指出一件事:我不知道这是否正是您想要的,但是由于您将相同的数组传递给所有 DietListView,因此从 DietListView 中删除一个元素实际上会删除所有其他元素DietListView 也是如此。 非常感谢。你的编辑是我想要的。上行代码只是用于描述我的问题的演示。实际上,我只想要一个待办事项列表之类的东西,例如可以删除、移动列表单元格等。你的编辑给了我灵感。

以上是关于如何在 SwiftUI 中删除列表选择指示器和分隔符?的主要内容,如果未能解决你的问题,请参考以下文章

如何着色/删除 SwiftUI 列表中最后一行和倒数第二行之间的分隔符?

点击 SwiftUI 时从列表中删除

如何更改 SwiftUI 列表中分隔符的颜色?

在 swiftUI 列表中添加、选择和删除文件名 - MacOS

在 macOS 上的 SwiftUI 列表视图中选择和删除核心数据实体

没有 NavigationLink 的 SwiftUI 列表披露指示器