swiftui 使用 现有的ui
22 May 2023
SwiftUI 使用
现有的UIViewController页面中,集成一个SwiftUI视图模块
// 创建一个 SwiftUI 视图
import SwiftUI
struct MySwiftUIView: View {
var body: some View {
Text("Hello, SwiftUI!")
.padding()
}
}
// 在 UIViewController 中创建一个 UIHostingController 对象,并将 SwiftUI 视图添加到该控制器中:
import UIKit
import SwiftUI
class MyViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// 创建一个 UIHostingController 对象,并将 SwiftUI 视图添加到该控制器中
let hostingController = UIHostingController(rootView: MySwiftUIView())
addChild(hostingController)
view.addSubview(hostingController.view)
// 设置约束
hostingController.view.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
hostingController.view.topAnchor.constraint(equalTo: view.topAnchor),
hostingController.view.leadingAnchor.constraint(equalTo: view.leadingAnchor),
hostingController.view.trailingAnchor.constraint(equalTo: view.trailingAnchor),
hostingController.view.bottomAnchor.constraint(equalTo: view.bottomAnchor)
])
}
}
使用SwiftUI建一个名为PreViewDetail的视图,这个视图是个纵向的可滚动列表视图,其中包含titleBar, personal info bar, 基于webView的description view,以及基于grid 布局的product list view, 其中的子视图高度都自适内容的内度, PreViewDetail与PreViewDetailViewModel进行数据绑定,数据都在PreViewDetailViewModel中管理,实现如下:
import SwiftUI
struct PreViewDetail: View {
@ObservedObject var viewModel: PreViewDetailViewModel
var body: some View {
ScrollView {
VStack(spacing: 0) {
// TitleBar
HStack {
Text(viewModel.titleBarTitle)
.font(.title)
.fontWeight(.bold)
.foregroundColor(.black)
Spacer()
Button(action: {
// 按钮点击处理
}, label: {
Image(systemName: "heart")
.foregroundColor(.red)
})
}
.padding()
// Personal Info Bar
HStack {
Image(systemName: "person.circle.fill")
.foregroundColor(.blue)
VStack(alignment: .leading, spacing: 5) {
Text(viewModel.personalInfoName)
.font(.headline)
Text(viewModel.personalInfoText)
.font(.subheadline)
.foregroundColor(.secondary)
}
Spacer()
Button(action: {
// 按钮点击处理
}, label: {
Image(systemName: "chevron.right")
.foregroundColor(.gray)
})
}
.padding()
// Description View (基于 WebView)
WebView(url: viewModel.descriptionURL)
// Product List View (基于 Grid 布局)
ScrollView(.horizontal) {
LazyHGrid(rows: [GridItem(.flexible(minimum: 150))], spacing: 10) {
ForEach(viewModel.productList) { product in
VStack(alignment: .leading, spacing: 5) {
Image(systemName: "photo")
.resizable()
.frame(width: 150, height: 150)
Text(product.name)
.font(.headline)
Text(product.price)
.font(.subheadline)
.foregroundColor(.secondary)
}
.padding()
.background(Color.white)
.cornerRadius(10)
.shadow(radius: 2)
}
}
.padding()
}
Spacer()
}
}
}
}
struct PreViewDetail_Previews: PreviewProvider {
static var previews: some View {
PreViewDetail(viewModel: PreViewDetailViewModel())
}
}
