[Flutter] iOS 스와이프 뒤로가기 문제와 해결 과정

임효진·2025년 5월 27일
0

Flutter

목록 보기
27/28

문제 상황

Flutter로 커뮤니티 앱을 개발하던 중, iOS에서 Cupertino 스타일의 스와이프 제스처(뒤로가기) 가 앱의 특정 화면에서 의도치 않게 동작하는 문제가 발생했다.
특히게시글 상세 페이지 등에서 사용자가 데이터를 입력 중(예: 좋아요, 댓글 작성) 혹은 좋아요 상태를 변경한 상태에서 스와이프하면, 데이터 반영 없이 화면이 닫혀버린다.
뒤로가기를 해서 다시 데이터를 호출하여 갱신하는 경우는 좋은 방식이 아니였기에 객체 내에서만 업데이트가 필요했다.

반면 Android에서는 이런 문제가 없었고, 뒤로가기 버튼과 WillPopScope로 제어가 가능했다.

첫 시도: WillPopScope

Flutter 기본 WillPopScope를 사용하여 뒤로가기 이벤트를 감지하고, 사용자 확인 팝업을 띄우는 방식으로 시도했다.

WillPopScope(
  onWillPop: () async {
    // 사용자 확인 및 데이터 처리
    return false; // 혹은 true
  },
  child: Scaffold(...),
);

하지만 iOS의 스와이프 제스처는 WillPopScope를 우회하여 작동했다. 즉, 사용자가 왼쪽 엣지를 스와이프하면 바로 화면이 닫혀버렸고, 뒤로가기 시 감지가 불가능했다.

두 번째 시도: PopScope (Flutter 3.7+)

Flutter 3.7부터 도입된 PopScope는 iOS 스와이프까지 감지할 수 있는 강력한 기능을 제공한다. 이를 적용해 iOS에서도 뒤로가기 제어를 시도했다.

PopScope(
  canPop: false,
  onPopInvoked: (didPop) {
    if (didPop) {
      // 뒤로가기 또는 스와이프 감지됨
    }
  },
  child: Scaffold(...),
);

하지만 canPop: false만으로는 스와이프를 완전히 차단하지 못했다. 또한 사용자가 제스처를 완전히 완료하기 전에 차단할 방법은 없었다.

시행착오: iOS만 스와이프 차단, Android는 기존 유지

PopScope + canPop + onPopInvoked는 유용했지만, 사용자가 의도적으로 스와이프하려는 행위를 감지하고 직접 처리하는 방식을 고려했다.
또한 Android에서는 기존 WillPopScope를 유지하고자 했다.

최종 해결: Platform 분기 + GestureDetector

최종적으로 아래와 같이 정리했다:

iOS: PopScope(canPop: false) + GestureDetector(onHorizontalDragUpdate)를 사용하여 스와이프 감지 및 직접 처리.

Android: 기존 WillPopScope 유지.

return Platform.isIOS
    ? PopScope(
        canPop: false,
        onPopInvoked: (didPop) {
          print('iOS 스와이프 막힘');
        },
        child: GestureDetector(
          onHorizontalDragUpdate: (details) {
            if (details.delta.dx > 10) {
              ctl._onWillPop().then((canPop) {
                if (canPop) Get.back();
              });
            }
          },
          child: scaffold,
        ),
      )
    : WillPopScope(
        onWillPop: ctl._onWillPop,
        child: scaffold,
      );

왜 이 방법을 선택했나?

PopScope는 iOS의 스와이프를 감지할 수 있지만, 완벽한 제어는 어렵다.

GestureDetector를 추가하여 스와이프 방향과 거리를 감지하면, 스와이프 시작 시도 자체를 제어 가능하다.

Android는 스와이프 대신 하드웨어 뒤로가기 버튼을 사용하므로, 기존 WillPopScope로 충분하다.

플랫폼별 분기 처리로 일관성을 유지했다.

결론

Flutter의 기본 네비게이션과 제스처는 플랫폼별 동작 차이가 존재한다.
iOS의 Cupertino 네비게이션 스와이프는 기본적으로 우회 가능하므로, 직접 제어 로직을 고려해야 한다.
PopScope와 GestureDetector를 병행해 사용자 경험과 데이터 안정성을 모두 확보할 수 있었다.
Flutter에서는 기능별, 플랫폼별 분기 처리를 잘 설계하는 것이 유지보수성과 안정성에 매우 중요하다.

profile
기냥 저냥 개발함

0개의 댓글