如何让RealityKit文本Mesh完美适配visionOS SwiftUI窗口?
解决RealityView中文本Mesh被裁剪的问题
先理清containerFrame的工作机制
MeshResource.generateText里的containerFrame是文本在3D空间中的排版边界容器,单位和你设置的字体size一致(这里是RealityKit的3D空间单位,比如米)。文本会严格在这个矩形范围内排版,任何超出矩形的部分都会被直接裁剪。你之前设置y: -10会让容器的垂直范围是y=-10到y=0,而文本默认从基线开始排版,很容易导致部分文本落在容器外被裁剪。
具体解决步骤
动态计算文本实际尺寸
固定的containerFrame值无法适配不同长度的文本,应该先计算文本在指定字体下的实际宽高,再基于这个尺寸设置容器帧(留少量余量避免裁剪)。调整容器帧的合理位置
避免给y设置负偏移,默认从(0,0)开始排版,确保文本完全落在容器范围内。可选:对齐实体位置
生成的文本Mesh原点默认在左下角,若需要居中显示,可以调整实体的position来偏移。
修改后的代码示例
private func modelFromText(title: String) -> ModelEntity { let fontSize: CGFloat = 0.7 let font = UIFont.systemFont(ofSize: fontSize, weight: .heavy, width: .condensed) let text = title.localizedUppercase // 计算文本在指定字体下的实际尺寸(和3D空间单位一致) let textSize = text.boundingRect( with: CGSize(width: CGFloat.greatestFiniteMagnitude, height: CGFloat.greatestFiniteMagnitude), options: [.usesLineFragmentOrigin, .usesFontLeading], attributes: [.font: font], context: nil ).size // 设置容器帧,预留10%的余量防止边缘裁剪 let containerFrame = CGRect( x: 0, y: 0, width: textSize.width * 1.1, height: textSize.height * 1.1 ) let textMesh = MeshResource.generateText( text, extrusionDepth: 0.08, font: font, containerFrame: containerFrame, alignment: .left, lineBreakMode: .byWordWrapping ) let entity = ModelEntity(mesh: textMesh) let material = SimpleMaterial(color: .white, roughness: 1, isMetallic: true) entity.model?.materials = [material] entity.name = "title" // 调整位置让文本中心对齐实体原点(可选) entity.position = SIMD3<Float>(-Float(textSize.width)/2, -Float(textSize.height)/2, 0) return entity }
额外注意点
- 如果使用
byWordWrapping换行,计算textSize时要传入usesLineFragmentOrigin选项,确保计算出的高度包含所有换行后的内容。 - 字体的
size参数直接对应RealityKit的3D空间单位,所以计算出的textSize可以直接用于containerFrame,无需额外单位转换。
内容的提问来源于stack exchange,提问作者Bernd
相关产品推荐
相关产品推荐

