请稍侯

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())
    }
}