.clipped()基本用法

141 阅读2分钟

在 SwiftUI 中,clipped() 是一个修饰符(Modifier),用于 裁剪视图超出其边界的内容。它的作用类似于 CSS 中的 overflow: hidden,确保子视图不会超出父视图的框架范围。


1. 基本作用

  • 默认情况下,SwiftUI 中的视图如果超出父视图的尺寸(例如使用 offset()scaleEffect() 或负 padding),仍然会显示。
  • 使用 clipped() 后,超出父视图边界的内容会被裁剪掉,只显示父视图范围内的部分。

2. 基本语法

SomeView()
    .frame(width: 100, height: 100)
    .clipped() // 超出 100x100 范围的内容会被裁剪

3. 常见使用场景

场景 1:图片裁剪

Image("example")
    .resizable()
    .aspectRatio(contentMode: .fill) // 填充整个框架
    .frame(width: 100, height: 100)
    .clipped() // 超出 100x100 的部分隐藏

效果:图片保持原始比例填充,但只显示 100x100 范围内的部分。

场景 2:视图偏移后裁剪

Text("Hello, SwiftUI!")
    .font(.largeTitle)
    .offset(x: 30, y: 30) // 向右下方偏移
    .frame(width: 100, height: 50)
    .clipped() // 偏移后超出 frame 的部分隐藏

效果:文字偏移后,只有部分内容可见。

场景 3:圆形头像

Image("avatar")
    .resizable()
    .frame(width: 100, height: 100)
    .clipShape(Circle()) // 裁剪为圆形
    // 如果不需要圆形,仅需矩形裁剪,用 .clipped() 即可

4. 对比 clipped()clipShape()

修饰符作用示例
clipped()按视图的原始框架(矩形)裁剪.clipped()
clipShape(_:)按指定形状(如圆形、圆角矩形)裁剪.clipShape(Circle())

5. 实际代码示例

示例 1:裁剪超出边界的子视图

struct ContentView: View {
    var body: some View {
        VStack {
            Text("未裁剪时,超出边界仍然可见")
                .font(.title)
                .padding()
                .background(Color.yellow)
                .offset(y: -30) // 向上偏移

            Divider()

            Text("使用 clipped() 后,超出部分隐藏")
                .font(.title)
                .padding()
                .background(Color.green)
                .offset(y: -30)
                .clipped() // 关键代码
        }
        .frame(width: 300, height: 200)
        .border(Color.red)
    }
}

示例 2:图片裁剪

Image("landscape")
    .resizable()
    .aspectRatio(contentMode: .fill)
    .frame(width: 200, height: 100)
    .clipped()
    .border(Color.blue, width: 2)

6. 注意事项

  1. clipped() 只影响视觉渲染,不会改变视图的布局占用空间。
  2. clipShape() 的区别
    • clipped() 是矩形裁剪。
    • clipShape() 支持任意形状(如 CircleRoundedRectangle)。
  3. 性能优化:对复杂视图裁剪时,尽量在叶子节点(最内层视图)使用,以减少重绘范围。

7. 总结

  • 何时使用 clipped()
    • 需要隐藏视图超出父框架的部分时。
    • 实现图片的“填充并裁剪”效果(类似 aspectRatio(contentMode: .fill) 的配套操作)。
    • 替代 clipShape(Rectangle()) 的快捷方式。
  • 典型搭配
    • .frame() + .clipped()
    • .offset() + .clipped()
    • .scaleEffect() + .clipped()

通过 clipped(),你可以轻松控制视图的显示范围,避免内容溢出破坏布局!