我有一个列表视图,列表的每一行包含一个带有某些文本视图和图像的HStack,如下所示:
HStack{
Text(group.name)
Spacer()
if (groupModel.required) { Text("Required").color(Color.gray) }
Image("ic_collapse").renderingMode(.template).rotationEffect(Angle(degrees: 90)).foregroundColor(Color.gray)
}.tapAction { self.groupSelected(self.group) }
这似乎很好用,除非当我在文本和图像(Spacer()
所在的位置)之间的空白区域中点击时,未注册点击动作。仅当我在文本或图像上点击时,点击动作才会发生。
还有其他人遇到此问题/知道解决方法吗?
答案 0 :(得分:9)
据我最近了解,还有:
HStack {
...
}
.contentShape(Rectangle())
.onTapGesture { ... }
对我来说很好。
答案 1 :(得分:3)
我可以通过将Spacer包裹在ZStack中并添加不透明度非常低的纯色来解决此问题:
ZStack {
Color.black.opacity(0.001)
Spacer()
}
答案 2 :(得分:2)
为什么不只使用Button
?
Button(action: { self.groupSelected(self.group) }) {
HStack {
Text(group.name)
Spacer()
if (groupModel.required) { Text("Required").color(Color.gray) }
Image("ic_collapse").renderingMode(.template).rotationEffect(Angle(degrees: 90)).foregroundColor(Color.gray)
}
}.foregroundColor(.primary)
如果您不希望按钮将强调色应用于Text(group.name)
,则必须像在示例中一样设置foregroundColor
。
答案 3 :(得分:2)
基于Jim的答案的简单扩展
extension Spacer {
/// https://stackoverflow.com/a/57416760/3393964
public func onTapGesture(count: Int = 1, perform action: @escaping () -> Void) -> some View {
ZStack {
Color.black.opacity(0.001).onTapGesture(count: count, perform: action)
self
}
}
}
现在可以使用
Spacer().onTapGesture {
// do something
}
答案 4 :(得分:1)
我已为此提交了feedback,并建议您也这样做。
与此同时,不透明的Color
应该和Spacer
一样工作。不幸的是,您将不得不匹配背景色,这假定您在按钮后面没有任何显示。
答案 5 :(得分:1)
我只为clear
的作品添加背景色(HStack
除外)。
HStack {
Text("1")
Spacer()
Text("1")
}.background(Color.white)
.onTapGesture(count: 1, perform: {
})
答案 6 :(得分:1)
虽然接受的答案允许模仿按钮功能,但在视觉上它并不满足。不要用 Button
或 .onTapGesture
代替 UITapGestureRecognizer
,除非您只需要一个接受手指点击事件的区域。此类解决方案被认为是陈旧的,不是好的编程实践。
要解决您的问题,您需要实施 BorderlessButtonStyle
⚠️
创建一个通用单元格,例如SettingsNavigationCell
。
struct SettingsNavigationCell: View {
var title: String
var imageName: String
let callback: (() -> Void)?
var body: some View {
Button(action: {
callback?()
}, label: {
HStack {
Image(systemName: imageName)
.font(.headline)
.frame(width: 20)
Text(title)
.font(.body)
.padding(.leading, 10)
.foregroundColor(.black)
Spacer()
Image(systemName: "chevron.right")
.font(.headline)
.foregroundColor(.gray)
}
})
.buttonStyle(BorderlessButtonStyle()) // <<< This is what you need ⚠️
}
}
struct SettingsView: View {
var body: some View {
NavigationView {
List {
Section(header: "Appearance".text) {
SettingsNavigationCell(title: "Themes", imageName: "sparkles") {
openThemesSettings()
}
SettingsNavigationCell(title: "Lorem Ipsum", imageName: "star.fill") {
// Your function
}
}
}
}
}
}
答案 7 :(得分:0)
在每个视图上都像魔术一样工作:
df[4:7] <- lapply(df[4:7], function(x) ifelse(x == 1, df$born, x))
df
#> name sex born v4 v5 v6 v7
#> 1 tim male 1985 1985 0 1985 0
#> 2 tom male 1986 0 0 0 0
#> 3 ben male 1985 1985 0 0 0
#> 4 mary female 1986 0 0 1986 0
#> 5 jane female 1984 1984 1984 1984 0
答案 8 :(得分:0)
有点本着所说的一切精神:
struct NoButtonStyle: ButtonStyle {
func makeBody(configuration: Configuration) -> some View {
configuration.label
.background(Color.black.opacity(0.0001))
}
}
extension View {
func wrapInButton(action: @escaping () -> Void) -> some View {
Button(action: action, label: {
self
})
.buttonStyle(NoButtonStyle())
}
}
我创建了 NoButtonStyle
是因为 BorderlessButtonStyle
仍然提供与 .onTapGesture
不同的动画
示例:
HStack {
Text(title)
Spacer()
Text("Select Value")
Image(systemName: "arrowtriangle.down.square.fill")
}
.wrapInButton {
isShowingSelectionSheet = true
}
另一种选择:
extension Spacer {
func tappable() -> some View {
Color.blue.opacity(0.0001)
}
}
我注意到 Color
在放入堆栈时并不总是与 Spacer
相同,所以我建议不要使用该 Spacer 扩展,除非您知道这些差异. (间隔器沿堆栈的单个方向推送(如果在 VStack
中,则垂直推送,如果在 HStack
中,则水平推出,而 Color
视图则向内推出所有方向。)