【问题标题】:Expandable SwiftUI View in UIKit gets vertically centeredUIKit 中的可扩展 SwiftUI 视图垂直居中
【发布时间】:2020-04-19 07:28:05
【问题描述】:

我在 UIKit 应用程序中集成了一些新的 SwiftUI 视图,但遇到了问题。我已经研究了以下问题很长一段时间,但还没有找到原因和解决方案。在 UIKit 中集成 View 时会出现此问题。我正在尝试创建一个简单的可点击视图,在点击时可以垂直展开/折叠。

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

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

似乎即使我将 UIHostingController 视图的顶部操作限制为父视图,UIHostingController 视图也会垂直居中。

如 cmets 中所述,我可以将 HostController 视图的底部限制到其父级的底部,但这会使下面的内容无法交互。

我正在寻找的是 HostController 视图约束(特别是高度)与 SwiftUI 视图框架匹配的解决方案。

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()
    }
  }
}

非常感谢任何帮助。

【问题讨论】:

    标签: ios uikit swiftui


    【解决方案1】:

    这是在 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()
    

    【讨论】:

    • 嗨。感谢您试用。您的方法的问题(将主机控制器视图的底部限制为父视图)是父视图的内容不再可交互,因为另一个视图在它前面(即使主机控制器视图不一定有与父视图的高度相同)。
    • 那是不同的问题))
    猜你喜欢
    • 2021-12-25
    • 2020-05-08
    • 2020-01-27
    • 1970-01-01
    • 1970-01-01
    • 2021-10-16
    • 2017-12-13
    • 2020-10-13
    • 2010-12-13
    相关资源
    最近更新 更多