11

点击时列表行的默认颜色为灰色。

我知道如何使用 .listRowBackground 更改背景颜色,但随后它会更改为整个列表。

点击时如何更改为自定义颜色,以便只有点击的行保持红色?

import SwiftUI

struct ExampleView: View {
    @State private var fruits = ["Apple", "Banana", "Grapes", "Peach"]

    var body: some View {
        NavigationView {
            List {
                ForEach(fruits, id: \.self) { fruit in
                    Text(fruit)
                }
                .listRowBackground(Color.red)

            }


        }
    }


}

struct ExampleView_Previews: PreviewProvider {
    static var previews: some View {
        ExampleView()
    }
}

在此处输入图像描述

4

6 回答 6

16

首先,您希望行上的 .ListRowBackground 修饰符不是整个列表,然后使用它有条件地设置每行的行背景颜色。如果将点击行的 ID 保存在 @State 变量中,则可以根据选择状态将该行设置为红色或默认颜色。这是代码:

import SwiftUI

struct ContentView: View {
    @State private var fruits = ["Apple", "Banana", "Grapes", "Peach"]
    @State private var selectedFruit: String?

    var body: some View {
        NavigationView {
            List {
                ForEach(fruits, id: \.self) { fruit in
                    Text(fruit)
                        .onTapGesture {
                            self.selectedFruit = fruit
                    }
                    .listRowBackground(self.selectedFruit == fruit ? Color.red : Color(UIColor.systemGroupedBackground))
                }
            }
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}
于 2019-12-16T05:21:55.303 回答
5

关注@Chuck H,

我在用着:

        List {
            ForEach(viewModel.sharingGroups, id: \.self) { group in
                Button(action: {
                    self.selectedGroup = group
                }, label: {
                    Text(group.name)
                })
                .listRowBackground(self.selectedGroup == group ? Color.gray : Color(UIColor.systemGroupedBackground))
            }
        }

如果您直接使用按钮而不是文本,这使我能够点击行上的任意位置,而不仅仅是文本。

于 2020-10-05T01:29:47.957 回答
2

如果您正在为 iOS 上的样式目的寻找替代方案并且不想引入状态管理,因为列表由 UITableView 支持,您可以使用

UITableViewCell.appearance().selectedBackgroundView = UIView()

完全删除选择颜色。或者:

UITableViewCell.appearance().selectedBackgroundView = {
            let view = UIView()
            view.backgroundColor = .blue
            return view
        }()

设置特定的高亮颜色

请注意,这适用于整个应用程序,并且仅适用于支持 UITableView 的平台,因此 MacOS 或 WatchOS 需要另一种解决方案。

于 2021-01-17T02:32:33.920 回答
0

不完美但有效,如果您有改进,请发表评论:

struct CustomNavigationLink<ContentView: View, DestinationView: View>: View {

    let content: () -> ContentView
    let destinationView: () -> DestinationView
    @State private var showDetail = false
    @State private var isTouchDown = false

    var body: some View {
        ZStack(alignment: .leading) {
            Color(.red)
                .opacity(isTouchDown ? 0.3 : 0)
            HStack {
                content()
                Spacer()
                NavigationLink(destination: destinationView(),
                               isActive: self.$showDetail) { EmptyView() }
                               .hidden()
                               .frame(width: 0)
                Image(systemName: "chevron.right")
                    .foregroundColor(.red)
            }
            .contentShape(Rectangle())
            .onTapGesture {
                showDetail = true
            }
            ._onButtonGesture { isTouchDown in
                withAnimation {
                    self.isTouchDown = isTouchDown
                }
            } perform: {}
        }
    }
}
于 2021-12-21T00:09:38.147 回答
0

Apple 在 SwiftUI 中遇到了一些愚蠢的事情。在把我的头撞到墙上之后,我终于取得了一些成功。只需添加一个 Zstack 和 Empty Button。

var body: some View {
    List {
        ForEach(data, id: \.self) { item in
            ZStack {
                Button("") {}
                NavigationLink(destination: ItemView(item: item)) {
                    ItemRow(item: item)
                }
            }
        }
    }
}

于 2021-08-20T12:34:13.783 回答
0

这是改进的优雅解决方案,没有按钮,整行都是可点击的。也适用于 iOS13。

@ObservedObject var viewModel: TypesListViewModel
@State private var selectedType: Type?   

 List{
       ForEach(viewModel.types, id: \.id){ type in
            TypeRowView(type: type)
                 .contentShape(Rectangle()) //makes whole row tappable
                 .onTapGesture {
                      selectedType = type
                     }
                 .listRowBackground(selectedType == type ? Color(.systemFill) : Color(.systemBackground))
           }//ForEach
       }//List
于 2021-11-26T11:30:17.640 回答