Load image to uiimageview based on the selected target in Xcode - swift

I'm trying to create two applications from same codebase. These application will have same functionality but different logos, app name etc. I have created two targets with different bundle Ids so now I get unique apps when running each target.In my app, I have a viewcontroller with an UIImageView.
Now I want to assign an image to UIImageView based on the running target. So I created two assets folders.
Target1 -> Assest1 -> logo.png
Target2 -> Assest2 -> logo.png
logo.png is different file with same name.
How can I assign the correct logo.png to uiimageview based on the running target? Your help is appreciated.

Ensure that your asset is in the correct target an then use the following method:
UIImage(named: "example", in: Bundle(for: YourClass.self), with: nil)
To obtain your bundle you could use your class to refer to your bundle:
Bundle(for: YourClass.self)

Related

Could not load the "block" image referenced from a nib in the bundle with identifier - can't access image in other bundle

I got error Could not load the "block" image referenced from a nib in the bundle with identifier while trying to set image from from .xib file in one module, which (image) reside in another module. I'm trying to set image for a UIButton (not an UIImageView)
I've seen this iOS: How to use images in custom bundle in Interface Builder?
Article but it wasn't helpful.
I've tried
MyBundleName.bundle/iconName
MyBundleName/iconName
MyBundleName.bundle/Resources/Assets/Images.xcassets/iconName
I putted that in .xib GUI (when you suppose to set image for UIButton) but didn't succeed
In fact, in preview (.xib file in XCode) everything is nice, but after i visit the screen it doesn't work (and i see error i specify in article name in console)

Swift how to reference an image file that is not in *.xcassets folder in storyboard

I was trying to update the icon of my app in LaunchScreen, turned out that the UIImage doesn't update for the situation that a user update from old version to new version, and I searched on web for some solutions, there is one suggesting that I should load image files that are out of the *.xcassets folder, I know how to put the image files to my project root directory, but I don't know how to load it in storyboard, as LaunchScreen.storyboard can't have a view controller class
So my question is: How to reference image files in storyboard
This is the source link: http://arsenkin.com/launch_screen_image_cache.html
You can't use any custom behavior in LaunchScreen.storyboard. And loading images from anywhere except *.xcassets is a custom behavior.
Generally you'd use something like
let path = Bundle.main.path(forResource: "image", ofType: "imageType")
let image = UIImage(contentsOfFile: path!)
to load such an image, but as I've already mentioned, this approach doesn't work for launch screens

How can I migrate an xcassets catalog to Swift Package Manager?

I am migrating an app to Swift Package Manager. All my images are in an .xcassets, with their configurations for different display sizes etc.
How can I migrate those assets to SPM?
Starting with XCode 12 and Swift 5.3, it is possible to include images in Swift Package. I had to do a few modifications:
Add // swift-tools-version:5.3 as the header of the Swift package file
Simply create a new asset catalog, or copy an existing one to the package hierarchy. .assets folder get compiled automatically.
Make the image available in external targets by resolving the correct bundle. I went for this in the target containing the assets and an alternative would be to make each public asset available as a specific value.:
public func SCImage(named name: String) -> UIImage? {
UIImage(named: name, in: Bundle.module, compatibleWith: nil)
}
I can now do
import SCImages
let image = SCImage(named: "foo")

Access NSImage from Assets programmatically with IBDesignable

The regular loading via NSImage(named: "image_name") crashes the IBDesignable renderer as it apparently runs in a separate bundle.
In iOS there is a workaround to load images passing in the bundle explicitly:
let bundle = Bundle(for: self.classForCoder)
let image = UIImage(named: "image_name", in: bundle, compatibleWith: self.traitCollection)!
In Cocoa the analog initializer is missing.
Is there any other way to load the images from the Assets catalog?
If you're using Swift 3 or higher, you can try image literals. It should auto-complete in Xcode so if it doesn't work it might indicate a problem with the asset itself. Using a UIButton for example:
let myButton = UIButton()
myButton.setImage(#imageLiteral(resourceName: "image_name"), for: .normal)
By typing Image Literal Xcode should auto-complete it and create a small icon which you can double-click to open an image picker and select the image you want to use. A more complete guide on image literals and literals in general can be found here

iOS: How to use images in custom bundle in Interface Builder?

I have a bundle where i put images in it.
The contents are:
MyBundle.bundle/images/picture1.png
MyBundle.bundle/images/picture2.png
I dragged MyBundle.bundle into my project.
Now I can see these images in Interface Builder and can even use them. However, when I run the app, I don't see the images.
What's wrong?
Thanks,
Make sure the bundle is getting copied over in the "Build Phases" of the project settings for the target.
Also, try setting them progrmatically and see if they show:
myImageView.image = [UIImage imageNamed:#"MyBundle.bundle/images/picture1.png"];
I just tried this in my project and found that what you need to do is specify the image with the bundle name in front like this:
In the IB the image will look broken:
but when you build and run your project the image will show correctly.
So, in your case, use MyBundle.bundle/images/picture1.png in the actual Interface Builder Image box.
Also, when you dont put the bundle name in front, you get this warning when you load the view with the bundle image:
2011-10-12 08:22:16.360 UTDebug[721:11c03] Could not load the "map.png" image referenced from a nib in the bundle with identifier "com.companyname.myproject"
You need to put the XIB in the bundle, too. When you do that, resources for the interface will be relative to the bundle, so they'll work both in IB and when you load the interface in your app.
You might have a stray build setting from having created the bundle as a Mac OS X target.
See my other answer for the solution.