Storyboard, UIImageView. Load image from bundle
Asked Answered
S

1

6

My issue is: I have several projects/targets with shared xcassets. What I want to do is to set images inside storyboard without code.

As I was able to find, there are no way to set image in storyboard from different bundle.

I created UIImageView extension, but don't think about like the best solution.

Is there exist a way to use assets in storyboard from different bundle?

Thanks.

Sixteenth answered 20/12, 2016 at 15:7 Comment(4)
https://mcmap.net/q/137681/-share-data-between-two-or-more-iphone-applicationsCornerwise
@Adrian, so, there is no way to share resources even inside single workspace? (just to confirm)Sixteenth
I'm not 100% certain, but from a security standpoint, I don't think Apple wants you reaching into other apps for resources.Cornerwise
@Adrian, that's 100% true. But the difference is that I want to share resources between my xcodeprojects in single workspace.Sixteenth
F
5

So, based on answers to this question, I do know of one solution. Sounds like you've already done some of this, but just in the interest of giving a complete answer:

  1. Create a framework project to house your shared images (it's great for shared code too!): File > New > Project > iOS > Cocoa Touch Framework.
  2. Create a new Asset Catalogue within the framework File > New > File > iOS > Resource > Asset Catalogue.
  3. Import your images into the Asset Catalogue.
  4. Create a new workspace: File > New > Workspace.
  5. Add both your app and the framework to the workspace: File > Add Files to WorkspaceName.
  6. Include the framework as an 'Embedded Binary' within the app's project: Click the blue project file icon in the project navigator, go to the General project settings and locate Embedded binaries. Click + and select the Framework from the list (e.g. ExampleFramework.framework).

The above should be enough to allow you to use images from the framework's Asset Catalogue when they are called using code...

let frameworkBundle = Bundle(for: FrameWorkClass.self)
guard let image = UIImage(named: "MyImage", in: frameworkBundle, compatibileWith: nil) else { ... }

...however, to use it in a storyboard or XIB, there's one more step needed. Whilst the image names will now be selectable from Interface Builder (and even display there when selected), storyboards can only reference their own bundles, so it'll give you the following error when the app runs, and the image will be missing:

Could not load the "ImageName" image referenced from a nib in the bundle with identifier "BundleName"

To fix this, you need to go to the Workspace's navigator (left panel) and drag the Asset Catalogue (i.e. the .xcassets file) from the framework to somewhere within the app project itself (e.g. the project's root folder). In the dialog that appears, be sure that your app is checked in the Add to targets list, and that you leave the following option unchecked.

enter image description here

This will create a reference in your app's main bundle to the Asset Catalogue in the framework, but without creating a duplicate of it.

Once you've done that, you can use the images from that catalogue just like any other within your storyboards & XIBs.

Honestly, I can't vouch for if this is a best-practice, but it's the only way I've found to achieve what I also feel to be a sensible means of minimizing duplication between projects. In case you're interested, I've posted a question here to try and determine if this causes any duplication of the assets on build.

Flat answered 26/4, 2019 at 1:3 Comment(2)
I have multiple targets in one project, and I needed to add the .xcassets file under "Target Membership" to both app targets to be able to see the framework assets in my app targets, instead of dragging the xcassets in between projects. Your explanation here gave me the hint though, thanks.Colander
The problem with this approach is that it will duplicate the assets in all linked frameworks. If you inspect the final built app, inside each framework where you did this you will see the same asset, increasing the final app size. If you have a small catalog and not many modules it might work, but not for big assets or many modules.Belaud

© 2022 - 2024 — McMap. All rights reserved.