问题描述
我正在创建一个包含自定义组件列表的主屏幕。这些组件是一个或多个带有导航链接或按钮的点击区域,如上图:
但不尊重点击区域,如果我点击行中的任何空间,即使它在按钮/导航链接区域之外,也会触发点击
代码在 https://github.com/isaquedev/swiftui-list-click-bug 中可用,如下所示:
import SwiftUI
struct ContentView: View {
var items: [HomeSection] = [
HomeSection(title: "Mais próximos",type: .nearest),HomeSection(title: "",type: .list,items: [
SectionItem(title: "Românticos",cover: "prato-1"),SectionItem(title: "Especiais",cover: "prato-2"),SectionItem(title: "Agradáveis",SectionItem(title: "Interessantes",])
]
var body: some View {
VList {
ForEach(items) { item in
switch item.type {
case .nearest:
NearestCell(title: item.title)
case .list:
ListCell(items: item.items ?? [])
}
}
}
}
}
VList
import SwiftUI
struct VList<Content:View>: View {
var content: () -> Content
var body: some View {
if #available(iOS 14.0,*) {
ScrollView {
Lazyvstack(spacing: 0) {
content()
}
}
} else {
List {
content()
.padding(.horizontal,-20)
}
.onAppear {
UITableView.appearance().separatorStyle = .none
UITableViewCell.appearance().selectionStyle = .none
}
}
}
}
最近单元
import SwiftUI
struct NearestCell: View {
var title: String
var body: some View {
vstack(alignment: .leading) {
Text(title)
.font(.title)
.padding(.bottom,16)
vstack {
Text("Veja restaurantes a sua volta")
Button(action: {
print("Click")
},label: {
Text("Visualizar")
})
.padding(.top,16)
}
.frame(idealWidth: .infinity,maxWidth: .infinity,alignment: .center)
.padding(.vertical,16)
.overlay(
RoundedRectangle(cornerRadius: 12)
.stroke(Color.black,linewidth: 1)
)
}
.padding(.all,16)
.frame(idealWidth: .infinity,alignment: .leading)
}
}
列表单元
import SwiftUI
struct ListCell: View {
var items: [SectionItem]
var body: some View {
vstack(alignment: .leading) {
Text("Categorias")
.font(.title)
ScrollView(.vertical,showsIndicators: false) {
HStack {
ForEach(items) { item in
vstack {
Image(item.cover)
.resizable()
.scaledToFill()
.frame(width: 80,height: 80,alignment: .center)
.clipped()
Text(item.title)
}
}
}
}
.frame(height: 113)
}
.padding(.all,16)
}
}
首页部分
enum HomeSectionType {
case nearest,list
}
class HomeSection: Identifiable {
let id = UUID()
var title: String
var type: HomeSectionType
var items: [SectionItem]?
init(title: String,type: HomeSectionType,items: [SectionItem]? = nil) {
self.title = title
self.type = type
self.items = items
}
}
部分项目
class SectionItem: Identifiable {
let id = UUID()
var title: String
var cover: String
init(title: String,cover: String) {
self.title = title
self.cover = cover
}
}
解决方法
你的代码没有问题,都是因为List
,List
将一行的Button
的动作应用到所有行,解决问题只需使用{ {1}} 并将操作代码放在 Text
中。
onTapGesture