Model, ViewModel, EnvironmentObject 的使用

1. Model 数据模型的定义与使用

  1.1 案例

struct UserModel: Identifiable{
    let id: String = UUID().uuidString
    let dispalyName: String
    let userName:    String
    let followerCount: Int
    let isVerified:  Bool
}

/// 数据模型
struct ModelBootcamp: View {
    @State var users:[UserModel] = [
       //"Nick", "Emily", "Samantha", "Chris"
        UserModel(dispalyName: "Nick", userName: "nick123", followerCount: 33, isVerified: false),
        UserModel(dispalyName: "Emily", userName: "emily1997", followerCount: 88, isVerified: true),
        UserModel(dispalyName: "Samantha", userName: "ninja", followerCount: 56, isVerified: false),
        UserModel(dispalyName: "Chris", userName: "chris2002", followerCount: 108, isVerified: true),
    ]
    
    var body: some View {
        NavigationView {
            List{
                //id:\.self : 在内容中为每个用户创建一个 id
                //ForEach(users, id:\.self) { user in
                //}
                ForEach(users) { user in
                    HStack(spacing: 15) {
                        Circle()
                            .frame(width: 35, height: 35)
                        VStack(alignment: .leading) {
                            Text(user.dispalyName)
                                .font(.headline)
                            Text("@\(user.userName)")
                                .foregroundColor(.gray)
                                .font(.caption)
                        }
                        Spacer()
                        
                        if user.isVerified{
                            Image(systemName: "checkmark.seal.fill")
                                .foregroundColor(.blue)
                        }
                        VStack{
                            Text("\(user.followerCount)")
                                .font(.headline)
                            Text("Follower")
                                .foregroundColor(.gray)
                                .font(.caption)
                        }
                    }
                    .padding(.vertical, 10)
                }
            }
            .listStyle(.insetGrouped)
            .navigationTitle("Users")
        }
    }
}

  1.2 效果图:

2. ViewModel MVVM 视图模型的定义与使用

  2.1 实现

/// 定义模型
struct FruitModel: Identifiable{
    let id: String  = UUID().uuidString
    let name: String
    let count: Int
}

//ObservableObject: 观察者对象
class FruitViewModel: ObservableObject{
    // Published:
    @Published var fruitArray:[FruitModel] = []
    @Published var isLoading:Bool = false
    
    init() {
        getFruits()
    }
    
    /// 获取数据
    func getFruits(){
        let fruit1 = FruitModel(name: "Orange", count: 12)
        let fruit2 = FruitModel(name: "Banana", count: 22)
        let fruit3 = FruitModel(name: "Watermelon", count: 65)
        
        isLoading = true
        DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
            self.fruitArray.append(fruit1)
            self.fruitArray.append(fruit2)
            self.fruitArray.append(fruit3)
            self.isLoading = false
        }
    }
    
    /// 删除数据
    func deleteFruit(index: IndexSet){
        fruitArray.remove(atOffsets: index)
    }
}

/// MVVM 视图模型
struct ViewModelBootcamp: View {
    
    // ObservedObject: 观察者对象,加载子 view 时,也会调用对象,更新数据
    // StateObject: 除非视图重新加载的时候,才会去掉用对象,视图需要更新时,底层数据并没有更新改变
    // @StateObject -> USE THIS ON CREATION / INIT
    // @ObservedObject -> USE THIS FOR SUBVIEWS
    @StateObject var fruitViewModel: FruitViewModel = FruitViewModel()
    
    var body: some View {
        NavigationView {
            List {
                if fruitViewModel.isLoading{
                    ProgressView()
                }else{
                    ForEach(fruitViewModel.fruitArray) { fruit in
                        HStack{
                            Text("\(fruit.count)")
                                .foregroundColor(.red)
                            Text(fruit.name)
                                .font(.headline)
                                .bold()
                        }
                    }
                    .onDelete(perform: fruitViewModel.deleteFruit)
                }
            }
            .listStyle(.grouped)
            .navigationTitle("Fruit List")
            .navigationBarItems(trailing:
                                    NavigationLink(destination: RandomScreen(fruitViewModel: fruitViewModel),
                                                   label: {
                Image(systemName: "arrow.right")
            }))
        }
    }
}

// 第二个页面
struct RandomScreen: View{
    // 呈现模式
    @Environment(\.presentationMode) var presentationMode
    
    @ObservedObject var fruitViewModel: FruitViewModel
    
    var body: some View{
        ZStack{
            Color.green.ignoresSafeArea()
            VStack{
                ForEach(fruitViewModel.fruitArray) { fruit in
                    Text(fruit.name)
                        .foregroundColor(.white)
                        .font(.headline)
                }
            }
        }
    }
}

  2.2 效果图:

3. EnvironmentObject 环境对象的使用

  3.1 实现

// ObservedObject
// StateObject
// EnvironmentObject

class EnvironmentViewModel: ObservableObject{
    @Published var dataArray: [String] = []
    
    init(){
        getData()
    }
    
    func getData(){
        self.dataArray.append(contentsOf: ["iPhone", "iPad", "iMac", "Apple Watch"])
    }
}

/// 环境对象 View 之间传递对象
struct EnvironmentObjectBootcamp: View {
    // 环境视图模型
    @StateObject var viewModel: EnvironmentViewModel = EnvironmentViewModel()
    
    var body: some View {
        NavigationView{
            List {
                ForEach(viewModel.dataArray, id: \.self) { item in
                    // DetailView(selectedItem: item, viewModel: viewModel)
                    NavigationLink(destination: DetailView(selectedItem: item)) {
                      Text(item)
                    }
                }
            }
            .navigationTitle("iOS Devices")
        }
        .environmentObject(viewModel)
    }
}

/// 详情 View
struct DetailView: View{
    let selectedItem: String
    //@ObservedObject var viewModel: EnvironmentViewModel
    
    var body: some View{
        ZStack{
            // background
            Color.orange.ignoresSafeArea()
            // foreground
            NavigationLink {
                //FinalView(viewMode: viewModel)
                FinalView()
            } label: {
                Text(selectedItem)
                    .font(.headline)
                    .foregroundColor(.orange)
                    .padding()
                    .padding(.horizontal)
                    .background(Color.white)
                    .cornerRadius(30)
            }
        }
    }
}

struct FinalView: View{
    //@ObservedObject var viewMode: EnvironmentViewModel
    // 添加环境视图模型
    @EnvironmentObject var viewMode: EnvironmentViewModel
    
    var body: some View{
        ZStack{
            // background 阴影从左上到下
            LinearGradient(gradient: Gradient(colors: [Color(#colorLiteral(red: 0.1764705926, green: 0.01176470611, blue: 0.5607843399, alpha: 1)), Color(#colorLiteral(red: 0.09019608051, green: 0, blue: 0.3019607961, alpha: 1))]),
                           startPoint: .leading,
                           endPoint: .trailing)
                           .ignoresSafeArea()
            // foreground
            ScrollView{
                VStack(spacing: 20) {
                    ForEach(viewMode.dataArray, id: \.self) { item in
                        Text(item)
                    }
                }
                .foregroundColor(.white)
                .font(.largeTitle)
            }
        }
    }
}

  3.2 效果图:

猜你喜欢

转载自blog.csdn.net/u011193452/article/details/131703030
今日推荐