SwiftUI List with NavigationLink how to make custom highlight on tap

后端 未结 2 815
不思量自难忘°
不思量自难忘° 2021-01-21 07:03

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

UITable         


        
相关标签:
2条回答
  • 2021-01-21 07:58

    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()
        }
    }
    
    0 讨论(0)
  • 2021-01-21 08:00

    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)
        }
    }
    
    0 讨论(0)
提交回复
热议问题