[Flutter] iOS scrollsToTop

Intro 🤗

이 글에서는 아이폰의 scrollsToTop 기능을 간단한 예제를 통해 소개하고, 스크린이 ScrollView일경우 고려해야 할 사항에 대해 다루고 있습니다.


scrollsToTop 📌

아이폰에서는 스크린이 ScrollView이고, 상태 표시줄을 탭하는 제스처가 발생하면 시스템은 맨 위로 스크롤하도록 요청합니다.

아래의 예제는 scroolsToTop 기능이 정상적으로 동작할 때 확인할 수 있는 이벤트입니다.


# 예제 01 (정상 동작)


class ScrollToTopGestureExample extends StatefulWidget {
  
  _ScrollToTopGestureExampleState createState() => _ScrollToTopGestureExampleState();
}

class _ScrollToTopGestureExampleState extends State<ScrollToTopGestureExample> {

  
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: customAppBar("Scroll To Top Gesture Example"),
        body: ListView(
          children: [
            for(int i = 0; i < 100; i++)
              Container(
                height: 100.0,
                alignment: Alignment.center,
                color: i % 2 == 0 ? Colors.grey[100] : Colors.white,
                child: Text("$i"),
              ),
          ],

        ));
  }
}

고려 사항 📌

공식 홈페이지에는 다음과 같은 고려 사항을 확인할 수 있습니다.

On iPhone, the scroll-to-top gesture has no effect if there is more than one scroll view on-screen that has scrollsToTop set to true.

이를 토대로 scroll view가 두 개 이상 있을 경우 맨 위로 스크롤되는 제스처는 사라지게 된다는 것을 알 수 있으며, 이에 대한 조건을 만족시키는 예제는 위의 예제에서 ScrollController만 추가하면 됩니다.


# 예제 02 (scroll view가 두 개 이상 있을 경우)


class ScrollToTopGestureExample extends StatefulWidget {
  
  _ScrollToTopGestureExampleState createState() => _ScrollToTopGestureExampleState();
}

class _ScrollToTopGestureExampleState extends State<ScrollToTopGestureExample> {

  ScrollController _scrollController = ScrollController();

  
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: customAppBar("Scroll To Top Gesture Example"),
        body: ListView(
          controller: _scrollController,
          children: [
            for(int i = 0; i < 100; i++)
              Container(
                height: 100.0,
                alignment: Alignment.center,
                color: i % 2 == 0 ? Colors.grey[100] : Colors.white,
                child: Text("$i"),
              ),
          ],

        ));
  }
}

# 예제 03 (문제 해결)

예제 02번에서 ScrollController을 추가한 뒤 상태 표시줄을 클릭해도 scrollsToTop 기능이 동작하지 않는 것을 확인할 수 있었습니다.

Controller을 사용하지 않는다면 문제가 되지 않겠지만, Controller을 사용해야 하는 경우(ex. 무한 스크롤)라면 다음과 같은 솔루션을 적용할 수 있습니다.



class ScrollToTopGestureExample extends StatefulWidget {
  
  _ScrollToTopGestureExampleState createState() => _ScrollToTopGestureExampleState();
}

class _ScrollToTopGestureExampleState extends State<ScrollToTopGestureExample> {
  List contents = [for (int i = 0; i < 10; i++) i];

  
  Widget build(BuildContext context) {
  
    return Scaffold(
        appBar: customAppBar("Scroll To Top Gesture Example"),
        body: NotificationListener(
          onNotification: (Notification notification) {
            ScrollController scrollController = PrimaryScrollController.of(context);

            if (scrollController.offset == scrollController.position.maxScrollExtent && notification is ScrollEndNotification) {
              setState(() {
                contents.addAll([1, 2, 3, 4, 5]);
              });
            }

            return false;
          },
          child: ListView.builder(
            controller: PrimaryScrollController.of(context),
            itemBuilder: (context, index) {
              return Container(
                height: 100.0,
                alignment: Alignment.center,
                child: Text("$index"),
              );
            },
            itemCount: contents.length,
          ),
        ));
  }
}

좋은 웹페이지 즐겨찾기