我是SwiftUI的新手,我一直在尝试如何在同一个应用程序中将SwiftUI和UIKit集成在一起。我用SwiftUI制作了一个简单的登录屏幕。
struct LoginView: View {
var body: some View {
VStack {
LogoView()
InputView(title: "Company Code")
ButtonView(title: "Proceed")
}
}
}
我通过将视图中的所有组件提取到单独的视图(LogoView、InputView、ButtonView)中,使它们可以重用。
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])
}
}
我通过将视图嵌入到视图控制器的UIHostingController
中来显示视图。
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中点击按钮,一直到视图控制器?
在这个tutorial中,它使用ObservableObject
将数据传回视图控制器,尽管在那个示例中,整个视图都在一个SwiftUI文件中,但在我的示例中,我将视图分解为单独的组件。
所以我想知道,ObservableObject
仍然是这样做的吗?因为我的视图是子视图,我觉得创建多个可观察对象来传播子视图链上的值并不理想。
有没有更好的方法来实现这一目标?
Demo project
3条答案
按热度按时间e5nqia271#
首先,使用绑定到你的输入视图。对于动作,使用闭包将动作从SwiftUI获取到UIKit。
这里有一个可能的解决方案。
最后,在
viewDidLoad()
中svujldwt2#
对于这个问题,肯定没有一个 * 绝对 * 正确的答案。您提到的
ObservableObject
解决方案就是一个。假设您只需要单向数据流(您的示例似乎有),我可能会倾向于使用一个结构,该结构只有一个简单的委托函数,该函数通过操作调用--这是一种Redux风格的方法:这样的话,您仍然可以向所有子视图传递一些东西,但是像这样传递
DispatchFunction
是一个非常简单和轻微的依赖。aelbi1ox3#
首先使用NavigationLink和UIViewControllerRepresentable将动作数据(点击列表)从SwiftUI传递到UIKit。
设计将看起来像屏幕截图。
其次,您需要在SwiftUI视图中添加UIViewControllerRepresentable。
现在创建一个UIKit视图控制器,您将从SwiftUi获取数据并将其发送到UIKit类。