Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to remove highlight on tap of List with SwiftUI?

Tags:

ios

swiftui

How to remove highlight on tap of List with SwiftUI?

List {

}.whatModifierToAddHere?

The selection manager documentation doesnt say anything about it.

like image 971
Just a coder Avatar asked Jun 11 '19 13:06

Just a coder


6 Answers

I know I'm a bit late, but it's for those of you who are searching (like me 😇)

What I found

I guess you should take a look at the short article How to disable the overlay color for images inside Button and NavigationLink from @TwoStraws

Just add the .buttonStyle(PlainButtonStyle()) modifier to your item in the List and you'll have what you wanted. It also makes the Buttons work again in the List, which is another problem I encountered.

A working example for 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

As said in the article, it also works with NavigationLinks. I hope it helped some of you 🤞🏻

like image 76
Rémi B. Avatar answered Oct 19 '22 17:10

Rémi B.


Simple answer to you question. Any cell that you don't want to highlight when tapped just add this modifier

.buttonStyle(PlainButtonStyle())

Therefore the modifier is not for the whole List is for each cell inside

var body: some View{
    List{
        ForEach(self.getElementsForList()){ element in
            ElementCell(element: element)
                .buttonStyle(PlainButtonStyle())
        }
    }
}
like image 27
Julio Bailon Avatar answered Oct 19 '22 16:10

Julio Bailon


I know I'm a bit late but hope this will solve your problem. You need to use UIKit modifiers to remove this. I recommend you to place them on 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: This will disable all table view selections in your app. If instead, you want to disable the selection on a specific table view, you can disable it inside init().

struct SomeViewWithTableView: View {

    init() {
        //MARK: Disable selection.
        UITableView.appearance().allowsSelection = false
        UITableViewCell.appearance().selectionStyle = .none
    }

    var body: some View {
        //your view code here
    }
}
like image 16
iAlex11 Avatar answered Oct 19 '22 15:10

iAlex11


.listRowBackground worked for me

List {
   ListItem()
       .listRowBackground(Color.clear)
}
like image 5
Nico Cobelo Avatar answered Oct 19 '22 17:10

Nico Cobelo


Just adding the .buttonStyle(PlainButtonStyle()) modifier to the item in the List, unfortunately didn't work for my case. Instead I was able to obtain the desired effect -- not seeing any highlighting effect when tapping on a row -- by using the .onAppear() modifier on the List and the Appearance API for UITableViewCell.

As in the following example:

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

}
like image 2
Aleph_0 Avatar answered Oct 19 '22 17:10

Aleph_0


This needs different approaches depending on the iOS.

For iOS 14:

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

For iOS 15:

List {
   ListItem()
       .listRowBackground(Color.clear)
}
like image 2
Vkharb Avatar answered Oct 19 '22 16:10

Vkharb