如何将Uikit ViewController嵌入Swiftui视图中
#初学者 #ios #swiftui #uikit

您好社区,前几天我试图使用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我们的结构需要三件事

  1. typealias UIViewControllerType:这是UikitClass的类型别名,在我们的情况下是ViewController。
  2. func makeUIViewController(context: Context):此函数是将为swiftui
  3. 创建我们的ViewController实例的功能
  4. 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组件,您可以在按钮上单击它,它将起作用!

swiftui-preview

现在,您可以更改Uikit代码,并在Swiftui预览中查看实时更新。

结论

在第一个教程中,我们能够在Swiftui视图中嵌入Uikit View Controller,并且能够在实时预览中预览工作。第一次尝试向我们展示了在Swiftui和Uikit之间创建互操作性多么容易。

在即将到来的教程中,我们将与@Binding@State添加双向通信。

谢谢您的阅读。