Titanium JIRA Archive
Titanium SDK/CLI (TIMOB)

[TIMOB-8614] iOS: ImageView's load event fires before image's size is known

GitHub Issuen/a
TypeBug
PriorityHigh
StatusClosed
ResolutionFixed
Resolution Date2012-04-16T15:36:04.000+0000
Affected Version/sRelease 2.0.0, Release 1.8.2
Fix Version/sn/a
ComponentsiOS
LabelsSupportTeam
ReporterVarun Joshi
AssigneeMarshall Culpepper
Created2012-04-09T10:36:23.000+0000
Updated2014-06-19T12:43:44.000+0000

Description

Problem

The imageView's load event seems to fire prematurely on the first load of the app. Subsequent loads work as intended however it's most likely because the image is cached. Deleting the app and re-running will make the problem appear again.

Steps to Reproduce

1. Run the code sample below {noformat} //create component instance var self = Ti.UI.createWindow({ backgroundColor:'#ffffff', navBarHidden:true, exitOnClose:true }); //construct UI var boundingBox = Ti.UI.createView({ backgroundColor:'red', width:355, height:160 }); var sampleImageFromFarAway = Ti.UI.createImageView({ image:'https://www.google.com/images/logo_sm.gif', height:'auto', width:'auto', preventDefaultImage:true, borderAroundMeView:boundingBox }); var lateImageLoadingHandler = function(e) { Ti.API.info('Height: ' + e.source.size.height + ' Width: ' + e.source.size.width); var borderView = e.source.borderAroundMeView; borderView.width = e.source.width + 24; borderView.height = e.source.height + 24; } sampleImageFromFarAway.addEventListener('load', lateImageLoadingHandler); boundingBox.add(sampleImageFromFarAway); self.add(boundingBox); self.open(); {noformat} 2. On initial load, the size and width are returned as 0, On later runs the approproiate size and width are returned. 3. To recreate the issue, delete the app from the simulator and clean the project and rerun the app.

Comments

  1. Stephen Tramer 2012-04-09

    size does not refer to the image's size, but to the rendered size during the layout pass. This is expected behavior unless it regresses a previous custom definition on Ti.UI.ImageView.
  2. Vishal Duggal 2012-04-16

    In 2.0.1 and above you can listen for the 'postlayout' event after load to determine when the image view is refreshed In earlier versions of the titanium SDK, use the toImage() functionality on the imageView to get the size of the image. Code attached.
       //create component instance
           var self = Ti.UI.createWindow({
               backgroundColor:'#ffffff',
               navBarHidden:true,
               exitOnClose:true
           });
                
           //construct UI
           var boundingBox = Ti.UI.createView({
               backgroundColor:'red',
               width:355,
               height:160
           });
            
           var sampleImageFromFarAway = Ti.UI.createImageView({
               image:'https://www.google.com/images/logo_sm.gif',
               height:'auto',
               width:'auto',
               preventDefaultImage:true,
               borderAroundMeView:boundingBox
           });
            
           var lateImageLoadingHandler = function(e) {
               Ti.API.info('Height: ' + e.source.size.height + ' Width: ' + e.source.size.width);
               if ( (e.source.size.width == 0) || (e.source.size.height == 0) )
               {
               	var blob = e.source.toImage();
               	Ti.API.info('Height: ' + blob.height + ' Width: ' + blob.width);
       	        var borderView = e.source.borderAroundMeView;
           	    borderView.width = blob.width + 24;
               	borderView.height = blob.height + 24;
               } 
               else
               {
       	        var borderView = e.source.borderAroundMeView;
           	    borderView.width = e.source.width + 24;
               	borderView.height = e.source.height + 24;
               }
           }
            
           sampleImageFromFarAway.addEventListener('load', lateImageLoadingHandler);
           boundingBox.add(sampleImageFromFarAway);
           self.add(boundingBox);  
            
       self.open();
       
  3. Vishal Duggal 2012-04-16

    You can also set the width and height of boundingBox to 'auto' and set left,right,top,bottom of sampleImageFromFarAway to 12. In which case there is no need to listen for the load event as the boundingBox will automatically resize when image loads.
           var boundingBox = Ti.UI.createView({
               backgroundColor:'red',
               width:'auto',
               height:'auto',
           });
            
           var sampleImageFromFarAway = Ti.UI.createImageView({
               image:'https://www.google.com/images/logo_sm.gif',
               height:'auto',
               width:'auto',
               top:12,
               bottom:12,
               left:12,
               right:12,
               preventDefaultImage:true,
               borderAroundMeView:boundingBox
           });
       

JSON Source