SwiftUI Tips: clipped()后hit testing区域不会变

使用 clipped() 裁切视图后,虽然视图的显示区域变小了,但是点击区域却还是被裁前的区域。因此如果有的视图需要裁剪后要接收触摸事件,需要做一下处理。

举例说明

假设我们把一个300x300矩形的 frame 设置成100x100:

swift 复制代码
Rectangle()
  .fill(.orange.gradient)
  .frame(width: 300, height: 300)
  // Set view to 100×100 → renders out of bounds
  .frame(width: 100, height: 100)
  .border(.blue)

从图上可以看出有边框的部分是实际UI渲染的面积,外面的部分在 frame 外的。如果我们把这个视图裁切后,把一个按钮放置在蓝色边框外,按钮其实会因为被矩形遮挡而接收不了点击事件。

swift 复制代码
struct ContentView: View {
    @State var buttonTapCount = 0
    @State var rectTapCount = 0

    var body: some View {
        VStack {
            Text("buttonTapCount:\(buttonTapCount)")
            Text("rectTapCount:\(rectTapCount)")
            Button("点击无效") {
                buttonTapCount += 1
            }
            .buttonStyle(.borderedProminent)
            
            Rectangle()
                .fill(.orange.gradient)
                .frame(width: 300, height: 300)
                .frame(width: 100, height: 100)
                .clipped()
                .onTapGesture {
                    rectTapCount += 1
                }
        }
    }
}

效果如下,可以看到点击按钮的事件没有被正确的接受,还是算到了矩形上:

修复:使用 .contentShape()

使用 contentShape 方法可以设置 view 的点击响应区域。因此在裁剪后如果加上 .contentShape() 后就可以得到正确的点击区域。

swift 复制代码
Rectangle()
    .fill(.orange.gradient)
    .frame(width: 300, height: 300)
    .frame(width: 100, height: 100)
    .clipped()
    .contentShape(Rectangle())

在设置完 contentShape 效果就和我预期的一样了:


相关推荐
Daniel_Coder2 天前
我用 SwiftUI + GRDB 做了一个「按时吃药·服药提醒」App
ios·swiftui·swift·widgetkit
懋学的前端攻城狮5 天前
把 SwiftUI List 换成 NSTableView:一次目录树卡顿的排查记录
macos·swiftui·swift
东坡肘子6 天前
AI 想放弃了,人没有 -- 肘子的 Swift 周报 #150
人工智能·swiftui·swift
东坡肘子13 天前
越来越慢的 App Review,拦住了谁? -- 肘子的 Swift 周报 #149
人工智能·swiftui·swift
大熊猫侯佩18 天前
Xcode 预览新升级:arguments 让界面调试井井有条
swiftui·xcode·swift
大熊猫侯佩19 天前
WWDC26:把 SwiftUI Toolbar 真正握在手心里
swiftui·swift·apple
大熊猫侯佩19 天前
WWDC 26 全新 ResultsObserver:终于能在 View 外面盯着 SwiftData 了
swiftui·swift·apple
东坡肘子20 天前
Apple Intelligence 已通过审核,即将在中国提供服务 -- 肘子的 Swift 周报 #148
人工智能·swiftui·swift
2501_9151063225 天前
SwiftUI项目创建详解:使用Xcode从零开始创建第一个App项目
ide·vscode·ios·swiftui·个人开发·xcode·敏捷流程
东坡肘子1 个月前
热茶还是冰咖啡 -- 肘子的 Swift 周报 #147
人工智能·swiftui·swift