Generics/泛型, ViewBuilder/视图构造器 的使用

1. Generics 泛型的定义及使用

1.1 创建使用泛型的实例 GenericsBootcamp.swift

Swift 复制代码
import SwiftUI

struct StringModel {
    let info: String?
    func removeInfo() -> StringModel{
        StringModel(info: nil)
    }
}

struct BoolModel {
    let info: Bool?
    func removeInfo() -> BoolModel{
        BoolModel(info: nil)
    }
}

// CustomType = T
struct GenericModel<T>{
    let info: T?
    func removeInfo() -> GenericModel{
        GenericModel(info: nil)
    }
}

class GenericsViewModel: ObservableObject{
    /// 定义具体类型
    @Published var stringModel = StringModel(info: "hello, word!")
    @Published var boolModel = BoolModel(info: true)
    
    /// 定义泛型
    @Published var genericStringModel = GenericModel(info: "Hello, world!")
    @Published var genericBoolModel = GenericModel(info: true)
    
    func removeData(){
        stringModel = stringModel.removeInfo()
        boolModel = boolModel.removeInfo()
        genericStringModel = genericStringModel.removeInfo()
        genericBoolModel = genericBoolModel.removeInfo()
    }
}

/// 泛型 View
struct GenericView<T: View>: View{
    let content: T
    let title: String
    
    var body: some View{
        VStack {
            Text(title)
            content
        }
    }
}

/// 泛型
struct GenericsBootcamp: View {
    @StateObject private var viewModel: GenericsViewModel
    
    init() {
        _viewModel = StateObject(wrappedValue: GenericsViewModel())
    }
    
    var body: some View {
        VStack {
            GenericView(content: Text("custom content"), title: "new View")
            Text(viewModel.stringModel.info ?? "No data")
            Text(viewModel.boolModel.info?.description ?? "No data")
            
            Text(viewModel.genericStringModel.info ?? "No data")
            Text(viewModel.genericBoolModel.info?.description ?? "No data")
        }.onTapGesture {
            viewModel.removeData()
        }
    }
}

struct GenericsBootcamp_Previews: PreviewProvider {
    static var previews: some View {
        GenericsBootcamp()
    }
}

1.2 效果图:

2. ViewBuilder 视图构造器的定义及使用

2.1 创建视图构造器的实例 ViewBuilderBootcamp.swift

Swift 复制代码
import SwiftUI

/// 常规标题视图
struct HeaderViewRegular: View{
    let title: String
    let description: String?
    let iconName: String?
    
    var body: some View{
        VStack(alignment: .leading) {
            Text(title)
                .font(.largeTitle)
                .fontWeight(.semibold)
            
            if let description = description{
                Text(description)
                    .font(.callout)
            }
            
            if let iconName = iconName{
                Image(systemName: iconName)
            }
            
            RoundedRectangle(cornerRadius: 5)
                .frame(height: 2)
        }
        .frame(maxWidth: .infinity, alignment: .leading)
        .padding()
    }
}
/// 通用的标题视图
struct HeaderViewGeneric<Content: View>: View {
    let title: String
    // 泛型,可以为任何类型
    let content: Content
    
    init(title: String, @ViewBuilder content: () -> Content) {
        self.title = title
        self.content = content()
    }
    
    var body: some View{
        VStack(alignment: .leading) {
            Text(title)
                .font(.largeTitle)
                .fontWeight(.semibold)
            
            content
            
            RoundedRectangle(cornerRadius: 5)
                .frame(height: 2)
        }
        .frame(maxWidth: .infinity, alignment: .leading)
        .padding()
    }
}

/// 自定义水平堆栈视图
struct CustomHStack<Content: View>:View{
    let content: Content
    
    init(@ViewBuilder content: () -> Content){
        self.content = content()
    }
    
    var body: some View{
        HStack {
            content
        }
    }
}

/// 视图构造器
struct ViewBuilderBootcamp: View {
    var body: some View {
        VStack {
            HeaderViewRegular(title: "New Title", description: "Hello", iconName: "heart.fill")
            HeaderViewRegular(title: "Another title", description: nil, iconName: nil)
            HeaderViewGeneric(title: "Generic 3") {
                VStack {
                    Text("Hello, world!")
                    Image(systemName: "bolt.fill")
                }
            }
            
            CustomHStack {
                Text("Hi")
                Text("Wo")
            }
            
            HStack {
                Text("Hi")
                Text("Wo")
            }
            Spacer()
        }
    }
}

/// 本地视图构造器
struct LocalViewBuilder: View{
    
    enum ViewType {
        case one, two, three
    }
    
    let type: ViewType
    
    /// 视图构造器
    var body: some View {
        VStack {
            headerSection
        }
    }
    
    /// 标题部分 头部分
    @ViewBuilder private var headerSection: some View{
        switch type {
        case .one:
            oneView
        case .two:
            twoView
        case .three:
            threeView
        }
    }
    
    /// 视图一
    @ViewBuilder private var oneView: some View{
        Text("One!")
    }
    
    /// 视图二
    private var twoView: some View{
        VStack {
            Text("Two 2")
            Image(systemName: "heart.fill")
        }
    }
    
    /// 视图三
    private var threeView: some View{
        Image(systemName: "heart.fill")
    }
}

struct ViewBuilderBootcamp_Previews: PreviewProvider {
    static var previews: some View {
        //ViewBuilderBootcamp()
        LocalViewBuilder(type: .one)
    }
}

2.2 效果图:

相关推荐
Magnetic_h7 小时前
【iOS】方法与消息底层分析
笔记·学习·macos·ios·objective-c·cocoa
MaoJiu14 小时前
Flutter与原生端的通信
flutter·ios
iReaShare16 小时前
如何将 iPhone 备份到云端:完整指南
ios
前端开发与ui设计的老司机16 小时前
从UI设计到数字孪生实战应用:构建智慧金融的风险评估与预警平台
ui·金融
小赵小赵福星高照~17 小时前
iOS UI视图面试相关
ui·ios·面试
float_六七18 小时前
Vue:构建高效UI的渐进式框架
javascript·vue.js·ui
杂雾无尘20 小时前
苹果高管揭示苹果背后秘密:苹果为何不涉足搜索引擎领域?
ios·apple
二流小码农20 小时前
鸿蒙开发:一键更新,让应用无需提交应用市场即可下载安装
android·ios·harmonyos
2501_915921431 天前
没有Mac如何完成iOS 上架:iOS App 上架App Store流程
android·ios·小程序·https·uni-app·iphone·webview
共享ui设计和前端开发人才2 天前
UI前端与数字孪生结合案例分享:智慧城市的智慧能源管理系统
前端·ui·智慧城市