【问题标题】:Separating Data Source to another class in Swift and then handling data changes将数据源分离到 Swift 中的另一个类,然后处理数据更改
【发布时间】:2016-09-17 15:13:54
【问题描述】:

我正在尝试遵循此处看到的模式:https://www.objc.io/issues/1-view-controllers/lighter-view-controllers/ 并且还在这里查看了此问题:Separating Data Source to another class in Swift

我有以下代码:

class ApplicationsViewController: UIViewController {

    @IBOutlet var tableView: UITableView!
    let tableViewDataSource = ApplicationTableDataSource()

    override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) {
        super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
    }

    required init?(coder aDecoder: NSCoder) {
        //fatalError("init(coder:) has not been implemented")
        super.init(coder: aDecoder)
    }

    override func viewDidLoad() {
        setupView()
    }

    func setupView() {
        tableView.dataSource = tableViewDataSource
    }
}

但是,我不完全了解将数据通信/传递到数据源的最佳方式是什么。

作为一个例子,让我们假设应用程序启动并且我们的数据源中没有数据。在我们的 ApplicationTableDataSource 类中,我们有一个名为 setApplicationData 的方法。在 viewController 中,我们单击添加按钮,该按钮为作业添加新应用程序:

func buttonPressed() {
    let data = NSData()        

    //Here we want to add the data to array in data source

    // We can't do the following as tableView.dataSource doesn't know about the setApplicationData method:
    tableView.dataSource.setApplicationData(data)

    // We could do: 
    tableViewDataSource.setApplicationData(data)
}

我不确定这是否是更新数据源的最佳方式。

有没有更好的方法来处理更新数据源?

【问题讨论】:

  • 您使用的实际数据源是什么?它只是一个静态数组,从核心数据中提取的数据,一个网络请求吗? UITableViewDataSourceDelegate 提供了向表格视图提供数据源所需的一切,您无需设置数据,只需告诉表格视图发生了变化。
  • 是的,这是有道理的。这将是核心数据。然而,这更像是一个笼统的问题。有人使用按钮添加内容。控制器处理按钮按下。但是,需要更新底层模型,在这种情况下,它是 dataSource 类中的一个数组。这将如何运作?
  • 这是否意味着数据源类直接与核心数据或网络层对话?

标签: ios swift uitableview design-patterns datasource


【解决方案1】:

如果您使用核心数据并在表格视图中显示此信息,我强烈建议您查看NSFetchedResultsController

我第一次使用this guide,发现它是一个非常有效的解决方案。

当用户将新信息添加到核心数据表中,与您用于显示数据的查询相匹配时,tableview 会自动为您插入行。

如果您想保持简单并使用数组,您可以将新数据附加到数组中,然后在 tableView 上调用 reloadDatainsertRowsAtIndexPaths。这个SO answer 将帮助您实现这种方法。

只是为了让您了解如何将另一个文件用于 tableView 数据源,请参见下文:

class ViewController: UIViewController {

    @IBOutlet weak var tableView: UITableView!
    var dataSource = TBDataSource()

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.

        tableView.dataSource = dataSource
        tableView.delegate = self

        dataSource.insertData("Data Row 1")
        dataSource.insertData("Data Row 2")
        dataSource.insertData("Data Row 3")
        dataSource.insertData("Data Row 4")
    }
}

class TBDataSource: NSObject, UITableViewDataSource  {

    var data = [String]()

    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return data.count
    }

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

        let cell = tableView.dequeueReusableCellWithIdentifier("cell")!
        cell.textLabel?.text = data[indexPath.row]
        return cell

    }

    func insertData(str:String) {
        data.append(str)
    }
}

这几乎是从外部类向表提供数据的最低设置。如果您在初始加载后添加数据,如果您不使用 NSFectchedResultsController,则需要调用 reloadData 或 insertRowAtSection

【讨论】:

    猜你喜欢
    • 2014-11-05
    • 2019-04-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-30
    • 2020-11-05
    • 1970-01-01
    相关资源
    最近更新 更多