使用按钮点击列表中的某行时,即使在按钮区域外单击也会触发操作
On tap some row in List with a button the action is triggered even clicking outside the button area
我正在创建一个包含自定义组件列表的主屏幕。这些组件是一个或多个带有导航link或按钮的点击区域,如上图:
App Home
但是不考虑点击区域,如果我点击行中的任何 space,即使它在 button/navigation link 区域之外也会触发点击
Click buttom area
代码在 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", cover: "prato-1"),
SectionItem(title: "Interessantes", cover: "prato-2"),
])
]
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, maxWidth: .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
apply action of a Button
of a row of a Button
to all row,解决问题使用只需 Text
并将操作代码放入 onTapGesture
.
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")
Text("Visualizar") // <<: here
.foregroundColor(Color.blue)
.padding(.top, 16)
.onTapGesture { print("Click") } // <<: here
}
.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, maxWidth: .infinity, alignment: .leading)
}
}
我正在创建一个包含自定义组件列表的主屏幕。这些组件是一个或多个带有导航link或按钮的点击区域,如上图:
App Home
但是不考虑点击区域,如果我点击行中的任何 space,即使它在 button/navigation link 区域之外也会触发点击
Click buttom area
代码在 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", cover: "prato-1"),
SectionItem(title: "Interessantes", cover: "prato-2"),
])
]
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, maxWidth: .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
apply action of a Button
of a row of a Button
to all row,解决问题使用只需 Text
并将操作代码放入 onTapGesture
.
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")
Text("Visualizar") // <<: here
.foregroundColor(Color.blue)
.padding(.top, 16)
.onTapGesture { print("Click") } // <<: here
}
.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, maxWidth: .infinity, alignment: .leading)
}
}