跳转至

iOS TableView Storyboard示例 - 列表页使用UITableViewDataSource

更新日期 2022-2-18
  • 2022-2-18 创建文档
开发环境与工具
  • Xcode13
  • iOS 14.4
  • Swift

本文在显示列表示例基础上进行修改。引入UITableViewDataSource使用。

主要修改都在列表页。

一共涉及4个swift文件:

  • SampleEntity.swift
  • SampleListCell.swift
  • SampleListDataSource.swift # 新文件
  • SampleListVC.swift

SampleEntity

首先SampleEntity保持不变

import Foundation // an.rustfisher.com

struct SampleEntity {
    var title: String
    var desc: String
    var isComplete: Bool = false
    var updatedDate: Date
}

extension SampleEntity {
    static var testData = [
        SampleEntity(title: "iOS入门开发3", desc: "https://an.rustfisher.com", updatedDate: Date().addingTimeInterval(800.0)),
        // 测试数据..
    ]
}

SampleListCell

数据类SampleEntity没有变,我们改变一下控制Cell的UI的SampleListCell

import UIKit

// an.rustfisher.com
class SampleListCell : UITableViewCell {

    @IBOutlet weak var doneBtn: UIButton!

    @IBOutlet weak var titleLabel: UILabel!

    @IBOutlet weak var subtitleLabel: UILabel!

    typealias DoneAction = () -> Void

    private var doneAction: DoneAction? // 改成private

    @IBAction func onClickDoneBtn(_ sender: UIButton) {
        doneAction?()
    }

    // 新增一个方法用来传送数据
    func cfg(title:String, subtitle:String, isDone:Bool, inputDoneBtnAction: @escaping DoneAction) {
        // 在里面控制ui
        titleLabel.text = title
        subtitleLabel.text = subtitle
        let image = isDone ? UIImage(systemName: "circle.fill") : UIImage(systemName: "circle")
        doneBtn.setBackgroundImage(image, for: .normal)
        self.doneAction = inputDoneBtnAction
    }
}

首先是给doneAction加上private,缩小访问范围。

swift中可见范围(访问范围)有如下3种:

  • public 任何位置的代码都可以访问,非常开放
  • internal (默认的)在同一个模块内的代码可以访问。同一个模块指的是同一个应用或者framework。
  • private 本类中自己的代码,或者是extension中的代码可以访问。

增加cfg方法,从外面传入要显示的数据。注意参数中不要忘记@escaping DoneAction

现在的SampleListCell更像一个纯粹的组件。

SampleListDataSource

新建SampleListDataSource.swiftSampleListDataSource类继承自NSObject

import UIKit

class SampleListDataSource: NSObject {

}

extension SampleListDataSource: UITableViewDataSource {
    static let sampleDataCellId = "SampleListCell"

    // 已经删去这里的 override
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return SampleEntity.testData.count
    }

    // 已经删去这里的 override
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        guard let cell = tableView.dequeueReusableCell(withIdentifier: Self.sampleDataCellId, for: indexPath) as? SampleListCell else {
            fatalError("找不到SampleListCell")
        }
        let dataEntity = SampleEntity.testData[indexPath.row]
        cell.cfg(title: dataEntity.title, subtitle: dataEntity.desc, isDone: dataEntity.isComplete,
                 inputDoneBtnAction: {
                    SampleEntity.testData[indexPath.row].isComplete.toggle()
                    tableView.reloadRows(at: [indexPath], with: .none)
        })
        return cell
    }
}
extension SampleListDataSource里面的代码是从原来的SampleListVC里移动过来的。

这个类的作用是控制详情的显示。

SampleListVC

下面是SampleListVC

import UIKit

class SampleListVC: UITableViewController {
    static let showDetailSegueId = "ShowDetailSegueId"

    private var sampleListDataSource: SampleListDataSource? // 持有 dataSource

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == Self.showDetailSegueId,
           let destination = segue.destination as? SampleDetailVC,
           let cell = sender as? UITableViewCell,
           let indexPath = tableView.indexPath(for: cell) {
            let entity = SampleEntity.testData[indexPath.row] // 取出数据
            destination.cfg(with: entity)
        }
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        sampleListDataSource = SampleListDataSource() // 初始化
        tableView.dataSource = sampleListDataSource // 交给tableView
    }
}

// 把extension SampleListVC的代码移动去了extension SampleListDataSource

我们把extension SampleListVC的代码移动去了extension SampleListDataSource

SampleListVC持有一个sampleListDataSource变量,复写viewDidLoad(),在页面加载的时候创建一个SampleListDataSource(),并把它交给tableView

至此,运行app试一下,可以看到效果。


使用storyboard与TableView的一个ToDo例子

本站说明

一起在知识的海洋里呛水吧。广告内容与本站无关。如果喜欢本站内容,欢迎投喂作者,谢谢支持服务器。如有疑问和建议,欢迎在下方评论~

📖AndroidTutorial 📚AndroidTutorial 🙋反馈问题 🔥最近更新 🍪投喂作者

Ads