欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

SwiftUI MVVM架构案例(教程含源码)

程序员文章站 2024-03-24 13:03:40
...

什么是 MVVM 架构

MVVM是Model-View-ViewModel的简写。它本质上就是MVC 的改进版。MVVM 就是将其中的View 的状态和行为抽象化,让我们将视图 UI 和业务逻辑分开。当然这些事 ViewModel 已经帮我们做了,它可以取出 Model 的数据同时帮忙处理 View 中由于需要展示内容而涉及的业务逻辑。

看看SwiftUI如何实现

1、主界面代码

import SwiftUI

struct Sidebar: View {
    @StateObject private var viewModel = SidebarViewModel()
    @State private var isSearchPopoverPresented = false
    
    var body: some View {
        List(selection: $viewModel.selection) {
            ForEach(SidebarViewModel.MainSubreddits.allCases, id: \.self) { item in
                NavigationLink(destination: SubredditView(name: item.rawValue)) {
                    Label(LocalizedStringKey(item.rawValue.capitalized), systemImage: item.icon())
                }.tag(item.rawValue)
            }
 
            Divider()
            
            Group {
                Text("Account").foregroundColor(.white)
                Label("Profile", systemImage: "person.crop.square")
                Label("Inbox", systemImage: "envelope")
                Label("Posts", systemImage: "square.and.pencil")
                Label("Comments", systemImage: "bubble.middle.bottom.fill")
                Label("Saved", systemImage: "archivebox")
            }.listItemTint(Color("RedditGold"))
            
            Divider()
            
            Group {
                subredditsHeader.foregroundColor(.white)
                Label("r/games", systemImage: "globe")
                Label("r/gaming", systemImage: "globe")
                Label("r/fun", systemImage: "globe")
                Label("r/Diablo", systemImage: "globe")
            }.listItemTint(Color("RedditBlue"))
        }
        .listStyle(SidebarListStyle())
        .frame(minWidth: 150, idealWidth: 150, maxWidth: 200, maxHeight: .infinity)
        .padding(.top, 16)
    }
    
    private var subredditsHeader: some View {
        HStack {
            Text("Subreddits")
            Button {
                isSearchPopoverPresented = true
            } label: {
                Image(systemName: "plus.circle")
                    .imageScale(.large)
                    .foregroundColor(.blue)
            }
            .buttonStyle(BorderlessButtonStyle())
            .popover(isPresented: $isSearchPopoverPresented) {
                SearchSubredditsPopover()
            }

        }
    }
}

2、ViewModel代码

import Foundation
import SwiftUI

class SidebarViewModel: ObservableObject {
    enum MainSubreddits: String, CaseIterable {
        case best, hot, new, top, rising
        
        func icon() -> String {
            switch self {
            case .best: return "airplane"
            case .hot: return "flame.fill"
            case .new: return "calendar.circle"
            case .top: return "chart.bar.fill"
            case .rising: return "waveform.path.ecg"
            }
        }
    }
    
    @Published var selection: Set<String> = [MainSubreddits.best.rawValue]
}

推荐

基础文章推荐

经典教程推荐

上新

技术源码推荐

推荐文章

CoreData篇

Combine篇

TextField篇

JSON文件篇


一篇文章系列

技术交流

QQ:3365059189
SwiftUI技术交流QQ群:518696470