SwiftUI UIRepresentable设备旋转时比例变形问题求助
解决方案
问题根源在于两个核心点:
- UIView默认的
contentMode为.scaleToFill,会直接拉伸已有绘制内容而非重新绘制,导致旋转时文字变形 - 原代码中文字绘制的位置计算未考虑文字自身尺寸,直接使用
rect.midX/midY会导致垂直方向不居中,且无法适配尺寸变化
修复步骤:
- 优化自定义UIView的绘制逻辑与内容模式
给自定义UIView设置contentMode = .redraw,确保尺寸变化时重新调用draw(_:)方法;同时通过计算文字尺寸来确定居中位置,固定字体大小避免拉伸:
class UIViewTestClass: UIView { override init(frame: CGRect) { super.init(frame: frame) contentMode = .redraw // 尺寸变化时触发重新绘制 backgroundColor = .white } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } override func draw(_ rect: CGRect) { let text = "Test" let font = UIFont.systemFont(ofSize: 16) let textAttributes: [NSAttributedString.Key: Any] = [.font: font] // 计算文字实际尺寸 let textSize = text.size(withAttributes: textAttributes) // 计算文字居中的左下角坐标(draw(at:)以文字左下角为原点) let textX = rect.midX - textSize.width / 2 let textY = rect.midY + textSize.height / 2 text.draw(at: CGPoint(x: textX, y: textY), withAttributes: textAttributes) // 绘制边框 let context = UIGraphicsGetCurrentContext() context?.addRect(rect) context?.stroke(rect) } }
- 修正UIViewRepresentable的类型匹配
让UIViewType直接指向UIViewTestClass,避免不必要的类型转换:
struct TestUIView: UIViewRepresentable { typealias UIViewType = UIViewTestClass func makeUIView(context: Context) -> UIViewTestClass { UIViewTestClass() } func updateUIView(_ uiView: UIViewTestClass, context: Context) { // 无需额外操作 } }
- 保留原ContentView布局
原布局设置可以直接保留,无需启用aspectRatio,现在视图会占满屏幕,旋转时文字会自动重新绘制并保持正确比例:
struct ContentView: View { var body: some View { TestUIView() .frame(maxWidth: .infinity, maxHeight: .infinity) .padding() } }
原理说明
.redraw模式会在视图边界变化时触发draw(_:)方法,重新绘制内容,而非拉伸原有像素内容- 通过计算文字尺寸确定居中位置,确保文字始终处于视图中心,且字体大小固定,不会随视图拉伸变形
内容的提问来源于stack exchange,提问作者Samuel Cederlund
相关产品推荐
相关产品推荐

