我如何在列表行上制作自定义覆盖层以在轻击时突出显示它。我正在使用NaviagationLink并已更改
UITableViewCell.appearance().cellSelectionStyle = .none
为了避免使用默认的灰色选择,我尝试在我的单元格中添加一些 `@State isSelected`,但我不知道如何/何时更改此设置以获得所需的效果。我尝试添加 `onTapGesture()`,但它会阻止 NavigationLink,并且不提供开始、结束状态,只有结束状态。
我如何在列表行上制作自定义覆盖层以在轻击时突出显示它。我正在使用NaviagationLink并已更改
UITableViewCell.appearance().cellSelectionStyle = .none
List {
ForEach(0..<self.contacts.count) { i in
ZStack {
NavigationLink(destination: ContactDetails(contact: self.contacts[i])) {
EmptyView()
}.opacity(0)
Button(action: {}) {
ContactRow(contact: self.contacts[i])
}.buttonStyle(ListButtonStyle())
}.listRowBackground( (i%2 == 0) ? Color("DarkRowBackground") : .white)
.listRowInsets(EdgeInsets(top: 0, leading: 0, bottom: 0, trailing: 0))
}
}
而且 ButtonStyle
:
struct ListButtonStyle: ButtonStyle {
func makeBody(configuration: Self.Configuration) -> some View {
configuration.label
.overlay(configuration.isPressed ? Color("Dim").opacity(0.4) : Color.clear)
}
}
好的,这里是一个非常简单的演示方法。思路是将NavigationLink排除在List之外,并在行点击时手动激活它(这样可以轻松地进行点击而不需要在导航链接内部)......其他所有内容,如动画、效果和高亮类型都由您自己决定。
import SwiftUI
import UIKit
struct TestCustomCellHighlight: View {
@State var selection: Int = -1
@State var highlight = false
@State var showDetails = false
init() {
UITableViewCell.appearance().selectionStyle = .none
}
var body: some View {
NavigationView {
VStack {
NavigationLink(destination: Text("Details \(self.selection)"), isActive: $showDetails) {
EmptyView()
}
List(0..<20, id: \.self) { i in
HStack {
Text("Item \(i)")
Spacer()
}
.padding(.vertical, 6)
.background(Color.white) // to be tappable row-wide
.overlay(self.highlightView(for: i))
.onTapGesture {
self.selection = i
self.highlight = true
// delay link activation to see selection effect
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
self.highlight = false
self.showDetails = true
}
}
}
}
}
}
private func highlightView(for index: Int) -> AnyView {
if self.highlight && self.selection == index {
return AnyView(Rectangle().inset(by: -5).fill(Color.red.opacity(0.5)))
} else {
return AnyView(EmptyView())
}
}
}
struct TestCustomCellHighlight_Previews: PreviewProvider {
static var previews: some View {
TestCustomCellHighlight()
}
}
对我来说,@Michał Ziobro答案的这个稍微改变了的版本最好:
struct DemoView: View {
let listNames = ["Navigation1", "Navigation2", "Navigation3"]
var body: some View {
NavigationView {
List {
ForEach(listNames, id: \.self) { listName in
ZStack {
// NavigationLink tint is applied to invisible EmptyView
NavigationLink(destination: Text(listName)) {
EmptyView()
}.opacity(0)
// Button handles tint selection
Button(action: {}) {
Text(listName) // displayed list item (cell)
}
}
}
}
}
}
}
Button
,它就可以正常工作。 - user2619824.background
而不是.overlay
,因为如果使用.overlay
,则颜色会添加并与标题混合。 - StackUnderflow