Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When a UIImageView's image is set from Interface Builder, how is that image loaded?

When an image view's source is pre-set from the attributes inspector, when/how is the actual path to the file resolved? There don't seem to be any calls to NSBundle, but I may be wrong.

EDIT: I'm trying to swizzle whatever method is called (if possible) to dynamically replace the assets later.

enter image description here

like image 573
kasrak Avatar asked Jun 04 '13 01:06

kasrak


People also ask

What happens when you set an Imageview image property to nil?

image property will automatically handle that for you (when the new image is assigned). Where setting to nil is useful is where you want to explicitly mark the image as no longer in use, but do not want to remove / delete the UIImageView itself or set a new image. In those cases, setting . image = nil is a good idea.

What is the difference between a UIImage and a UIImageView?

UIImage contains the data for an image. UIImageView is a custom view meant to display the UIImage .

What is UIImageView in Swift?

A view that displays a single image or a sequence of animated images in your interface.

How do I display an image in Xcode?

Drag and drop image onto Xcode's assets catalog. Or, click on a plus button at the very bottom of the Assets navigator view and then select “New Image Set”. After that, drag and drop an image into the newly create Image Set, placing it at appropriate 1x, 2x or 3x slot.


2 Answers

None of UIImage initializers or factories are getting called.
I made some research with debugger (on iOS Simulator 7.0.3) and found following:
1) UIImageView which is set up in IB is initialised via -initWithCoder:.
2) In initWithCoder: method decodeObjectForKey: is called. And (!) key named UIImage contains image from IB. This image is set to UIImageView through ivar, not through setImage: setter.
So, seems like IB packs raw image data into XIB / Storyboard while compiling. Nonsense, but true.
That's why we cannot swizzle +imageNamed: or some another factory and should use conditional code to setup images for retina4 and iOS6

EDIT:

Comments show up that hexdumping of compiled IB file has png name inside.

In fact, looking at the output of "hexdump -C BYZ-38-t0r-view-8bC-Xf-vdC.nib " indicates that the filename of the PNG appears in the compiled file. So, it must be loading the file data via the file name from the same bundle.

However, they're still loaded via some internal mechanism, not via imageNamed:

like image 180
Petro Korienev Avatar answered Nov 10 '22 14:11

Petro Korienev


iOS will automatically look for your file overflow.png in the same bundle as your xib file. If your xib file is just in your application's target, then by default it looks inside the main bundle.

If you want to programatically load a new image into an image view and your image is inside the main bundle:

UIImage *image = [UIImage imageNamed:@"MyAwesomeImage"];
self.imageView.image = image;

If your image is inside another bundle:

NSBundle *imageBundle = ... // [NSBundle mainBundle] if your image is inside main bundle
NSString *imagePath = [imageBundle pathForResource:@"MyAwesomeImage" ofType:@"png"];
UIImage *image = [UIImage imageWithContentsOfFile:imagePath];
self.imageView.image = image;
like image 36
Sonny Saluja Avatar answered Nov 10 '22 14:11

Sonny Saluja