I've tried
self.frame.size
self.view!.frame.size
UIScreen.mainScreen().bounds.size
None of them work.
How do I get the correct screen size for the device?
You can use following swift code to get the screen size.
let displaySize: CGRect = UIScreen.mainScreen().bounds
let displayWidth = displaySize.width
let displayHeight = displaySize.height
You can use:
let deviceWidth = UIScreen.mainScreen().bounds.width
let deviceHeight = UIScreen.mainScreen().bounds.height
And if you need to get the ratio so you can detect what device they are using, you can use the following for portrait mode or switch it for landscape mode.
let maxAspectRatio: CGFloat = deviceHeight / deviceWidth
You can then check what ratio the device is to determine certain things.
if maxAspectRatio == (4 / 3) {
//The ratio of an iphone 4S is 4:3
print("The user is using an iPhone 4S or iPod 4th Generation.")
} else if maxAspectRatio >= 1.7 && maxAspectRatio <= 1.8 {
//The ratio of these devices is 16:9
print("The user is using an iPhone 5, 5S, 5C, 6, 6S, 6 Plus, 6S Plus, or iPod 5th Generation.)
} else {
print("The user is using an iPad, iPad Mini, iPad Air, iPad Retina, or iPad Pro.")
}
If you want to get the correct view that the player can see, as in the bounding frame of the device's size, you can use the following guide.
Related
UIScreen.main.bounds.width and UIScreen.main.bounds.height are both wrong. It's returning 414x736 but it should be about 360x640.
Device: iPhone 8 Plus.
iPhone [Any] Plus native rendering resolutions are downsampled by ÷1.15 because screens didn't have enough pixels to show #3x until iPhone X arrived.
Screen resolution is 360x640 physical points but screen rendering is 414x736 software points. That only happens on Plus models.
414 ÷ 1.15 = 360
736 ÷ 1.15 = 640
Check out this: https://www.paintcodeapp.com/news/iphone-6-screens-demystified
It depends on when you call the function.
You have to call this after View Appear fully.
override func viewDidLoad() { // Or viewDidAppear()
{
let frame = self.view.bounds; // or UIScreen.main.bounds also works
}
You will get different value if you call the function on viewWillAppear.
I read the native height of the phone to size my display output, and determine top and bottom keep out areas. This is a tab based app. My display is purely programmatic, it is graphically layed out based on screen dimension only. On the iPhone 12 mini, the display is smaller than it should be. The other iPhone 12 types display correctly.
While testing my new app on various iPhone types in the xcode simulator, they
looked correct. But when I put the app on my iPhone 12 mini, the display was smaller than it should be. I learned the simulator returns the value 2436 for native height, but the phone returns the value 2340.
This code examines the display and tells me how much to reserve on the top and bottom of the screen by type of phone:
nativeHeight=UIScreen.main.nativeBounds.height
if nativeHeight==1136 || nativeHeight==1334 // SE,6S,7,8
{reserveTopPixels=40; reserveBottomPixels=98}
else if nativeHeight==1792 // 11, XR
{reserveTopPixels=88; reserveBottomPixels=198}
else if nativeHeight==2208 // 6s+ 7+ 8+
{reserveTopPixels=54; reserveBottomPixels=146}
else if nativeHeight==2436 || nativeHeight==2688 // X, XS, 11Pro, 11, Xr
{reserveTopPixels=132; reserveBottomPixels=260}
else if nativeHeight==2340 //iPhone 12 mini "downsampled screen"
{reserveTopPixels=132; reserveBottomPixels=260; nativeHeight = 2436}
else if nativeHeight==2532 // 12, 12 pro
{reserveTopPixels=132; reserveBottomPixels=260}
else if nativeHeight==2778 // 12 pro max
{reserveTopPixels=132; reserveBottomPixels=260}
else {reserveTopPixels=40; reserveBottomPixels=98}
My correction is to change the value received from the phone, 2340, to a larger value, 2436.
The app displays correctly now on both the simulator and the phone. My question is, is this a reasonable solution, or should I try something else.
nativeBounds: CGRect. : provides the bounding rectangle of the physical screen, measured in pixels. And the physical screen for iPhone 12 mini is 1080×2340 pixels
The iPhone 12 mini has a physical screen resolution of 1080 x 2340 pixels (476 ppi). This is lower than the native resolution reported by the operating system (using nativeBounds on UIScreen). I assume this is to maintain compatibility with the resolutions of the 5.8" models (iPhone X/XS/11 Pro).
Reference :
https://hacknicity.medium.com/how-ios-apps-adapt-to-the-various-iphone-12-screen-sizes-e45c021e1b8b
https://useyourloaf.com/blog/iphone-12-screen-sizes/
It depends on where you are using this nativeHeight to layout.
As you indicated you have problem just for on the iPhone 12 mini simulator. Then Why do you need all checking logic ? Just be sure you working on simulator and catch the iPhone 12 mini and make your adjustment. I think that extension would make sense.
static var isSimulator: Bool {
return TARGET_OS_SIMULATOR != 0
}
extension UIDevice {
var modelIdentifier = ""
modelIdentifier = ProcessInfo.processInfo.environment["SIMULATOR_MODEL_IDENTIFIER"] ?? ""
let nativeHeight = UIScreen.main.nativeBounds.height
if nativeHeight==2340 // your specific case
{
reserveTopPixels=132; reserveBottomPixels=260; nativeHeight = 2436
}
}
Edit
Then If you want certain code to be run only in the iOS simulator either device, you should use this:
func adjust() {
#if targetEnvironment(simulator)
// we're on the simulator
}
#else
// we're on a device
}
#endif
}
I'm trying to customise the design for XS Max. Previously I just identified the device by checking the main.bound.screen.height, which, for XS Max, according to this site: https://www.paintcodeapp.com/news/ultimate-guide-to-iphone-resolutions, should return 896.0, right?
The Xcode 10.0 XS Max simulator returns 812.0 as screen height (the same goes for XR, which should have the same screen points), though. Any idea how to fix this?
enum IPhone: String {
case SE, normal, plus, X, XSMax
init?(height: CGFloat) {
switch height {
case 568: self = .SE
case 667: self = .normal
case 736: self = .plus
case 812: self = .X
case 896: self = .XSMax
default:
return nil
}
}
}
struct Design {
static var iPhone = IPhone(height: UIScreen.main.bounds.height)!
}
In the viewDidLoad() of the view controller:
print("screen height: \(UIScreen.main.bounds.height), iPhone: \(Design.iPhone.rawValue)")
Ok, after some searching I've found the answer to my question here: UIScreen MainScreen Bounds returning wrong size
Turns out, Xcode will guess the size of the screen by going through the launch images you've provided. Can you believe that? So if you didn't provide an image in the proper size for the new XS Max it will fall back to the biggest launch image it finds. That's why in a new project without launch images it worked fine.
I've provided launch images for XS Max and XR and now the screen sizes are correct.
I'm making a universal game across all apple platforms. The problem is there are lots of aspect ratios, and with the growing numbers of devices, it becomes a hassle. I've tried the following:
var deviceAspectRatio: CGFloat? {
#if os(iOS)
if UIDevice.current.model.contains("iPhone") {
return 16/9
} else if UIDevice.current.model.contains("iPad") {
return 4/3
}
#elseif os(tvOS)
return 16/9 //There might be other aspect ratios also
#elseif os(watchOS)
return 1
#elseif os(macOS)
//figure out aspect ratio
#else
return nil
#endif
}
But even with this, Xcode gives me an error:
Missing return in a function expected to return 'CGFloat?'
The trick on macOS is that there might be more than one screen, so if this is the case, you'll have to decide which one you're interested in. However, if you settle on a screen, you can just get the frame from NSScreen.frame and divide the width by the height.
This code will get the aspect ratio for the screen a given window is on:
guard let frame = someWindow.screen?.frame else { return nil }
let aspectRatio = NSWidth(frame) / NSHeight(frame)
Also, you should probably be doing something similar with UIScreen on iOS instead of hard-coding the values there. Apple may someday release a new device with some other aspect ratio your app doesn't anticipate.
In order to make it universal code for all devices you can use DeviceKit dependency and then
import DeviceKit
let device = Device.current
let deviceAspectRatio = device.screenRatio.height / device.screenRatio.width
OR
let deviceWidth = UIScreen.main.bounds.width * UIScreen.main.scale
let deviceHeight = UIScreen.main.bounds.height * UIScreen.main.scale
let testDeviceAspectRatio = deviceHeight / deviceWidth
I've been searching for this issue with no results, so I ask this question.
I created a game in HTML5, 650x510 pixels resolution. The game scales to fit in all devices resolution, this is my scaling function:
function onResize() {
var w = window.innerWidth;
var h = window.innerHeight;
var ow = 650;
var oh = 510;
// keep aspect ratio
scale = Math.min(w / ow, h / oh);
stage.scaleX = scale;
stage.scaleY = scale;
// adjust canvas size
stage.canvas.width = ow * scale;
stage.canvas.height = oh * scale;
stage.update();
}
On all devices the game scales perfectly but on iPhone5(iOS 7.1), iPhone6(iOS 8.1) and iPhone6 Plus(iOS 8.4) when I rotate to landscape the canvas looks really blurry.
The thing is that with iOS 9.0, the canvas looks perfect on iPhone6 and iPhone6 Plus.
I've done this tests with the Xcode simulator.
Does anyone have any clues about why this blur can be happening and how to solve it?
Thanks a lot,
Mikeldi