UIKit视图SwiftUI式预览异常:画布显示设备而非视图本身大小
解决UIKit视图在SwiftUI Canvas预览中显示设备尺寸的问题
你的问题核心在于UIKit视图未正确提供自身的固有尺寸(intrinsicContentSize),SwiftUI的.previewLayout(.sizeThatFits)依赖视图的固有尺寸来计算合适的预览大小,而你的MyYellowButton没有重写这个属性,导致预览无法识别视图实际大小,只能 fallback 到设备尺寸。
修复步骤:
- 给
MyYellowButton重写intrinsicContentSize,让它根据按钮标题和内边距自动计算自身大小 - 可选:给按钮添加默认内边距,让显示更美观合理
修改后的MyYellowButton代码:
import UIKit class MyYellowButton: UIButton { override init(frame: CGRect) { super.init(frame: frame) setupView() } required init?(coder: NSCoder) { fatalError("not support coder") } // MARK: - Private private func setupView() { backgroundColor = .yellow setTitleColor(.black, for: .normal) // 添加默认内边距,避免按钮紧贴文字 contentEdgeInsets = UIEdgeInsets(top: 8, left: 16, bottom: 8, right: 16) } // 重写固有尺寸,让视图能告知SwiftUI自身的大小 override var intrinsicContentSize: CGSize { let titleSize = titleLabel?.sizeThatFits(CGSize(width: CGFloat.greatestFiniteMagnitude, height: CGFloat.greatestFiniteMagnitude)) ?? .zero return CGSize( width: titleSize.width + contentEdgeInsets.left + contentEdgeInsets.right, height: titleSize.height + contentEdgeInsets.top + contentEdgeInsets.bottom ) } }
同时可以简化你的UIViewPreview,无需在updateUIView中设置内容拥抱优先级(已通过固有尺寸明确视图大小):
#if canImport(SwiftUI) && DEBUG import SwiftUI struct UIViewPreview<View: UIView>: UIViewRepresentable { let view: View init(_ builder: @escaping () -> View) { view = builder() } func makeUIView(context: Context) -> UIView { view } func updateUIView(_ view: UIView, context: Context) {} } struct MyYellowButtonPreview: PreviewProvider{ static var previews: some View { UIViewPreview { let button = MyYellowButton(frame: .zero) button.setTitle("buttonTest", for: .normal) return button }.previewLayout(.sizeThatFits) // 可选:添加背景色,更清晰看到按钮边界 .background(Color.gray.opacity(0.2)) } } #endif
修改完成后,Canvas预览就会显示按钮自身的实际大小,而非整个设备尺寸。
内容的提问来源于stack exchange,提问作者MrGarlic
相关产品推荐
相关产品推荐

