#6 GeometryReader

GeometryReady 很费性能, 所以能不用就不用

功能

GeometryReader 不是布局容器,而是一个只读测量盒 :它把父视图分配给自己的实际尺寸与坐标 通过 GeometryProxy 实时向下注入,让子视图能够:

  • 按百分比计算帧大小
  • 实现屏幕驱动动画(3D 旋转、视差、滑动缩放等)
  • 获取全局坐标,用于拖拽、碰撞检测、滚动联动

API

swift 复制代码
GeometryReader { proxy in
    // 子视图
}

proxy 提供:

  • sizeCGSize ------ Reader 得到的确定尺寸

  • frame(in:) ------ 在不同坐标系里的 frame:

    • .local:自身坐标系
    • .global:屏幕原点
    • .named(id):自定义坐标空间(配合 .coordinateSpace(name:) 使用)
  • safeAreaInsets ------ 当前 Safe Area 插值

示例

swift 复制代码
struct GeometryReaderBootcamp: View {
    var body: some View {
        // GeometryReady 很费性能, 所以能不用就不用
        //        GeometryReader { geometry in
        //            HStack(spacing: 0) {
        //                Rectangle()
        //                    .fill(.red)
        //                    .frame(width: geometry.size.width * 0.66)
        //                Rectangle().fill(.blue)
        //            }
        //            .ignoresSafeArea()
        //        }
        
        ScrollView(.horizontal, showsIndicators: false) {
            HStack {
                ForEach(0..<20) { index in
                    GeometryReader { geometry in
                        RoundedRectangle(cornerRadius: 16)
                            .rotation3DEffect(
                                Angle(degrees: getPercentage(geometry: geometry) * 40),
                                axis: (x: 0, y: 1.0, z: 0.0))
                    }
                    .frame(width: 320, height: 240)
                    .padding()
                }
            }
        }
    }
        
    private func getPercentage(geometry: GeometryProxy) -> Double {
        let maxDistance = UIScreen.main.bounds.width / 2
        let currentX = geometry.frame(in: .global).midX
        
        return Double(1 - (currentX / maxDistance))
    }
}

性能与最佳实践

  1. 避免深层嵌套:布局阶段每帧都会重新调用闭包。
  2. 仅需尺寸时,优先使用 .frame(maxWidth: .infinity, maxHeight: .infinity) + 背景图层,代替嵌套 Reader。
  3. 需要全局坐标再 frame(in: .global),不要一上来就放在最外层。
  4. ScrollViewLazyVStack 联用时,把 Reader 放在叶子节点,减少重算范围。
  5. 若只关心 Safe Area 插值,可用 .padding(.safeArea) 替代 Reader。

小结

GeometryReader 是 SwiftUI 的"尺子"------不绘制、只测量

合理用它可实现百分比布局、视差动画、滑动联动等高级效果;

但牢记:能靠固有布局解决的,就不要让尺子上场。

相关推荐
CocoaKier8 小时前
喜大普奔!2027年春季起,iOS提审最低支持iOS15.0以上
ios·apple
初级代码游戏11 小时前
iOS开发 Swift 速记2:三种集合类型 Array Set Dictionary
开发语言·ios·swift
凡泰AI14 小时前
APP同时覆盖了iOS、安卓和鸿蒙,如何选择混合开发架构才能减少重复建设,提高功能上线效率~
android·ios·harmonyos·mpaas·uni·小程序容器
AIsoft_868819 小时前
iPhone录音重点标记:会议录音与重点内容同步保存功能实测
ios·iphone
00后程序员张19 小时前
使用Instruments工具深入分析iOS应用性能与启动时间优化
android·macos·ios·小程序·uni-app·cocoa·iphone
90后的晨仔21 小时前
Xcode 26.6编译 AFNetworking 报错全解:5 种方案从应急到根治
ios
初级代码游戏1 天前
iOS开发 Swift 速记1:变量和基本数据类型
开发语言·ios·swift
for_ever_love__2 天前
iOS:网络请求再学习
网络·学习·ios·objective-c
2501_915921432 天前
SwiftUI开发框架入门指南:从基础到实战
ide·vscode·ios·objective-c·个人开发·swift·敏捷流程
2501_916007472 天前
Python实现HTTPS爬虫的完整指南:使用requests、BeautifulSoup、Selenium和Scrapy
爬虫·python·ios·小程序·https·uni-app·iphone