选择要加载到 table 视图 Swift 中的数据

Selecting data to be loaded into table view Swift

我有一个 table 视图控制器,单元格上方是一个分段控件。分段控件有 3 个选项。过去 Post 秒,当前 Post 秒,未来 Post 秒。我试图弄清楚如何根据在分段控件上选择的索引将特定数据加载到 table 视图中。

例如,如果选择过去的 Post,我想将过去的 Post 数据从 Parse Server 加载到 table 视图中。或选择 Future Posts 将 Future Posts 日期从 Parse Server 加载到 table 视图中。

我完全不确定如何加载 "selected" 数据,然后在索引更改时删除并加载不同的数据。非常感谢任何帮助!

此外,我知道如何从 Parse Server 获取数据。我只是提到这一点来解释我的数据来自哪里。

基本思路是,当分段控件发生变化时,您将启动一个 PFQuery 来填充您的模型,然后触发 table 的重新加载。例如,类似于:

class ViewController: UIViewController, UITableViewDataSource {

    @IBOutlet weak var tableView: UITableView!

    var posts: [Post]?

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    @IBAction func didChangeValueForSegmentedControl(sender: UISegmentedControl) {
        // first empty the table

        posts = nil
        tableView.reloadData()

        // prepare new query

        let query = PFQuery(className: "Posts")

        switch sender.selectedSegmentIndex {
        case 0:
            query.whereKey("status", equalTo: "past")
        case 1:
            query.whereKey("status", equalTo: "current")
        case 2:
            query.whereKey("status", equalTo: "future")
        default:
            fatalError("unexpected segment index")
        }

        // now perform query

        query.findObjectsInBackgroundWithBlock { objects, error in
            guard error == nil else {
                // report error
                return
            }

            guard let searchResults = objects as? [Post] else {
                // handle situation where results were not an array of `Post` objects
                return
            }

            self.posts = searchResults
            self.tableView.reloadData()
        }
    }

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

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! PostCell

        let post = posts![indexPath.row]

        // configure `cell` using `post`

        return cell
    }
}

现在,那些 whereKey 子句肯定是不对的,这会根据您的对象模型的设置方式而改变,但这说明了基本思想。根据选择的分段控件启动PFQuery,然后相应地更新结果。

现在,这一切都做出了很多假设(您已经定义了 table 视图并将视图控制器指定为它的数据源;您已经为 table 视图;您已经在分段控件上为 valueChanged 连接了 IBAction;您已经定义了具有自定义单元格类型的单元格原型;等等),但它说明了关键解决方案的一部分。

我会做一些事情来创建一个控制器来执行获取、解析和 returns 一个带有关联标识符的闭包,如果它发生变化,您仍然可以使用这种方法。沿着这些路线。

更新

的帮助下,为了完整性,我想在我的回答中加入一些背景信息。

typealias PostsCompletionClosure = (requestIdentifier : String, posts : [Post])->Void

class PostController {

    func fetchPastPosts(requestIdentifier : String,
                        completion : PostsCompletionClosure,
                        queue : dispatch_queue_t?) {

        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) {

            let queryParams = ["status" : "past"]

            self.performQuery(queryParams, completion: { (requestID, posts) in
                dispatch_async(queue != nil ? queue : dispatch_get_main_queue()) {
                   completion(requestIdentifier : requestIdentifier, posts : posts)
                }
            })
        }
    }

    func fetchCurrentPosts(requestIdentifier : String, 
                           completion : PostsCompletionClosure, 
                           queue : dispatch_queue_t?) {
        // Same as Above
    }

    func fetchFuturePosts(requestIdentifier : String, 
                          completion : PostsCompletionClosure, 
                          queue : dispatch_queue_t?) { {
        // Same as Above
    }

    private func performQuery(queryParams: [String : String], 
                              completion : PostsCompletionClosure) {

         let query = PFQuery(className: "Posts")

         for {key, value) in queryParams {
             query.whereKey(key, equalTo: value)
         }

         query.findObjectsInBackgroundWithBlock { objects, error in
            guard let error == nil else {
                // Handle Error
                return
            }

             if let results = objects as? [Post] {
                dispatch_get_main_queue()) {
                   completion(requestIdentifier : requestIdentifier, posts : posts)
             }
          })
    }
}

您甚至可以为段请求创建一个 post 请求队列,如果您要开始一个新的请求,则取消所有先前的操作,这样就永远不会给它机会重新加载您的数据第一名.


这是关于如何实现 viewController :)

的可能方法
class ViewController: UIViewController, UITableViewDataSource {

    @IBOutlet weak var tableView: UITableView!
    @IBOutlet var segnmentControl: UISegmentedControl!

    var posts: [Post]?
    var activeRequestId: String = ""

    // This should prolly be injected or a singleton
    let postsController = PostController()

    override func viewDidLoad() {
        super.viewDidLoad()
        didSelectSelegment(segnmentControl)
    }

    @IBAction func didSelectSelegment(sender: UISegmentedControl) {
        posts = nil
        tableView.reloadData()

        activeRequestId = "\(sender.selectedSegmentIndex)"

        switch sender.selectedSegmentIndex {
        case 0:
            self.postsController.fetchPastPosts(activeRequestId, completion: { (requestIdentifier, posts) in
                 self.reloadDataWith(requestIdentifier, posts : [Post])
            })
        case 1:
            self.postsController.fetchCurrentPosts(activeRequestId, completion: { (requestIdentifier, posts) in
                 self.reloadDataWith(requestIdentifier, posts : [Post])
            })
        case 2:
            self.postsController.fetchFuturePosts(activeRequestId, completion: { (requestIdentifier, posts) in
                 self.reloadDataWith(requestIdentifier, posts : [Post])
            })
        default:
            fatalError("unexpected segment index")
        }
    }

    func reloadDataWith(requestIdentifier : String,
                        posts : [Post]) {

        if self.requestIdentifier == requestIdentifier {
            self.posts = posts
            self.tableView.reloadData()
        }
     }                         
}