为啥在 SwiftUI 中点击按钮的手势甚至在它的框架之外也会被触发?
Posted
技术标签:
【中文标题】为啥在 SwiftUI 中点击按钮的手势甚至在它的框架之外也会被触发?【英文标题】:Why tap Gesture of Button get triggered even out side of it's frame in SwiftUI?为什么在 SwiftUI 中点击按钮的手势甚至在它的框架之外也会被触发? 【发布时间】:2020-12-17 02:50:03 【问题描述】:我正在测试识别 SwiftUI 中一个简单按钮的点击手势的准确性,我注意到它甚至在框架之外也被激活了!我想确保我没有弄乱按钮的标签或其他东西,在那里我构建了 2 个不同的按钮以找到任何改进,但它们都在给定框架之外触发。我制作了一个 gif 来显示问题。
gif:
代码:
struct ContentView: View
var body: some View
Spacer()
Button("tap me!")
print("you just tapped Button1!")
.font(Font.largeTitle.bold()).background(Color.red)
Spacer()
Button(action:
print("you just tapped Button2!")
, label:
Text("tap me!").font(Font.largeTitle.bold()).background(Color.red)
)
Spacer()
更新:
有人说:
点击时你看到圆圈了吗? - 它是活动点击点(一种手指)的大小,如您所见,从您自己的演示中,它与红色正方形重叠 - 因此检测到手势。就是这样
我制作了另一个 gif 来表明这样的想法是完全错误的,在这个 gif 中,即使有重叠点击也没有注册!
【问题讨论】:
点击时看到圆圈了吗? - 它是活动点击点(一种手指)的大小,如您所见,从您自己的演示中,它与红色正方形重叠 - 因此检测到手势。就是这样。 @Asperi:就这样?太简单?我不这么认为!谁设置了那个圈子?我?那个圆的半径在哪里?我怎样才能更新那个圈子?顺便说一句,我可以从视频录制设置中隐藏那个圆圈,它只是为了显示点击或点击区域。 我看不出问题出在哪里。人们不会用针点击按钮。你的指尖是 1 厘米宽。 @ElTomato:为什么 o 为什么你是这个级别的东西,兄弟?问题不在于! 【参考方案1】:我不知道为什么会发生这种情况,只是可能有一些内置功能可以在可能的情况下增加可点击区域以获得更好的用户体验?无论如何,如果您在其后面或旁边放置另一个可点击按钮,您会注意到这种情况不再发生,并且可点击区域正是您所期望的。因此,我不会担心它。但是,如果您需要将点击区域剪切到确切的帧,您可以为按钮添加一个清晰的背景,并添加一个不执行任何操作但优先于该位置的点击事件。
var body: some View
VStack
// Button behind button will take priority tap.
ZStack
Button(action:
print("tap 2")
, label:
Text("tap me!")
.padding()
.font(Font.largeTitle.bold())
.background(Color.green)
)
Button(action:
print("tap 1")
, label:
Text("tap me!")
.font(Font.largeTitle.bold())
.background(Color.red)
)
// Clear background with "fake" tap event
Button(action:
print("tap 3")
, label:
Text("tap me!")
.font(Font.largeTitle.bold())
.background(Color.red)
)
.padding()
.background(Color.black.opacity(0.001).onTapGesture
//print("tap 4")
)
【讨论】:
@nicksarno:正如你所说,我同意你的一些内置功能,这些功能可以在可能的情况下增加可点击区域以获得更好的用户体验。如果我想解释我的想法,它将是视图周围的(对我们而言)无法访问的框架,并且比实际框架大一点!但是我如何访问这个框架或停用这个框架是我的问题。 我的回答解释了为什么这不是一个真正的问题,并展示了如何将可点击区域完全限制在框架内。 这是一个真正的问题!我不必翻转我的代码来获得代码的正常行为。 什么时候会出现问题?如果有的话,这对开发人员来说是一件好事,因为它改善了用户体验。【参考方案2】:我认为这是扩展可点击区域的内置功能:
Color.red
.frame(width: 30.0, height: 30.0)
.gesture(DragGesture(minimumDistance: 0).onEnded( (value) in
// Tap with Apple Pencil: location is exactly the frame
// Tap with finger or an capacitance pen: the hit location is inaccurate
print(value.startLocation)
))
解决方案(Bug:如果视图在 ScrollView 内,这将阻止滚动手势):
let size = CGSize(width: 200.0, height: 200.0)
Color.red
.frame(width: size.width, height: size.height)
.gesture(DragGesture(minimumDistance: 0).onEnded( (value) in
print(value.startLocation)
if value.startLocation.x >= 0 && value.startLocation.y >= 0 && value.startLocation.x <= size.width && value.startLocation.y <= size.height
print("inside frame")
// action ...
else
print("outside frame")
))
【讨论】:
以上是关于为啥在 SwiftUI 中点击按钮的手势甚至在它的框架之外也会被触发?的主要内容,如果未能解决你的问题,请参考以下文章