解析:按行检索数据
Posted
技术标签:
【中文标题】解析:按行检索数据【英文标题】:Parse: Retrieving Data by Row 【发布时间】:2015-12-27 00:08:23 【问题描述】:概述:我怎样才能使当单元格与 segue 标识符为 0 将加载 ID 为 0 的行中的数据,segue 标识符为 1 的单元格将加载 ID 为 1 的行中的数据,依此类推。数据包括 ID(响应单元格标识符)、navTitle(导航栏标题)、write(文章作者)、date(文章日期)和 article(文章本身)。
我正在努力做到这一点,以便一旦在我的表格视图中点击一个单元格,它就会打开该单元格独有的数据。最好的方法是什么?我在想也许我应该让它检查我在 Parse 上的 ID 列并将数据加载到该行中的数据,但我不知道该怎么做。有一个更好的方法吗?任何帮助表示赞赏!如有任何其他信息,请随时向我询问。
^ 所以这里我有一个表格视图,其中数据从 Parse 中获取并用于两个标签。
^ 这个视图控制器被连接到上面的单元格:
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath)
if indexPath.row == 0
self.performSegueWithIdentifier("0a", sender: nil)
self.tableview.deselectRowAtIndexPath(indexPath, animated: true)
这是我的 EventsDetailViewController,点击单元格时调用的控制器:
import UIKit
import Parse
import ParseUI
import Bolts
class EventDetailViewController: UIViewController
@IBAction func eventDetail(sender: AnyObject)
dismissViewControllerAnimated(true, completion: nil)
@IBOutlet weak var articleTitle: UILabel!
@IBOutlet weak var writtenBy: UILabel!
@IBOutlet weak var date: UILabel!
@IBOutlet weak var article: UITextView!
@IBOutlet weak var navBar: UINavigationBar!
var dateDetail = [String]()
var articleDetail = [String]()
override func viewDidLoad()
super.viewDidLoad()
loadEvents()
// Do any additional setup after loading the view.
override func didReceiveMemoryWarning()
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
func loadEvents () -> Void
var query = PFQuery(className: "eventsdetail")
query.findObjectsInBackgroundWithBlock
(objects: [PFObject]?, error : NSError?) -> Void in
if error == nil
if let objects = objects as [PFObject]!
for object in objects
var output1 = object.objectForKey("navTitle") as! String
self.navBar.topItem?.title = output1
var output2 = object.objectForKey("articleTitle") as! String
self.articleTitle.text = output2
var output3 = object.objectForKey("written") as! String
self.writtenBy.text = output3
var output4 = object.objectForKey("date") as! String
self.date.text = output4
var output5 = object.objectForKey("article") as! String
self.article.text = output5
这是我的 EventsViewController:
import UIKit
import Parse
import Bolts
import ParseUI
class EventsViewController: UIViewController, UITableViewDataSource, UITableViewDelegate
var timer: NSTimer!
var isAnimating = false
var currentColorIndex = 0
var currentLabelIndex = 0
var customView: UIView!
var labelsArray: Array<UILabel> = []
var refreshControl: UIRefreshControl!
var testArray = [String]()
var subArray = [String]()
@IBOutlet weak var tableview: UITableView!
@IBOutlet weak var webView: UIWebView!
override func viewDidLoad()
super.viewDidLoad()
refreshControl = UIRefreshControl()
tableview.delegate = self
tableview.dataSource = self
refreshControl.addTarget(self, action: Selector("loadEvents"), forControlEvents: UIControlEvents.ValueChanged)
self.tableview.addSubview(refreshControl)
loadEvents()
loadCustomRefreshContents()
//refreshControl colors
refreshControl.backgroundColor = UIColor.clearColor() //color of background
refreshControl.tintColor = UIColor.clearColor() //color of indicator
override func didReceiveMemoryWarning()
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
func loadEvents () -> Void
testArray = [String]()
subArray = [String]()
let query = PFQuery(className: "events")
let runkey = query.orderByDescending("eventTitle")
runkey.findObjectsInBackgroundWithBlock
(objects: [PFObject]?, error:NSError?) -> Void in
if error == nil
if let objects = objects as [PFObject]!
for object in objects
let load = object.objectForKey("eventTitle") as! String
self.testArray.append(load)
let subload = object.objectForKey("date") as! String
self.subArray.append(subload)
//reload TableView
self.tableview.reloadData()
print(self.testArray)
else
print("error:\(error!) \(error!.userInfo)")
refreshControl.endRefreshing()
func do_table_refresh()
dispatch_async(dispatch_get_main_queue())
self.tableview.reloadData()
return
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath)
if indexPath.row == 0
self.performSegueWithIdentifier("0a", sender: nil)
self.tableview.deselectRowAtIndexPath(indexPath, animated: true)
func tableView(tableView:UITableView!, numberOfRowsInSection section:Int) -> Int
return testArray.count
func numberOfSectionsInTableView(tableView: UITableView) -> Int
return 1
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
let cell = tableView.dequeueReusableCellWithIdentifier("eventcell", forIndexPath: indexPath) as! EventTableViewCell
cell.title.text = self.testArray[indexPath.row]
cell.subTitle.text = self.subArray[indexPath.row]
return cell
//refreshes tableview; starts refresh
func loadCustomRefreshContents()
let refreshContents = NSBundle.mainBundle().loadNibNamed("RefreshControl", owner: self, options: nil)
customView = refreshContents[0] as! UIView
customView.frame = refreshControl.bounds
for var i=0; i<customView.subviews.count; ++i
labelsArray.append(customView.viewWithTag(i + 1) as! UILabel)
refreshControl.addSubview(customView)
//stops refresh
func scrollViewDidEndDecelerating(scrollView: UIScrollView)
do_table_refresh()
if refreshControl.refreshing
if !isAnimating
animateRefreshStep1()
//cycles through colors
func getNextColor() -> UIColor
var colorsArray: Array<UIColor> = [UIColor.magentaColor(), UIColor.brownColor(), UIColor.yellowColor(), UIColor.redColor(), UIColor.greenColor(), UIColor.blueColor(), UIColor.orangeColor()]
if currentColorIndex == colorsArray.count
currentColorIndex = 0
let returnColor = colorsArray[currentColorIndex]
++currentColorIndex
return returnColor
func doSomething()
timer = NSTimer.scheduledTimerWithTimeInterval(4.0, target: self, selector: "endOfWork", userInfo: nil, repeats: true)
self.do_table_refresh()
func endOfWork()
refreshControl.endRefreshing()
timer.invalidate()
timer = nil
//first part of animation
func animateRefreshStep1()
isAnimating = true
UIView.animateWithDuration(0.1, delay: 0.0, options: UIViewAnimationOptions.CurveLinear, animations: () -> Void in
self.labelsArray[self.currentLabelIndex].transform = CGAffineTransformMakeRotation(CGFloat(M_PI_4))
self.labelsArray[self.currentLabelIndex].textColor = self.getNextColor()
, completion: (finished) -> Void in
UIView.animateWithDuration(0.05, delay: 0.0, options: UIViewAnimationOptions.CurveLinear, animations: () -> Void in
self.labelsArray[self.currentLabelIndex].transform = CGAffineTransformIdentity
self.labelsArray[self.currentLabelIndex].textColor = UIColor.blackColor()
, completion: (finished) -> Void in
++self.currentLabelIndex
if self.currentLabelIndex < self.labelsArray.count
self.animateRefreshStep1()
else
self.animateRefreshStep2()
)
)
//second part of animation
func animateRefreshStep2()
UIView.animateWithDuration(0.35, delay: 0.0, options: UIViewAnimationOptions.CurveLinear, animations: () -> Void in
self.labelsArray[0].transform = CGAffineTransformMakeScale(1.5, 1.5)
self.labelsArray[1].transform = CGAffineTransformMakeScale(1.5, 1.5)
self.labelsArray[2].transform = CGAffineTransformMakeScale(1.5, 1.5)
self.labelsArray[3].transform = CGAffineTransformMakeScale(1.5, 1.5)
self.labelsArray[4].transform = CGAffineTransformMakeScale(1.5, 1.5)
self.labelsArray[5].transform = CGAffineTransformMakeScale(1.5, 1.5)
self.labelsArray[6].transform = CGAffineTransformMakeScale(1.5, 1.5)
self.labelsArray[7].transform = CGAffineTransformMakeScale(1.5, 1.5)
self.labelsArray[8].transform = CGAffineTransformMakeScale(1.5, 1.5)
self.labelsArray[9].transform = CGAffineTransformMakeScale(1.5, 1.5)
, completion: (finished) -> Void in
UIView.animateWithDuration(0.25, delay: 0.0, options: UIViewAnimationOptions.CurveLinear, animations: () -> Void in
self.labelsArray[0].transform = CGAffineTransformIdentity
self.labelsArray[1].transform = CGAffineTransformIdentity
self.labelsArray[2].transform = CGAffineTransformIdentity
self.labelsArray[3].transform = CGAffineTransformIdentity
self.labelsArray[4].transform = CGAffineTransformIdentity
self.labelsArray[5].transform = CGAffineTransformIdentity
self.labelsArray[6].transform = CGAffineTransformIdentity
self.labelsArray[7].transform = CGAffineTransformIdentity
self.labelsArray[8].transform = CGAffineTransformIdentity
self.labelsArray[9].transform = CGAffineTransformIdentity
, completion: (finished) -> Void in
if self.refreshControl.refreshing
self.currentLabelIndex = 0
self.animateRefreshStep1()
else
self.isAnimating = false
self.currentLabelIndex = 0
for var i=0; i<self.labelsArray.count; ++i
self.labelsArray[i].textColor = UIColor.blackColor()
self.labelsArray[i].transform = CGAffineTransformIdentity
)
)
【问题讨论】:
请用实际代码更改截图。 使用 objectID 获取整个对象。你是如何填充 tableview 控制器的?我假设获取所有对象?然后,您已经拥有所需的所有数据。只需将解析对象传递给下一个视图控制器并填写第二个屏幕。 @DogCoffee 我正在使用 Parse 填充 tableviewcontroller,使用一个名为 events 的单独类。我有另一个名为 eventsdetail 的类,它包含 detailviewcontroller 的所有数据。我将如何传递它?第二屏填什么? Tableview 数据源应该已经持有每个 PFObject。当您选择该单元格时,只需将该对象传递给第二个视图控制器。那是你问的对吗? “一旦在我的表格视图中点击一个单元格,它就会打开该单元格独有的数据” Parse: How do I get data from Parse that will be displayed in different unique view controllers的可能重复 【参考方案1】:由于您在 tableView 上有数据,只需确保您在情节提要中创建一个连接原型单元和目标视图控制器的转场,并向转场添加标识符。
接下来,在带有 tableView 的控制器上确保您调用:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?)
if (segue.identifier == "segueIdentifier")
let detailScene = segue.destinationViewController as! EventDetailViewController
if let indexPath = self.tableView.indexPathForSelectedRow
let row = Int(indexPath.row)
//here you can pass all the data to the destination viewController. But you CANT POPULATE YOUR LABELS. make sure you pass the data to some auxiliar variable(s). Next line is an example
detailScene.selectedData = (self.myData[row] as! PFObject)
更新:
detailScene.selectedData = (self.myData[row] as! PFObject)
detailScene
是目标 viewController 的一个实例。 selectedData
在这种情况下是一个 PFObject 实例,将用于填充我的目标 viewController 中的标签。 self.myData
是我的源 viewController 中的一个数组,其中的数据显示在我的 tableView 中。
因此,如果您想发送您在单元格中显示的数据。 (
self.testArray[indexPath.row]
self.subArray[indexPath.row]
) 确保在 EventsDetailViewController
上声明将接收此数据的变量,如下所示:
var testString:String!
var subString:String!
然后在您的 prepareForSegue (EventsViewController
) 中确保使用正确的数据实例化此变量:
detailScene.test = self.testArray[row]
detailScene.sub = self.subArray[row]
最后在EventsDetailViewController
上,您可以将数据传递给viewDidLoad()
上所需的标签:
self.articleTitle.text = testString
如有任何疑问,请告诉我。
【讨论】:
您能否详细说明detailScene.selectedData = (self.myData[row] as! PFObject)
我对此感到困惑。
它说'eventdetailviewcontroller'没有成员'selectedData'
您应该在 EventDetailViewController 中创建变量,以便将数据从带有 tableView 的控制器发送到 EventDetailViewController。
在detailScene.selectedData = (self.myData[row] as! PFObject)
行上给我一个错误提示:无法赋值:函数调用返回不可变值
@Hunter 更新了问题的更多细节【参考方案2】:
您要问的是典型的基本应用程序:在表格视图中显示项目列表并能够点击一行以查看更多详细信息。
在我看来不寻常的是你有两个不同的类:events 和 eventdetails。
将其与书籍数据库进行比较。你不会有 Book 类和 BookDetails 类。您将只有一个 Book 类,其中包含有关一本书的所有详细信息。因此,当您想显示书籍列表时,您需要获取所有 Book 对象。在 tableviewcontroller 中,您显示 Book 对象的字段子集(例如标题和作者)。当用户然后点击特定的书时,您打开一个视图控制器并将该行的 Book 对象传递给它。这个细节视图控制器然后只显示来自同一个 Book 对象的更多信息/字段。
【讨论】:
是的,我现在确实意识到我只需要一个。我知道怎么做,所以当你点击一行时,你会看到更多细节。我只是不知道如何做到这一点,以便您使用一个 detailviewcontroller 在不同的单元格中使用相同的列显示不同的数据。以上是关于解析:按行检索数据的主要内容,如果未能解决你的问题,请参考以下文章
java利用WatchService实时监控某个目录下的文件变化并按行解析(注:附源代码)