Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
922 views
in Technique[技术] by (71.8m points)

ios - SwiftUI List Button with Disclosure Indicator

I have a SwiftUI view that consists of a list with some items. Some of these are links to other screens (so I use NavigationLink to do this) and others are actions I want to perform on the current screen (E.g. button to show action sheet).

I am looking for a way for a Button in a SwiftUI List to show with a disclosure indicator (the chevron at the right hand sign that is shown for NavigationLink).

Is this possible?

E.g.

struct ExampleView: View {
    @State private var showingActionSheet = false
    
    var body: some View {
        NavigationView {
            List {
                NavigationLink("Navigation Link", destination: Text("xx"))
                Button("Action Sheet") {
                    self.showingActionSheet = true
                }
                .foregroundColor(.black)
            }
            .listStyle(GroupedListStyle())
            .actionSheet(isPresented: $showingActionSheet) {
                ActionSheet(title: Text("Title"), buttons: [
                    .default(Text("Do Something")) {  },
                    .cancel()
                ])
            }
        }
    }
}

Current Behaviour:

Current Behaviour

Wanted Behaviour:

Wanted Behaviour

question from:https://stackoverflow.com/questions/65836990/swiftui-list-button-with-disclosure-indicator

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

My answer uses the SwiftUI-Introspect framework, used to:

Introspect underlying UIKit components from SwiftUI

In this case, it is used to deselect the row after the NavigationLink is pressed.

I would think a button with the normal accent color and without the NavigationLink be more intuitive to a user, but if this is what you need, here it is. The following answer should work for you:

import Introspect
import SwiftUI


struct ExampleView: View {
    
    @State private var showingActionSheet = false
    @State private var tableView: UITableView?
    
    var body: some View {
        NavigationView {
            List {
                NavigationLink("Navigation Link", destination: Text("xx"))
                
                NavigationLink(
                    destination: EmptyView(),
                    isActive: Binding<Bool>(
                        get: { false },
                        set: { _ in
                            showingActionSheet = true
                            
                            DispatchQueue.main.async {
                                deselectRows()
                            }
                        }
                    )
                ) {
                    Text("Action Sheet")
                }
            }
            .introspectTableView { tableView = $0 }
            .listStyle(GroupedListStyle())
            .actionSheet(isPresented: $showingActionSheet) {
                ActionSheet(title: Text("Title"), buttons: [
                    .default(Text("Do Something")) {  },
                    .cancel()
                ])
            }
        }
    }
    
    private func deselectRows() {
        if let tableView = tableView, let selectedRow = tableView.indexPathForSelectedRow {
            tableView.deselectRow(at: selectedRow, animated: true)
        }
    }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...