基于 SwiftUI 创建一个可删除、可添加列表项的列表

1,854 阅读1分钟

执行环境

  • macOS Mojave: 10.14.5
  • xcode: Version 11.0 beta 6 (11M392q)

预览效果

完整代码

import SwiftUI

class Item: Identifiable {
    var uuid: Int;
    var title: String
    
    init(title: String) {
        self.title = title
        self.uuid = generatteID()
    }
}

func _generateID() -> () -> Int {
    var id = 0
    
    return {
        id += 1
        return id
    }
}

var generatteID = _generateID()

struct ContentView: View {
    @State var list: [Item] = [
        Item(title: "A"),
        Item(title: "B"),
        Item(title: "C"),
        Item(title: "D"),
        Item(title: "E"),
    ]

    func delItemBy(uuid: Int) {
        let index = list.firstIndex(where: { $0.uuid == uuid })
        
        if index != nil {
            list.remove(at: index!)
        }
    }
    
    func push() {
        list.append(Item(title: "F"))
    }
    
    func remove() {
        list.removeLast()
    }
    
    var body: some View {
        NavigationView {
            List {
                ForEach(list) { item in
                    Button(action: { self.delItemBy(uuid: item.uuid) }) {
                        Text(item.title + item.uuid.description)
                    }
                }
            }
            .navigationBarTitle(Text("List"))
            .navigationBarItems(leading: Button(action: { self.push() }) { Text("Append") }, trailing: Button(action: { self.remove()}) { Text("RemoveLast") })
        }
    }
}

代码剖析

利用闭包创建一个自增长的 ID 生成器

func _generateID() -> () -> Int {
    var id = 0
    
    return {
        id += 1
        return id
    }
}

var generatteID = _generateID()

定义数据结构

class Item: Identifiable {
    var uuid: Int;
    var title: String
    
    init(title: String) {
        self.title = title
        self.uuid = generatteID()
    }
}
  • Item 实现了 Identifiable 协议,用来在 List 中可循环遍历功能
  • 每次创建这个对象时内部的成员变量 uuid 会调用 generatteID 方法获取自增长的 id

视图部分代码

详解参考注释

struct ContentView: View {
    // 使用 @State 属性包裹器,修饰 list 属性,关联视图的关系。
    // 修改属性值,视图也会更新
    @State var list: [Item] = [
        Item(title: "A"),
        Item(title: "B"),
        Item(title: "C"),
        Item(title: "D"),
        Item(title: "E"),
    ]

    // 删除 list 里的数据
    func delItemBy(uuid: Int) {
        let index = list.firstIndex(where: { $0.uuid == uuid })
        
        if index != nil {
            list.remove(at: index!)
        }
    }
    
    // 追加数据
    func push() {
        list.append(Item(title: "F"))
    }
    
    // 删除数据
    func remove() {
        list.removeLast()
    }
    
    var body: some View {
        // 使用导航视图
        NavigationView {
            // 定义一个列表
            List {
                // 循环数据源
                ForEach(list) { item in
                    // 使用按钮,绑定事件
                    Button(action: { self.delItemBy(uuid: item.uuid) }) {
                        Text(item.title + item.uuid.description)
                    }
                }
            }
            .navigationBarTitle(Text("List")) // 设置导航视图的 Title
            .navigationBarItems(leading: Button(action: { self.push() }) { Text("Append") }, trailing: Button(action: { self.remove()}) { Text("RemoveLast") }) // 设置顶部的按钮
        }
    }
}

运行代码