UIViewRepresentable 自动大小 - 将 UIKit UIView 大小传递给 SwiftUI

Posted

技术标签:

【中文标题】UIViewRepresentable 自动大小 - 将 UIKit UIView 大小传递给 SwiftUI【英文标题】:UIViewRepresentable automatic size - Passing UIKit UIView size to SwiftUI 【发布时间】:2020-05-16 05:17:58 【问题描述】:

假设你有一个 UIKit 视图想要决定它自己的大小(通过 intrinsicContentSize 或布局约束,大小可能会改变)。例如:

/// Some UIKit view that wants to have a specific size
class YellowBoxUIKitView : UIView 

    init() 
        super.init(frame: .zero)
        self.backgroundColor = .yellow
    

    required init?(coder: NSCoder) 
        fatalError("init(coder:) is not supported")
    

    override var intrinsicContentSize: CGSize 
        return CGSize(width: 100, height: 100)
    


如何将其包装为 SwiftUI UIViewRepresentable 并使其自动将 UIView 大小传递给 SwiftUI?

struct YellowBoxView : UIViewRepresentable 

    func makeUIView(context: Context) -> YellowBoxUIKitView 
        // TODO: How do you pass the size from UIKit up to SwiftUI?
        YellowBoxUIKitView()
    

    func updateUIView(_ uiView: YellowBoxUIKitView, context: Context) 
    


SwiftUI 不考虑 UIView 的大小,只是给它最大可能的宽度/高度。

可运行示例:SizedUIViewRepresentableView

这里有一个关于 UITextView 的类似问题:Update UIViewRepresentable size from UIKit in SwiftUI

【问题讨论】:

【参考方案1】:

解决方案是为表示的UIView 显式设置压缩/拥抱优先级

使用 Xcode 11.4 / ios 13.4 测试

struct YellowBoxView : UIViewRepresentable 

    func makeUIView(context: Context) -> YellowBoxUIKitView 
        let view = YellowBoxUIKitView()

        view.setContentHuggingPriority(.required, for: .horizontal) // << here !!
        view.setContentHuggingPriority(.required, for: .vertical)

        // the same for compression if needed

        return view
    

    func updateUIView(_ uiView: YellowBoxUIKitView, context: Context) 
    

【讨论】:

请注意,此策略似乎不适用于 UIStackViews。似乎堆栈总是占据所有可用的区域。 makeUIView 中的两个setContentHuggingPriority 替换为view.translatesAutoresizingMaskIntoConstraints = false 对我有用。

以上是关于UIViewRepresentable 自动大小 - 将 UIKit UIView 大小传递给 SwiftUI的主要内容,如果未能解决你的问题,请参考以下文章

可调整大小的 UITextView 的 sizeThatFits 在 UIViewRepresentable 中给出了错误的大小

如何在 SwiftUI 中更改 UIViewRepresentable 内的 UITextField 大小

更新 UIViewRepresentable 中的绑定

更新 SwiftUI 中的 inputAccessoryView (UIViewRepresentable)

协调器不适用于 UIViewRepresentable?

如何使 UIViewRepresentable @ViewBuilder 与动态内容一起使用?