I agree with Yun CHEN, as I think the most bulletproof solution is to have an Image Set for each resolution, thus avoiding image scaling performed on the device.
It is also correct that, on the basis of the rendering factor (2x, 3x, etc.) of the device (e.g. 2x on 4.7" iPhones, as the iPhone 8), you only need to put your appropriately sized image in the respective slot.
For instance, the Image Sets for iPhones 8 only require the 2x image.
However, mind the following:
UIScreen.main.bounds.height returns the height of the logical resolution - i.e. points, contrarily to UIScreen.main.nativeBounds.height that returns the height of the actual resolution - i.e. pixels (actually, UIScreen.main.nativeBounds.height always returns the pixel height of the device in Portrait mode, even if you are in Landscape). You should always use images that match the actual resolution - i.e. pixels, even if you check for points.
From iOS 8 onwards UIScreen.main.bounds.height will return different values whether your device is in portrait or landscape mode.
Therefore, if you want to use it to differentiate among devices, you should check for all the values that your App can use, and you should have a separate Image Set for each.
For instance, for Apps that work in both portrait and landscape modes:
var backgroundImageName = ""
if UIDevice().userInterfaceIdiom == .phone
{
switch UIScreen.main.bounds.height
{
case 812: // 5.8" (iPhone X) (3x) (Portrait)
backgroundImageName = "background_1125x2436"
case 736: // 5.5" (iPhone 8+, 7+, 6s+, 6+) (3x) (Portrait)
backgroundImageName = "background_1242x2208"
case 414: // 5.5" (iPhone 8+, 7+, 6s+, 6+) (3x) (Landscape)
backgroundImageName = "background_2208x1242"
case 667: // 4.7" (iPhone 8, 7, 6s, 6) (2x) (Portrait)
backgroundImageName = "background_750x1334"
case 375:
// 5.8" (iPhone X) (3x) (Landscape)
if (UIScreen.main.bounds.width == 812) {
backgroundImageName = "background_2436x1125"
}
// 4.7" (iPhone 8, 7, 6s, 6) (2x) (Landscape)
else if (UIScreen.main.bounds.width == 667) {
backgroundImageName = "background_1334x750"
}
case 568: // 4.0" (iPhone SE, 5s, 5c, 5) (2x) (Portrait)
backgroundImageName = "background_640x1136"
case 320: // 4.0" (iPhone SE, 5s, 5c, 5) (2x) (Landscape)
backgroundImageName = "background_1136x640"
default:
break
}
}
else if UIDevice().userInterfaceIdiom == .pad
{
switch UIScreen.main.bounds.height
{
case 1366: // 12.9" (iPad Pro 12.9) (2x) (Portrait)
backgroundImageName = "background_2048x2732"
case 1112: // 10.5" (iPad Pro 10.5) (2x) (Portrait)
backgroundImageName = "background_1668x2224"
case 834: // 10.5" (iPad Pro 10.5) (2x) (Landscape)
backgroundImageName = "background_2224x1668"
case 1024:
// 12.9" (iPad Pro 12.9) (2x) (Landscape)
if (UIScreen.main.bounds.width == 1366) {
backgroundImageName = "background_2732x2048"
}
// 9.7" & 7.9" (iPad Pro 9.7, iPad Air 2, iPad Air, iPad 4, iPad 3, iPad Mini 4, iPad Mini 3, iPad Mini 2) (2x) (Portrait)
else if (UIScreen.main.bounds.width == 1366) {
backgroundImageName = "background_1536x2048"
}
case 768: // 9.7" & 7.9" (iPad Pro 9.7, iPad Air 2, iPad Air, iPad 4, iPad 3, iPad Mini 4, iPad Mini 3, iPad Mini 2) (2x) (Landscape)
backgroundImageName = "background_2048x1536"
default:
break
}
}
self.backgroundImageView.image = UIImage(named: backgroundImageName)
and so on if other devices need to be included (e.g. Apple Watch).