SwiftUI:如何更改用户按住导航链接或按钮等内容时发生的颜色变化?

Posted

技术标签:

【中文标题】SwiftUI:如何更改用户按住导航链接或按钮等内容时发生的颜色变化?【英文标题】:SwiftUI: How can I change the color change that occurs when the user holds down something like a navigation link or a button? 【发布时间】:2019-11-19 08:44:01 【问题描述】:

我遇到的问题是,当用户按住导航链接时,各个“卡片”周围的空间颜色会发生变化。当然,这不是我想要的。但作为一个完全的 SwiftUI 初学者,我不知道如何修复它。但是我真的很想修复这个错误,因为它不是很有创新性并且会激怒用户。因此,如果有人找到改变卡片颜色而不是周围空间的解决方案,我将不胜感激。

我怀疑我的问题是因为系统将侧面的空间和相应的卡片视为一个列表单元格。当然,就像系统中的其他任何地方一样,当用户按住这些列表单元格时,它们会改变颜色。

还有我的代码:

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

【问题讨论】:

【参考方案1】:

这是由于List的设计;当您单击一行时,整行都会突出显示。这不是可配置的设置,至少目前是这样。

一种选择是将List ... 替换为ScrollView VStack ... 。这还需要您将NavigationLink 移动到Card 视图的顶层,在NavigationLink 上设置PlainButtonStyle,这样它就不会将您的图像变成蓝色,并在边缘添加一些填充。

请注意,您将无法在单元格后面设置背景颜色。这里有一个 couple questions 试图解决它,但我无法成功地将这些方法与您的观点结合起来。目前,您可能只需要选择您更喜欢的:自定义背景颜色,或仅应用于卡片的点按颜色。

struct ***Tests: 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)
            )
        
    

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

【讨论】:

谢谢,效果很好。我只需要解决一个将滚动指示器向左移动的小问题。但除此之外,它的效果出奇的好。 改变背景颜色其实很简单UIScrollView.appearance().backgroundColor = UIColor.red 感谢您的出色回答。很难相信 List 实际上是以其当前状态发布的,因为除了一些简单的教程之外,它对于任何类型的工作都几乎没有用......【参考方案2】:

这是因为您的填充而发生的

.padding(.bottom, -32) 

在名单上。

【讨论】:

不,负填充只是为了删除由GroupedListStyle创建的List下的空间。我想我的问题出现是因为系统将侧面的空间和相应的卡片视为一个列表单元格。因此,如果我能找到一种方法来签署相应列表单元格的空白。我怀疑我的问题会得到解决。 删除它,你会看到选择没问题 不,不幸的是,这不是我的问题的解决方案。但我稍微改变了我的问题,因为我认为这有点误导。

以上是关于SwiftUI:如何更改用户按住导航链接或按钮等内容时发生的颜色变化?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 SwiftUI 的按钮中添加导航按钮链接?

更改导航按钮 SwiftUI 的颜色

SwiftUI 如何创建一个将项目添加到包含导航链接的列表的按钮

导航链接在 SwiftUI 中只能使用一次

如何在 SwiftUI 列表中设置 NavigationLink

包含按钮的 SwiftUI 导航链接