iPad Orientation Issues

I am developing an iOS app. I want to change the layout of the controls on the screen when the iPad is rotated from portrait to landscape. Specifically, I want the MobileCanvas and ScrollableArea to be aligned vertically when the iPad is in portrait orientation, and aligned horizontally when the iPad is in landscape orientation.

Looking at the Documentation, the properties related to their positions (Top, Width, etc.) are set to Read-Only, and I am wondering what to do about it.

Is there any way to solve this?

Thank you.

There are intricate ways to achieve this at runtime, but having tried and failed to do something similar, my best advice is to design two different screens, and ‘show’ the suitable one when the orientation changes.

Create a class to handle control events, and you can use small stub methods on each control which call a common method, passing ‘me’ as a parameter.

You can do this by adding and removing constraints programmatically in the resized event.

Thank you @Jeff_Tullin .

It seems that it is difficult to achieve this simply. If you create two screens and display them according to their orientation, you may need to come up with some way to display them smoothly when rotating. First, try transitioning between two screens without worrying about the UI.

Thank you.

Thank you @Greg_O .

The coordinate parameters of each control could not be directly controlled in the Resized event. Do you know any good ways to do this?

Thank you.

You can’t do it by coordinates. The underlying system uses constraints and are so much more powerful than coordinates alone and because you never know how much space you’re going to get (especially on iPad) they’re also really important.

Constraints allow you to define relationships within and between controls and their views. So for instance, for these two canvases, you could have eight constraints if you wanted them to be square:

Let’s call them c1 and c2. Vertical first

  1. c1.top standard gap from view.top
  2. c2.top, standard gap from c1.bottom
  3. View.bottom, standard gap from c2.bottom
  4. c2.height, equal to c1.height

This in of itself is kinda magic. The two canvases are going to stay away from the top and bottom edges, away from each other and have the same heights, no matter what size screen they’re on.

Now horizontal:
5. c1.left, standard gap from view.left
6. c2.left, equal to c1.left
7. c1.width, equal to c1.height
8. c2.width, equal to c2.height

This group makes sure there’s a gap on the left and that the canvases have the same widths as their heights.

I find it easier if you draw out the layout you want and then draw lines representing the constraints within and between the controls and views. A good rule of thumb is “Two constraints per control in each direction when dealing with things being equal.”

Once in a while you’ll get into situations where you just can’t do what you want by purely using equals though. Like if these canvases have a minimum size. That’s when priorities and inequalities come into play. If, for instance, you needed the minimum size of these canvases to be 200, you can just say that:

  1. c1.width >= 200, Required

In that case, you’d need to give the system some indication of what to do if that wasn’t possible (like if the screen height < 400, in which case they both can’t be 200 tall, but we also told them that height = width.

It can get complicated, but I assure you that the results are worth learning this stuff.

FWIW, I did a Xojo webinar in 2023 about constraints and released a project which exposes their full power in Xojo projects. There’s even a method that converts Xojo layout constraints at runtime for use in this system.

3 Likes

I was able to set the default position (Auto-Layout) of each control without any problems. I now realize that, unlike Mac apps, layout settings are important on the iPad, which has a wide variety of display spaces.

I can’t control the position of the controls, but I was able to create two screens as you taught me the other day and display them alternately with the Resized event. I’m also satisfied with the rotation effect, as the screen transition was smoother than I expected.

I’m very grateful for your detailed reply. Thank you very much.

1 Like

I have some kind of love / hate relationship with the iOS constraints.
It can easily mess up my layout, when I decide to add a control, which I want to position below other controls.

Also, when I change the orientation, like the OP mentioned, the positions may not be how I would like them to be. I would love a more CSS flex-position approach.

Wouldn’t it be nice for Xojo to add a Constraint-Set? Something that can be active based on orientation or device type (iPad, iPhone)? I think that might tackle the OP’s issues…

ColorGroup does that based on dark/light mode.
It would be nice to have a ConstraintGroup, where the group is active, based on the mentioned orientation and / or device type.
Is that worth a feature request?

You can already do groups of constraints in code.

Really? I’ve already been working around this by creating multiple screens and switching between them on orientation change, but if there’s an easier way to do this I’d like to explore that.

1 Like

Constraints can be created in code. You could do this, and store them into two different arrays. When you want to switch, just loop through the two arrays and set their Active properties appropriately.