I'm using Parse. I have a column in my table to store images as PFFiles. I am using a PFQueryTableViewController. I want to display images in my Parse table's "image" column as thumbnails for each table view cell that has an image associated with it.
Here is the relevant cellForRowAtIndexPath code I'm suspicious of:
override func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!, object: PFObject!) -> PFTableViewCell! {
let cell = tableView.dequeueReusableCellWithIdentifier("ListingCell", forIndexPath: indexPath) as PFTableViewCell
// This works as you can see "grapes" displayed on the screenshot I added.
var label = cell.viewWithTag(2) as UILabel
label.text = object["title"] as? String
// Accessing the PFImageView within my custom PFTableViewCell via a tag
let imageView = cell.viewWithTag(3) as PFImageView
// Extracting the image stored as a PFFile stored in the database
imageView.file = object["image"] as? PFFile // remote image
// Setting the actual thumbnail with the image when loaded
imageView.loadInBackground { (image: UIImage!, error: NSError!) -> Void in
imageView.image = image
}
return cell
}
I have 2 records stored in this Parse table, the first does not have an image and the second one does (hence why the "grapes" cell is empty). My question is, why is the image not displaying in the thumbnail (properly constrained) I created and rather taking up the entire screen? What am I doing wrong here? The even weirder part is that I used Xcode's view debugging to capture the view hierarchy and it shows it properly placed within the thumbnail. Any ideas?
You need to make sure your image mode is set to something like "Scale To Fill".
Related
I am settiing an image onto a tableViewCell with Alamofire
let messageImage = cell?.viewWithTag(6) as! UIImageView
messageImage.image = nil
messageImage.af_setImage(withURL: photoUrl! as URL)
return cell
I am appending each cell item to an array using Firebase:
ref.child("messages").child(ticker.current).queryOrderedByKey().observe(.childAdded, with: {snapshot in
let snapDict = snapshot.value as? NSDictionary
let photoUrl = snapDict?["photo_url"] as? String ?? ""
messageArray.insert(messageCellStruct(photoUrl: photoUrl), at: 0)
})
Then I am updating the image on the Same Exact URL with FirebaseStorage
When I re-call the cell ViewController that the TableViewCell is in, the image is not changed on the first couple of cells. But as I scroll to older cells the image is updated:
messageArray.removeAll()
tableView.reload()
If I rebuild the app all cell images are how they are supposed to be.
I am assuming this is because of an Observer error or Im not removing the observer. I really dont know.
1.) The cells share the same exact URL im just changing the data.
2.) It seems to be only working when a cell hasnt loaded yet(or been assigned).
3.) It works perfectly fine after I rebuild and run the app.
Maybe I need to clear the Alamofire cach?
It sounds like you need to set the old image to nil before you set the image in messageImage.af_setImage(withURL: photoUrl! as URL).
Cell's are supposed to get cleaned up before they are reused: Apple -PrepareForReuse but Apple also says:
For performance reasons, you should only reset attributes of the cell
that are not related to content, for example, alpha, editing, and
selection state. The table view's delegate in
tableView(_:cellForRowAt:) should always reset all content when
reusing a cell.
That basically means you Shouldn't set your imageView's image to nil in prepareForReuse BUT if you sub classed the cell you can create a function inside the subclass and in cellForRowAtIndePath call it before you run messageImage.af_setImage(withURL: photoUrl! as URL). Example Below:
Create subclass for cell and name it MyCustomCell
class MyCustomCell: UITableViewCell {
#IBOutlet weak var messageImage: UIImageView!
func setImageToNil(){
messageImage.image = nil
// I don't use AlamoFire and don't know anything about it but if they have something to set the imageView's image to nil you can also try using that instead
}
}
Inside your tableView's cellForRowAtIndexPath cast the cell then call setImageToNil() before you run messageImage.af_setImage
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
// 0. cast the cell as MyCustomCell
let cell = tableView.dequeueReusableCell(withIdentifier: "MyCustomCell", for: indexPath) as! MyCustomCell
// 1. call the setImageToNil() method and whatever image is inside messageImage will get set to nil every time the cell is reused
cell.setImageToNil()
// 2. the new image should always appear because the old image was set to nil
cell.messageImage.af_setImage(withURL: photoUrl! as URL)
return cell
}
Alamofire saves image cache locally.
Because I was changing data to the Same Exact URL I had to remove the cache.
UIImageView.af_sharedImageDownloader.imageCache?.removeAllImages()
UIImageView.af_sharedImageDownloader.sessionManager.session.configuration.urlCache?.removeAllCachedResponses()
I'm writing a Swift app that displays photos fetched from server on each cell of my UITableViewController.
So far my code looks as follows:
func tableView(detailsPanel: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = detailsPanel.dequeueReusableCellWithIdentifier("cell") as! DetailsCell
let test:SingleTest = self.items[indexPath.row] as! SingleTest
if(test.photo != "") {
cell.myPhoto.af_setImageWithURL(NSURL(string: test.photo)!)
}
}
Now, the problem is that not every cell has a photo stored in cell.photo. Some of them are empty strings (""). In that situation when I quickly scroll through the table view, I see that those empty UIImageViews are filled with photos from other cells.
The quick fix for that seems to be adding an else block:
if(test.photo != "") {
cell.myPhoto.af_setImageWithURL(NSURL(string: test.photo)!)
} //this one below:
else {
cell.myPhoto.image = UIImage(named: "placeholderImg")
}
Now whenever there is no photo, the placeHolderImg will be displayed there. But... is there a way of avoiding it and just do not display anything there? And by not displaying anything I mean not displaying images from different cells?
You are reusing your cells, thus the cell will still use the previous image that it has loaded unless you set it to nil or a placeholder image. However I believe you do not need to use an if statement. You can use the placeholderImage parameter of af_setImageWithURL.
cell.myPhoto.af_setImageWithURL(NSURL(string: test.photo)!, placeholderImage: image)
Here I am displaying images in imageView. I am able to display image but only single image in all rows of TableView I am using SDWebImage with swift for the first time. So I want to pass the array in the following code to display the respective images in each row.Here I am successfully displaying name by passing it through array now just wanted to display the images.
NOTE : see the code in comments below but its giving error want to pass the same array but don't know how to write in swift.
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell : TableViewCell = self.tableView.dequeueReusableCellWithIdentifier("Cell") as! TableViewCell
let strTitle : NSString = arrDict[indexPath.row].valueForKey("clip_name") as! NSString
cell.clipName.text = strTitle as String
cell.videoImage.sd_setImageWithURL(NSURL(string:"http://example.com/test/images/clips", arrDict(indexPath.row).objectForKey("clip_image_path")))
return cell
}
You need to append your image name with your URL like this way.
let imagePath = String(format: "http://example.com/test/images/clips/%#",arrDict[indexPath.row].valueForKey("clip_image_path") as! NSString)
cell.videoImage.sd_setImageWithURL(NSURL(string: imagePath))
I'm trying to put images into my UITableView. The Table is set up with a custom subclass cell. In the Subclass I have outlets:
#IBOutlet var titleLabel: UILabel!
`#IBOutlet var pillarIcon: UIImageView!`
In the Superclass I created a NSMutableArray for both:
var objects: NSMutableArray! = NSMutableArray()
var imageObjects: NSMutableArray! = NSMutableArray()
I place things into the Arrays within the viewDidLoad Method Each array has 4 items.
So when I call the Items:
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.objects.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = self.tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! TableViewCell
cell.titleLabel.text = self.objects.objectAtIndex(indexPath.row) as? String
cell.pillarIcon.image = self.imageObjects.objectAtIndex(indexPath.row) as? UIImage
return cell
}
The cell.titleLabel.text items come up but the images in the cell.pillarIcon.image do not come show up in the table.
I have been working on this for a couple hours now and am going in circles it feels like. Also the image files have been loaded into the main file so that is not the problem.
Thanks in advance.
Make sure that your images are loaded into your Images.xcassets and then use the UIImage(name:) method to load the images.
Currently, you are loading your images into your imageObjects array as follows:
self.imageObjects.addObject("book.jpg")
You are not using the UIImage to load the image.
Once your images are a part of your project's image assets (Images.xcassets), load your images like so:
self.imageObjects.addObject(UIImage(named: "book"))
(The above example assumes that book is the name of the image asset group.)
Note, this Adding Image Assets web page has instructions on how to set up an image asset group.
It seems like you are loading images incorrectly, like #whyceewhite said in his answer.
I will try to make it clear to you:
open Assets.xcassets
Drop all images you want to use under AppIcon
Add images to your array this way:
imageObjects.addObject(UIImage(named: "whiteboardapp")!)
Use the same name displayed on Assets.xcassets folder
I have to use UITableViewCellStyle.Subtitle (as it works brilliantly with PFTableViewCell) and I can add a default image through storyboard where there is an option to add an image. This works fine but I want to update this image myself through code. I have the following code:
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath, object: PFObject?) -> PFTableViewCell {
var cell = tableView.dequeueReusableCellWithIdentifier("Cell") as! SBGestureTableViewCell!
if cell == nil {
cell = SBGestureTableViewCell(style: UITableViewCellStyle.Subtitle, reuseIdentifier: "Cell")
}
// update cell image from default image to questionMark
cell.imageView?.image = UIImage(named: "Question_Mark#2x")
}
However, the image does not update and I am still seeing the default image.
If you are using png images ( since your image name contains #2x), you are missing .png.
If you are using xcassets, then double check the name in the assets.
Also, check console, if you don't have the image name right, it should output it there.
That's all I can get from your code.