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

时间:2016-05-28 05:32:15

标签: ios swift uitableview uisegmentedcontrol

我有一个表视图控制器,单元格上方是一个分段控件。分段控件有3个选项。过去的帖子,当前的帖子和未来的帖子。我试图弄清楚如何将特定数据加载到表视图中,具体取决于在分段控件上选择的索引。

例如,如果选择了过去的帖子,我想将过去的数据从解析服务器加载到表格视图中。或选择Future Posts将未来帖子日期从Parse Server加载到表格视图中。

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

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

2 个答案:

答案 0 :(得分:0)

基本思想是,随着分段控件的更改,您将启动一个PFQuery来填充模型,然后触发重新加载表。例如,像:

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,然后相应地更新结果。

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

答案 1 :(得分:0)

我会做一些事情来创建一个控制器来执行获取,解析,并返回一个带有关联标识符的闭包,如果它发生了变化,你仍然可以使用这种方法。这些方面的东西。

更新

Rob's answer的帮助下,我想在完整性的答案中加入一些背景。

<from uri="file://user/tempdir?delete=true"/>

您甚至可以为段请求创建一个发布请求队列,如果您要开始一个新的操作,则取消所有先前的操作,因此从来没有给它机会重新加载您的数据。


这是一个关于如何实现viewController的可能方法:)

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)
             }
          })
    }
}