1

In order to limit the number of query to my database and consumption of data and battery, I would like to segue all the data of my TableView to my CollectionView.

import UIKit
import ParseUI
import Parse

class ListControllerView: PFQueryTableViewController {

   // Initialise the PFQueryTable tableview

  override init(style: UITableViewStyle, className: String!) 
   {
      super.init(style: style, className: className)
   }

  required init(coder aDecoder: NSCoder) 
    {
       super.init(coder: aDecoder)!

       // Configure the PFQueryTableView
       self.parseClassName = "Shopz"
       self.textKey = "shopName"
       self.pullToRefreshEnabled = true
       self.paginationEnabled = false
    }

   // Define the query that will provide the data for the table view
   override func queryForTable() -> PFQuery {
      var query = PFQuery(className: "Shopz")
      // query.orderByAscending("updatedAt")
      return query
   }

   //override func tableView(tableView: UITableView,       cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
   override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath, object: PFObject?) -> PFTableViewCell {

    var cell = tableView.dequeueReusableCellWithIdentifier("Cell") as! ListControllerViewCell!
    if cell == nil {
        cell = ListControllerViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: "Cell")
    }

    // Display flag image

   if let finalImage = object?["imagePromo"] as? PFFile
    {
        finalImage.getDataInBackgroundWithBlock
            {(imageData: NSData?, error: NSError?) -> Void in
            if error == nil
            {
                if let imageData = imageData
                {
                    cell.ImagePromo!.image = UIImage(data:imageData)
                }
            }
           }
    }

    // Extract values from the PFObject to display in the table cell
    if let shopnamelabel = object?["shopName"] as? String
    {
        cell.ShopName!.text = shopnamelabel
        print(shopnamelabel)
    }

    if let shopaddresslabel = object?["shopAddress"] as? String
    {
        cell.ShopAddress!.text = shopaddresslabel
        print(shopaddresslabel)
    }



        return cell;
 }


// In a storyboard-based application, you will often want to do a little preparation before navigation

   override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {

    // Get the new view controller using [segue destinationViewController].
    var detailScene = segue.destinationViewController as! CollectionView

                detailScene.shopzcollection = object as PFObject?

   }


   override func viewDidAppear(animated: Bool) {

        // Refresh the table to ensure any data changes are displayed
        tableView.reloadData();
   }
}`

collection view controller:

import UIKit
import Parse
import ParseUI

var shopzcollection = [PFObject]()`

class CollectionView: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate {


// Connection to the collection view
@IBOutlet weak var collectionView: UICollectionView!

override func viewDidLoad() {
    super.viewDidLoad()

}

/*
==========================================================================================
Ensure data within the collection view is updated when ever it is displayed
==========================================================================================
*/

// Load data into the collectionView when the view appears
override func viewDidAppear(animated: Bool) {
    loadCollectionViewData()
}

/*
==========================================================================================
Fetch data from the Parse platform
==========================================================================================
*/

func loadCollectionViewData() {

    // Build a parse query object
    var query = PFQuery(className:"Shopz")


    // Fetch data from the parse platform
    query.findObjectsInBackgroundWithBlock {
        (objects: [PFObject]?, error: NSError?) -> Void in

        // The find succeeded now rocess the found objects into the countries array
        if error == nil {

            // Clear existing data
            shopzcollection.removeAll(keepCapacity: true)

            // Add shop objects to our array
            if let objects = objects as [PFObject]? {
                shopzcollection = Array(objects.generate())
            }

            // reload our data into the collection view
            self.collectionView.reloadData()

        } else {
            // Log details of the failure
            print("Error: \(error!) ")
        }
    }
}

/*
==========================================================================================
UICollectionView protocol required methods
==========================================================================================
*/

func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
    return 1
}

func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    return shopzcollection.count
}

func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {

    let cell = collectionView.dequeueReusableCellWithReuseIdentifier("CollectionCell", forIndexPath: indexPath) as! CollectionViewCell

    // Display the country name
    if let value = shopzcollection[indexPath.row]["shopName"] as? String {
        cell.cellTitle.text = value
    }

    if let value = shopzcollection[indexPath.row]["shopAddress"] as? String {
        cell.cellDetail.text = value
    }

    // Fetch final flag image - if it exists

    if let finalImage = shopzcollection[indexPath.row]["imagePromo"] as? PFFile {

        finalImage.getDataInBackgroundWithBlock
            {(imageData: NSData?, error: NSError?) -> Void in
                if error == nil
                {
                    if let imageData = imageData
                    {
                        cell.cellImage!.image = UIImage(data:imageData)
                    }
                }
        }
    }

    return cell
}




/*
==========================================================================================
Process memory issues
To be completed
==========================================================================================
*/

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}   

}`

I guess I have to think again about the structure of my code/project:

  • create a swift file with all my var ( shopName, shopAddress, imagePromo)

  • create a wife file for the query to the data ( query.findObjectsInBackgroundWithBlock) with a function to call but it involves to change my list controller

  • file with my list

  • file with my collection
    I just don't know how to call properly the function which executes the query...

rici
  • 234,347
  • 28
  • 237
  • 341
L.Vl
  • 113
  • 2
  • 14
  • are you trying to forward all data (PFObjects shops) to your collectionView ? – LHIOUI Jan 24 '16 at 19:34
  • Yes exactly! It is two different views. I want to avoid to load two times the data. – L.Vl Jan 24 '16 at 20:52
  • you can pass `objects` to the UICollectionViewController – LHIOUI Jan 24 '16 at 21:42
  • I tried it, but I got an error: "Cannot convert value of type '[PFObject]?' to type 'PFObject?' in coercion" . I need to have a [PFObject]() in my UICollectionViewController... – L.Vl Jan 24 '16 at 22:46

1 Answers1

1

In the prepareForSegue of your tableViewController, you are trying to pass only one object (detailScene.shopzcollection = object as PFObject?).

You should pass the entire collection of objects (self.objects) to your collectionView.

I'm not well versed with Swift, but an obj-c equivalent would be:

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    ....
    detailScene.shopzcollection = self.objects;   // shopzcollection is an NSArray in the destination as well
}
kRiZ
  • 2,320
  • 4
  • 28
  • 39
  • Okay, I see what you mean. I am trying to pass all my Array to my CollectionView. – L.Vl Jan 24 '16 at 22:48
  • `override func prepareForSegue(segue: UIStoryboardSegue, sender: [PFObject]?) { if "id" == segue.identifier { detailScene.shopzcollection = self.objects } }` – L.Vl Jan 24 '16 at 22:51
  • I am thinking about reorganize my code as I mentioned on my post with a file for the query, a file for the var (shopName, shopAddress..), and after the files for the list and the collection. Do you think it is better? – L.Vl Jan 24 '16 at 22:54
  • Only if the same vars and queries will be used in multiple places. Else, would do with just having them in the same place as where needed. – kRiZ Jan 24 '16 at 22:56
  • Ok, but it is maybe better mainly if I want to implement a filter view in order to change the query? ( I implemented categories with boolean in my upload view, the filter view will be here to allow the users to select the categories that they want) – L.Vl Jan 24 '16 at 23:07
  • I get an error : **Method does not override any method from its superclass**, moreover I had **performSegueWithIdentifier("id", sender: self)** just before the return in my override fun tableview – L.Vl Jan 24 '16 at 23:15
  • Just before the return? `performSegueWithIdentifier` is a separate method. – kRiZ Jan 24 '16 at 23:19
  • ok I get it : ` override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) { if segue.destinationViewController is UINavigationController { let navigationController = segue.destinationViewController as! UINavigationController if navigationController.viewControllers[0] is CollectionView { var detailScene = navigationController.viewControllers[0] as! CollectionView detailScene.shopzcollection = self.objects! } } }` – L.Vl Jan 24 '16 at 23:23
  • Just to know please, Because I am not an expert! What is the best configuration when you want to add a filter view? Several distincts files or just one more view for the filter, I get the different booleans and when I click on the search button on the top of the filter view, I reload my Tableview with the new requirements for the query? – L.Vl Jan 24 '16 at 23:29
  • You acn have the search in the same view, iOS has direct features for that. And if you have all your objects already downloaded into self.objects, you don't need another query, just filter from the existing array (ios has built in methods for filtering arrays based on predicates) – kRiZ Jan 24 '16 at 23:34