Images Inaccessible from Asset Catalog in a Swiftui Framework

Images inaccessible from asset catalog in a SwiftUI framework

By default

Image("MyImage") is Image("MyImage", bundle: Bundle.main)

ie. in bundle of application.

You have to explicitly specify bundle (of framework) in which Assets catalog is located, as

Image("MyImage", bundle: bundle)

where bundle is instantiated in usual way by class or identifier.

Image not showing in SwiftUI preview when using Swift Package Manager - works fine in Xcode project

When you are inside a package, you need to pass in the bundle, because it is the main by default and there is no main in a module.

So you need to use .module as the bundle:

Image("star_5", bundle: .module)

.module is an auto-generated resource. You don't need to manually write it!



Note

If you faced this error:

Type 'Bundle' has no member 'module'

Follow this instruction to make it automatically build for your package

How could Image view display photo by URL in SWiftUI?

See documented Image constructor

/// Creates a labeled image usable as content for controls.
///
/// - Parameters:
/// - name: the name of the image resource to lookup, as well as
/// the localization key with which to label the image.
/// - bundle: the bundle to search for the image resource and
/// localization content. If `nil`, uses the main `Bundle`.
/// Defaults to `nil`.
public init(_ name: String, bundle: Bundle? = nil)

This one "name: the name of the image resource to lookup" - not a file name, but image resource name, and all image resources are now in assets catalogs.

For external images there is Image(uiImage:) which you already found - just use it.

NSImage from Asset Catalog in Test Target

There is an extension on Bundle that allows to load a named image from an asset catalog:

extension Bundle {
@available(OSX 10.7, *)
open func image(forResource name: NSImage.Name) -> NSImage?
}

Referring to your example, you may use the following in an XCTestCase to access the image (Swift 5):

guard let image = Bundle(for: type(of: self)).image(forResource: "TestSourceImage") else {
fatalError("Test Resource is Missing.")
}

Tested on macOS 10.14.

Asset catalog slicing using aspect fit

One approach would be to slice the image into three pieces:

  • A top which has a fixed height in order to keep the proportions of the shape.
  • A body which stretches in height according to the content.
  • A bottom which also has a fixed height, again in order to keep the proportions.

By slicing like this, you have full flexibility of the height of your content. You would then align these three pieces e.g. by using auto layout.



Related Topics



Leave a reply



Submit