#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 的"尺子"------不绘制、只测量

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

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

相关推荐
_瑞32 分钟前
APM_寄存器
ios·汇编语言
懋学的前端攻城狮2 小时前
把 SwiftUI List 换成 NSTableView:一次目录树卡顿的排查记录
macos·swiftui·swift
2501_916008893 小时前
iOS App 请求地址查看,不用配置看到 App 调了哪些接口
网络协议·计算机网络·网络安全·ios·adb·https·udp
2501_915106325 小时前
Swift 开发环境搭建指南:三条路径按目标对号入座
开发语言·vscode·ios·objective-c·个人开发·swift·敏捷流程
_瑞7 小时前
APM_符号化
ios
ii_best8 小时前
ios群控鹰眼中控系统越狱版 PC 端 v3.1.9 版本更新|三大核心功能迭代,优化群控投屏作业流程
ios
二流小码农8 小时前
鸿蒙开发:了解Context
android·ios·harmonyos
时代分流9 小时前
云手机推荐2026:安卓全能、批量挂机、原生iOS全覆盖
android·ios·智能手机
catchadmin20 小时前
NativePHP v4 让 Blade 构建原生 iOS 与 Android 界面
android·ios·ai·php
weixin_403810131 天前
iOS免越狱自动化三种方式对比:代理模式、蓝牙HID与OTG HID怎么选
ios·自动化·跨境电商·ios脚本·苹果群控·苹果投屏·苹果脚本