For those who built app for iPhone 5

Did you have to submit two different project folders, one for the iPhone 5 and the other for iPhone 4? I found a way to test the app to my iPhone 5 but I had to change the size of some objects and the x and y locations based on the iPhone 5 screen. It doesn’t automatically fit everything in the iPhone 4 screen size, most objects get cut offscreen. I was also told to do the zoom stretch but I prefer the image size and location to match the iPhone 5 screen. What is the best solution to build for both devices but having to avoid changing the image size and x/y locations of objects to match the screen size of the specific iPhone device? [import]uid: 69494 topic_id: 33065 reply_id: 333065[/import]

I only use one folder.

If you think about positioning as anchoring to the top, bottom or center, and you’ve setup your config.lua right, things you’ve positioned relative to the top will be the same distance from the top. Things you’ve positioned relative to the bottom will be the same distance from the bottom. Things positioned based on center will be the same distance from the center.

The net effect is those things based on the top and bottom will be pulled away from the center.

If you have things that need to be a bit more absolute, then you will need to determine if you are a tall device and set a variable that contains an offset:

local isTallOffset = 0  
if display.pixelHeight \> 970 then  
 isTallOffset = 44 -- half of the 88 pixels you gain  
end  
  
someobject = display.newImageRect("blahblahblah")  
someobject.y = 100 + isTallOffset  

[import]uid: 19626 topic_id: 33065 reply_id: 131333[/import]

That’s actually a little confusing. Am I supposed to put this in my main lua file or in config.lua? Let’s say if I have two separate folders, will the device detect which project folder to use from a certain code? My config lua looks like this:

[lua]local targetDevice = ( system.getInfo( “model” ) )
local isTall = ( “iPhone” == system.getInfo( “model” ) ) and ( display.pixelHeight > 960 )

if isTall == false and targetDevice == “iPhone” then
application =
{
content =
{
width = 320,
height = 480,
scale = “letterbox”,
fps = 60,
antialias = true,
xalign = “center”,
yalign = “center”,
imageSuffix =
{
["@2x"] = 2,
},
},
}

elseif isTall == true then
application =
{
content =
{
width = 320,
height = 568,
fps = 60,
antialias = true,
xalign = “center”,
yalign = “center”,
},
}

elseif targetDevice == “iPad” then
application =
{
content =
{
width = 768,
height = 1024,
scale = “letterbox”,
fps = 60,
antialias = true,
xalign = “center”,
yalign = “center”,
imageSuffix =
{
["@2x"] = 2,
},
},
}
end [import]uid: 69494 topic_id: 33065 reply_id: 131336[/import]

First of all, your ipad settings are going to cause your positioning to be way off unless you want your iPad version to be completely different. Try making your iPad size 384 and 512 or 320 and 426. That way all devices share the same relative positioning.

You only want one project folder.

The code I posted goes in main.lua or if you’re using Director or Storyboard, it would go in each module. Without seeing how you’re trying to position elements, it’s hard to [import]uid: 19626 topic_id: 33065 reply_id: 131337[/import]

Well for instance:

I am trying to spawn objects from x=590 or my background imageRect is (570, 320). If I’m spawning an object from x=590, it would look strange on an iPhone 4 screen compared to the 5. I’m still not understanding your code and how that transforms everything based on the screen size. When you type someobject.y = 100 + isTallOffset, does that mean the actual size (100) and whatever is left if it detects the iPhone 5 screen? [import]uid: 69494 topic_id: 33065 reply_id: 131349[/import]

I only use one folder.

If you think about positioning as anchoring to the top, bottom or center, and you’ve setup your config.lua right, things you’ve positioned relative to the top will be the same distance from the top. Things you’ve positioned relative to the bottom will be the same distance from the bottom. Things positioned based on center will be the same distance from the center.

The net effect is those things based on the top and bottom will be pulled away from the center.

If you have things that need to be a bit more absolute, then you will need to determine if you are a tall device and set a variable that contains an offset:

local isTallOffset = 0  
if display.pixelHeight \> 970 then  
 isTallOffset = 44 -- half of the 88 pixels you gain  
end  
  
someobject = display.newImageRect("blahblahblah")  
someobject.y = 100 + isTallOffset  

[import]uid: 19626 topic_id: 33065 reply_id: 131333[/import]

That’s actually a little confusing. Am I supposed to put this in my main lua file or in config.lua? Let’s say if I have two separate folders, will the device detect which project folder to use from a certain code? My config lua looks like this:

[lua]local targetDevice = ( system.getInfo( “model” ) )
local isTall = ( “iPhone” == system.getInfo( “model” ) ) and ( display.pixelHeight > 960 )

if isTall == false and targetDevice == “iPhone” then
application =
{
content =
{
width = 320,
height = 480,
scale = “letterbox”,
fps = 60,
antialias = true,
xalign = “center”,
yalign = “center”,
imageSuffix =
{
["@2x"] = 2,
},
},
}

elseif isTall == true then
application =
{
content =
{
width = 320,
height = 568,
fps = 60,
antialias = true,
xalign = “center”,
yalign = “center”,
},
}

elseif targetDevice == “iPad” then
application =
{
content =
{
width = 768,
height = 1024,
scale = “letterbox”,
fps = 60,
antialias = true,
xalign = “center”,
yalign = “center”,
imageSuffix =
{
["@2x"] = 2,
},
},
}
end [import]uid: 69494 topic_id: 33065 reply_id: 131336[/import]

First of all, your ipad settings are going to cause your positioning to be way off unless you want your iPad version to be completely different. Try making your iPad size 384 and 512 or 320 and 426. That way all devices share the same relative positioning.

You only want one project folder.

The code I posted goes in main.lua or if you’re using Director or Storyboard, it would go in each module. Without seeing how you’re trying to position elements, it’s hard to [import]uid: 19626 topic_id: 33065 reply_id: 131337[/import]

Well for instance:

I am trying to spawn objects from x=590 or my background imageRect is (570, 320). If I’m spawning an object from x=590, it would look strange on an iPhone 4 screen compared to the 5. I’m still not understanding your code and how that transforms everything based on the screen size. When you type someobject.y = 100 + isTallOffset, does that mean the actual size (100) and whatever is left if it detects the iPhone 5 screen? [import]uid: 69494 topic_id: 33065 reply_id: 131349[/import]

So any solution to figure this out? I’m so close to being finished but now I have the problem of having everything fit into the iPhone 4 screen. I do have another project folder where everything fits in the iPhone 4 screen. I’m still not understanding your code Rob. Can you further explain to me if you don’t mind? :slight_smile: [import]uid: 69494 topic_id: 33065 reply_id: 131603[/import]

This is tough to do with words… No the 100 has nothing to do with the image size, only its location on the Y axis (up and down).

Lets drop back 10 and punt. For these examples, I’m assuming portrait orientation. You have 3 target screen shapes: iPad: which is a 3:4 ratio device. That means for every 3 pixels wide, it’s 4 pixels high (or 1.3333 high for every one wide). The iPhone’s before the iPhone 5 were a 2:3 ratio devices (1.5 high for every one wide). The iPhone 5 is a 16:9 screen, for every 1 wide, there are 1.7777 high.

The devices have a physical width and height, measured in pixels:

3Gs: 320 x 480
4, 4s; 640 x 960
5 640 x 1136

iPad 1, 2, mini: 768 x 1024
iPad 3, 4: 1536 x 2048

If you were to set your Corona SDK’s config.lua to match your devices physical sizes, you would have to compensate in code to adjust positions based on the device size. Corona though lets us set a scale factor to make sure we are all on the same playing field. When we do this, our screen positions become known as points, not pixels since the devices all have different pixel dimensions.

If we set our screens to all be based off of the same scale (either width or height the same and the other different), then we get 0,0 being the top left, display.contentWidth, 0 being the top right corner, 0, display.contentHeight being the bottom left corner and display.contentWidth, display.contentHeight being the bottom right corner.

So for fun lets say we are going to normalize all of our devices based on 320 points wide. You could do 640 or 768 depending on how your art is scaled. But lets use 320 for now.

If we are to maintain the aspect ratios and make it so that 0,0 is top left and display.contentWidth,display.contentHeight is bottom right, then you need to tell your config.lua the following (in pseudo code)

If you’re an iPad, then make my width 320 and my height 426 (320 * 1.3333). If you’re a short iPhone/iPod touch, then with the standard 320 width, the height needs to be 480 (320 * 1.5). If you’re a tall iPhone/iPod touch, then your height needs to be 568 (320 * 1.77777)

Oh for fun, lets assume we are dealing with a rectangle or image that is 64px wide and 64px high. And remember by default, Corona uses the center of the object for positioning. Our 64px x 64 px object will be 32px above and below X and 32px left and right of Y.

Now that we’ve normalized our devices to the same point system, an object at x=100, y=100 will be the same relative position on all devices: 100 points left, 100 points down. Something at x=100, y=500 will be off screen on the iPad (>426) and partially off screen on the short iPhones but will be fully on screen on the tall iPhones.

If you design your app based on only using positions based from the top of the device and you keep everything no lower than 426 px - half the height, then you don’t ever have to worry about adding or subtracting any offsets. This is pretty simple. You might be asking, “Why not do this then?” well its because you end up with a bunch of space at the bottom that you’re not using (again, we are dealing with portrait, flip it horizontal and you have a bunch of space on the right you’re not using)

Obviously, we want to use all of our screen real estate. By taking some design elements that need to be relative to the Top/Left and just use a simple X, Y we can take care of that part of the screen. But to move things on the Right/Bottom, you need to use display.contentWidth - someOffset, and display.contentHeight - someOffset. Now those elements will be positioned “someOffset” away from the right or bottom edge.

Doing this these elements will stay their relative distances from their edges. On the tall devices they will be further apart. On the iPads they will be closer together.

For other elements you can use display.contentCenterX and display.contentCenterY (or if you want to do your own math: display.contentWidth / 2, display.contentHeight / 2) Elements positioned based on those values +/- some offset will stay in the middle of your screen regardless of the device shape and size.

You should not need to mess with the isTallOffset code at all… except in the case of where you need to move part of the UI to keep it proportional to everything else. Lets look at an example. Goto:

https://itunes.apple.com/us/app/speedy-sender/id492006277?mt=8

This is an app of mine that I just submitted with iPhone 5 support. The screen shots currently up are for the iPhone 3/4 devices. Look at the 3rd screen shot with the pickerWheel and the button. In my code, I positioned all those elements relative to the top. In other words, my pickerWheel was defined as:

local picker = widget.newPickerWheel{ top=64 + display.statusBarHeight + 20}  

64 is the height of my black bar on top, display.statusBarHeight is the height of the device’s status bar and the last + 20 has how may pixels down I wanted it from the the black button bar on top.

However on the iPhone5 this type of positioning left a bunch of unused space at the bottom. The “Send Message” button was practically in the middle of the screen. My tabBar at the bottom is positioned so that it automatically went to the bottom on the tall device. To solve this, I changed my picker wheel to:

local isTallPad = 0  
if display.pixelHeight \> 960 then  
 isTallPad = 44  
end  
  
local picker = widget.newPickerWheel{ top=64 + display.statusBarHeight + 20 + isTallPad}  

Where did the 44 come from? Using a 320 x height scale factor, the iPhone 5 is 88 points taller than the 2:3 phones (568-480=88). Since I wanted these elements to move down, but not that far down, I chose to add half of my extra height to the elements, to space them out better. Since this is NOT an iPad app (can’t send text messages), I didn’t worry about iPad positioning. Hopefully that will explain how I’m using offsets to push things around a bit.

Continuing this line of thinking, lets say you have a button that you’ve put at: y = display.contentHeight - 32 (making up numbers here) and with the taller device you now want it to be a bit higher on the tall devices, then you would do obj.y = display.contentHeight - (32 + isTallPad) On tall devices, those elements will stretch out a bit.

“So what about the 360x570 background graphics?” Good question. Remember that Corona wants to center things. Your background will be centered and bleed off the edges avoiding letterBox black bars. “Shouldn’t 320x570 work?” Yes in fact if you scale your iPads to 320x426, then you really don’t need a 360x570. But sometimes I prefer to use a 360 x 512 scale for the iPads so I have a little more real estate to work with. 426 is considerably shorter than 480 and by using 360x512, I can use the same sized graphics on a little bit bigger canvas. Now my 360x570 backgrounds will cover me in those cases. And yes, if you put something at an X of 350 it will probably be offscreen on the iPhones. But if you do display.contentWidth - someOffset it will be on screen relative to the screen shape.

Now while not part of the question, while I’m writing this up, why not use 640 or 768 instead of 320?

Well it has to do with dynamic scaling. By using the smaller size, I can have regular sized graphics for the 320x480 world, then i have have graphics twice the size for the 640x960 world and then 4x graphics for the big Retina devices. That way I get the most optimal size for older devices and can follow the @2x and @4x nomenclature for image naming instead of having something like:

graphic@0.5.png
graphic.png
graphic@2x.png

Hope this helps.
[import]uid: 19626 topic_id: 33065 reply_id: 131619[/import]

That is really awesome advice Rob! Thank so much for taking the time to write all that. I’m sure it was a little tedious lol. I’ll try to follow the steps and see where it takes me on my app. Most of my objects are centered from display.contentCenterX etc. It’s just the little things I might need to change. Thanks again! [import]uid: 69494 topic_id: 33065 reply_id: 131632[/import]

So any solution to figure this out? I’m so close to being finished but now I have the problem of having everything fit into the iPhone 4 screen. I do have another project folder where everything fits in the iPhone 4 screen. I’m still not understanding your code Rob. Can you further explain to me if you don’t mind? :slight_smile: [import]uid: 69494 topic_id: 33065 reply_id: 131603[/import]

This is tough to do with words… No the 100 has nothing to do with the image size, only its location on the Y axis (up and down).

Lets drop back 10 and punt. For these examples, I’m assuming portrait orientation. You have 3 target screen shapes: iPad: which is a 3:4 ratio device. That means for every 3 pixels wide, it’s 4 pixels high (or 1.3333 high for every one wide). The iPhone’s before the iPhone 5 were a 2:3 ratio devices (1.5 high for every one wide). The iPhone 5 is a 16:9 screen, for every 1 wide, there are 1.7777 high.

The devices have a physical width and height, measured in pixels:

3Gs: 320 x 480
4, 4s; 640 x 960
5 640 x 1136

iPad 1, 2, mini: 768 x 1024
iPad 3, 4: 1536 x 2048

If you were to set your Corona SDK’s config.lua to match your devices physical sizes, you would have to compensate in code to adjust positions based on the device size. Corona though lets us set a scale factor to make sure we are all on the same playing field. When we do this, our screen positions become known as points, not pixels since the devices all have different pixel dimensions.

If we set our screens to all be based off of the same scale (either width or height the same and the other different), then we get 0,0 being the top left, display.contentWidth, 0 being the top right corner, 0, display.contentHeight being the bottom left corner and display.contentWidth, display.contentHeight being the bottom right corner.

So for fun lets say we are going to normalize all of our devices based on 320 points wide. You could do 640 or 768 depending on how your art is scaled. But lets use 320 for now.

If we are to maintain the aspect ratios and make it so that 0,0 is top left and display.contentWidth,display.contentHeight is bottom right, then you need to tell your config.lua the following (in pseudo code)

If you’re an iPad, then make my width 320 and my height 426 (320 * 1.3333). If you’re a short iPhone/iPod touch, then with the standard 320 width, the height needs to be 480 (320 * 1.5). If you’re a tall iPhone/iPod touch, then your height needs to be 568 (320 * 1.77777)

Oh for fun, lets assume we are dealing with a rectangle or image that is 64px wide and 64px high. And remember by default, Corona uses the center of the object for positioning. Our 64px x 64 px object will be 32px above and below X and 32px left and right of Y.

Now that we’ve normalized our devices to the same point system, an object at x=100, y=100 will be the same relative position on all devices: 100 points left, 100 points down. Something at x=100, y=500 will be off screen on the iPad (>426) and partially off screen on the short iPhones but will be fully on screen on the tall iPhones.

If you design your app based on only using positions based from the top of the device and you keep everything no lower than 426 px - half the height, then you don’t ever have to worry about adding or subtracting any offsets. This is pretty simple. You might be asking, “Why not do this then?” well its because you end up with a bunch of space at the bottom that you’re not using (again, we are dealing with portrait, flip it horizontal and you have a bunch of space on the right you’re not using)

Obviously, we want to use all of our screen real estate. By taking some design elements that need to be relative to the Top/Left and just use a simple X, Y we can take care of that part of the screen. But to move things on the Right/Bottom, you need to use display.contentWidth - someOffset, and display.contentHeight - someOffset. Now those elements will be positioned “someOffset” away from the right or bottom edge.

Doing this these elements will stay their relative distances from their edges. On the tall devices they will be further apart. On the iPads they will be closer together.

For other elements you can use display.contentCenterX and display.contentCenterY (or if you want to do your own math: display.contentWidth / 2, display.contentHeight / 2) Elements positioned based on those values +/- some offset will stay in the middle of your screen regardless of the device shape and size.

You should not need to mess with the isTallOffset code at all… except in the case of where you need to move part of the UI to keep it proportional to everything else. Lets look at an example. Goto:

https://itunes.apple.com/us/app/speedy-sender/id492006277?mt=8

This is an app of mine that I just submitted with iPhone 5 support. The screen shots currently up are for the iPhone 3/4 devices. Look at the 3rd screen shot with the pickerWheel and the button. In my code, I positioned all those elements relative to the top. In other words, my pickerWheel was defined as:

local picker = widget.newPickerWheel{ top=64 + display.statusBarHeight + 20}  

64 is the height of my black bar on top, display.statusBarHeight is the height of the device’s status bar and the last + 20 has how may pixels down I wanted it from the the black button bar on top.

However on the iPhone5 this type of positioning left a bunch of unused space at the bottom. The “Send Message” button was practically in the middle of the screen. My tabBar at the bottom is positioned so that it automatically went to the bottom on the tall device. To solve this, I changed my picker wheel to:

local isTallPad = 0  
if display.pixelHeight \> 960 then  
 isTallPad = 44  
end  
  
local picker = widget.newPickerWheel{ top=64 + display.statusBarHeight + 20 + isTallPad}  

Where did the 44 come from? Using a 320 x height scale factor, the iPhone 5 is 88 points taller than the 2:3 phones (568-480=88). Since I wanted these elements to move down, but not that far down, I chose to add half of my extra height to the elements, to space them out better. Since this is NOT an iPad app (can’t send text messages), I didn’t worry about iPad positioning. Hopefully that will explain how I’m using offsets to push things around a bit.

Continuing this line of thinking, lets say you have a button that you’ve put at: y = display.contentHeight - 32 (making up numbers here) and with the taller device you now want it to be a bit higher on the tall devices, then you would do obj.y = display.contentHeight - (32 + isTallPad) On tall devices, those elements will stretch out a bit.

“So what about the 360x570 background graphics?” Good question. Remember that Corona wants to center things. Your background will be centered and bleed off the edges avoiding letterBox black bars. “Shouldn’t 320x570 work?” Yes in fact if you scale your iPads to 320x426, then you really don’t need a 360x570. But sometimes I prefer to use a 360 x 512 scale for the iPads so I have a little more real estate to work with. 426 is considerably shorter than 480 and by using 360x512, I can use the same sized graphics on a little bit bigger canvas. Now my 360x570 backgrounds will cover me in those cases. And yes, if you put something at an X of 350 it will probably be offscreen on the iPhones. But if you do display.contentWidth - someOffset it will be on screen relative to the screen shape.

Now while not part of the question, while I’m writing this up, why not use 640 or 768 instead of 320?

Well it has to do with dynamic scaling. By using the smaller size, I can have regular sized graphics for the 320x480 world, then i have have graphics twice the size for the 640x960 world and then 4x graphics for the big Retina devices. That way I get the most optimal size for older devices and can follow the @2x and @4x nomenclature for image naming instead of having something like:

graphic@0.5.png
graphic.png
graphic@2x.png

Hope this helps.
[import]uid: 19626 topic_id: 33065 reply_id: 131619[/import]

That is really awesome advice Rob! Thank so much for taking the time to write all that. I’m sure it was a little tedious lol. I’ll try to follow the steps and see where it takes me on my app. Most of my objects are centered from display.contentCenterX etc. It’s just the little things I might need to change. Thanks again! [import]uid: 69494 topic_id: 33065 reply_id: 131632[/import]