Lor*_*lor 7 uiviewcontroller uiview ios swift swiftui
另一个问题标题可能是“如何将UIHostingController的视图添加为UIView的子视图?” 。
我正在创建一个新的UI组件,很想尝试SwiftUI。下图是当前视图结构。UIView是我现在正在使用的(右上),而SwiftUI视图是我尝试使用的(右下)。
观看了WWDC 2019中的所有SwiftUI视频之后,我仍然不知道如何使用SwiftUI视图并将其放在应该将UIView实例放到哪里。
我从“ Integrating SwiftUI”演讲中注意到,有一个NSHostingView适用于macOS的https://developer.apple.com/documentation/swiftui/nshostingview#,这让我想知道是否有类似的东西或可以实现的替代方法它。
我读了类似现有UIKit应用程序中的“ 包括SwiftUI视图”之类的问题,其中提到SwiftUI和UIKit可以一起使用UIHostingController。但是,我想做的是仅采用一小段SwiftUI,并将其放入我现有的UIKit视图组件中,而不是将其用作控制器。
我是iOS开发的新手,如果有一种方法可以将视图控制器用作UIView视图,请发表评论。谢谢。
Rob*_*Rob 14
视图控制器不仅适用于顶级场景。我们通常将视图控制器放在视图控制器中。它被称为“视图控制器包含”和/或“子视图控制器”。(顺便说一句,视图控制器容器通常是抵抗传统UIKit应用程序中的视图控制器膨胀,将复杂的场景分解为多个视图控制器的一种好方法。)
所以,
继续使用UIHostingController:
let controller = UIHostingController(rootView: ...)
Run Code Online (Sandbox Code Playgroud)
和;
添加视图控制器,然后可以将托管控制器添加为子视图控制器:
addChild(controller)
view.addSubview(controller.view)
controller.didMove(toParent: self)
Run Code Online (Sandbox Code Playgroud)
显然,您还要frame为主机控制器设置或布局约束view。
有关将一个视图控制器嵌入另一个视图控制器的一般信息,请参见文档的“ 实现容器视图控制器”部分。UIViewController
例如,假设我们有一个SwiftUI视图来渲染一个带有文本的圆:
struct CircleView : View {
@ObjectBinding var model: CircleModel
var body: some View {
ZStack {
Circle()
.fill(Color.blue)
Text(model.text)
.color(Color.white)
}
}
}
Run Code Online (Sandbox Code Playgroud)
假设这是我们视图的模型:
import Combine
class CircleModel: BindableObject {
var didChange = PassthroughSubject<Void, Never>()
var text: String { didSet { didChange.send() } }
init(text: String) {
self.text = text
}
}
Run Code Online (Sandbox Code Playgroud)
然后,我们的UIKit视图控制器可以添加SwiftUI视图,在中设置其框架/约束UIView,并根据需要更新其模型:
class ViewController: UIViewController {
private weak var timer: Timer?
private var model = CircleModel(text: "")
override func viewDidLoad() {
super.viewDidLoad()
addCircleView()
startTimer()
}
deinit {
timer?.invalidate()
}
}
private extension ViewController {
func addCircleView() {
let circleView = CircleView(model: model)
let controller = UIHostingController(rootView: circleView)
addChild(controller)
controller.view.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(controller.view)
controller.didMove(toParent: self)
NSLayoutConstraint.activate([
controller.view.widthAnchor.constraint(equalTo: view.widthAnchor, multiplier: 0.5),
controller.view.heightAnchor.constraint(equalTo: view.heightAnchor, multiplier: 0.5),
controller.view.centerXAnchor.constraint(equalTo: view.centerXAnchor),
controller.view.centerYAnchor.constraint(equalTo: view.centerYAnchor)
])
}
func startTimer() {
var index = 0
timer = Timer.scheduledTimer(withTimeInterval: 1, repeats: true) { [weak self] _ in
index += 1
self?.model.text = "Tick \(index)"
}
}
}
Run Code Online (Sandbox Code Playgroud)
我心里有一些想法。
UIHostingController因此:
addChild(hostingViewController)
hostingViewController.view.frame = ...
view.addSubview(hostingViewController.view)
hostingViewController.didMove(toParent: self)
Run Code Online (Sandbox Code Playgroud)
视图控制器总是使用其他视图控制器作为视图。
斯坦福大学 CS193P,https://youtu.be/w7a79cx3UaY?t=679
参考
| 归档时间: |
|
| 查看次数: |
2492 次 |
| 最近记录: |