简体   繁体   中英

SwiftUI button inactive inside NavigationLink item area

I have a view for a list item that displays some news cards within a navigationLink.

I am supposed to add a like/unlike button within each news card of navigationLink, without being took to NavigationLink.destination page.

It seems like a small button inside a big button. When you click that small one, execute the small one without executing the bigger one. (note: the click area is covered by the two buttons, smaller one has the priority) (In javascript, it seems like something called.stopPropaganda)

This is my code:


    var body: some View {
        NavigationView {
            List {
                ForEach(self.newsData.newsList, id:\.self) { articleID in
                    NavigationLink(destination: NewsDetail(articleID: articleID)) {
                        HStack {
                            Text(newsTitle)

                            Button(action: {
                                self.news.isBookmarked.toggle()
                            }) {
                                if self.news.isBookmarked {
                                    Image(systemName: "bookmark.fill")
                                } else {
                                    Image(systemName: "bookmark")
                                }
                            }
                        }
                    }
                }
            }
        }
    }

Currently, the button action (like/dislike) will not be performed as whenever the button is pressed, the navigationLink takes you to the destination view. I have tried this almost same question but it cannot solve this problem.

Is there a way that makes this possible?

Thanks.

as of XCode 12.3, the magic is to add.buttonStyle(PlainButtonStyle()) or BorderlessButtonStyle to the button, when said button is on the same row as a NavigationLink within a List.

Without this particular incantation, the entire list row gets activated when the button is pressed and vice versa (button gets activated when NavigationLink is pressed).

This code does exactly what you want.

struct Artcle {
  var text: String
  var isBookmarked: Bool = false
}

struct ArticleDetail: View {
  var article: Artcle
  var body: some View {
    Text(article.text)
  }
}

struct ArticleCell: View {
  var article: Artcle
  var toggle: () -> ()
  @State var showDetails = false
  var body: some View {
    HStack {
        Text(article.text)
        Spacer()
        Button(action: {
            self.toggle()
        }) {
            Image(systemName: article.isBookmarked ? "bookmark.fill" : "bookmark").padding()
        }
        .buttonStyle(BorderlessButtonStyle())
    }
    .overlay(
        NavigationLink(destination: ArticleDetail(article: article), isActive: $showDetails) { EmptyView() }
    )
    .onTapGesture {
        self.showDetails = true
    }
  }
}

struct ContentView: View {

  @State var articles: [Artcle]

  init() {
    _articles = State(initialValue: (0...10).map { Artcle(text: "Article \($0 + 1)") })
  }

  func toggleArticle(at index: Int) {
    articles[index].isBookmarked.toggle()
  }

  var body: some View {
    NavigationView {
        List {
            ForEach(Array(self.articles.enumerated()), id:\.offset) { offset, article in
                ArticleCell(article: article) {
                    self.toggleArticle(at: offset)
                }
            }
        }
    }
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM