GeometryReader in SwiftUI

GeometryReader 可以获取父视图的大小信息,用来适配不同尺寸的容器

再开始今天的主角前,我们先看一个使用普通手段布局的例子。

我们用两个视图来平分整个页面。

scss 复制代码
HStack(spacing: 0) {
                Rectangle()
                    .fill(Color.red)
                    .frame(width: UIScreen.main.bounds.width * 0.8)
                Rectangle()
                    .fill(Color.blue)
            }
            .ignoresSafeArea()

当我们竖屏时,它确实可以正常工作。但是当我们旋转屏幕后就出现了下

的一幕。

可以看到并没有合理的布局我们需要的视图,当我们旋转了屏幕,视图不自动更新布局。那么此时我们就需要使用GeometryReader来解决这个问题了。


利用GeometryReader布局

代码很简单,只需要把布局 视图放在GeometryReader的内部,然后内部视图布局使用GeometryReader返回的结果就可以办到。

scss 复制代码
GeometryReader { geo in
            HStack(spacing: 0) {
                Rectangle()
                    .fill(Color.red)
 .frame(width: geo.size.width * 0.8)
                Rectangle()
                    .fill(Color.blue)
            }
            .ignoresSafeArea()
        }

把设定宽度的代码从UIScreen.bounds.width 改成geo.size.width即可完成布局。

结果就是我们设定一样了。


做一个炫酷效果

我们做一个图片滚动时有一定3D旋转的效果。首先我们先用ScrollerView把图片布局起来。

scss 复制代码
VStack {
            ScrollView(.horizontal,showsIndicators: false) {
                HStack {
                    ForEach(0..<6) { i in
                        Image("(i)")
                            .resizable()
                            .scaledToFill()
                            .frame(width: 300, height: 280)
                            .cornerRadius(30)
                            .padding()
                    }
                }
            }
            Spacer()
        }

我们想在图片滑动时有一个3D效果, 我们需要得到当前图片移动的位置, 当图片在中心点时,图片的旋转角度就是0 ,否则当视图在中心点的两侧 ,就按照当前位置除以屏幕宽度的一半,来计算百分比

less 复制代码
VStack {
            ScrollView(.horizontal,showsIndicators: false) {
                HStack {
                    ForEach(0..<6) { i in
                        GeometryReader { geo in
                            Image("(i)")
                                .resizable()
                                .scaledToFill()
                                .frame(width: 300, height: 200)
                                .cornerRadius(20)
                               .rotation3DEffect(
                                    Angle(degrees: getPercentage(geo: geo) * 40),
                                    axis: (x: 0.0, y: 1.0, z: 0.0)) 
                        }
                        .frame(width: 300, height: 200)
                        .padding()
                    }
                }
            }
            
            Spacer()
        }
swift 复制代码
 func getPercentage(geo: GeometryProxy) -> Double {
        let maxDistance = UIScreen.main.bounds.width / 2
        let currentX = geo.frame(in: .global).midX
        return Double(1 - (currentX / maxDistance))
    }

geo.frame(in: .global).midX 的表达式返回了当前视图的全局坐标系中的横向中心位置(X 坐标)。这在计算偏移量、动画效果等方面非常有用。在你提供的函数中,它用于计算滑动偏移量的百分比.

GeometryReader 是一个非常消耗内存的View,它会实时计算位置,会对app性能有影响

大家有什么看法呢?欢迎留言讨论。

公众号:RobotPBQ

相关推荐
2501_916007471 小时前
如何查看 iOS 设备系统与硬件信息,iOS系统信息显示工具
android·ios·小程序·https·uni-app·iphone·webview
2501_916007473 小时前
iOS APP 开发,从项目创建、证书与描述文件配置、安装测试和IPA 上传
android·ios·小程序·https·uni-app·iphone·webview
Swift社区3 小时前
在Swift中实现允许重复的O(1)随机集合
开发语言·ios·swift
大熊猫侯佩21 小时前
拯救巴别塔:WWDC24 全新 Translation API 实战
swiftui·wwdc·language·coreml·translation api·翻译接口·translationsess
初级代码游戏1 天前
iOS开发 SwiftUI 8:NavigationView 导航
ios·swiftui·swift
美狐美颜SDK开放平台1 天前
跨平台开发实战:直播美颜sdk动态贴纸在 Android / iOS / HarmonyOS 的落地方案
android·ios·harmonyos·美颜sdk·直播美颜sdk·视频美颜sdk·美颜api
2501_916008891 天前
在不越狱前提下导出 iOS 应用文件的过程,访问应用沙盒目录,获取真实数据
android·macos·ios·小程序·uni-app·cocoa·iphone
2501_915106321 天前
Android和IOS 移动应用App图标生成与使用 Assets.car生成
android·ios·小程序·https·uni-app·iphone·webview
虹少侠1 天前
基于 WebKit 构建 macOS 多浮窗视频播放的技术实践(含完整产品落地)
前端·macos·swift·webkit
2501_915918411 天前
Mac 抓包软件有哪些?Charles、mitmproxy、Wireshark和Sniffmaster哪个更合适
android·ios·小程序·https·uni-app·iphone·webview