1

I have the problem that when the user holds down the navigation link, the color of the space around the respective "cards" changes. Of course, this is not what I want. But as a total SwiftUI beginner, I do not know how to fix it. But I really want to fix this bug because it is not very innovative and irritates the user. So I would appreciate it if someone finds a solution that changes the color of the card instead of the space around it.

The space around the card changes

I suspect that my problem is because the system considers the space on the sides and the corresponding cards as one list cell. And of course, just like anywhere else in the system, these list cells are changing color when the user holds them down.

System list that changes color when the user holds it down

And my code:

import SwiftUI

struct ContentView: View {
    var body: some View {
        UITableView.appearance().separatorStyle = .none
        UITableViewCell.appearance().backgroundColor = .none

        return NavigationView {
            List {
                Cards()
                    .listRowInsets(EdgeInsets(top: 0, leading: 16, bottom: 16, trailing: 16))
                Cards()
                    .listRowInsets(EdgeInsets(top: 0, leading: 16, bottom: 16, trailing: 16))
                Cards()
                    .listRowInsets(EdgeInsets(top: 0, leading: 16, bottom: 16, trailing: 16))
            } .listStyle(GroupedListStyle()).padding(.bottom, -32) // GroupedListStyle is needed for the background color

            // Navigation bar
            .navigationBarTitle(Text("Header"))
            .navigationBarItems(
                leading:
                Button(action: { print("add") }) {
                   Image(systemName: "plus")
                },
                trailing:
                Button(action: { print("edit") }) {
                   Text("Edit")
                }.disabled(true)
            )
        }
    }
}

// For the Cards on the main screen
struct Cards: View {
    var body: some View {
        VStack(spacing: 0) {
            Image("swiftui")
                .resizable()
                .aspectRatio(contentMode: .fit)

            HStack {
                VStack(alignment: .leading, spacing: 0) {
                    Text("Title")
                        .font(.title)
                        .foregroundColor(.primary)
                        .lineLimit(3)
                    Text("Subtitle")
                        .font(.caption)
                        .foregroundColor(.secondary)
                }
                .layoutPriority(100)

                Spacer()

                NavigationLink(destination: EmptyView()) {
                    EmptyView()
                }.opacity(0) // Hiding the default navigation bar chavron

                Image(systemName: "chevron.right")
                    .foregroundColor(.secondary)
                    .font(Font.body.weight(.semibold))
            }
            .padding(.all, 16)
            .background(Color("CustomCardBackgroundColor")) // This is a custom color set
        }
        .cornerRadius(10)
        .overlay(
            RoundedRectangle(cornerRadius: 10)
                .stroke(Color(.sRGB, red: 150/255, green: 150/255, blue: 150/255, opacity: 0.1), lineWidth: 1)
        )
    }
}
Mattis Schulte
  • 639
  • 1
  • 10
  • 18

2 Answers2

4

This is due to the design of List; when you click on a row, the whole row is highlighted. This is not a configurable setting, at least at this point.

One option would be to replace List { ... } with ScrollView { VStack { ... } }. This would also require you to move your NavigationLink to the top level of your Card view, set a PlainButtonStyle on the NavigationLink so it doesn't turn your image blue, and add some padding around the edges.

Note that you will have trouble setting a background color behind the cells. Here are a couple questions that try to address it, but I could not successfully combine any of those methods with your views. For now, you will probably just have to pick which you like better: custom background color, or tap coloration only being applied to the cards.

struct StackOverflowTests: View {
    var body: some View {

        return NavigationView {
            // CHANGED THIS
            ScrollView {
                VStack {
                    Cards()
                    Cards()
                    Cards()
                }.padding(.horizontal)
            }

            // Navigation bar
            .navigationBarTitle(Text("Header"))
            .navigationBarItems(
                leading:
                Button(action: { print("add") }) {
                    Image(systemName: "plus")
                },
                trailing:
                Button(action: { print("edit") }) {
                    Text("Edit")
                }.disabled(true)
            )
        }
    }
}

and

// For the Cards on the main screen
struct Cards: View {
    var body: some View {
        // MOVED THIS
        NavigationLink(destination: EmptyView()) {
            VStack(spacing: 0) {
                Image("swiftui")
                    .resizable()
                    .aspectRatio(contentMode: .fit)

                HStack {
                    VStack(alignment: .leading, spacing: 0) {
                        Text("Title")
                            .font(.title)
                            .foregroundColor(.primary)
                            .lineLimit(3)
                        Text("Subtitle")
                            .font(.caption)
                            .foregroundColor(.secondary)
                    }
                    .layoutPriority(100)

                    Spacer()

                    Image(systemName: "chevron.right")
                        .foregroundColor(.secondary)
                        .font(Font.body.weight(.semibold))
                }
                .padding(.all, 16)
                    .background(Color("CustomCardBackgroundColor")) // This is a custom color set
            }
            .cornerRadius(10)
            .overlay(
                RoundedRectangle(cornerRadius: 10)
                    // ATTENTION NEEDED: You will probably need to make this border darker/wider
                    .stroke(Color(.sRGB, red: 150/255, green: 150/255, blue: 150/255, opacity: 0.1), lineWidth: 1)
            )
        }
            // ADDED THIS
            .buttonStyle(PlainButtonStyle())
    }
}
John M.
  • 8,892
  • 4
  • 31
  • 42
  • Thanks, it works great. I just had to fix a little problem that has shifted the scroll indicator to the left. But otherwise, it works surprisingly well. – Mattis Schulte Nov 19 '19 at 21:05
  • Changing the background color was actually pretty easy ```UIScrollView.appearance().backgroundColor = UIColor.red``` – Mattis Schulte Nov 19 '19 at 21:23
  • Thanks for the great answer. Hard to believe that List was actually released in its current state as it's pretty much useless for any kind of work, except some simple tutorials... – vfxdev Apr 01 '20 at 17:10
0

this happens because of your padding

.padding(.bottom, -32) 

on the list.

Chris
  • 7,579
  • 3
  • 18
  • 38
  • No, the negative padding is just for deleting the space under the List that is created by the GroupedListStyle. I guess that my problem arises because the system considers the space on the sides and the respective cards as one list cell. So if I could find a way to sign the gaps to the respective list cells. I suspect that my problem would be solved. – Mattis Schulte Nov 19 '19 at 11:33
  • just delete it and you will see the selection is ok then – Chris Nov 19 '19 at 12:01
  • No, this was unfortunately not the solution to my problem. But I changed my question a bit because I thought it was a bit misleading. – Mattis Schulte Nov 19 '19 at 17:54