美文网首页
swiftUI combine 实现简单TodoList(一)

swiftUI combine 实现简单TodoList(一)

作者: garyZlot | 来源:发表于2020-09-10 08:29 被阅读0次

    目标:任务列表展示,任务添加

    1. Xcode新建项目TodoList,选择Tabbed App, User Interface 选择swiftUI。

    2. swiftUI实现list add界面

    Xcode 自动生成两个Tab页面,ContentView.swift preview 窗口


    ContentView Preview

    First 改为list页面, Second 改为add页面


    List Add 界面
    @State private var todoStr = ""
    @State private var descStr=""
    

    TextField text参数需要Binding<String>类型,使用$符号将String类型转换为Binding<String>类型,关于 @State,@Binding 请参考 https://www.jianshu.com/p/527db4ae79de

    3. 数据管理类TodoManager

    import SwiftUI
    import Combine
    
    class TodoManager: NSObject, ObservableObject {
        @Published var todos = [todo]()
        
        func addTask(name: String, desc: String) {
            todos.append(todo(name: name, desc: desc))
        }
    }
    
    struct todo: Identifiable {
        var id:  UUID = UUID()
        var name: String
        var desc: String
    }
    

    实现Combine协议ObservableObject, 作为被观察者。添加一个数组变量todos, 添加Combine关键字 @Published

    @Published 官方解释

    /// Properties annotated with `@Published` contain both the stored value and a publisher which sends any new values after the property value has been sent. New subscribers will receive the current value of the property first.
    /// Note that the `@Published` property is class-constrained. Use it with properties of classes, not with non-class types like structures.
    

    这样todos数组有任何变化,都能及时通知订阅者。

    SwiftUI的ForEach使用Identifiable来确保数组改变的时,准确定位要插入的元素,或者删除的元素。所以让struct todo实现协议Identifiable并提供id生成方法。

    4. 数据显示

    ContentView.swift 中 添加

    @EnvironmentObject private var todoManager: TodoManager
    

    @EnvironmentObject 会在环境中自动查找一个 TodoManager 实例,并且把找到的结果放进 todoManager 属性。所以在ContentView_Previews 及 SceneDelegate 中需要添加这个实例,否则会报错。

    ContentView().environmentObject(TodoManager())
    

    Add页面

    实现Add页面按钮事件,点击Add按钮,更新todoMangaer并切换到List页面

    self.todoManager.addTask(name: self.todoStr, desc: self.descStr)
    self.selection = 0
    

    List 页面

    替换原来的假数据

    ForEach(todoManager.todos) { todo in
           VStack {
                Text(todo.name)
                    .font(.title)
                Text(todo.desc)
                    .font(.subheadline)
           }
    }
    

    Over~
    源码 https://github.com/garyZlot/TodoList

    相关文章

      网友评论

          本文标题:swiftUI combine 实现简单TodoList(一)

          本文链接:https://www.haomeiwen.com/subject/qbfeektx.html