1

Almost all Apple apps as well as most third party apps on iOS have a uniform header area. It consists of a narrow app bar for buttons, below that a big title and finally a search/filter text field. The special thing about it is the animation, which I can't get right. The images of Apple's Contacts app show the described header area.

Default Header

Refresh Control

Search/Filter text field

hero effect -> large title moves to the middle range.

At first glance, the header could be translated into Cupertino widgets as follows:

  • CustomScrollView
  • CupertinoSliverNavigationBar
  • CupertinoSliverRefreshControl
  • SliverToBoxAdapter
  • CupertinoTextField

However, between the sliver app bar and the LargeTitle is the UpdateIndicator and the text field moves up when focused and gets a cancel button.

My current code:

class TestTab extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return CupertinoPageScaffold(
          child: SafeArea(
            child: CustomScrollView(
              slivers: <Widget>[
                /*
                SliverPersistentHeader(
                  delegate: MyNav(),
                  pinned: true,
                  floating: false,
                ),
                */
                CupertinoSliverNavigationBar(
                  padding: EdgeInsetsDirectional.fromSTEB(5, 0, 5, 0),
                  leading: CupertinoButton(
                    padding: EdgeInsets.zero,
                    child: Text('Leading'),
                    onPressed: () => {},
                  ),
                  middle: Text('Middle'),
                  trailing: Icon(CupertinoIcons.add),
                  largeTitle: Text('LargeTitle'),
                ),
                CupertinoSliverRefreshControl(
                  onRefresh: () {
                    print("Refresh was triggered");
                    return Future<void>.delayed(const Duration(seconds: 1));
                  },
                ),
                SliverToBoxAdapter(
                  child: Column(
                    children: <Widget>[
                      CupertinoTextField(
                        prefix: Icon(CupertinoIcons.search),
                        textInputAction: TextInputAction.done,
                        autocorrect: true,
                        placeholder: "Filter",
                        clearButtonMode: OverlayVisibilityMode.editing,
                        maxLength: 40,
                        onChanged: (String value) {
                          return;
                        },
                        onSubmitted: (String value) {
                          return;
                        },
                      ),
                    ],
                  ),
                ),
                SliverSafeArea(
                  top: false,
                  minimum: const EdgeInsets.only(top: 8),
                  sliver: SliverList(
                    delegate: SliverChildListDelegate(
                      [
                        Container(
                          child: Text('Content'),
                        ),
                      ],
                    ),
                  ),
                ),
              ],
            ),
          ),
        );
      }
    }
  1. How can the CupertinoSliverNavigationBar be separated so that the largeTitle is placed separately in the ListView so that the UpdateIndicator is in between?

  2. How to move the search bar to the top when focusing?

  3. How to display a cancel button to the right of the search box?

  • You can add a cancel button with an inkwell or something. Look at the suffix parameter for [CupertinoTextField](https://api.flutter.dev/flutter/cupertino/CupertinoTextField-class.html). – aklingam Dec 27 '20 at 06:16
  • Hi, did you find the answer to this? – Dmitry Grin Mar 08 '23 at 05:32

0 Answers0