【问题标题】:Swift UI: UIHostingController.view is not fit to content view size at iOS 13Swift UI:UIHostingController.view 不适合 iOS 13 的内容视图大小
【发布时间】:2021-05-20 00:20:53
【问题描述】:

我想根据通讯结果更新 Swift UI View。 但是 UIHostingController.view 不适合 iOS 13 的 rootView 大小。 当我尝试使用下面的示例代码时,也会发生同样的事情。 我想将自调整大小的 SwiftUI 视图添加到 UIStackView,但由于这个问题,SwiftUI 视图与上一个和下一个视图重叠。 如何避免这个问题?

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        
        let object = SampleObject()
        let sampleView = SampleView(object: object)
        let hosting = UIHostingController(rootView: sampleView)
        hosting.view.backgroundColor = UIColor.green
        addChild(hosting)
        view.addSubview(hosting.view)
        hosting.view.translatesAutoresizingMaskIntoConstraints = false
        hosting.view.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
        hosting.view.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
        hosting.view.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
        hosting.didMove(toParent: self)
        
        DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
            object.test()
        }
    }
}


struct SampleView: View {
    @ObservedObject var object: SampleObject
    
    var body: some View {
        VStack {
            Text("test1").background(Color.blue)
            Text("test2").background(Color.red)
            if object.state.isVisibleText {
                Text("test2").background(Color.gray)
            }
        }
        .padding(32)
        .background(Color.yellow)
    }
}


final class SampleObject: ObservableObject {
    struct ViewState {
        var isVisibleText: Bool = false
    }
    
    @Published private(set) var state = ViewState()
    
    func test() {
        state.isVisibleText = true
    }
}

如果如下添加Subview 到 UIStackView,iOS13 中 Swift UI View 的高度不会改变。

iOS13(不正确)

iOS14(正确)

【问题讨论】:

    标签: ios swift swiftui ios13 uihostingcontroller


    【解决方案1】:

    你还没有设置底部锚点,添加这一行

    hosting.view.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
    

    另一种简单的方法是将框架设置为托管控制器视图并移除约束。

    class ViewController: UIViewController {
    
        override func viewDidLoad() {
            super.viewDidLoad()
            
            let object = SampleObject()
            let sampleView = SampleView(object: object)
            let hosting = UIHostingController(rootView: sampleView)
            hosting.view.frame = UIScreen.main.bounds //<---here
            hosting.view.backgroundColor = UIColor.green
            addChild(hosting)
            view.addSubview(hosting.view)
            hosting.didMove(toParent: self)
            
            DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
                object.test()
            }
        }
    }
    

    【讨论】:

    • 使用此解决方法,屏幕大小和 Swift UI 视图大小将相同。但我希望 Swift UI View 的大小可以自行调整。
    • 你能添加一张你想要的图片吗?
    • 我想让它看起来像附加的 iOS 14 图像。 i.stack.imgur.com/Q2SUq.jpg
    • 我添加了描述和截图。请检查一下。
    • @RajaKishan 完全正确 - 您必须添加顶部 + 底部 + 前导 + 尾随约束。
    【解决方案2】:

    仅适用于 iOS 13

    试试这个:

    每次视图大小改变时,调用这个:

    sampleView.view.removeFromSuperview()
    let sampleView = SampleView(object: object)
    let hosting = UIHostingController(rootView: sampleView)
    view.addArrangedSubview(hosting.view)
    

    【讨论】:

    • 是的,我没有提到它,但我是这样解决的。
    猜你喜欢
    • 1970-01-01
    • 2018-04-29
    • 1970-01-01
    • 1970-01-01
    • 2020-11-22
    • 1970-01-01
    • 1970-01-01
    • 2013-09-21
    • 1970-01-01
    相关资源
    最近更新 更多