Unity中无法获取iPhone刘海精确尺寸的技术求助
iOS刘海/灵动岛尺寸与位置获取(Unity兼容方案)
问题核心:pt转px出错的原因
你遇到的转换后尺寸过小的问题,本质是未正确使用设备的屏幕缩放因子(UIScreen.main.scale)。iOS的pt是逻辑单位,Unity使用的是物理像素(px),正确转换公式是:物理像素值 = 逻辑pt值 × 屏幕缩放因子。不同设备的scale不同:
- iPhone 8及以下:scale=2
- iPhone X系列(除14 Pro):scale=3
- iPhone 14 Pro/Max:scale=3
修正后的硬编码方案(含scale转换)
先在Xcode中通过设备型号判断对应的刘海/灵动岛逻辑尺寸,再乘以scale得到Unity可用的像素值:
// 定义设备类型枚举 enum NotchType { case large // iPhone X/XS/11 Pro/12 Pro/13 Pro case medium // iPhone XR/11/12/13/14 case pill // iPhone 14 Pro/Max(灵动岛) } extension UIDevice { var notchType: NotchType { let modelName = self.modelName switch modelName { case "iPhone 14 Pro", "iPhone 14 Pro Max": return .pill case "iPhone XR", "iPhone 11", "iPhone 12", "iPhone 12 mini", "iPhone 13", "iPhone 13 mini", "iPhone 14": return .medium default: return .large } } // 获取设备型号名称 var modelName: String { var systemInfo = utsname() uname(&systemInfo) let machineMirror = Mirror(reflecting: systemInfo.machine) let identifier = machineMirror.children.reduce("") { identifier, element in guard let value = element.value as? Int8, value != 0 else { return identifier } return identifier + String(UnicodeScalar(UInt8(value))) } return identifier } // 获取刘海/灵动岛的物理像素尺寸(Unity可用) var notchPixelSize: CGSize { let scale = UIScreen.main.scale switch notchType { case .large: let hasSmallNotch = modelName == "iPhone 12 Pro" || modelName == "iPhone 13 Pro" let ptSize = hasSmallNotch ? CGSize(width: 206.30, height: 29.10) : CGSize(width: 207.50, height: 31.30) return CGSize(width: ptSize.width * scale, height: ptSize.height * scale) case .medium: let ptSize = CGSize(width: 160.90, height: 33.20) return CGSize(width: ptSize.width * scale, height: ptSize.height * scale) case .pill: let ptSize = CGSize(width: 124, height: 35.20) return CGSize(width: ptSize.width * scale, height: ptSize.height * scale) } } // 获取刘海/灵动岛的物理像素位置(Unity可用,原点为屏幕左上角) var notchPixelFrame: CGRect { let size = notchPixelSize let screenWidth = UIScreen.main.bounds.width * UIScreen.main.scale let x = (screenWidth - size.width) / 2 return CGRect(x: x, y: 0, width: size.width, height: size.height) } }
传递数据到Unity
在Xcode中计算好后,通过UnitySendMessage把尺寸和位置传给Unity的C#脚本:
// 假设Unity中有一个名为"NotchManager"的GameObject,脚本中有ReceiveNotchInfo方法 let size = UIDevice.current.notchPixelSize let frame = UIDevice.current.notchPixelFrame UnitySendMessage("NotchManager", "ReceiveNotchInfo", "\(size.width),\(size.height),\(frame.x),\(frame.y)")
Unity端C#脚本示例:
using UnityEngine; public class NotchManager : MonoBehaviour { public void ReceiveNotchInfo(string data) { string[] parts = data.Split(','); float width = float.Parse(parts[0]); float height = float.Parse(parts[1]); float x = float.Parse(parts[2]); float y = float.Parse(parts[3]); Debug.Log($"刘海/灵动岛尺寸:{width}x{height},位置:({x},{y})"); // 后续可根据这些值做UI布局 } }
关键说明
- 硬编码的pt尺寸来自iOS官方设计规范,确保精确匹配设备
- 必须使用设备实际的
UIScreen.main.scale,不能用固定值,否则会出现尺寸偏差 - 灵动岛的位置和尺寸会随系统状态变化(比如后台播放音乐时会变大),如果需要实时更新,需监听UIWindow的safeAreaInsets变化,重新计算
内容的提问来源于stack exchange,提问作者durazno
相关产品推荐
相关产品推荐

