UIKit 视图在 SwiftUI VStack 中占据相等的空间

问题描述 投票:0回答:1

UIKit 视图在 SwiftUI 堆栈中占据相同的空间

class CustomView: UIView {
    let label: UILabel = {
        let label = UILabel()
        label.text = "Hello"
        label.textColor = .black
        label.textAlignment = .center
        return label
    }()
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        addSubview(label)
        label.translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint.activate([
            label.centerXAnchor.constraint(equalTo: centerXAnchor),
            label.centerYAnchor.constraint(equalTo: centerYAnchor)
        ])
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    override var intrinsicContentSize: CGSize {
        return label.intrinsicContentSize
    }
}

struct SwiftUIView: View {
    var body: some View {
        VStack {
            GeometryReader { geometry in
                // Wrapping the UIKit UIView inside a SwiftUI View
                UIKitView(view: CustomView())
                    .background(Color.gray)
                    .frame(width: geometry.size.width, height: geometry.size.height, alignment: .center)
                    .aspectRatio(contentMode: .fit) // Ensure aspect ratio
            }
            
            List(0..<5) { index in
                Text("Row \(index)")
            }
        }
    }
}

struct UIKitView: UIViewRepresentable {
    let view: UIView
    
    func makeUIView(context: Context) -> UIView {
        return view
    }
}

想要 Hello 视图达到标签高度(动态标签尺寸)而不是一半尺寸。 根据标签尺寸使自定义视图高度动态化。

我尝试了不同的方法,但没有成功。

enter image description here

swift swiftui
1个回答
0
投票

您可以覆盖

sizeThatFits
来为
UIViewRepresentable
选择合适的尺寸。

struct UIKitView: UIViewRepresentable {
    let view: () -> UIView
    
    init(view: @escaping @autoclosure () -> UIView) {
        self.view = view
    }
    
    func makeUIView(context: Context) -> UIView {
        view()
    }
    
    func updateUIView(_ uiView: UIView, context: Context) { }
    
    func sizeThatFits(_ proposal: ProposedViewSize, uiView: UIView, context: Context) -> CGSize? {
        uiView.intrinsicContentSize
    }
}

假设包装的

UIView
不需要更新,您应该让初始化程序采用
@autoclosure
(如上),这样您就不会在每次视图更新时分配
UIView
实例。

然后您可以删除

GeometryReader
aspectRatio

VStack {
    UIKitView(view: CustomView())
        .frame(maxWidth: .infinity) // assuming you want the label to fill the width of the VStack
        .background(Color.gray)
    List(0..<5) { index in
        Text("Row \(index)")
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.