You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 17:01:07