ios UIViewRepresentable忽略 Package 的UIView的约束

hmmo2u0o  于 2023-02-01  发布在  iOS
关注(0)|答案(1)|浏览(95)

我有UIButton的子类,它通过使用NSLayoutConstraints定义了它内部的高度,我需要通过将它 Package 到UIViewRepresentable中来在SwiftUI视图中重用它。
代码如下:

struct TestView: View {
    var body: some View {
        TestButtonWrapper()
            .background(Color.red)
    }
}

final class TestButton: UIButton {
    override init(frame: CGRect) {
        super.init(frame: frame)
        setup()
    }

    required init?(coder: NSCoder) {
        super.init(coder: coder)
        setup()
    }

    func setup() {
        translatesAutoresizingMaskIntoConstraints = false
        setTitle("Hello", for: .normal)
        // these are ignored:
        heightAnchor.constraint(equalToConstant: 200).isActive = true
        widthAnchor.constraint(equalToConstant: 300).isActive = true
    }
}

struct TestButtonWrapper: UIViewRepresentable {
    func makeUIView(context: Context) -> TestButton {
        let view = TestButton()
        view.translatesAutoresizingMaskIntoConstraints = false
        view.setContentHuggingPriority(.defaultHigh, for: .horizontal)
        view.setContentHuggingPriority(.defaultHigh, for: .vertical)
        return view
    }

    func updateUIView(_ uiView: TestButton, context: Context) {
    }
}

结果为:

    • 重要:**无法从TestButton中删除约束并在TestView中设置框架。此UIKit按钮正在常规UIKit屏幕中重用

如何求解?为什么UIViewRepresentable忽略其子节点的约束?

enyaitl3

enyaitl31#

SwiftUI和UIKit的布局约束不相同...
一种方法是在TestButton中覆盖intrinsicContentSize,而不是尝试设置约束。
试试看:

struct TestView: View {
    var body: some View {
        TestButtonWrapper()
            .background(Color.red)
    }
}

final class TestButton: UIButton {
    override init(frame: CGRect) {
        super.init(frame: frame)
        setup()
    }
    
    required init?(coder: NSCoder) {
        super.init(coder: coder)
        setup()
    }
    
    func setup() {
        translatesAutoresizingMaskIntoConstraints = false
        setTitle("Hello", for: .normal)
        // these are ignored:
        //heightAnchor.constraint(equalToConstant: 200).isActive = true
        //widthAnchor.constraint(equalToConstant: 300).isActive = true
    }
    
    // add this override
    override var intrinsicContentSize: CGSize {
        return .init(width: 300.0, height: 200.0)
        
    }
}

struct TestButtonWrapper: UIViewRepresentable {
    func makeUIView(context: Context) -> TestButton {
        let view = TestButton()
        view.translatesAutoresizingMaskIntoConstraints = false
        view.setContentHuggingPriority(.defaultHigh, for: .horizontal)
        view.setContentHuggingPriority(.defaultHigh, for: .vertical)
        return view
    }
    
    func updateUIView(_ uiView: TestButton, context: Context) {
    }
}

相关问题