Locking Flutter Screen Orientation in main() Silently Kills iPad Multitasking
Welcome to follow the WeChat public account: FSA Full Stack Action 👋
I. Preface
I stepped on a big pitfall when developing an app before, and this pit was hidden particularly deep, going undiscovered for three whole months.
At the time, to save effort and ensure consistent visual effects of the app on different devices, I casually wrote a line of code in the main() function, directly locking the Orientation to portrait only. Everything was normal when we tested on iPhone and Simulator, until we later saw a user review saying: "This app does not support Multitasking." Only then did I suddenly realize: we had personally destroyed the app's split-screen functionality on iPad.
II. Problem Reproduction
The most insidious part is: this produces no errors at all, nor does it cause the app to crash.
The IPA you package installs and runs fine on the iPad, and the interface looks okay. The problem is, when you try to use the iPad's Slide Over or Split View features, you'll find your app simply cannot enter them, or even if it does, it cannot switch flexibly like other apps.
I didn't discover this through a test device, but because of a user feedback. When I got a real iPad and started reproducing it, the problem was very obvious:
// This line of code performs perfectly on iPhone, but is a "split-screen killer" on iPad
await SystemChrome.setPreferredOrientations([
DeviceOrientation.portraitUp,
]);
III. Principle Analysis
Why does code that works fine on iPhone turn sour on iPad? Behind this is actually Apple's hard requirement for Multitasking.
By comparison, we can intuitively see the difference in SystemChrome processing logic between iPhone and iPad:
Device Type |
|
Impact on Multitasking |
iPhone |
Forces lock on the current orientation; the interface does not change with screen rotation. |
No impact. Users are accustomed to single-screen operation; locking orientation meets expectations. |
iPad |
Locking orientation is considered as abandoning "multitasking capability". |
Fatal impact. Because it cannot respond to rotation, the app is excluded from |
The core logic is: Apple's design philosophy is that if you want to support split-screen (Split View) on iPad, your app must support all interface orientations. Because during split-screen, the sizes of the left and right apps change dynamically; they must be able to Reflow according to environmental changes. If you forcibly lock the orientation at the code level, the iPad system considers your app unqualified for multitasking, thus directly revoking your "split-screen eligibility".
IV. Solutions
Now that we know this pitfall, how should we gracefully handle screen orientation? It depends on your business requirements.
1. If your app truly does not support landscape at all
If your app is indeed a portrait-only business (like some form-heavy tools) and you completely disregard split-screen on iPad, then absolutely do not use SystemChrome to dynamically lock it in main().
You should tell the system through native configuration: this app was never intended to support landscape. This way, although it still cannot split-screen, at least the logic is clear and won't cause the system to misjudge due to runtime code behavior.
iOS: Configure
UISupportedInterfaceOrientationsinInfo.plist.Android: Set
screenOrientationinAndroidManifest.xml.
2. If you only want to lock orientation on specific pages
This is my most recommended solution currently. If your app supports rotation in most scenarios, but only needs to force portrait on certain specific pages (like full-screen video playback, or a particular interactive interface), you should adopt the strategy of "local locking, release when done".
On the page that needs locking, use initState to lock, and remember to release it in dispose:
// Perform local locking on pages that must be portrait
@override
void initState() {
super.initState();
// Lock to portrait when entering the page
SystemChrome.setPreferredOrientations([
DeviceOrientation.portraitUp,
]);
}
@override
void dispose() {
// When leaving the page, be sure to return control to the system!
// Pass an empty list to let the system handle it automatically based on device rotation state
SystemChrome.setPreferredOrientations([]);
super.dispose();
}
The benefits of doing this are:
The app's global environment still supports rotation and split-screen.
Only the current page is "forced" to display in portrait.
When the user returns to the previous page from this page, or switches to another app, all logic conforms to the
iPad's multitasking standards.
V. Conclusion
To summarize: Never use a global locking method in the main() function to handle screen orientation.
This operation is "harmless" on iPhone, but "self-sabotage" on iPad. If you need to control orientation, try to limit the control scope to the page level and return the freedom of rotation to the user.
If you have encountered similar "invisible pitfalls" during Flutter development, feel free to share and discuss in the comments.
If the article has been helpful to you, please don't hesitate to click and follow my WeChat public account: FSA Full Stack Action, this will be the greatest encouragement to me. The public account not only has Android technology, but also iOS, Python and other articles, possibly covering the skill points you want to know~