【问题标题】:How to remove highlight on tap of List with SwiftUI?如何使用 SwiftUI 删除列表中的突出显示?
【发布时间】:2019-10-25 23:29:32
【问题描述】:

如何使用 SwiftUI 移除 List 的高亮显示?

List {

}.whatModifierToAddHere?

selection manager documentation 什么也没说。

【问题讨论】:

  • 运气好能找到前进的道路吗?我也坚持这个!
  • 我最终使用了 ScrollView 而不是 List。 scrollView 就像一个准系统列表。您必须自己制作所有额外的东西,这对我有好处。
  • @Justacoder 谢谢!!!!!!
  • @Justacoder 我在使用 Scrollview 时也遇到了同样的问题(iOS 14)。这个线程中到处提到的.buttonStyle(PlainButtonStyle())“解决方案”不起作用。它只是在滚动或正常按钮单击期间降低突出显示效果。
  • 我只花了大约两天时间,首先推断这是问题所在,然后在这里和其他地方尝试了各种方法来尝试解决它。我在 Xcode 12.5.1 上。大多数都没有任何效果,尽管也许我用错了。对我有用的是在行视图上放置一个 onTapGesture() 。也许这个拦截导致该行被选中。现在适合我,因为我不想要任何意外选择,但我可能还没有走出困境

标签: ios swiftui


【解决方案1】:

我知道我来晚了,但它是为那些正在搜索的人准备的(比如我?)

我发现了什么

我想你应该看看How to disable the overlay color for images inside Button and NavigationLink来自@TwoStraws的短文

只需将.buttonStyle(PlainButtonStyle()) 修饰符添加到List 中的项目,你就会得到你想要的。也让Buttons在List中再次工作,这是我遇到的另一个问题。

Swift 5.1 的工作示例:

import Combine
import SwiftUI

struct YourItem: Identifiable {
    let id = UUID()
    let text: String
}

class YourDataSource: ObservableObject {
    let willChange = PassthroughSubject<Void, Never>()
    var items = [YourItem]()

    init() {
        items = [
            YourItem(text: "Some text"),
            YourItem(text: "Some other text")
        ]
    }
}

struct YourItemView: View {
    var item: YourItem

    var body: some View {
        VStack(alignment: .leading) {
            Text(item.text)
            HStack {
                Button(action: {
                    print("Like")
                }) {
                    Image(systemName: "heart.fill")
                }
                Button(action: {
                    print("Star")
                }) {
                    Image(systemName: "star.fill")
                }
            }
        }
        .buttonStyle(PlainButtonStyle())
    }
}

struct YourListView: View {
    @ObservedObject var dataSource = YourDataSource()

    var body: some View {
        List(dataSource.items) { item in
            YourItemView(item: item)
        }
        .navigationBarTitle("List example", displayMode: .inline)
        .edgesIgnoringSafeArea(.bottom)
    }
}

#if DEBUG
struct YourListView_Previews: PreviewProvider {
    static var previews: some View {
        YourListView()
    }
}
#endif

正如文章中所说,它也适用于NavigationLinks。我希望它对你们中的一些人有所帮助??

【讨论】:

  • 此解决方案不适用于 XCode 11.3.1,点击列表项时仍会出现选择,我使用的项目是 ZStack
  • 您确定将修饰符直接应用于列表项(而不是子视图)吗?如果是这样,我会尝试并告诉你我是否有同样的问题??
  • 两种方法都试过了,但同样的问题发生了,把我的列表放在导航视图中
  • 选择仍然出现在初始点击时,但通过此修复,它在从 NavigationLink 返回(即“返回”)时取消选择,这是我主要想要修复的。
【解决方案2】:

简单回答你的问题。任何您不想在点击时突出显示的单元格只需添加此修饰符

.buttonStyle(PlainButtonStyle())

因此修饰符不是针对整个列表,而是针对内部的每个单元格

var body: some View{
    List{
        ForEach(self.getElementsForList()){ element in
            ElementCell(element: element)
                .buttonStyle(PlainButtonStyle())
        }
    }
}

【讨论】:

    【解决方案3】:

    我知道我来晚了,但希望这能解决您的问题。 您需要使用 UIKit 修饰符来删除它。我建议你把它们放在SceneDelegate.swift

    class SceneDelegate: UIResponder, UIWindowSceneDelegate {
    
        var window: UIWindow?
    
    
        func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
            // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
            // If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
            // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
    
            // Create the SwiftUI view that provides the window contents.
            let contentView = TabController()
    
            // Use a UIHostingController as window root view controller.
            if let windowScene = scene as? UIWindowScene {
    
                //MARK: Disable selection.
                UITableView.appearance().allowsSelection = false
                UITableViewCell.appearance().selectionStyle = .none
    
                let window = UIWindow(windowScene: windowScene)
                window.rootViewController = UIHostingController(rootView: contentView)
                self.window = window
                window.makeKeyAndVisible()
    
            }
        }
    }
    

    EDIT:这将禁用您应用中的所有表格视图选择。相反,如果您想禁用特定表视图上的选择,可以在 init() 中禁用它。

    struct SomeViewWithTableView: View {
    
        init() {
            //MARK: Disable selection.
            UITableView.appearance().allowsSelection = false
            UITableViewCell.appearance().selectionStyle = .none
        }
    
        var body: some View {
            //your view code here
        }
    }
    

    【讨论】:

    • 我可以确认这是可行的,我什至不知道 SwiftUI 的 List 只是一个 UITableView 包装器!
    • 您可以在视图本身中禁用基于视图的选择。像这样: init() { UITableView.appearance().allowsSelection = false UITableViewCell.appearance().selectionStyle = .none }
    • 是否有适用于 ScrollViews 的版本?他们似乎没有响应 TableView 设置。
    • UITableViewCell.appearance().selectionStyle = .none 对我来说已经足够了。
    【解决方案4】:

    只是将.buttonStyle(PlainButtonStyle()) 修饰符添加到列表中的项目,不幸的是不适用于我的情况。 相反,我能够通过使用 List 上的 .onAppear() 修饰符和 UITableViewCell 的 Appearance API 来获得所需的效果——点击一行时看不到任何突出显示效果。

    如下例:

    List {
        ForEach(items) { item in
            NavigationLink(destination: DetailView(item)) {
                RowView(item)
            }
        }
    }
    .onAppear {
    
        // this will disable highlighting the cell when is selected
        UITableViewCell.appearance().selectionStyle = .none
    
        // you can also remove the row separators
        UITableView.appearance().separatorStyle = .none
    
    }
    

    【讨论】:

    • 在 iOS 15 中不起作用
    【解决方案5】:

    编辑:

    仅当 SwiftUI 视图嵌入在 UIKit 父级中时,以下内容才有效。



    对于任何仍然想知道的人,您可以使用 .onAppear 修饰符来实现这一点。

    .onAppear {
                UITableViewCell.appearance().selectionStyle = .none
        }
    

    这类似于 UIKit 中的 viewWillAppear。 来源:HackingWithSwift

    【讨论】:

    • 刚刚签入一个新项目,你是对的,它不起作用。所以我检查了我使用它的原始项目,结果它在不同的环境中工作。我在 Scrollview 中嵌入了一个 SwiftUI 视图,因为我需要一个拉动来刷新功能。这可能就是为什么它对我有用,因为在这种情况下它使用 UIKit api。无法使用纯 SwiftUI 方法使其工作。
    【解决方案6】:

    一种可能的解决方案是使用 ZStack。并将插图调整为 .zero。将 Color.red 更改为您的颜色。 你的清单:

    ForEach(items) { item in
        ZStack {
            NavigationLink(destination: DetailView()) {
                EmptyView()
            }
            ItemRowWrap(item: item)
                .background(Color.red)
        }
        
    }
    .listStyle(InsetListStyle())
    .listRowInsets(EdgeInsets(top: 0, leading: 0, bottom: 0, trailing: 0))
    

    您的 ItemRowView:

    struct ItemRowWrap: View {
        
        let item: ListItem
        
        var body: some View {
            ItemRow(item: item)
                .padding(EdgeInsets(top: 5, leading: 8, bottom: 5, trailing: 8))
        }
        
    }
    

    您可以根据需要调整填充。

    【讨论】:

      【解决方案7】:

      Assets.xcassets 中的全局AccentColor 设置为如下所述

      【讨论】:

        【解决方案8】:

        我遇到了同样的问题,我认为这是一个错误。

        如果我将文本放在列表顶部,则导航链接项将突出显示;

        如果我删除它或将它放在列表下面,导航链接项将不会突出显示。

        VStack {
            Text("Some word") // Remove it or put it below List
            List {
                NavigationLink(destination: RedirectionFromList(data: data.first!)) {
                    Text("test")
                }
            }
            
        }
        

        如果将文本放在列表的顶部,我找不到关闭突出显示的方法,非常恼火。

        【讨论】:

        • 最后,我将Text作为一个item放入List中。
        • 在 iOS 15 中不起作用
        【解决方案9】:
        .onDisappear {
            UITableViewCell.appearance().isSelected = false
        }
        

        当界面消失或出现时,您可以将 selected 设置为 false。

        【讨论】:

          猜你喜欢
          • 2020-11-18
          • 1970-01-01
          • 2016-12-08
          • 2021-05-03
          • 1970-01-01
          • 1970-01-01
          • 2011-08-31
          • 1970-01-01
          • 2014-01-02
          相关资源
          最近更新 更多