List 带NavigationLink的SwiftUI列表如何在点击时进行自定义高亮显示

List 带NavigationLink的SwiftUI列表如何在点击时进行自定义高亮显示,list,swiftui,navigationlink,List,Swiftui,Navigationlink,如何在点击时将其高亮显示的列表行上自定义覆盖。我正在使用NavigationLink,我已更改 UITableViewCell.appearance().cellSelectionStyle = .none 为了不使用默认的灰色选择 我试图在我的手机中添加一些@State isSelected,但我不知道如何/何时更改此设置以获得此效果。我试图添加ontapsignature(),但它阻止了NavigationLink,并且不提供开始、结束和刚刚结束的状态 好的,这里是该方法的一个非常简单的

如何在点击时将其高亮显示的列表行上自定义覆盖。我正在使用NavigationLink,我已更改

UITableViewCell.appearance().cellSelectionStyle = .none 
为了不使用默认的灰色选择


我试图在我的手机中添加一些
@State isSelected
,但我不知道如何/何时更改此设置以获得此效果。我试图添加
ontapsignature()
,但它阻止了NavigationLink,并且不提供开始、结束和刚刚结束的状态

好的,这里是该方法的一个非常简单的演示。其想法是将NavigationLink保留在列表之外,并在行点击时手动激活它(在没有导航链接的情况下很容易点击)。。。其他一切,如动画、效果和亮点,都取决于您

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()
    }
}
导入快捷界面
导入UIKit
结构TestCustomCellHighlight:视图{
@状态变量选择:Int=-1
@状态变量highlight=false
@状态变量showDetails=false
init(){
UITableViewCell.appearance().selectionStyle=.none
}
var body:一些观点{
导航视图{
VStack{
导航链接(目的地:文本(“详细信息\(self.selection)”),isActive:$showDetails){
EmptyView()
}
列表(0..AnyView){
如果self.highlight&&self.selection==索引{
返回任意视图(矩形().inset(by:-5).填充(颜色.红色.不透明度(0.5)))
}否则{
返回任意视图(EmptyView())
}
}
}
结构TestCustomCellHighlight\u预览:PreviewProvider{
静态var预览:一些视图{
TestCustomCellHighlight()
}
}
我是这样做的:

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))
     }
}

不错,但现在我正在考虑实施这种方法
struct ListButtonStyle: ButtonStyle {

    func makeBody(configuration: Self.Configuration) -> some View {

        configuration.label
            .overlay(configuration.isPressed ? Color("Dim").opacity(0.4) : Color.clear)
    }
}