I have a UIImage array populated with PFFiles from Parse.
how do I put the UIImages into the cell?
Below is my code.
var arrayOfFriends = [UIImage]()
var imagequery = PFQuery(className: "_User")
query.findObjectsInBackgroundWithBlock {( objects: [AnyObject]?, error: NSError?) -> Void in
for object in objects!{
let userPic = object["ProPic"] as! PFFile
userPic.getDataInBackgroundWithBlock({ (imageData: NSData?, error: NSError?) -> Void in
if(error == nil){
let image = UIImage(data: imageData!)
self.arrayOfFriends.append(image!)
print(self.arrayOfFriends)
}
dispatch_async(dispatch_get_main_queue()) {
self.collectionView.reloadData()
}
})
}
}
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell: friendcellView = collectionView.dequeueReusableCellWithReuseIdentifier("friendcell", forIndexPath: indexPath) as! friendcellView
//this is where the error occurs(error message above)
cell.friendpic.image = UIImage(named: arrayOfFriends[indexPath.row])
cell.friendpic.layer.cornerRadius = cell.friendpic.frame.size.width/2;
cell.friendpic.clipsToBounds = true
return cell
}
You already have it:
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell: friendcellView = collectionView.dequeueReusableCellWithReuseIdentifier("friendcell", forIndexPath: indexPath) as! friendcellView
//this is where the error occurs(error message above)
// change this line
// cell.friendpic.image = UIImage(named: arrayOfFriends[indexPath.row])
cell.friendpic.image = arrayOfFriends[indexPath.row] // here, arrayOfFriends[indexPath.row] is a UIImage, you don't have to do anything more
cell.friendpic.layer.cornerRadius = cell.friendpic.frame.size.width/2;
cell.friendpic.clipsToBounds = true
return cell
}
Just change this line
cell.friendpic.image = UIImage(named: arrayOfFriends[indexPath.row])
to this:
cell.friendpic.image = arrayOfFriends[indexPath.row]
arrayOfFriends[indexPath.row].getDataInBackgroundWithBlock { (data: NSData?, erreur: NSError?) -> Void in
if erreur == nil {
let image = UIImage(data: data)
cell.friendpic.image = image
}
}
this goes in cellForRowAtIndexPath
Related
I defined var postImgData = [UIImage]() at beginning of class to store all the images get from sever. The following is the code to get the image from sever
func loadPosts(){
let query = PFQuery(className: "posts")
query.whereKey("username", equalTo:PFUser.current()!.username!)
query.skip = self.picArray.count // skip the already loaded images
query.findObjectsInBackground { (objects, error) in
if error == nil {
if let objects = objects{
for object in objects{
self.collectionView?.performBatchUpdates({
let indexPath = IndexPath(row: self.uuidArray.count, section: 0)
self.uuidArray.append(object.value(forKey: "uuid") as! String)
self.picArray.append(object.value(forKey: "pic") as! PFFile)
self.collectionView?.insertItems(at: [indexPath])
}, completion: nil)
}
}
} else{
print(error!.localizedDescription)
}
}
}
Then i want to use self.postImgData[indexPath.row] = UIImage(data: data!)! to save each image data into postImgData array that defined earlier. But when i run the app it gives error said this line self.postImgData[indexPath.row] = UIImage(data: data!)! Thread 1: Fatal error: Index out of range. I am not sure why its happening? I tried use append function and its working but its didn't show the correct photo when i selected each cell. I am note sure what is correct way to do that? thanks
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return picArray.count
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
//define cell
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) as! pictureCell
picArray[indexPath.row].getDataInBackground { (data, error) in
if error == nil {
cell.picImg.image = UIImage(data: data!)
self.postImgData[indexPath.row] = UIImage(data: data!)!
} else {
print(error!.localizedDescription)
}
}
return cell
}
I have a problem trying to load an image from a controller to another. The problem is that when trying to load the new Controller runs 2 times the same class.
Code in ViewController
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
tableView.deselectRowAtIndexPath(indexPath, animated: true)
let row = ids[indexPath.row]
let next = self.storyboard?.instantiateViewControllerWithIdentifier("NewsController") as! NewsController
next.id = row
self.presentViewController(next, animated: true, completion: nil)
}
And code in NewsController:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
// Retrieve cell
let cellIdentifier: String = "NewCell"
let myCell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier, forIndexPath: indexPath) as!NewDetailCell
// Get the location to be shown
let item: LocationModel = feedItems[indexPath.row] as! LocationModel
myCell.titLabel!.text = item.titulo
myCell.subLabel!.text = item.subtitulo
myCell.cuerpoLabel!.text = item.cuerpo
var urlimg : String = item.imgNot!
if urlimg == ""{
urlimg = "abc.jpg"
}
var image = UIImageView()
image = loadImageFromUrl("MyURL" + urlimg, view: myCell.newImage!)!
myCell.newImage = image
.
.
.
loadImageFromUrl():
func loadImageFromUrl(url: String!, view: UIImageView!) -> UIImageView?{
// Create Url from string
let url = NSURL(string: url)!
// Download task:
// - sharedSession = global NSURLCache, NSHTTPCookieStorage and NSURLCredentialStorage objects.
let task = NSURLSession.sharedSession().dataTaskWithURL(url) { (responseData, responseUrl, error) -> Void in
// if responseData is not null...
if let data = responseData{
// execute in UI thread
dispatch_async(dispatch_get_main_queue(), { () -> Void in
view.image = UIImage(data: data)
})
}
}
// Run task
task.resume()
return UIImageView (image : view.image)
}
THANKS!
You should check your URL string that you pass in loadImageFromUrl.
Also i think it's better to get as a parameter only URlString and return a completionBlockWith UIImage?
I am trying to import a PFFile which is an image and put that in a cell, but I get the error fatal error: Index out of range. Why am I getting this? How do I fix it? Am I importing the image correctly?
if let imagepic = object["Animal"] as? PFObject{
if let imageofpic = imagepic["Pic"] as? PFFile{
imageofpic.getDataInBackgroundWithBlock({ (data: NSData?, error: NSError?) -> Void in
if(error == nil){
let image = UIImage(data: data!)
self.imagepro.append(image!)
dispatch_async(dispatch_get_main_queue()){
self.table.reloadData()
}
}else{
print(error)
}
})
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell: extrasescell = table.dequeueReusableCellWithIdentifier("extra") as! extrasescell
cell.pic.image = imagepro[indexPath.row]
return cell
}
Here is function where I try to fetch images from parse for users that are in the namesArray.
func fetchData(){
let imagePredicate = NSPredicate(format: "username IN %#", namesArray)
let imageQuery = PFQuery(className: "_User", predicate: imagePredicate)
imageQuery.findObjectsInBackgroundWithBlock { (objects: [PFObject]?, error: NSError?) -> Void in
if error == nil {
for object in objects! {
self.imagesArray.append(object["image"] as! PFFile)
if self.imagesArray.count == self.namesArray.count {
self.tableView.reloadData()
}
} else {
print("error: \(error?.localizedDescription)")
}
}
}
Here is my tableView:cellForRowAtIndexPath method:
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("Cell") as! ChatsCell
cell.nameLabel.text = namesArray[indexPath.row]
if imagesArray.count == namesArray.count && self.imagesLoaded == false{
imagesArray[indexPath.row].getDataInBackgroundWithBlock { (imageData: NSData?, error: NSError?) -> Void in
if error == nil {
let image = UIImage(data: imageData!)
cell.imageView?.image = image
self.tableView.reloadData()
self.imagesLoaded = true
}
}
}
return cell
}
But when I do so I see that images are not synchronised with names of the users. Even if I put my users in other order images will stay in the same order as they was before.
How can I change it?
Not sure what you're asking here. Is it that you were expecting the images to be returned in an array sorted by the user?
If so, then you will need to add a sort order to your PFQuery. I suggest you sort your namesArray by username, and then also sort the imageQuery by username:
imageQuery.orderByDescending("username")
Hope I understood the question ;]
--T
So I found that if you use one query you will receive ordered data so I've changed my code and now it works pretty well. So what I've done is that I do query for every separate member of the namesArray:
func fetchData() {
for index in 0..<self.namesArray.count {
let imagePredicate = NSPredicate(format: "username == %#", namesArray[index])
let imageQuery = PFQuery(className: "_User", predicate: imagePredicate)
imageQuery.findObjectsInBackgroundWithBlock({ (objects: [PFObject]?, error: NSError?) -> Void in
if error == nil {
for object in objects! {
self.imageFilesArray![index] = object["image"] as? PFFile
}
for imageFile in self.imageFilesArray! {
let index = self.imageFilesArray?.indexOf{$0 == imageFile}
imageFile?.getDataInBackgroundWithBlock({ (imageData: NSData?, error: NSError?) -> Void in
let userImage = UIImage(data: imageData!)
self.imagesArray?[index!] = userImage
self.tableView.reloadData()
})
}
}
})
}
}
and here is tableView:cellForRowAtIndexPath:
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("Cell") as! ChatsCell
cell.nameLabel.text = namesArray[indexPath.row]
cell.messageTextLabel.text = messagesArray[indexPath.row]
cell.chatImageView.image = self.imagesArray![indexPath.row] != nil ? self.imagesArray![indexPath.row] : UIImage(named: "add")
return cell
}
I don't understand what is going on. I have an image saved as a PFFile in Parse. I can see it and I know it is there. I want to have it as a cell image. The rest of the code below works fine and the memory addresses of PFFile also print. textLabel and detailTextLabel also fine but the images won't show (even if I delete 'loadInBackground'). Any ideas?
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath, object: PFObject?) -> PFTableViewCell? {
var cell = tableView.dequeueReusableCellWithIdentifier("Cell") as! PFTableViewCell!
if cell == nil {
cell = PFTableViewCell(style: .Subtitle, reuseIdentifier: "Cell")
}
if let name = object?["name"] as? String {
cell.textLabel?.text = name
}
if let artist = object?["artist"] as? String {
cell.detailTextLabel?.text = artist
}
if let artwork = object?["artwork"] as? PFFile {
println("we've got an artwork image \(artwork)")
//cell!.imageView!.image = UIImage(named: "placeholder.jpg")
cell.imageView?.file = artwork
cell.imageView?.loadInBackground()
}
return cell
}
Parse just saves an reference to the image in the table, you will have to do another async call to retrieve the message.:
let artwork = object?["artwork"] as PFFile
artwork.getDataInBackgroundWithBlock {
(imageData: NSData?, error: NSError?) -> Void in
if error == nil {
if let imageData = imageData {
let image = UIImage(data:imageData)
}
}
}