解析:按行检索数据

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实时监控某个目录下的文件变化并按行解析(注:附源代码)

JAVA之NIO按行读取大文件

HBase 精华一页纸

如何解析此 xml 并检索 iPhone 中的数据 [重复]

从数据库中检索和解析 MIME 电子邮件

javascript 检索并解析WHOIS数据