As an iOS Engineer, I am trying to learn Flutter.

Jerry PM
7 min readJan 26, 2023

--

These are several things that I obtained, I think this part I 😊.

Photo by Fahim Muntashir on Unsplash

This article chronicles my journey of learning Flutter, as an iOS developer who has experience using Swift, learning Flutter has been a great opportunity for me to expand my skillset. One of the things I appreciate most about Flutter is its ability to create beautiful and responsive user interfaces. The framework’s rich set of customizable widgets and animations make it easy to create visually appealing apps. Additionally, the use of Dart as the programming language is similar to Swift, making it easy for me to understand the basic concepts and dive into the development process quickly. I also appreciate the ability to develop for multiple platforms with one codebase, which allows me to reach a wider audience and save time in development. Overall, learning Flutter has been a valuable experience for me as an iOS developer, and I look forward to continuing to improve my skills in this framework.

Reverse position when creating a string variable

“When you create a new variable in Swift, it looks like this:

let newValueString: String = "data string"
let newValueInt: Int = 0

In Flutter, however, it's the reverse, it looks like this:

String newValueString = "data string";
int newValueInt = 0;

Don’t forget the semicolon

When working with Flutter, one important thing to keep in mind is the use of semicolons ( ; ). Unlike other languages such as Swift, in Flutter, a semicolon is required at the end of every statement. This means that you will always need to pay close attention to the placement of semicolons in your code to avoid any errors. So, don’t forget the semicolon when working with Flutter, it is very important.

Constructor

In Swift, a constructor is called ‘init’ and the process is the same.
a constructor is a special method that is called when an object of a class is created. It is used to initialize the object’s state and perform any other setup that is required before the object can be used.

// class
class Person {
String name;
int age;

// constructor
Person() {
name = "John Doe";
age = 30;
}
}

When using “this” like “self”

In Flutter, use the ‘this’ keyword to reference a variable in a class when the variable has the same name as a parameter in the constructor.

class Person {
String name;
int age;

Person(String inputName, int age) {
this.name = inputName;
this.age = age;
}
}

// OR

class Person {
String name;
int age;

Person(this.name, this.age);
}

“extend” and “with”

In Flutter, “extend” and “with” are used to create new classes that inherit properties and methods from existing classes, the same used with “Protocol” in swift.

  • “extend” is used to create a new class that inherits from an existing class, also known as a subclass. The new class is called a child class, and the existing class is called the parent class. The child class has access to all the properties and methods of the parent class, and can also add new properties and methods.
class Parent {
String name;
int age;
}

class Child extends Parent {
String address;
}

“with” is used to mixin properties and methods from one or more classes into a new class. This allows the new class to reuse existing code, without inheriting the entire class. Mixins are used to share common functionality between classes that don’t have a subclass relationship.

class Parent {
String name = "";
int age = 0;
}

// one property
class Child with Parent {
String address = "";
}


// more clasess

class Childtwo {
String address = "";
}

class Children with Childtwo, Parent {
String address = "";
}

When using “with” cannot multiply Parent, it will be an error.

Call Class

When call function in flutter you need import name file, example if you now in file `main.dart` but you want to call class HomePage in file HomePage.dart. when you using swift you don’t need to import file if you have same module.

Home Class

import 'package:flutter/material.dart';

class HomePageClass extends StatelessWidget {
HomePageClass({super.key});


// Main Process
@override
Widget build(BuildContext context) {
// Scafold
return Scaffold(
// background color
backgroundColor: Colors.white.withOpacity(0.9),

// App bar
appBar: AppBar(
// title: const Text("Home Page"),
title: Text(Texts.titleHome()),
),

// Body
body: Container(),
));
}
}

Main Class

import 'package:flutter/material.dart';
import 'HomePage.dart'; // import file here


void main() {
runApp(MyApp());
}

class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'My App',
home: HomePageClass(), // This class is what you call
);
}
}

Hide Debug Mode

In Flutter when youI ran app, I noticed a `debug` banner in the corner look like this image, but in swift when run debug not have this banner debug.

Source: Author

import 'package:flutter/material.dart';
import 'HomePage.dart';

void main() {
runApp(MyApp());
}

class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false, // hide debug mode
title: 'My App',
home: HomePageClass(),
);
}
}

This result image when hide the Banner debug.

Source: Author

Row and Column

Swift uses TableView where creating a table in Flutter you can use Row for horizontal direction and Column for vertical direction.

.
.
child: Column(
children: [
Row(
// ignore: prefer_const_literals_to_create_immutables
children: [
Text("data 1 "),
Text("data 2 "),
Text("data 3 "),
],
),
Text("data 2 1 "),
Text("data 2 2 "),
Text("data 2 3 "),
],
),
.
.
Result: Row and column

Container in Flutter is like UIView

When I work with Swift, I always use UIView for custom UI, and in Flutter, the equivalent is Container.


Container(
color: Colors.amber,
height: 100,
width: 100,
padding: EdgeInsets.all(24),
child: Text('Ok'),
)

Navigation

In Flutter, there are two types of navigation in flutter `MaterialPageRoute` and `Cupertino`, the difference is the animation. this default navigation, this navigation is not too different from iOS

MaterialPageRoute is a route that uses Material Design principles to create a smooth and consistent animation when transitioning between pages. This type of route is typically used in apps that follow the Material Design guidelines, and it includes features like a consistent app bar, drawer, and bottom navigation.

On the other hand, CupertinoPageRoute is a route that uses iOS design principles to create a smooth and consistent animation when transitioning between pages. This type of route is typically used in apps that follow the iOS design guidelines, and it includes features like a consistent navigation bar and tab bar.

The main difference between these two types of navigation routes is the animation used when transitioning between pages. MaterialPageRoute uses a sliding animation that is consistent with the Material Design guidelines, while CupertinoPageRoute using a modal animation that is consistent with the iOS design guidelines.

// I. Push navigation
Navigator.push(
context,
MaterialPageRoute(builder: (context) => SecondScreen()),
);

// II. Dismiss or back navigation
Navigator.pop(context);


// III. Push navigation with send data to second page
// First Page
Navigator.push(
context,
MaterialPageRoute(builder: (context) => DetailScreen(item: item)),
);

// Second Page
class DetailScreen extends StatelessWidget {
final Item item;

DetailScreen({Key key, this.item}) : super(key: key);

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(item.title),
),
body: Center(
child: Text(item.description),
),
);
}
}


// IV. Navigation by changing the page

Navigator.pushReplacement(
context,
MaterialPageRoute(builder: (context) => HomeScreen()),
);

// V. Navigation by removing all the pages that are above the current page:

Navigator.pushAndRemoveUntil(
context,
MaterialPageRoute(builder: (context) => HomeScreen()),
(Route<dynamic> route) => false,
);


// VI. Navigation to a new page and closing all the previous pages:

Navigator.pushNamedAndRemoveUntil(
context,
'/home',
(Route<dynamic> route) => false,
);

// VII. Navigation by selecting a page from the bottom navigation bar

int _selectedIndex = 0;
List<Widget> _pages = [HomeScreen(), ProfileScreen()];

void _onItemTapped(int index) {
setState(() {
_selectedIndex = index;
});
}

@override
Widget build(BuildContext context) {
return Scaffold(
body: _pages[_selectedIndex],
bottomNavigationBar: BottomNavigationBar(
currentIndex: _selectedIndex,
onTap: _onItemTapped,
items: [
BottomNavigationBarItem(
icon: Icon(Icons.home),
label: 'Home',
),
BottomNavigationBarItem(
icon: Icon(Icons.person),
label: 'Profile',
),
],
),
);
}

This example is normal to push navigation in iPhone simulator.

Example: Normal push navigation

There are two types of Bottom TabBar

I'd find in Flutter has two types TabBar `BottomNavigationBar` and `CupertinoTabBar`

//MARK: First
BottomNavigationBar(
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(icon: Icon(Icons.list_alt), label: 'Home'),
BottomNavigationBarItem(
icon: Icon(Icons.assignment), label: 'Manuals'),
BottomNavigationBarItem(
icon: Icon(Icons.settings), label: 'Settings'),
],
onTap: (index) async {
debugPrint('$index');
if (index == 2) {
homeViewModel.navigationLogout(context);
}
},
)


//MARK: Second

CupertinoTabBar(
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(icon: Icon(Icons.list_alt), label: 'Home'),
BottomNavigationBarItem(
icon: Icon(Icons.assignment), label: 'Manuals'),
BottomNavigationBarItem(
icon: Icon(Icons.settings), label: 'Settings'),
],
onTap: (index) async {
debugPrint('$index');
if (index == 2) {
homeViewModel.navigationLogout(context);
}
},
),

For `CupertinoTabBar` I think this is correct https://medium.flutterdevs.com/cupertino-tabbar-in-flutter-bc0944e69499
but, my code is working.

.

.

--

--

No responses yet