SwiftUI:增加用户交互的点击/拖动区域

47
我在SwiftUI中构建了一个自定义滑块,拖动器大小为20x20。一切正常,但由于只是20x20的视图,因此点击目标相当小。我正在寻找一种方法来增加它,以使用户更容易与我的滑块交互。在SwiftUI中有一种方法可以做到这一点吗?我尝试将我的thumb包装在Color.clear.overlay中,并将框架设置为60x60。如果颜色是纯色(如red),则可以正常工作,但是使用clear时,点击目标似乎会恢复到可见像素20x20。您可以在此gif上看到,即使在拇指外面单击,我也能拖动滑块。

slider with red background

然而,一旦我将颜色更改为clear,这个区域就不再接收交互。

slider with clear background


1
在Swift UI中,透明背景是不能被触摸的,我不久前问过类似的问题 - 我建议在其后面放置一个按钮,并将其背景颜色设置为与其背后的颜色相同,而不是透明的。 - Quinn
1
我的问题参考:https://dev59.com/olMI5IYBdhLWcg3wDXDi - Quinn
这里我只展示了灰色,但我想在滑块的背景中展示多种颜色,这样它就不会是一个纯色。 - keegan3d
真遗憾 - 我认为这只是一个SwiftUI的问题,你可以提交一个错误报告,希望最终他们能够允许你点击清除按钮,但现在我不确定你能做什么。 - Quinn
另一个选择可能是添加一个背景,它在技术上并不清晰,但 Alpha 值非常低,以至于几乎不会被注意到 - 不过我不确定你能否使其完全不可见。 - Quinn
6个回答

68
frame后添加一个.contentShape(Rectangle())

是的,完全正确。因此,在上面的示例中创建20x20圆形。然后添加额外的.frame,并在此之后添加.contentShape(Rectangle())。 - Pbk
我认为值得一提的是,如果您有一个用于设置可见大小的框架,您可以添加另一个框架用于可点击区域,然后再添加contentShape。这看起来很奇怪,但如果您使用.frame.contentShape.frame,则无法正常工作,必须使用.frame.frame.contentShape。 - José Manuel Sánchez

17

我相信有很多方法可以实现这个功能,但这是我制作大按钮并使整个区域可点击的方法:

Button(action: { someAction() }, label: {
                Text("OK")
                .frame(minWidth: 200)
                .contentShape(Rectangle())
                .padding()
            })
                .background(Color.blue)
                .foregroundColor(.white)
                .cornerRadius(5.0)

5

我有同样的问题。但我不想让扩展的叠加影响到其余布局。如果您将所有内容嵌入ZStack中,并在可交互对象之前放置一个矩形,则可以控制手势的大小,类似这样:

Rectangle().frame(width: screen.width, height: 300).opacity(0.001)
                    .layoutPriority(-1)

只需确保将透明度设置为接近零,这样你就看不到它,而布局优先级设置为-1,这样它就不会影响视图。


正是我所需要的!但对我来说,我不需要费心设置layoutPriority;它并没有影响任何东西。 - wristbands

1
作为对上面答案的跟进,您可以使用此示例整天扩大可点击矩形。
ZStack {
    Image(systemName: secured ? "eye.slash" : "eye")
        .resizable()
        .renderingMode(.template)
        .aspectRatio(contentMode: .fit)
        .frame(width: 16, height: 16)

    Rectangle()
        .frame(width: 22, height: 20)
        .opacity(0.001)
        .onTapGesture {
            self.secured.toggle()
        }
}

1
将所有修饰符移动到按钮的标签中
Button {
    print("Tap")
} label: {
    Text("Button Content")
        .frame(maxWidth: .infinity, maxHeight: .infinity)
        .cornerRadius(8)

}

现在整个按钮都可以点击了

0
另一种增加按钮可点击区域的方法是对其应用.padding()修饰符。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接