SwiftUI List with NavigationLink how to make custom highlight on tap

别说谁变了你拦得住时间么 提交于 2020-01-22 00:48:25

问题


How I can make custom overlay over List row that will highlight it on tap. I am using NaviagationLink and I've changed

UITableViewCell.appearance().cellSelectionStyle = .none 

in order to not use default gray selection.

I've tried to add some @State isSelected to my Cell but I do not know how/when to change this to get this affect. I've tried to add onTapGesture() but it prevents NavigationLink, and doesn't provide begin, ended states, just ended.


回答1:


I do it this way:

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

And ButtonStyle:

struct ListButtonStyle: ButtonStyle {

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

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



回答2:


Ok, here is very simple demo of the approach. The idea is to keep NavigationLink out of List and activate it manually on row tap (which becomes easily tappable w/o navigation link inside)... everything else, like animations, effects, and kind of highlight is up to you.

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


来源:https://stackoverflow.com/questions/59089400/swiftui-list-with-navigationlink-how-to-make-custom-highlight-on-tap

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!