UIKit中的可扩展SwiftUI视图垂直居中

时间:2019-12-30 14:53:13

标签: ios uikit swiftui

我在UIKit应用程序中集成了一些新的SwiftUI视图,但遇到了问题。我已经看了很长时间以下问题,但尚未找到原因和解决方案。当在UIKit中集成视图时,特别会发生此问题。我正在尝试创建一个简单的可点击视图,当点击时会垂直扩展/折叠。

这是SwiftUI视图的预览样子(以及它的确切行为):
Screenshot
Video

这是我在UIKit中实现SwiftUI视图时得到的结果:
Screenshot
Video

即使我将UIHostingController视图的顶部约束为父视图,也似乎UIHostingController视图垂直居中。

SwiftUI视图的代码:

import SwiftUI

struct ColorView: View {
  @State var isCollapsed = true

  var body: some View {
    VStack {
      VStack(spacing: 5) {
        HStack {
          Spacer()
          Text("Title")
          Spacer()
        }
        .frame(height: 100)

        if !isCollapsed {
          HStack {
            Spacer()
            Text("description")
            Spacer()
          }
          .padding(40)
        }
      }
      .background(Color(isCollapsed ? UIColor.red : UIColor.blue))
      .onTapGesture {
        withAnimation {
          self.isCollapsed.toggle()
        }
      }

      Spacer()
    }
  }
}

struct ColorView_Previews: PreviewProvider {
  static var previews: some View {
    return ColorView()
  }
}

以及上述SwiftUI View的ViewController中的UIKit实现:

struct ViewControllerRepresentable: UIViewControllerRepresentable {
  typealias UIViewControllerType = ViewController

  func makeUIViewController(context: UIViewControllerRepresentableContext<ViewControllerRepresentable>) -> ViewControllerRepresentable.UIViewControllerType {
    return ViewController()
  }

  func updateUIViewController(_ uiViewController: ViewControllerRepresentable.UIViewControllerType, context: UIViewControllerRepresentableContext<ViewControllerRepresentable>) { }
}

class ViewController: UIViewController {
  override func viewDidLoad() {
    super.viewDidLoad()

    let colorView = ColorView()
    let colorController = UIHostingController(rootView: colorView)

    addChild(colorController)
    view.addSubview(colorController.view)
    colorController.didMove(toParent: self)

    colorController.view.translatesAutoresizingMaskIntoConstraints = false
    colorController.view.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
    colorController.view.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
    colorController.view.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
  }
}

struct ViewControllerRepresentable_Previews: PreviewProvider {
  static var previews: some View {
    Group {
      ViewControllerRepresentable()
    }
  }
}

非常感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

以下是经过测试的代码快照,这些代码已在iOS Single View Playground(Xcode 11.2)中经过测试。原始ColorView未被更改,因此在下面不再重复。

UIKit UIViewController中集成的SwiftUI视图的行为与纯SwiftUI环境中的行为相同。

import UIKit
import PlaygroundSupport
import SwiftUI

class MyViewController : UIViewController {
    override func loadView() {
        let view = UIView()
        view.backgroundColor = .white
        self.view = view
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        let child = UIHostingController(rootView: ColorView())
        addChild(child)
        self.view.addSubview(child.view)
        child.didMove(toParent: self)

        child.view.translatesAutoresizingMaskIntoConstraints = false
        child.view.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
        child.view.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
        child.view.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
        child.view.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
    }
}
// Present the view controller in the Live View window
PlaygroundPage.current.liveView = MyViewController()