I have a UITableView in which each cell represents a user's post. The height of the cells is dynamic. The cell is customized, it has text fields, buttons and pictures (avatar and pictures of the post). This is all done through autolayout.
In each post images can be up to 10 pieces. And there can be an infinite number of posts. For post pictures, there is in each cell of UIView to which these same pictures are added, but they are compiled with tiles, something like in VK. Pictures on the server do not have a miniature version, they are all full-sized. And there may even be 1000x1000 in rare cases. But more often in a post there is only one picture approximately 600x600. If you comment out the output of pictures, then the table scrolls perfectly smoothly (well, almost). But with pictures, it “gets stuck” when scrolling during almost every scrolling.
I have a url for each picture. And with this method, I load the picture from the url and add it to the subview.
let picData: NSData = NSData(contentsOfURL: NSURL(string: picture.url! as String)!)! picIMG = UIImageView(frame: CGRect(x: xoffset, y: y, width: picture.resizeW, height: picture.resizeH)) picIMG.contentMode = .ScaleToFill picIMG.image = UIImage(data: picData) cell.viewVW.addSubview(picIMG) And I noticed that there are lags not only if there are pictures in the post. I tried to disable them and left only avatars (which are also downloaded from the Internet in each post). But it still slows down, even though the avatars are approximately up to 500x500 pixels in size.
Question: Maybe this is not quite the right way to load images via NSData(contentsOfURL: url) ? What is the best way to load pictures in such cases? Or maybe you need to independently upload pictures via NSURLSession or some other method and then display it already from the device?
Since everything works smoothly without pictures, the thing is still in pictures.
Updt: I tried to add the SDWebImage library for loading using the lazy method image loading. With avatars it helped, but with the loading of pictures of the post is not very, although it is still better than it was. Thanks for the tip @markov Avatar download code is as follows:
if let avurl = post.useravatar { cell.avatarIMG.layer.cornerRadius = 30 cell.avatarIMG.clipsToBounds = true let url = NSURL(string: avurl) cell.avatarIMG.sd_setImageWithURL(url, placeholderImage: UIImage(named: "logo_anm_one.png")) } And this is the code where the pictures are added to the post. The principle is this: I create a UIImageView, assign it .sd_setImageWithURL and set the URL from which to download the image, and then add it to cell.viewVW as a subview. And so 10 pictures (if there are 10).
let picsCount = allposts[indexPath.row].pic.count if picsCount > 0 { var xoffset = 0 var yoffset = 0 if picsCount > 3 { yoffset = post.pic[0].resizeH } for i in 1...picsCount { let picture = post.pic[i-1] let picData: NSData = NSData(contentsOfURL: NSURL(string: picture.url! as String)!)! var picIMG : UIImageView! var y = 0 if picsCount > 3{ if i > 2 { y = yoffset + 1 } if i == 3 { xoffset = 0 } } picIMG = UIImageView(frame: CGRect(x: xoffset, y: y, width: picture.resizeW, height: picture.resizeH)) xoffset += picture.resizeW + 1 picIMG.contentMode = .ScaleToFill let url = NSURL(string: picture.url! as String)! picIMG.sd_setImageWithURL(url, placeholderImage: UIImage(named: "logo_anm_one.png")) cell.viewVW.addSubview(picIMG) } var picblockH = CGFloat(post.pic[0].resizeH) if picsCount > 3 { picblockH += 1 + CGFloat(post.pic[2].resizeH) } let heightConstraint = NSLayoutConstraint(item: cell.viewVW, attribute: .Height, relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute, multiplier: 1.0, constant: picblockH) cell.viewVW.addConstraint(heightConstraint) } else if picsCount == 0 { let heightConstraint = NSLayoutConstraint(item: cell.viewVW, attribute: .Height, relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute, multiplier: 1.0, constant: 1) cell.viewVW.addConstraint(heightConstraint) } Updt2:
As it turned out, when using the suggested method, I just forgot to comment out the line that was downloading the pictures in the old way:
let picData: NSData = NSData(contentsOfURL: NSURL(string: picture.url! as String)!)!
NSData(contentsOfURL:- this is a synchronous web request, that's the problem. Use some lazy image libu, in no case can you usecontentsOfURLfor resources that aren't the ones on your device, this is a very bad style. Now there is little of time for a detailed answer, if you figure it out - write, then I will sign for the thread in more detail - Markov