UA-17470720-3

Jump to content


Photo
- - - - -

willDisplay vs lazyload


  • Please log in to reply
13 replies to this topic

#1 designwerks

designwerks

    Advanced Member

  • STV 5.0 Std
  • PipPipPipPipPip
  • 141 posts
  • LocationKingsville, Ontario, Canada
Reputation: 23
Excellent

Posted 04 October 2015 - 04:23 PM

Hi all,

 

Running into the same problem I always have (never been successful doing this)... when I add images to my app, it simply does not work properly. I have created a short movie https://vimeo.com/141356699

 

If you review, you'll notice that lazy load the images need a few seconds to load and then they bounce to the correct image. I am not doing anything strange to my image - user takes picture with camera and then saves using core data. Then the image should appear as it does, but slowly when scrolling with lazyload... this is only with 7 entries, I am not sure what will happen with 100's of entries.  It's as though the code is redrawing the entire 6, 7 or 8 MB image in that little tiny window... I am not sure, but takes a long time to redraw (see video)...

 

Any help would be greatly appreciated...

 

Also, notice the image records appear in a different sequence each time the UIView returns... is there a way to organize alphabetically?

 

If I put that same info onto willDisplay, the entire system slows right down as it needs to draw and redraw the cells over and over over again...

 

Here is code...  I've also been trying to use AsyncImageView but have had no luck

 

This code is found in viewDidLoad...

 

SCTableViewSection *Section2 = [self.tableViewModel sectionAtIndex:0];

    Section2.cellActions.willDisplay = ^(SCTableViewCell *cell, NSIndexPath *indexPath)

    

    {

        

        //AsyncImageView *imageView = (AsyncImageView *)[cell viewWithTag:2];

        //imageView.image = [UIImage imageNamed:@"Placeholder.png"];

        

    };

    

    SCTableViewSection *Section3 = [self.tableViewModel sectionAtIndex:0];

    Section3.cellActions.lazyLoad = ^(SCTableViewCell *cell, NSIndexPath *indexPath)

    

    {

        

        AsyncImageView *imageView = (AsyncImageView *)[cell viewWithTag:1];

        NSString *imageString = (NSString *)[cell.boundObject valueForKey:@"thumbnail"];

        NSString *fullName = [NSString stringWithFormat:@"Documents/%@", imageString];

        NSString *imagePath = [NSHomeDirectory() stringByAppendingPathComponent:fullName];

        UIImage *originalImage = [UIImage imageWithContentsOfFile:imagePath];

        NSLog(@"added a new image with lazyload");

        

        // size of actual thumbnail to display in cell

        CGSize destinationSize = CGSizeMake(154,95); // size of actual thumbnail

        UIGraphicsBeginImageContext(destinationSize);

        [originalImage drawInRect:CGRectMake(0,0,destinationSize.width,destinationSize.height)];

        UIImage *thumbnail = UIGraphicsGetImageFromCurrentImageContext();

        

        imageView.imageURL =[NSURL URLWithString:(NSString *)[cell.boundObject valueForKey:@"thumbnail"]];

        imageView.image = thumbnail;

        UIGraphicsEndImageContext();

        

        

        

    };



#2 wizgod

wizgod

    I'm what you guys call a User

  • STV 5.0 Pro
  • PipPipPipPipPipPipPip
  • 575 posts
  • LocationThe Grid
Reputation: 149
Popular

Posted 05 October 2015 - 08:07 AM

Greetings Program!

 

The cells are being reused so they contain the old image before the new one has finished loading.

 

In my app, I load the images from a URL but I load the images into a dictionary and display them from it.

 

This is my willDisplay; if the image doesn't exist in the dictionary, I download it from the URL. You'd need an Obj-C version :).

 

Also, if the original image sizes are in the MB, you'd need to resize the image after loading before storing it in the dictionary to cut down the size to a manageable KB.

 

self.tableViewModel.cellActions.willDisplay = {
    (cell, indexPath) in
    
    if !cell.isKindOfClass(SCCustomCell) || cell.boundObject == nil {
        return
    }
    
    cell.accessoryType = UITableViewCellAccessoryType.None
    
    func getDataFromUrl(urL:NSURL, completion: ((data: NSData?) -> Void)) {
        NSURLSession.sharedSession().dataTaskWithURL(urL) { (data, response, error) in
            completion(data: NSData(data: data))
            }.resume()
    }
    
    func downloadImage(url:NSURL, imageView:UIImageView, cache:Bool) {
        if let image = Global.variables.site.imageDictionary.objectForKey(url) as? UIImage
        {
            println("\n-------------------\nRetrieving image from cache.\n-------------------\n")
            imageView.image = image
        }
        else
        {
            let filename = url.lastPathComponent! as String
            if !filename.isEmpty
            {
                println("\nStarted downloading \"\(filename.stringByDeletingPathExtension)\".")
                
                getDataFromUrl(url) { data in
                    dispatch_async(dispatch_get_main_queue()) {
                        println("\nFinished downloading \"\(filename.stringByDeletingPathExtension)\".")
                        
                        if let image = UIImage(data: data!) as UIImage!
                        {
                            if cache
                            {
                                println("Caching image.")
                                Global.variables.site.imageDictionary.setObject(image, forKey:url)
                            }
                            
                            imageView.image = image
                        }
                    }
                }
            }
        }
    }
    
    let imageView = cell.viewWithTag(7) as UIImageView
    let avatar = cell.boundObject.valueForKey("avatar") as String
    if let imageUrl = NSURL(string: "\(Global.variables.site.siteUrl)\(avatar)") {
        // If the NSURL is valid, download the image, cache and display it (or display it from the cache if it exists).
        downloadImage(imageUrl, imageView, true)
    }
}

 

I found this bit of code here http://stackoverflow...hanges-to-wrong that might do the trick if you modified it to download only if not cached otherwise display it from there.

 

    dispatch_async(kBgQueue, ^{
        NSData *imgData = [NSData dataWithContentsOfURL:[NSURL URLWithString:[NSString stringWithFormat:@"http://myurl.com/%@.jpg",[[myJson objectAtIndex:indexPath.row] objectForKey:@"movieId"]]]];
        if (imgData) {
            UIImage *image = [UIImage imageWithData:imgData];
            if (image) {
                dispatch_async(dispatch_get_main_queue(), ^{
                    myCell *updateCell = (id)[tableView cellForRowAtIndexPath:indexPath];
                    if (updateCell)
                        updateCell.poster.image = image;
                });
            }
        }
    });

 

Wg


Edited by wizgod, 05 October 2015 - 08:46 AM.

  • Tarek and designwerks like this

P.S. I love Swift... talk Swift.. Never too old school to learn yet another programming language. LOL! ;-)


#3 wizgod

wizgod

    I'm what you guys call a User

  • STV 5.0 Pro
  • PipPipPipPipPipPipPip
  • 575 posts
  • LocationThe Grid
Reputation: 149
Popular

Posted 05 October 2015 - 10:08 AM

Another thought; in my iParent Points Tracker app, when the user selects a picture for the child's avatar,  I save the thumbnail image of the selected image in core data and load it from there.

 

I have an extension function for SCTableViewCell that displays the image for me; it attempts to display the image based on the properties it finds. Throughout all my apps, when storing in core data, I always use the same naming convention for the properties - imageData, imageName and same tag # for the imageVIew and label (if I use it) - saves me a lot of time.

 

func displayImage(showBorder showBorder: Bool, borderColor: CGColor, roundEdges: Bool, useCircleRadius: Bool, cornerRadius: CGFloat) -> UIImageView {
    var displayImageView = UIImageView()

    if let imageView = viewWithTag(99) as? UIImageView {
        if let imageData = boundObject.valueForKey("imageData") as? NSData
        {
            imageView.image = UIImage(data: imageData)
        } else if let imageData = boundObject.valueForKey("imageData") as? String {
            imageView.image = UIImage(data: NSData(base64EncodedString: imageData))
        } else if let imageName = boundObject.valueForKey("imageName") as? String {
            let imagePath = NSHomeDirectory().stringByAppendingPathComponent("Documents/\(imageName)")
            
            imageView.image = UIImage(contentsOfFile: imagePath)
        } else {
            imageView.image = nil
        }
        
        let radius = useCircleRadius ? imageView.frame.size.width/2 : cornerRadius

        if showBorder {
            imageView.makeBorder(borderColor, cornerRadius: !roundEdges ? 0 : radius)
        } else if roundEdges {
            imageView.roundEdges(cornerRadius: radius)
        }
        
        displayImageView = imageView
    }
    
    if let label = viewWithTag(98) as? UILabel
    {
        let radius = useCircleRadius ? label.frame.size.width/2 : cornerRadius
        
        if showBorder {
            label.makeBorder(borderColor, cornerRadius: !roundEdges ? 0 : radius)
        } else if roundEdges {
            label.roundEdges(cornerRadius: radius)
        }
    }
    
    return displayImageView
}

 

Wg


P.S. I love Swift... talk Swift.. Never too old school to learn yet another programming language. LOL! ;-)


#4 designwerks

designwerks

    Advanced Member

  • STV 5.0 Std
  • PipPipPipPipPip
  • 141 posts
  • LocationKingsville, Ontario, Canada
Reputation: 23
Excellent

Posted 05 October 2015 - 03:39 PM

Thanks wizgod... going to try your suggestions later this evening...

 

I'll let you know what comes of it... Thank you for all your help and providing some sample code

 

John


Edited by designwerks, 05 October 2015 - 03:40 PM.


#5 designwerks

designwerks

    Advanced Member

  • STV 5.0 Std
  • PipPipPipPipPip
  • 141 posts
  • LocationKingsville, Ontario, Canada
Reputation: 23
Excellent

Posted 05 October 2015 - 04:01 PM

Thanks for all your help - Is your code written in Swift?


Edited by designwerks, 05 October 2015 - 04:02 PM.


#6 wizgod

wizgod

    I'm what you guys call a User

  • STV 5.0 Pro
  • PipPipPipPipPipPipPip
  • 575 posts
  • LocationThe Grid
Reputation: 149
Popular

Posted 05 October 2015 - 04:31 PM

It is; I really like it, it's so.... beautiful :D


P.S. I love Swift... talk Swift.. Never too old school to learn yet another programming language. LOL! ;-)


#7 ozie

ozie

    ¯\_(ツ)_/¯

  • STV 5.0 Pro
  • PipPipPipPipPipPipPip
  • 526 posts
  • LocationAustralia
Reputation: 169
Popular

Posted 05 October 2015 - 10:13 PM

now where is the dislike button for the use of the word beautiful about swift :)


  • Dave Guerin likes this

P.S. I hate Swift.. don't talk Swift.. Too old school to learn yet another programming language.


#8 wizgod

wizgod

    I'm what you guys call a User

  • STV 5.0 Pro
  • PipPipPipPipPipPipPip
  • 575 posts
  • LocationThe Grid
Reputation: 149
Popular

Posted 06 October 2015 - 05:34 PM

Aw come on Dave, how can you do that to me? :P

 

I guess I won't be getting any likes for that comment :lol:.


P.S. I love Swift... talk Swift.. Never too old school to learn yet another programming language. LOL! ;-)


#9 Dave Guerin

Dave Guerin

    Forum Master

  • STV 5.0 Pro
  • PipPipPipPipPipPipPip
  • 545 posts
  • LocationIreland
Reputation: 136
Popular

Posted 06 October 2015 - 06:13 PM

Hi Wizgod,

 

I particularly like the use of ; in your post there about Swift, when I thought that ; was optional in Swift :-)


Cheers,

Dave

www.dgapps.ie

#10 wizgod

wizgod

    I'm what you guys call a User

  • STV 5.0 Pro
  • PipPipPipPipPipPipPip
  • 575 posts
  • LocationThe Grid
Reputation: 149
Popular

Posted 06 October 2015 - 07:49 PM

Hahahaha!

P.S. I love Swift... talk Swift.. Never too old school to learn yet another programming language. LOL! ;-)


#11 designwerks

designwerks

    Advanced Member

  • STV 5.0 Std
  • PipPipPipPipPip
  • 141 posts
  • LocationKingsville, Ontario, Canada
Reputation: 23
Excellent

Posted 07 October 2015 - 05:59 AM

Thanks wizgod for all your help in this matter.  The app now works with your help.

 

It's great to know that others are willing to share the expertise and help others find the way...

 

John


  • Tarek and wizgod like this

#12 ozie

ozie

    ¯\_(ツ)_/¯

  • STV 5.0 Pro
  • PipPipPipPipPipPipPip
  • 526 posts
  • LocationAustralia
Reputation: 169
Popular

Posted 07 October 2015 - 03:12 PM

Aw come on Dave, how can you do that to me? :P

 

I guess I won't be getting any likes for that comment :lol:.

 

certainly not now for calling me Dave :) https://www.youtube....h?v=v1c2OfAzDTI


P.S. I hate Swift.. don't talk Swift.. Too old school to learn yet another programming language.


#13 wizgod

wizgod

    I'm what you guys call a User

  • STV 5.0 Pro
  • PipPipPipPipPipPipPip
  • 575 posts
  • LocationThe Grid
Reputation: 149
Popular

Posted 07 October 2015 - 05:13 PM

Hahaha! I was referring to his Like for your need of a Dislike button :D!

 

Remember this http://sensiblecocoa...geview/?p=11901 ? LOL!


P.S. I love Swift... talk Swift.. Never too old school to learn yet another programming language. LOL! ;-)


#14 ozie

ozie

    ¯\_(ツ)_/¯

  • STV 5.0 Pro
  • PipPipPipPipPipPipPip
  • 526 posts
  • LocationAustralia
Reputation: 169
Popular

Posted 07 October 2015 - 05:25 PM

hahaha


P.S. I hate Swift.. don't talk Swift.. Too old school to learn yet another programming language.





0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users