View

300x250

오늘도 간단한 문제로 3시간을 날렸다. 이전 글에서 SwiftUI의 FullscreenCover 방식의 화면전환을 사용하려면 fullscreenDialog를 사용하면 된다고 했었는데, 여기와 관련된 문제가 발생했다.

아래와 같은 구조로 되어있고, 화살표처럼 화면 전환을 만들고자 했다.

Untitled.png

여기에서, fullscreen dialog로 넘어간 2번째 줄에서는 push로 페이지를 전환한 다음에는 뒤로 pop을 할 수 없는 구조이기에 pushReplacement 같은 함수를 사용해 전환하려고 고려하고 있었다.

그러나, fullscreenDialog 첫 페이지에서 pushReplacement 함수를 호출하니, bottomSheet 이 있는 뷰로 가버리는 문제가 있었다! 아마 추측하건데, fullscreenDialog로 넘기면 새로운 뷰 트리(뷰 플로우)가 생기는데, 가장 root 인 뷰를 없애고 위에 새로운 뷰를 얹으려고 하다보니 뷰 트리 자체가 제거되면서 기존 뷰로 전환이 되어버리는 것 같았다.

사실 pop을 뷰에서 한 번만 실행해서 이전 뷰로 넘어갈 수 있다고 생각했기 때문에, 마지막 뷰에서 fullscreen의 뷰 트리를 탈출하기 위해서는 replacement 함수를 사용하는게 거의 반강제라고 생각했었다. 플러터의 fullscreen dialog에서 push replacement를 시도해보려 다양하게 검색을 했는데, 생각보다 스택오버플로우와 블로그 등에서 이 주제로 질문이 오가거나 다루지 않는 것을 확인할 수 있었다. 😢

그래서 한 번에 여러 개의 뷰를 pop 하는 방식을 키워드로 검색해봤는데, 요건 생각보다 사람들이 많이 사용하는 방법이였는지, 예쁜 함수 형태로 잘 정리가 되어있었다.

  int count = 0;
  Navigator.of(context).popUntil((_) => count++ >= 2);

돌아가고 싶은 뷰의 개수를 뒤 상수 숫자로 넣어주면 된다. 나의 경우에는 2칸 뒤로 가고싶어서 2를 넣었다.

위 코드를 기반으로 하여 replacement를 사용하는 대신에 pop gesture를 비활성화한 push로 navigation stack을 2개 쌓아주고, 완료 시 pop을 2번 실행하여 기존의 뷰로 돌아가는 형태로 코드를 작성해 navigation을 구현해주었다.

@override
Widget build(BuildContext context) {
	return PopScope(
    canPop: false,
		// onPopInvoked: (boolValue) {}, 
		//   pop gesture나 pop button이 눌리면 실행할 함수를 미리 정의해둘수도 있다. 
		//   여기에서 '진짜 뒤로갈거냐?' 등의 alert도 띄울 수 있겠다.
    child: Scaffold( ... ) 
  );
}

// 닫기 버튼 구현
TextButton(
  child: const Text('닫기'),
  onPressed: () {
    int count = 0;
    Navigator.of(context).popUntil((_) => count++ >= 2);
  },
),

bottom sheet이 있는 곳에서는 다시 해당 뷰로 돌아오면 bottom sheet을 자동으로 내리도록 구현해주었다. 이를 통해 bottom sheet 자체는 navigation pop 시에 신경쓰지 않아도 되도록 만들었다.

Navigator.push(
  context,
  MaterialPageRoute(
    fullscreenDialog: true,
    builder: (context) {
      return SubView();
    },
  ),
).then((_) => Navigator.pop(context));
// 요렇게 해주면 된다!

그러면 아래처럼 화면 전환이 원하는대로 잘 구성된 것을 확인할 수 있다!

Untitled.gif

320x100
Share Link
reply
반응형
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31