Due to the nature of startups, development is always rapid and tends to involve minimum number of developers. In startups, the development process of any product or solution is made in such a way that it takes less development effort, less maintenance, and is also cost-effective.

Requirement

So, there is an Android Application of ours which is being used by various government bodies of the country. So as usual after a certain time, the requirement evolves into the development of an iOS version of the same. Now like I said earlier, we had to look for a solution which takes lesser time and knowledge to develop. Its code needs to be more maintainable and we have to estimate how fast we can move it to production.

Existing Solutions

One obvious solution could have been to go with the native iOS App development using Objective-c or Swift but the problem with that was that developers with these skills were on a tight deadline for other products.

So we knew that we have to go for a cross-platform framework which is easy to learn and most importantly it gives a pure iOS feel to it. Though there were developers with React-Native knowledge, we wanted this app to have more natural feel like native iOS apps.

Hence, Flutter.

Mandatory GIF to make this post humorous.

Flutter

Flutter is Google’s UI toolkit for building beautiful, natively compiled applications for mobile, web, and desktop from a single codebase.

In Flutter everything is a Widget. Earlier Flutter releases didn’t have basic Cupertino Widgets (iOS UI Components) but now it has almost every UI component to make your app look and feel like it is developed using native technologies.

Existing App’s UI component level breakdown

For knowing how we can convert the Material Design looking Android App or iOS app built with flutter into more native-looking iOS App, We have to break it down on the level of view/UI components.

List and Grid views (RecyclerView with LinearLayoutManger or GridLayoutManager) Input Fields (TextInputLayout and TextInputEditText) Card style views (MaterialCardView ) Date Selection Dialogs (DatePickerDialog) Progress views/Loaders (ProgressBar) Tabs for segmented UI (TabsLayout with ViewPager) BottomSheet Dialogs (BottomSheetFragment) Alert Dialogs (MaterialAlertDialog) Icons (Material Icons) Call to Actions (MaterialButton)

Above mentioned UI components were the basic building elements of the different part of the screens, these elements were achieved using MaterialComponents Library of the Android.

Achieving the same with Flutter

First, we developed the Material design based iOS App. Then we thought of refactoring the entire app to make it look more like a native iOS App. Now I am not going to cover the Material Widgets of the Flutter. Assuming that you have gone through material widgets catalog of Flutter, we can move forward to see how we can use Cupertino Widgets in replacement with Material Widgets.

1. List and Grids

For showing lists, we can use ListView from material.dart and for grid GridView but the main catch here is not to give it a material child element instead we can use CupertinoButton parent widget to make list items clickable and give ios feel to it.

2. Input Fields

When you TextFormField from material.dart package, the validator can be used to validate. Here when we use CupertinoTextField, we have to use the controller to get the text and manually validate the data input.

3. Card Style Views

For showing cards, In Flutter we can use Card but again to give it an iOS look we can use different elevation on the card and can define a custom border shape with border colors and other attributes.

4. Date Selection Dialogs

Instead of showDatePicker from the material.dart package, use CupertinoDatePicker from cupertino.dart to show wheel type date selection widget.

5. Progress Views / Loaders

Use CupertinoActivityIndicator instead of CircularProgressIndicator to show loading/progress state when some background or time taking task is going on.

6. Tabbed View

In material design, we can use TabBar at bottom of AppBar but in cupertino.dart we have to use CupertinoSegmentedControl.

7. BottomSheet Dialogs

If we want users to choose from a few options then we can show a bottom sheet with those options. We have to use CupertinoActionSheet with CupertinoActionSheetAction.

8. Alert Dialogs

Using CupertinoAlertDialog with CupertinoDialogAction or CupertinoButton as action will give ios-style alert dialogs with action buttons.

9. Icons

Use cupertino_icons package for showing iOS style icons. Then we can use new CupertinoIcons.<name_of_icon> to add any ios-style icon.

10. Call to Actions

Use CupertinoButton where you have MaterialButtons in the UI.

Other Important Cupertino Widgets

Use CupertinoPageScaffold instead of Scaffold and CupertinoNavigationBar instead of AppBar for showing top title bar with action buttons to go back or perform any action like saving the form.

2. Use CupertinoScrollBar for ios-style scrollbar indicator.

3. CupertinoPicker for showing choice lists.

Conclusion

After creating a fully functional material design looking iOS App, the migration to its ios-style version was super easy and less time taking. With least efforts, it was easy to achieve the consistent look like native iOS app without losing any performance.

P.S. Can’t show any screenshots of the original app due to confidentiality reasons.

Resources