Search code examples
ioscocoa-touchuiimageviewinterface-buildernsbundle

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


Solution

  • 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: