Instruction 1
Supporting Landscape Orientation
Most commonly, iPhone users keep their phones in portrait orientation. That’s how most apps work and how most of them were built to work. However, it’s not the only way to use an iPhone. Many apps also support landscape orientation. Some apps are even built only for landscape orientation, like games or video apps. So while RGB Picker works great in portrait orientation, it has a ways to go on landscape.
And that’s not the only problem. Since SwiftUI views can be reused on the iPad too, and because the iPad is used in landscape orientation as much as in portrait orientation, you have to write code that adapts and better uses the available space on larger devices.
Notice how the sliders are excessively long on an iPad just like the color rectangle. The UI is not using the available space in a smart way. SwiftUI is just using the iPhone layout but stretched to match the bigger device screen.
On the other hand, if you try to run the app in landscape orientation on the iPhone, it’s unusable because you can’t use the blue slider or the button to set the color.
This isn’t good. Users are forced to use the app in portrait orientation, no matter their preference. VStack arranges its subviews vertically, and some of them end up being pushed out of bounds in landscape.
But supporting landscape orientation is not the only problem.
Accessibility and Large Fonts
Building UI that adapts to different context isn’t just about allowing users to use your app on landscape orientation. It’s also about allowing users to use your app in any way they need to. SwiftUI was built with the tools to make accessible apps right out of the box. It supports all accessibility features like Voice Over, Dynamic Type and Voice Control to deliver high-quality apps to everyone.
Supporting accessibility means enabling as many people as possible to use you your app, regardless of which device they have or how they use it. It means being aware of all the people that may want to use your app.
And for that reason, you as a developer have the responsibility to craft your app and UI with these features in mind. Understanding this can improve your app and be more inclusive, allowing any user to use your app, regardless of their abilities or disabilities.
Using the device in landscape is not the only use case that can cause problems with the current UI. When using large accessibility fonts the UI may also break on smaller devices, like the iPhone, even in portrait orientation.
It’s important to take these scenarios into consideration when building features. And Xcode Previews offers a bunch of tools so that you can visualize how your views adapt to these use cases.
Using the Dynamic Type variants on the canvas, you can check how your app looks with the different accessibility fonts and font size preferences.
Using ScrollView to Solve This Problem
A quick and simple way to fix the issue of the layout being out of bounds is to allow users to scroll through the view, so they can see the rest of the content that’s out of bounds. By adding a ScrollView to the view hierarchy, users can scroll down and see the button at the bottom.
This is a quick fix that not only solves the problem of landscape orientation and accessibility fonts, but also solves the problem with small devices. While most of Apple’s lineup consists of rather large iPhone screens, the latest iOS versions still support older devices with smaller screen sizes. And while a layout might look great on a big device, it might feel cramped or even fall out of bound on smaller devices, even in portrait orientation.
A common use case that often causes headaches for mobile developers is custom forms. A form with many input fields and spacing might look fine on a larger device, but push content too far down and out of the bounds on smaller devices.
That’s why the native SwiftUI view Form already embeds a ScrollView in it. Its a simple solution for handling these kinds of problems. You allow the user to scroll down if the content is out of bounds and fill the rest of the form.
On bigger devices, the ScrollView won’t affect the experience and the user will be able to see the entire content of the form on screen.
Drawbacks of Using ScrollView
While you might feel that using a ScrollView on every view might be a good idea, there are a couple of problems with this solution.
The first being that depending on how you build your layout, some views might not behave like you expect them to. For example, Spacer views. On a vertical ScrollView, if you have a VStack with views and a Spacer to push a part of the layout up or down, VStack won’t know how to apply the spacing on its views because ScrollView only allows its subviews to use the amount of space they need, and not the entire available space.
ScrollView {
VStack {
Header()
Spacer()
Title()
}
}
ScrollView might take the whole screen, but it doesn’t know the size of its subviews, as they might grow larger than the available space and out of bounds. So instead of using a Spacer view to space your views, you’ll have to use the spacing parameter of the VStack or even the frame() view modifier.
ScrollView {
VStack(spacing: 32) {
Header()
Title()
}
}
Another problem is that the layout is unchanged after you rotate the device. ScrollView only allows you to scroll through it. It won’t change how the views are placed on screen. And while users can scroll through the view to find the rest of the content, they might not know they can do that.
The layout is not optimized to use the new available space on the screen.
Using scroll views is a quick and good solution when handling layout breaks for forms and content that are expected to go out of bounds. In the next demo, you’ll add a ScrollView to the hierarchy of the app to solve these issues.