如何在用户调整Volumetric Window尺寸时正确缩放其内容?
解决VisionOS中Volumetric Window内容随窗口尺寸缩放的问题
要实现Volumetric Window内容随窗口尺寸动态缩放,不能依赖SwiftUI的aspectRatio或scaledToFill这类布局修饰符(它们对RealityKit内容的适配逻辑不适用),正确的做法是监听窗口尺寸变化,动态调整RealityKit实体的缩放比例。
以下是修改后的完整代码:
import RealityKit import SwiftUI @main struct SandboxApp: App { var body: some SwiftUI.Scene { WindowGroup { ContentView() } .windowStyle(.volumetric) .defaultSize(width: 1, height: 1, depth: 1, in: .meters) } } struct ContentView: View { @Environment(\.windowScene) private var windowScene @State private var sphereEntity: ModelEntity? var body: some View { RealityView { content in let sphere = ModelEntity(mesh: MeshResource.generateSphere(radius: 0.25), materials: [SimpleMaterial(color: .red, isMetallic: false)]) content.add(sphere) sphereEntity = sphere updateSphereScale() } update: { content in updateSphereScale() } .onChange(of: windowScene?.size) { _ in updateSphereScale() } } private func updateSphereScale() { guard let windowSize = windowScene?.size, let sphere = sphereEntity else { return } let windowWidth = windowSize.width let windowHeight = windowSize.height let windowDepth = windowSize.depth // 适配窗口最小维度,保证内容完全显示;若需填充窗口,可改为取最大维度 let minDimension = min(windowWidth, windowHeight, windowDepth) let scale = minDimension / 0.5 // 球体原始直径为0.5米 sphere.scale = SIMD3(x: scale, y: scale, z: scale) } }
关键逻辑说明
- 窗口尺寸监听:通过
@Environment(\.windowScene)获取当前Volumetric Window的场景实例,结合onChange监听窗口尺寸变化,触发内容缩放更新。 - 实体引用管理:用
@State保存RealityKit实体的引用,确保后续能动态修改其缩放属性。 - 缩放比例计算:根据窗口的宽、高、深三个维度计算缩放系数。示例采用适配窗口最小维度的逻辑,保证内容始终完全显示;若需要填充整个窗口,可改为取窗口的最大维度作为基准。
- 实时更新机制:RealityView的
update闭包配合onChange回调,确保窗口初始化和尺寸调整时,内容缩放都能及时生效。
如果需要保持内容的原始宽高比,可调整缩放逻辑,例如固定某一维度的缩放比例,按比例同步其他维度,避免内容扭曲。
内容的提问来源于stack exchange,提问作者Jim Marquardt
相关产品推荐
相关产品推荐

