How to load an image in prepareForInterfaceBuilder

2019-03-08 11:21发布

I would like to load a sample image in an IB designable UIImageView, to be shown in Interface Builder while editing the interface. The following code does not work, as the view placeholder in IB remains empty (the view area contains only the UIImageView text):

@IBDesignable
class TestImageView : UIImageView
{
    override func prepareForInterfaceBuilder() {
        //let bundle = NSBundle.mainBundle()
        let bundle = NSBundle(forClass: nil)
        let imagePath = bundle.pathForResource("Test", ofType: "jpg")
        self.image = UIImage(contentsOfFile: imagePath)
    }
}

Note that:

  • in IB the Custom Class class for the view is correct (TestImageView)
  • Test.jpg is present in the project (if I manually set the image property of the UIImageView in IB the image shows up).
  • I tried the two different methods of getting the bundle present in the code

This was tested with Xcode 6 beta 3.

Update: in both cases the bundle path I get is "/Applications/Temporary/Xcode6-Beta3.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/Library/Xcode/Overlays". In that path the image is obviously not present.

7条回答
我命由我不由天
2楼-- · 2019-03-08 11:51

Try getting the bundle of the class like this:

let bundle = NSBundle(forClass: self.dynamicType)

or specifying the class name like this

let bundle = NSBundle(forClass: TestImageView.self)

Assuming that your image is in the bundle, for example Images.xcassets, you can then load it using:

self.image = UIImage("Test", inBundle: bundle, compatibleWithTraitCollection: self.traitCollection)

Remember to check whether your image is nil before trying to use it. I have not been able to get the image path using bundle.pathForResource to work correctly with normal image assets. There also doesn't appear to be a UIImage call where you specify just the name and bundle, so you have to use trait collection.

This question is related to:

xcode 6 IB_DESIGNABLE- not loading resources from bundle in Interface builder

Response from Apple...

Engineering has determined that this issue behaves as intended based on the following:

We can't really make this any easier than specifying the bundle. You might say, "oh, let's swizzle -[NSBundle mainBundle]", but lots of call sites that reference a bundle don't go through there (or go through the CF API). One might say then "ok, well then how about we at least swizzle -[UIImage imageNamed:]". The problem here is that there is no single replacement for the main bundle. You might have multiple live view bundles (either frameworks or apps) loaded in at once, so we can't just pick one to be the main bundle.

Developers need to be aware of bundles and how to get images from a bundle. Developers should be using UIImage(named:inBundle:compatibleWithTraitCollection:) for all image lookups.

查看更多
登录 后发表回答