0

I have created a UITableView to display a feed of particular photos from Instagram. I made a custom tableViewCell to display the image and the header contains the username. Everything displays correctly but when I scroll it lags quite heavily. I have read other posts about heightForRowAtIndexPath instead of setting the tableView.rowHeight and have done that correctly, which has reduced a bit of the lag.

   override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    //Screen Width & Height
    let screenSize: CGRect = UIScreen.mainScreen().bounds; let screenWidth = screenSize.width;
    let screenHeight = screenSize.height;


    var cell:UITableViewCell = self.tableView.dequeueReusableCellWithIdentifier("feedCell") as UITableViewCell
    let url = NSURL(string: mediaArray[indexPath.section])
    let data = NSData(contentsOfURL: url!) 

    var cellImageName = UIImage(data: data!)
    var cellImage = cellImageName
    var cellImageView = UIImageView(image: cellImage)


    cellImageView.frame = CGRect(x: 0, y: 0, width: screenWidth, height: screenWidth)
    cell.addSubview(cellImageView)


    //cell.imageView?.image = UIImage(data: data!)
    return cell
}

Does anyone know how to fix the problem? Thanks

Edit: I have let data = NSData(contentsOfURL: url!) downloading on a background thread and the rest on the main thread.

        let url = NSURL(string: mediaArray[indexPath.section])
    let priority = DISPATCH_QUEUE_PRIORITY_HIGH
    dispatch_async(dispatch_get_global_queue(priority, 0)) {
        //IMAGE
        let data = NSData(contentsOfURL: url!)
        var cellImage = UIImage(data: data!)
        var cellImageView = UIImageView(image: nil)
        dispatch_async(dispatch_get_main_queue()) {

            if (cell.viewWithTag(1) == nil) {
                cellImageView.tag = 1
                var cellImage = UIImage(data: data!)
                var cellImageView = UIImageView(image: cellImage)
                cellImageView.frame = CGRect(x: 0, y: 0, width: screenWidth, height: screenWidth)
                cell.addSubview(cellImageView)
            }
        }

I still have a problem where the feed re-uses the same cell. Any ideas?

Matt
  • 97
  • 13
  • Do this in a background thread `let data = NSData(contentsOfURL: url!)` and update `cellImageView` on main thread. – gabbler Jan 09 '15 at 08:18
  • are you downloading the image? if so, check here: http://stackoverflow.com/questions/26310754/uitableview-scrolling-is-not-smooth/26626832#26626832 – longi Jan 09 '15 at 08:51
  • @gabbler Ok thanks, I did what you said above, but for some reason at the top the first photos are right, but as I scroll the photos are duplicated as previous ones and then updated after a second. Any ideas? – Matt Jan 09 '15 at 09:16
  • You can set a placeholder image for each cell initially and update the image after you get the data, tableview is reusing the cells when scrolling. – gabbler Jan 09 '15 at 09:21
  • `cell.addSubview(cellImageView)` this add hundreds of imageViews to your cell, you should set a tag to `cellImageView`, check if it exist, if not, you add it as a subview. – gabbler Jan 09 '15 at 09:40
  • @gabbler Sorry again, but I am unsure as how to set a tag and what they do. Is it something like cellImageView.tag = TAG? – Matt Jan 09 '15 at 10:18
  • Yes, a tag should be greater than 0, `cellImageView.tag = 2` and `if (cell.viewWithTag(2) != nil)`, you don't have to add it again, you can just set image for it. – gabbler Jan 09 '15 at 11:14
  • @gabbler Ok, I added `cellImageView.tag = 1 if (cell.viewWithTag(1) != nil) { cell.addSubview(cellImageView) }` and all of the photos are blank in the feed. Have I done something wrong? – Matt Jan 09 '15 at 20:52
  • Well, if it is nil, you should add it as subview, in both case,you should load the image from the url. A proper way to do is add an imageView in your prototype cell which can be configured in Interface builder and then you don't have to add subview here. – gabbler Jan 10 '15 at 02:46
  • What is the problem now? Do you have any code for the else entry? – gabbler Jan 10 '15 at 08:41
  • I still have the same problem as before where the cells are reused and duplicated until they update once scrolled over. I don't have any code for 'else', should I have? @gabbler – Matt Jan 10 '15 at 08:48
  • You only have code for `if (cell.viewWithTag(1) == nil)`, what about it is not nil? – gabbler Jan 10 '15 at 08:48
  • You should move `cellImageView.tag = 1` inside your if block, right now the check is always false. – gabbler Jan 10 '15 at 08:49
  • Moved the `cellImageView.tag` into the if block. Im confused as to what it should be if it is not nil? @gabbler – Matt Jan 10 '15 at 09:01
  • Then `cell.viewWithTag(1)` will return a `UIImageView`, you can directly set image to it. – gabbler Jan 10 '15 at 09:21
  • Thankyou for your help so far, and sorry for the somewhat dumb questions, but should the else statement contain something like this? `cell.viewWithTag(1) = UIImageView(image: cellImage)` @gabbler – Matt Jan 10 '15 at 09:57
  • No, `viewWithTag` method is used to access a subview of the caller, and `UIImageView(image: cellImage)` create a new object, for the else block, since the imageView has already exist, there is no need to assign a new `UIImageView` to it. `let imageView = cell.viewWithTag(1)` and `imageView.image = YourImage`. – gabbler Jan 10 '15 at 11:20
  • 1
    @gabbler Thanks for all the help. Everything appears to be working correctly! – Matt Jan 11 '15 at 09:02

0 Answers0