cell.imageView returns nil - ios

I am using Pars in this project and specially PFQueryTableViewController which subclasses PFTableViewCell instead of UITableViewCell.
cell.textLabeland cell.detailTextLabelare set no problem but cell.imageView returns nil. Why?
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath, object: PFObject?) -> PFTableViewCell? {
let cellIdentifier = "Cell"
let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier, forIndexPath: indexPath) as! PFTableViewCell
if let podcast = object {
if let name = podcast["name"] as? String {
cell.textLabel!.text = name
}
if let artist = podcast["artist"] as? String{
cell.detailTextLabel!.text = artist
}
if let artwork = podcast["artwork"] as? PFFile {
print(cell.imageView)
// cell.imageView!.file = artwork
// cell.imageView?.loadInBackground()
print("we have the artwork \(artwork)")
} else {
cell.imageView?.image = UIImage(named: "place")
print("using placeholder image")
}
}
return cell
}

So first, do you mean imageView is nil or do you mean imageView.image is nil? If your imageView is nil, that means the whole imageView is not being instantiated. How are you creating this imageView? Are you using a storyboard or a nib or are you creating the imageView programmatically? If you are doing it programmatically, make sure you are calling the init method on UIImageView before you try setting its .image property.
If the problem is that the .image property on your UIImageView is nil, then perhaps you have added your image incorrectly to your Images.xcassets folder or you have slightly misspelled the name of the image.
If the problem is you can't see the image, the perhaps if you have created the UIImageView programmatically, you haven't added it to your viewController's view heirarchy. This can be done with
self.view.addSubview(imageView)
So first narrow these things down, and if you come back with more information, then it will give me a better idea of the issue.

Related

collectionview are repeating inside a tableview cell

i am using a collectionview inside a tablview cell, in which collectionview cells are having an imageview on which images are displaying from the array of URLs in cellForItemAtIndexPath. I am calling webservice inside tableview cell class to getting array of URLs.
My problem is that whenever i scrolls down or up tableview, collectionview cells are repeating, images of collectionview are repeating itself. so how to get rid out of this.
My Code is as follows -
inside response of webservice
let imgList : NSArray = arrReponseDetails.value(forKey: "imageList") as! NSArray
self.arrImgUrls.removeAll()
for dict in imgList[0] as! NSArray {
let dictionary = dict as! NSDictionary
let strUrl : String = dictionary["url_highRes"] as! String
let url : URL = URL(string: strUrl)!
self.arrImgUrls.append(url)
}
self.collectionView.reloadData()
code inside of cellForItemAtIndexPath
let cell : CollectionCell = collectionView.dequeueReusableCell(withReuseIdentifier: "CollectionCell", for: indexPath) as! CollectionCell
let url : URL = self.arrImgUrls[indexPath.row]
cell.imgSticker.sd_setShowActivityIndicatorView(true)
cell.imgSticker.sd_setIndicatorStyle(.gray)
cell.imgSticker.sd_setImage(with: url, placeholderImage: nil)
cell.imgSticker.contentMode = .scaleAspectFit
return cell
I am not getting much insight from your question but i think problem is with caching of image with reusable cell.
Simply implement prepareForReuse() method in collectionView Cell class(CollectionCell).
override func prepareForReuse() {
super.prepareForReuse()
self.imgSticker = nil
}
Reference of prepareForReuse()
You need to clear it out the old content from the cell's view before setting new one as in some case some content might be left and that reported issue occurs.
func collectionView(collectionView: UICollectionView,
cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell
{
let cell : CollectionCell = collectionView.dequeueReusableCell(withReuseIdentifier: "CollectionCell", for: indexPath) as! CollectionCell
cell.imageView.image = nil; //Remove the image (cache one)
}
Hope this helps!!
Hi You should add the below code on CollectionCell class:
- (void)prepareForReuse
{
[super prepareForReuse];
[[self imgSticker] setImage:nil];
}
Note: It would be better if you can set the placeholder image also.
I wouldn' use colelctionView inside tableView, it's really strange approach. I used to do it myself for the first time and it got me into trouble. Consider changing the logic for collectionView with custom layout...
But to answer your question, it's better to use this approach (check out this answer)
just set in the CellForRow the imageView method according to this answer:
https://stackoverflow.com/a/27712427/5774854

Passing data from cellforRowatIndexPath to UITableViewCell

I am trying to pass in the String "random text" to equal the property imageURL that is located inside of the custom Cell UserCell from CellForRowAtIndexPath. In didSet of the cell class, I can print "random text" just fine, however, for reasons unrelated to this question, I need to print "random text" inside of the lazy var. When I try to print it inside the lazy var, or even awakeFromNib, it gives me nil. I have an idea of why this is happening. I'm assuming the compiler runs certain code for a custom cell class before initializing any self properties. I'm wondering if there is a way to get around that.
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier(cellId, forIndexPath: indexPath) as! UserCell
cell.imageURL = "random text"
return cell
}
Inside of the custom cell (UserCell)
class UserCell: UITableViewCell {
var imageURL: String? {
didSet{
print(imageURL) //prints the imageURL
}
}
lazy var profileImageView: UIImageView = {
let imageView = UIImageView()
print(imageURL) /////prints nil
return imageView
}()

Changing image properties UITableView Swift

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("NewsCell", forIndexPath: indexPath) as! UITableViewCell
cell.imageView?.image = nil
let imgURL = NSURL(string: urlString)
cell.imageView?.image = UIImage(named: "first")
// cell.imageView?.image?.drawInRect(CGRectMake(0,0,50,50))
// or
// cell.imageView?.frame = CGRectMake(0,0,50,50)
// also tried this
cell.imageView?.image = UIImage(named: "first")
cell.imageView?.contentMode = .ScaleAspectFill
cell.imageView?.clipsToBounds = true
Neither seems to make a difference.
When the image loads from the URL online it takes its original size.
I have omitted the code used for asynchronous image downloading because I figure its the same problem here. If not let me know. Thanks !
You should set Mode property of your UIImageView into Aspect Fit where you are showing the image at your cell.
You need to set the contentmode of the imageView either in code or in Interface Builder, and then once you do that you need to usecell.imageView?.clipsToBounds = true

Swift - UITableView lags with images

My problem is when I scroll down my UITableView, it looks too laggy. The images grab from facebook.
My code
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("UserCell", forIndexPath: indexPath) as UITableViewCell
let user = users[indexPath.row] as User //2
if let nameLabel = cell.viewWithTag(100) as? UILabel { //3
nameLabel.text = user.name
}
if let dateCreatedLabel = cell.viewWithTag(101) as? UILabel {
dateCreatedLabel.text = user.distance
}
if let profilePictureView = cell.viewWithTag(103) as? UIImageView {
if let url = NSURL(string: "https://graph.facebook.com/\(user.profilePhoto)/picture?type=large") {
if let data = NSData(contentsOfURL: url){
profilePictureView.contentMode = UIViewContentMode.ScaleAspectFit
profilePictureView.image = UIImage(data: data)
}
}
}
return cell
}
Please advice how to make it smooth.
OMG, never do like this not only in scrolling controls, but in general UI also:
data = NSData(contentsOfURL: url)
Thats why you table lags, and you lucky enougth with fast internet. If you connection will be slow, you app will hang, may be forever. ALWAYS do network asyncronously!
Also, when you make you network async, your tableView will still lag here:
UIImage(data: data)
And even here if you have many controls in your cell:
cell.viewWithTag(101)
So, use some library to download images, this is surprisingly not so easy task as it seems to be, you will not do it right yourself according to you experience (as I can see it).
Make separate class for you cell and use IB to connect outlets.
Try AFNetworking, it has category for UIImageView to download images.
I already found the answer. Use Haneke instead NSData.
import Haneke
/* .. */
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("UserCell", forIndexPath: indexPath) as UITableViewCell
let user = users[indexPath.row] as User //2
if let nameLabel = cell.viewWithTag(100) as? UILabel { //3
nameLabel.text = user.name
}
if let dateCreatedLabel = cell.viewWithTag(101) as? UILabel {
dateCreatedLabel.text = user.distance
}
if let profilePictureView = cell.viewWithTag(103) as? UIImageView {
if let url = NSURL(string: "https://graph.facebook.com/\(user.profilePhoto)/picture?type=large") {
profilePictureView.contentMode = UIViewContentMode.ScaleAspectFit
profilePictureView.hnk_setImageFromURL(url!)
}
}
return cell
}

UITableViewCell Images Changing after Scrolling Up and Down but TextLabel Text Remain Same (iOS8, Swift)

I'm trying to create an RSS app for practice. So my tableView cell has both textLabel and image. My textLabel's text and image data come from a dictionary stored in Core Data. Some cells have images, and some don't. The initial load of tableView looks fine to me. But when I scroll down and up, cell's images seem to change. The cells' textLabel text doesn't change though.
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as UITableViewCell
self.configureCell(cell, atIndexPath: indexPath)
return cell
}
func configureCell(cell: UITableViewCell, atIndexPath indexPath: NSIndexPath) {
let object = self.fetchedResultsController.objectAtIndexPath(indexPath) as NSManagedObject
cell.accessoryType = UITableViewCellAccessoryType.DisclosureIndicator
cell.textLabel!.text = object.valueForKey("title")!.description
var image: UIImage?
if let imageData = object.valueForKey("imageData") as? NSData {
image = UIImage(data: imageData)
let itemSize = CGSizeMake(80, 80)
UIGraphicsBeginImageContext(itemSize)
let imageRect = CGRectMake(0.0, 0.0, itemSize.width, itemSize.height)
image?.drawInRect(imageRect)
cell.imageView?.image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
}
}
If the initial tableView loads correctly, that means my Core Data stores my data's mapping correctly. But when scrolling down and up, configureCell is being called again since it needs to redraw the cell. cell.textLabel!.text = object.valueForKey("title")!.description is set correctly again, but not image here. Don't know why it behaves like this. Please give some pointer.
I had this same problem once and I think it has something to do with the reused cell not being in the default state so sometimes the image you set is being reused. To fix it, I just did an else condition on imageData and set the image to a default image if no image was found. I'm sure you could set it to nil here as well.
if let image = UIImage(contentsOfFile: imagePath) {
cell.imageView.image = image
} else {
// Default image or nil
cell.imageView.image = UIImage(named: "Calendar")
}
And I wouldn't suggest storing images as raw data in core data, as this can be very inefficient. Instead, download them to your documents directory and store a file name in core data.
What i did was remove the image from imageView and set image again. It works for me.
cell.imageView.image = nil
cell.imageView.image = UIImage(named:"Calendar")

Resources