gpt4 book ai didi

ios - 将数据从 SwiftUI 传递到 UIKit

转载 作者:行者123 更新时间:2023-12-05 02:44:58 25 4
gpt4 key购买 nike

我是 SwiftUI 的新手,我一直在尝试如何在同一个应用程序中将 SwiftUI 和 UIKit 集成在一起。我使用 SwiftUI 制作了一个简单的登录屏幕。

struct LoginView: View {

var body: some View {
VStack {
LogoView()
InputView(title: "Company Code")
ButtonView(title: "Proceed")
}
}
}

enter image description here

我通过将它们提取到单独的 View (LogoView、InputView、ButtonView)中,使该 View 中的所有组件都可重用。

struct LogoView: View {
var body: some View {
VStack {
Image("logo")
Text("Inventory App")
.foregroundColor(.blue)
.fontWeight(.bold)
.font(.system(size: 32))
}
}
}

struct InputView: View {
let title: String

@State private var text: String = ""

var body: some View {
VStack(alignment: .leading) {
Text(title)
.foregroundColor(.gray)
.fontWeight(.medium)
.font(.system(size: 18))

TextField("", text: $text)
.frame(height: 54)
.textFieldStyle(PlainTextFieldStyle())
.padding([.leading, .trailing], 10)
.cornerRadius(10)
.overlay(RoundedRectangle(cornerRadius: 10).stroke(Color.gray))
}
.padding()
}
}

struct ButtonView: View {
let title: String

var body: some View {
Button(title) {
print(#function)
}
.frame(minWidth: 100, idealWidth: 100, maxWidth: .infinity, minHeight: 60, idealHeight: 60)
.font(.system(size: 24, weight: .bold))
.foregroundColor(.white)
.background(Color.blue)
.cornerRadius(10)
.padding([.leading, .trailing])
}
}

我通过将 View 嵌入 View Controller 中的 UIHostingController 来显示 View 。

class LoginViewController: UIViewController {

override func viewDidLoad() {
super.viewDidLoad()

let controller = UIHostingController(rootView: LoginView(observable: observable))
controller.view.translatesAutoresizingMaskIntoConstraints = false
addChild(controller)
view.addSubview(controller.view)
controller.didMove(toParent: self)

NSLayoutConstraint.activate([
controller.view.leadingAnchor.constraint(equalTo: view.leadingAnchor),
controller.view.topAnchor.constraint(equalTo: view.topAnchor),
controller.view.trailingAnchor.constraint(equalTo: view.trailingAnchor),
controller.view.bottomAnchor.constraint(equalTo: view.bottomAnchor)
])
}

}

我的问题是如何在 InputView 中输入文本并在 ButtonView 中点击按钮,一直到 View Controller?

在此tutorial ,它使用 ObservableObject 将数据传回 View Controller 。尽管在该示例中,整个 View 位于单个 SwiftUI 文件中。就我而言,我将 View 分解为单独的组件。

所以我想知道,ObservableObject 仍然是这样做的方式吗?由于我的 View 是 subview ,我觉得创建多个可观察对象来将值传播到 subview 链上并不理想。

有没有更好的方法来实现这一目标?

Demo project

最佳答案

首先,使用绑定(bind)到您的输入 View 。对于操作,使用闭包将操作从 SwiftUI 获取到 UIKit。

这是一个可能的解决方案。

class LoginViewObservable: ObservableObject {
@Published var code: String = ""
var onLoginAction: (()->Void)! //<-- Button action closure
}

struct LoginView: View {
@ObservedObject var observable: LoginViewObservable

var body: some View {
VStack {
LogoView()
InputView(title: "Company Code", text: $observable.code) //<- Binding text
ButtonView(title: "Proceed", action: observable.onLoginAction) //<- Pass action
}
}
}

struct InputView: View {
let title: String
@Binding var text: String //<- Binding

var body: some View {
VStack(alignment: .leading) {
Text(title)
.foregroundColor(.gray)
.fontWeight(.medium)
.font(.system(size: 18))

TextField("", text: $text)
.frame(height: 54)
.textFieldStyle(PlainTextFieldStyle())
.padding([.leading, .trailing], 10)
.cornerRadius(10)
.overlay(RoundedRectangle(cornerRadius: 10).stroke(Color.gray))
}
.padding()
}
}

struct ButtonView: View {
let title: String
var action: () -> Void

var body: some View {
Button(title) {
action() //<- Send action
}
.frame(minWidth: 100, idealWidth: 100, maxWidth: .infinity, minHeight: 60, idealHeight: 60)
.font(.system(size: 24, weight: .bold))
.foregroundColor(.white)
.background(Color(hex: "4980F3"))
.cornerRadius(10)
.padding([.leading, .trailing])
}
}

最后,在 viewDidLoad()

override func viewDidLoad() {
super.viewDidLoad()
// Other code----
observable.onLoginAction = { [weak self] in //<-- Get login action
print(self?.observable.code ?? "")
}
}

关于ios - 将数据从 SwiftUI 传递到 UIKit,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66204509/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com