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 效果图:

相关推荐
2501_9160074725 分钟前
iOS 崩溃日志的分析方法,将崩溃日志与运行过程结合分析
android·ios·小程序·https·uni-app·iphone·webview
linweidong41 分钟前
美团ios开发100道面试题及参考答案(下)
objective-c·swift·jspatch·ios开发·ios面试·ios面经·xcode调试
2501_916007471 小时前
React Native 混淆在真项目中的方式,当 JS 和原生同时暴露
javascript·react native·react.js·ios·小程序·uni-app·iphone
00后程序员张1 小时前
苹果应用商店上架App流程,签名证书、IPA 校验、上传
android·ios·小程序·https·uni-app·iphone·webview
2501_916007471 小时前
iOS 上架需要哪些准备,围绕证书、描述文件和上传方式等关键环节展开分析
android·ios·小程序·https·uni-app·iphone·webview
2501_915106322 小时前
iOS 上架费用解析,哪些成本可以通过流程优化降低。
android·ios·小程序·https·uni-app·iphone·webview
xinyu_Jina2 小时前
Info Flow:大规模列表渲染中的UI虚拟化、数据懒-加载与前端性能工程
前端·ui
皇上o_O2 小时前
Swift 新并发框架之 async/await
ios
TheNextByte12 小时前
如何将文件从iPhone传输到USB闪存盘?
ios·iphone
lzhdim2 小时前
iPhone 18系列明年Q1试产:首发A20系列芯片
ios·iphone