选择要加载到 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()
}
}
}
我有一个 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()
}
}
}