您好社区,前几天我试图使用Xcode Playground测试一些UI,但体验并不是最好的。 Xcode不断崩溃,所以我决定尝试另一种方法。
使用Swiftui预览来测试我的Uikit视图!
因此,在本教程中,我们将学习将Uikit集成在Swiftui中的第一步。
让我们开始!
创建项目
首先让我们开始XCode并创建一个新项目,然后选择iOS>应用,然后单击下一步。这次选择SwiftUi作为接口,并给它提供任何您想要的名称。最后选择一个保存文件并创建项目的地方。
创建Uikit视图
让我们创建一个带有CounterViewController.swift
名称的新快文件。我们将在此文件中创建我们的Uikit接口。
为了简单起见,让我们做一个简单的视图,显示标签A按钮。
import UIKit
final class CounterViewController: UIViewController {
private var counter = 0
private lazy var button: UIButton = {
let button = UIButton()
button.setTitle("Tap me from UIKit", for: .normal)
button.setTitleColor(.systemBlue, for: .normal)
button.translatesAutoresizingMaskIntoConstraints = false
return button
}()
private lazy var label: UILabel = {
let label = UILabel()
label.text = getMessage()
label.textAlignment = .center
label.translatesAutoresizingMaskIntoConstraints = false
return label
}()
override func viewDidLoad() {
super.viewDidLoad()
addComponents()
addHandlers()
addConstrains()
}
}
private extension CounterViewController {
func getMessage() -> String{
"UIKit Button was tapped \(counter)"
}
func addConstrains() {
NSLayoutConstraint.activate([
label.topAnchor.constraint(equalTo: view.topAnchor, constant: 64),
label.centerXAnchor.constraint(equalTo: view.centerXAnchor),
label.widthAnchor.constraint(equalToConstant: 250),
label.heightAnchor.constraint(equalToConstant: 50),
button.centerXAnchor.constraint(equalTo: view.centerXAnchor),
button.topAnchor.constraint(equalTo: label.bottomAnchor, constant: 64),
button.heightAnchor.constraint(equalToConstant: 48),
button.widthAnchor.constraint(equalToConstant: 200),
])
}
func addComponents() {
[button, label]
.forEach { view.addSubview($0) }
}
func addHandlers() {
button.addTarget(self, action: #selector(didButtonTapped), for: .touchUpInside)
}
@objc func didButtonTapped(_ sender: UIButton) {
counter += 1
label.text = getMessage()
}
}
上面的代码显示了一个标签,该标签将在按下按钮后进行更新。
创建Swiftui绑定
要将我们的UIKIT代码嵌入SwiftUI中,我们需要创建一个包含符合UIViewControllerRepresentable
的结构的新文件。
创建一个名为CounterView
的新的Swift文件,并添加以下代码:
import SwiftUI
struct CounterView: UIViewControllerRepresentable {
typealias UIViewControllerType = CounterViewController
func makeUIViewController(context: Context) -> CounterViewController {
CounterViewController()
}
func updateUIViewController(_ uiViewController: CounterViewController, context: Context) {
// Update the ViewController here
}
}
这个结构是我们将使用的包装器来创建我们的swiftui视图。
要符合UIViewControllerRepresentable
我们的结构需要三件事
-
typealias UIViewControllerType
:这是UikitClass的类型别名,在我们的情况下是ViewController。 -
func makeUIViewController(context: Context)
:此函数是将为swiftui 创建我们的ViewController实例的功能
-
func updateUIViewController(_ uiViewController: CounterViewController, context: Context)
:每次发生我们的视图发生变化时,都称为此功能,我们可以在此功能中更新我们的Uikit。
在Swiftiu中创建我们的视图对象
最后,让我们创建我们将在Swiftui中使用的绑定视图。
这样做只需实例化新视图对象,仅此而已。
import SwiftUI
struct ContentView: View {
var body: some View {
VStack {
Text("SwiftUI + UIKit")
.padding(48)
.font(.title.bold())
CounterView(labelText: $label)
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
xcode live预览Uikit组件,您可以在按钮上单击它,它将起作用!
。现在,您可以更改Uikit代码,并在Swiftui预览中查看实时更新。
结论
在第一个教程中,我们能够在Swiftui视图中嵌入Uikit View Controller,并且能够在实时预览中预览工作。第一次尝试向我们展示了在Swiftui和Uikit之间创建互操作性多么容易。
在即将到来的教程中,我们将与@Binding
和@State
添加双向通信。
谢谢您的阅读。