How would you apply a background gradient to a launch screen file?
Are you supposed to just include large image for the background or can you run code in a launch screen file to do custom drawing?
You cannot run code or use any custom classes in the Launch Screen.
You'll have to supply a stretchable image, which contains enough data for it to be viable in all resolutions.
Also, you could take advantage of the #2x and #3x modifiers.
iPhone 6 plus will try to load a #3x modifier, AFAIK.
As a last resort, if the Launch Screen xib is not enough for you, you could still use the UILaunchImages plist key, and specify images for minimum version of 8.0. The downside is that Xcode does not automatically generate those for you, so you'll have to write those manually. Also remember that the modifier for iPhone 6 plus images is #3x
An example:
UILaunchImage = Default // This is for iOS 6, if you need it
UILaunchImages // iOS 7, 8
- [0]
- UILaunchImageName = Default
- UILaunchImageMinimumOSVersion = 7.0
- UILaunchImageSize = {320, 480}
- UILaunchImageOrientation = Portrait
- [1]
- UILaunchImageName = Default-568h
- UILaunchImageMinimumOSVersion = 7.0
- UILaunchImageSize = {320, 568}
- UILaunchImageOrientation = Portrait
- [2]
- UILaunchImageName = Default-667h
- UILaunchImageMinimumOSVersion = 8.0
- UILaunchImageSize = {375, 667}
- UILaunchImageOrientation = Portrait
- [3]
- UILaunchImageName = Default-736h
- UILaunchImageMinimumOSVersion = 8.0
- UILaunchImageSize = {414, 736}
- UILaunchImageOrientation = Portrait
P.S. The plist above is also a perfect solution for those who are struggling with the localization of Image Catalogs or Launch Screen files.
As long as you can add PDF single vector assets to your projects, I usually export gradients that have to be in launch image from Illustrator or Photoshop to PDF and include them in the layout with pretty good results.
Related
Xcode 10 Release Notes: "Code Completion for Swift image literals has been removed in Xcode 10"
So it's not a bug that I couldn't add images in the code (and run older projects). How do we then add images from now on in the code as just typing UIImageView(image: won't accept any png or jpeg.
let cellImage: UIImageView = {
let image = UIImageView(image: ???))
return image
}()
System: macOS Mojave
Xcode: Xcode 10 Beta 4
In Xcode 10 and Swift 4.2, only the code completion function (or auto-complete) of the Xcode IDE has been discontinued for the old way. Here is the new way:
Just type image literal and it will complete with default icon.
Double click on this icon and it will open the media library right side of it.
Just choose your imagem and it work like before!
Found the Shortcut to open the Media Library Tab:
⇧+⌘+M
At this point the official documentation does not cover some use cases at Xcode 10 beta so I'm not able to find a way to move the media part to the old position.
You can use Media Library in Xcode to add image literal to your code:
And then choose image from library and drag&drop it to your code
It will create image literal
For the benefit of others with legacy code that utlizes Swift Image Literals, the code and syntax of the image literal function themselves are still valid and work perfectly fine in Xcode 10 with Swift 4.2.
There is no need to rollback or refactor existing code that utlizes these image literals, and they can still be used as follows:
imageView.image = #imageLiteral(resourceName: imageNameString)
Only the code completion function (or auto-complete) of the Xcode IDE has been discontinued.
UPDATE
The difference in image-literal representation in previous and current versions or Xcode/Swift:
image = #imageLiteral(resourceName: "flower.jpg")
As the extract illustrates, image literals were represented in-line with thumbnails of their actual image. However, now, only a generic icon is used in its place. Presumably, this goes towards reducing the burden on the IDE, by eliminating the overheads of handling and displaying the in-line thumbnails.
TIP: To fix three resolutions after add a literal image in code.
1. Remove another, keep only one image
2. Comment your line code with literal image, then will appear literal image in code, like: #imageLiteral(resourceName: "image#2x.png"
3. in resourceName value, remove #2x and file extension, like .png, keep only image name: #imageLiteral(resourceName: "image")
4. Uncomment! Image will be showed in code.
In Xcode 11, the media library is now under View > Show Library (SHIFT+CMD+L).
If anyone using Xcode 11 then you can find all media using below option:
Using
UIImage(imageLiteralResourceName: 'imageName')
won't return an optional and works just fine
Just use #imageLiteral(
It will work
i'm using Xcode 10 beta 4 and i have the same problem !
Resolved using the old way to pass an image
PizzaModel(
nome: "Marinara",
ingredienti: "Pomodoro, Aglio",
calorie: "729",
img: UIImage(named: "marinara")!
)
you can use this code in Xcode 14.1
"UIImageVievName".image = #imageLiteral(resourceName: "imageName")
and then you can click the photo icon, you can chose what you want to add the image.
Just type command+shift+L , you will get the option for image addition.
Just got the new Apple TV and I am trying to setup App Icons for a new app. It is asking for Front, Middle and Back images for both "App Icon - Large" and for "App Icon Small". I have tried putting a 512x512 image in for Middle and get the following error:
The last image stack layer with content, "Middle", must exactly fill the image stack. Its current frame is {{384, 128}, {512, 512}} while the image stack's size is {1280, 768}.
Does a 1280x768 image need to be used? More importantly, what exactly is needed in terms of image assets for tvOS Apps?
You need at least 2 images for both the App Icon - Large & App Icon - Small
(So total of 4 images - I used at first just the front & back, then I used all three layers for a total of 6 images)
The large icon is 1280x768, and the small one is 400 x 240
Apple's document:
https://developer.apple.com/tvos/human-interface-guidelines/icons-and-images/
Doesn't seems to specify that you only need one image for the 1280x768. But
I wasn't able to submit my App with just one image. I rendered my icons in the
full 1280x768 size and then scaled to 400 x 240.
In addition, you need to add the Top Shelf image which is 1920 x 720.
(Top Shelf Wide seems to be 2320 x 720.)
https://developer.apple.com/forums/thread/20689
Yes, you have add mismatched icons, that's why getting the error
Once you check all the sizes is correct
How does vector support work in Xcode 6?
When I try resizing an image, it looks jagged, what gives?
How to use vectors in Xcode (7 and 6.3+):
Save an image as a .pdf file at the proper #1x size (e.g. 24x24 for a toolbar button).
In your Images.xcassets file, create a new Image Set.
In the Attributes Inspector, set the Scale Factors to Single Vector.
Drag and drop your pdf file into the All, Universal section.
You can now refer to your image by its name, just as you would any .png file.
UIImage(named: "myImage")
How to use vectors in older versions of Xcode (6.0 - 6.2):
Follow the steps above, except for step 3, set Types to Vectors.
How vectors work in Xcode
Vector support is confusing in Xcode, because when most people think of vectors, they think of images that can scale up and down and still look good. However, Xcode 6 and 7 don't have full vector support for iOS, so things work a little differently.
The vector system is really simple. It takes your .pdf image, and creates #1x.png, #2x.png, and #3x.png assets at build time. (You can use a tool to examine the contents of Assets.car to verify this.)
For example, assume you are given foo.pdf which is a 44x44 vector asset. At build time it will generate the following files:
foo#1x.png at 44x44
foo#2x.png at 88x88
foo#3x.png at 132x132
This works the same for any sized image. For example, if you have bar.pdf which is 100x100, you will get:
bar#1x.png at 100x100
bar#2x.png at 200x200
bar#3x.png at 300x300
Implications:
You cannot choose a new size for the image; it will only look good if you keep it at the 44x44 size. The reason is that full vector support is not implemented. The only thing these vectors do is save you the time of saving your image assets. If you have a tool (e.g. a Photoshop script) that already makes this a one-step process, the only thing you will gain by using pdf vectors is future-proof support (e.g. if in iOS 9 Apple begins to require #4x assets, these will just work), and you will have fewer files to maintain.
You should ask for all your assets at the #1x size, saved as PDF files. Among other things, this will allow UIImageViews to have the correct intrinsic content size.
Why it (probably) works this way:
This makes it backwards compatible with previous iOS versions.
Resizing vectors may be a computational intensive task at runtime; by implementing it this way, there are no performance hits.
In Xcode 8, you can still add a pdf, create a new Image Set, and in the Attributes Inspector, set the Scales to Single Scale option.
This is a supplement to the excellent answer by #Senseful.
How to make vector images in .pdf format
I will tell how to do this in Inkscape since it is free and open source but other programs should be similar.
In Inkscape:
Create a new project.
Go to File > Document Properties and set the custom page size to whatever your #1x size is (44x44, 100x100, etc) with the units in px.
Make your artwork.
Go to File > Save As... > Printable Document Format (*.pdf) > Save > OK. (Alternatively, you could go to Print > Print to File > Output format: PDF > Print but there are not as many options.)
Notes:
As is mentioned in the accepted answer, you cannot resize your image because Xcode still produces the rasterized images at build time. If you need to resize your image you should make a new .pdf file with a different size.
If you already have an .svg image that is the wrong page size, do the following:
Change the page size (Inkscape > File > Document Properties)
Select all objects (Ctrl+A) on the work space and resize them to fit in the new page size. (Hold down Ctrl to keep aspect size.)
To convert an .svg file into a .pdf you can also find online utilities to do the job for you. Here is one example from this answer. This has the benefit of allowing you to set the .pdf size easily.
Further reading
Using Vector Images in Xcode 6
For those who still not updated, there were changes in Xcode 9 (iOS 11).
What’s new in Cocoa Touch (WWDC 2017 Session 201) (#32:55)
https://developer.apple.com/videos/play/wwdc2017/201/
In few words, Asset Catalog now includes the new checkbox in Attributes Inspector named “Preserve Vector Data”. When checked, PDF data will be included in the compiled binary, increasing its size of course. But it gives a chance for iOS to scale the vector data in both directions and provide nice images.(With its own difficulties).
For iOS below 11, old scaling mechanisms described in answers upwards is used.
Xcode image types
Raster image .png
scale factor #1x, #2x, #3x
As a developer you are responsible for setting .png into corresponding factor
Official doc - Image Size and Resolution
Vector image .pdf and .svg
Vector PDF(Portable Document Format)
Not all pdf files are vector files.
Xcode 6 - single scale; Build time; PDF -> PNG(#1x, #2x, #3x);
Xcode 9 and iOS 11 - Preserve Vector Data; Run time; Dynamic scale
SVG(Scalable Vector Graphics)
Xcode 12 and iOS < 13 - SVG -> PNG(#1x, #2x, #3x)
Xcode 12 and iOS 13 - Preserve Vector Data; Run time; Dynamic scale
Diff
Most of the time, SVG are smaller than PDF
SVG is readable and editable in text editor
Experiments
If you create a project and build it ( not only for specific device - Any iOS device) with .pdf and .svg file you will see that they work at the same manner
png files are generated(Assets.car file[About])
when you select Preserve Vector Data and Individual scales (NOT Single scale) the result will be Dynamic scale
Preserve Vector Data off and on
Generated files
You can use normal PDF files inside your project as Vector images and render images of any size using this extension. This way is way better because iOS will not generate .PNG images out of your PDF files, plus you can render you images with any size you want:
extension UIImage {
static func fromPDF(filename: String, size: CGSize) -> UIImage? {
guard let path = Bundle.main.path(forResource: filename, ofType: "pdf") else { return nil }
let url = URL(fileURLWithPath: path)
guard let document = CGPDFDocument(url as CFURL) else { return nil }
guard let page = document.page(at: 1) else { return nil }
let imageRect = CGRect(x: 0, y: 0, width: size.width, height: size.height)
if #available(iOS 10.0, *) {
let renderer = UIGraphicsImageRenderer(size: size)
let img = renderer.image { ctx in
UIColor.white.withAlphaComponent(0).set()
ctx.fill(imageRect)
ctx.cgContext.translateBy(x: 0, y: size.height)
ctx.cgContext.scaleBy(x: 1.0, y: -1.0)
ctx.cgContext.concatenate(page.getDrawingTransform(.artBox, rect: imageRect, rotate: 0, preserveAspectRatio: true))
ctx.cgContext.drawPDFPage(page);
}
return img
} else {
// Fallback on earlier versions
UIGraphicsBeginImageContextWithOptions(size, false, 2.0)
if let context = UIGraphicsGetCurrentContext() {
context.interpolationQuality = .high
context.setAllowsAntialiasing(true)
context.setShouldAntialias(true)
context.setFillColor(red: 1, green: 1, blue: 1, alpha: 0)
context.fill(imageRect)
context.saveGState()
context.translateBy(x: 0.0, y: size.height)
context.scaleBy(x: 1.0, y: -1.0)
context.concatenate(page.getDrawingTransform(.cropBox, rect: imageRect, rotate: 0, preserveAspectRatio: true))
context.drawPDFPage(page)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image
}
return nil
}
}
}
iOS 8 introduces a UIImageAsset class with a method registerImage:withTraitCollection:. How do I use this class?
Normally, you won't have to. Instead, you'll use an asset catalog. UIImageAsset, in iOS 8, is simply the mechanism underlying image sets in asset catalogs.
For example, in iOS 8, an asset catalog can distinguish between versions of an image intended for different size class situations, using the Width and Height pop-up menus to specify different size class possibilities. Then, when you use an image from an asset catalog in your interface, the right thing happens automatically. If we're on an iPhone with the app rotated to landscape orientation, and if there's both an Any height and a Compact height alternative in the image set, the Compact height version is used. And these features are live; if the app rotates from landscape to portrait, and there's both an Any height and a Compact height alternative in the image set, the Compact height version is replaced with the Any height version in your interface, automatically.
You'll notice that I didn't mention UIImageAsset. However, UIImageAsset is the underlying mechanism. When an image is extracted from an asset catalog through init(named:) and the name of its image set, its imageAsset property is a UIImageAsset. All the images in that image set are available through the UIImageAsset; each image has a trait collection associated with it (its traitCollection), and you can ask the UIImageAsset for the image appropriate to a particular trait collection by calling imageWithTraitCollection:. That, in fact, is exactly what the interface is doing for you. An interface object that can display an image is automatically trait collection–aware in iOS 8; it receives the traitCollectionDidChange: message and responds accordingly.
However, it is also possible to combine images into your own UIImageAsset. In a way, this is like making an asset catalog (or at least an image set) in code! In this example, I'll fetch two images out of the app bundle, and configure them so that one is used when the app is in portrait orientation and the other is used when the app is landscape orientation, automatically:
let tcdisp = UITraitCollection(displayScale: UIScreen.mainScreen().scale)
let tcphone = UITraitCollection(userInterfaceIdiom: .Phone)
let tcreg = UITraitCollection(verticalSizeClass: .Regular)
let tc1 = UITraitCollection(traitsFromCollections: [tcdisp, tcphone, tcreg])
let tccom = UITraitCollection(verticalSizeClass: .Compact)
let tc2 = UITraitCollection(traitsFromCollections: [tcdisp, tcphone, tccom])
let moods = UIImageAsset()
let frowney = UIImage(named:"frowney")
let smiley = UIImage(named:"smiley")
moods.registerImage(frowney, withTraitCollection: tc1)
moods.registerImage(smiley, withTraitCollection: tc2)
After that, if frowney is placed into the interface — for example, by handing it over to a UIImageView as its image, or by assigning it as a UIButton's image — it automatically alternates with smiley when the app changes orientation.
The remarkable thing is that this magic works even though there is no persistent reference to frowney, smiley, or the UIImageAsset (moods). The reason is that frowney and smiley are cached by the system (because of the call to init(named:)), and they each maintain a strong reference to the UIImageAsset with which they are registered.
I am planning to make a universal app to support retina display. It will be a quiz with more than 100 questions. So, for the bg images the suffix will be: iPhone, iPod:320X480 = photo.png, retina iPhone, iPod: 640X960 = photo#2x.png iPad: 1024X748 = photo~ipad.png and for retina iPad 2048 X 1496 (apple doc?) (1536?) = photo#2x~ipad.png . Do I need to write any additional code? Would it be too much to include 4 images for every question, that means 4 images X 120 questions = 480 images!!!Would it be to heavy?
The suffix the OS is looking for is "#2x.png"
So if you want to do separate graphics for iPhone versus iPad, put those differences in their filenames before the #2x part.
And yeah, four images does seem a bit like overkill. Why not just simply have regular resolution image and a high resolution image for various UI widgets used in both your iPad and iPhone versions?