Search code examples
iosflutter

Bottom navigation bar is floating on iOS


My bottom navigation is malformed when I run my Flutter app on iOS. It seems to be floating:

enter image description here

My scaffold looks like this:

Scaffold(
  appBar: getAppbar(),
  drawer: getMainDrawer(context),
  floatingActionButton: ...,
  floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
  body: SafeArea(
    top: false,
    bottom: false,
    child: _widgetOptions.elementAt(_selectedIndex),
  ),
  extendBody: true,
  bottomNavigationBar: buildBottomNavigationBar())

My bottom navigation looks like this:

Widget buildBottomNavigationBar() {
  return BottomAppBar(
    key: const Key('bottomAppBar'),
    shape: const CircularNotchedRectangle(),
    elevation: 4,
    notchMargin: 8,
    clipBehavior: Clip.antiAlias,
    child: BottomNavigationBar(
      showUnselectedLabels: false,
      showSelectedLabels: false,
      items: const <BottomNavigationBarItem>[
        BottomNavigationBarItem(
          icon: FaIcon(FontAwesomeIcons.dumbbell),
          label: 'Sets',
        ),
        BottomNavigationBarItem(
          icon: FaIcon(FontAwesomeIcons.calendar),
          label: 'Timeline',
        ),
      ],
      currentIndex: _selectedIndex,
      onTap: _onItemTapped,
    ),
  );
}

Note that the bottom navigation looks fine on Android. Does anyone know what causes this on iOS?


Solution

  • Turns out @Ajil O. was correct after all. This bug was indeed caused by the notch effect. To fix it you have to set the elevation everywhere to 0.

    This code works both on iOS and Android now:

    Widget buildBottomNavigationBar() {
      return BottomAppBar(
        key: const Key('bottomAppBar'),
        shape: const CircularNotchedRectangle(),
        // Note: elevation has to be zero
        elevation: 0,
        notchMargin: 8,
        clipBehavior: Clip.antiAlias,
        child: BottomNavigationBar(
          showUnselectedLabels: false,
          // Note: elevation has to be zero
          elevation: 0,
          showSelectedLabels: false,
          items: const <BottomNavigationBarItem>[
            BottomNavigationBarItem(
              icon: FaIcon(FontAwesomeIcons.dumbbell),
              label: 'Sets',
            ),
            BottomNavigationBarItem(
              icon: FaIcon(FontAwesomeIcons.calendar),
              label: 'Timeline',
            ),
          ],
          currentIndex: _selectedIndex,
          onTap: _onItemTapped,
        ),
      );