xcode 如何使我的SwiftUI UIViewRepresentable在预览中尊重intrinsicContentSize?

x33g5p2x  于 2023-11-21  发布在  Swift
关注(0)|答案(3)|浏览(173)

当我在SwiftUI中创建视图并在Xcode预览中使用PreviewLayout.sizeThatFits渲染它时,预览会根据其内容调整其大小。当我使用UIViewRepresentable导入UIKIt视图时,它会显示一个完整的设备大小框架。
有没有办法让SwiftUI尊重UIView子类的intrinsicContentSize

struct Label: UIViewRepresentable {

    func makeUIView(context: UIViewRepresentableContext<Label>) -> UILabel {
        return UILabel()
    }

    func updateUIView(_ uiView: UILabel, context: UIViewRepresentableContext<Label>) {
        uiView.text = "Some text"
    }
}

#if DEBUG
struct Label_Previews: PreviewProvider {
    static var previews: some View {
        Group {
            Label().previewLayout(.sizeThatFits)
        }
    }
}
#endif

字符串

5kgi1eie

5kgi1eie1#

将以下内容添加到updateUIView函数:

uiView.setContentHuggingPriority(.defaultHigh, for: .vertical)
uiView.setContentHuggingPriority(.defaultHigh, for: .horizontal)

字符串

q5iwbnjs

q5iwbnjs2#

您也可以从 *SwiftUI侧 * 限制UIViewRepresentable的大小。
你可以使用fixedSize

struct Label_Previews: PreviewProvider {
    static var previews: some View {
        Label()
            .fixedSize()
            .previewLayout(.sizeThatFits)
    }
}

字符串
也可以仅在一个维度上固定视图大小:

.fixedSize(horizontal: false, vertical: true)

5kgi1eie

5kgi1eie3#

使用Swift 5,SwiftUI 15,以下是一个使用布局约束的视图层次结构的解决方案。
关键是将SwiftUI视图用来设置视图高度的绑定传递给representable。representable通过询问系统适合的最小大小来设置高度的值。
这适用于UIViewRepresentable和UIViewControllerRepresentable。

struct WrappingView: UIViewControllerRepresentable {
    @Binding var height: CGFloat
    
    func makeUIViewController(context: Context) -> WrappedViewController {   
        return WrappedViewController()
    }
    
    func updateUIViewController(_ uiViewController: WrappedViewController, context: Context) {

        DispatchQueue.main.async {
            height = uiViewController.view.systemLayoutSizeFitting(UIView.layoutFittingCompressedSize).height
        }
    }
    
    typealias UIViewControllerType = WrappedViewController
}

字符串
然后在SwiftUI视图中,设置框架高度以匹配可表示对象中的值。

struct MixedView: View {
    @State private var wrappedViewHeight: CGFloat = 0
   
    var body: some View {
        VStack {
            WrappingView(height: $wrappedViewHeight)
            .frame(height: wrappedViewHeight)
        }
    }
}


普通情况下的 Package 视图控制器示例

class WrappedViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        let label = UILabel()
        label.text = "Testing"
        label.backgroundColor = .lightGray
        label.translatesAutoresizingMaskIntoConstraints = false
        view.addSubview(label)
        NSLayoutConstraint.activate([
            label.topAnchor.constraint(equalTo: view.topAnchor),
            label.bottomAnchor.constraint(equalTo: view.bottomAnchor)
        ])
    }
}


在Xcode 15中,预览就像

#Preview {
    MixedView()
}

相关问题