View
ㅤ
최근에 해결하는데에 꼬박 4일이 걸린 문제가 있었다 ㅜㅜㅜㅜㅜ
ㅤ
뷰에서 작은 컴포넌트 위젯에서 GestureDetector를 통해 PanGesture를 인식하고, 터치 좌표값을 받아다가 뷰에게 전달하고, 뷰에서 이를 받아다가 setState로 값을 수정하면 다른 위젯에서 이 값으로 UI를 그리는 로직을 작성하고 있었다. 대충 그림으로 그리면 아래와 같다.
ㅤ
이를 위해서 대략적으로 아래 플로우로 실행을 제어하려고 했다.
- View에서 GestureDetector가 달린 위젯에 콜백함수를 전달
- onPanUpdate 시 콜백함수 호출
- 콜백함수에서 setState 실행
- 뷰 다시 그리기
- position UI 반영
ㅤ
그런데 왠걸? onPanUpdate 함수가 1-2번 호출되고나면 콜백함수가 더 이상 실행되지 않는 문제가 있었다. print를 찍어봐도 한 프레임만 호출되고, 바로 GestureDetector 자체가 먹통이 되어버렸다.
ㅤ
결론적으로 말하자면 내가 GestureDetector가 달린 위젯을 Column 위젯에 넣었는데, 키 값을 잘못 할당해준게 문제였다. 이걸 깨닫기까지 4일이나 걸렸고, 다시 생각해도 눈물이 줄줄 나온다 😢😢
ㅤ
처음에는 문제가 콜백함수의 정의 위치라고 생각했다. 애초에 매 프레임 호출되는 함수 내에서 setState를 호출하면 갑자기 반응이 없어지고 매 프레임 찍혀야 할 print도 출력되지 않아서 앱이 멈춰버린다고 생각했다. 지피티한테 “setState를 호출하니 앱이 멈춰버리는 현상”을 물어봤을 때에는 build context를 잘못 지정해줘서 setState가 잘 실행되지 않은 것 같다고 답변하기에 이에 대해 조치를 취해주려 했다. 그러나 실패! 아무리 context를 전달해서 함수를 실행하거나 조정하려 해도 문제가 해결되지 않았었다.
ㅤ
그 다음에 생각했던 문제는, setState()를 호출하면서 하위 뷰를 새로 그리는데, 이 시점에 GestureDetector 위젯도 새로 그려져서 초기화되는 것이였다. 합리적 의심… 이였지만, 새로운 뷰를 간단하게 짜서 재현했을 때 문제없이 동작했다. 애초에 매 프레임 실행되는 onPanUpdate 함수에 setState를 넣는 코드들도 자연스럽고 예제도 굉장히 많았다.
ㅤ
그러다가, GestureDetector 위젯의 initState에 print 문을 찍어봤는데, onPanUpdate가 한 프레임 호출되고 나서 바로 initState가 호출되는 것을 확인했다.
ㅤ
아! 뭔가 문제가 있어서 하위 뷰가 확실히 새로 빌드가 되고 있고, 이것 때문에 터치하자마자 위젯이 새로 만들어지면서 문제가 발생하는구나! 를 알았다. 그러나, 이때까지만 해도 setState의 호출이 문제라고 생각하고 있었다.
ㅤ
그렇게 setState와 build context와 기타 여러가지로 재현하면 잘 되는데 실제상황에서는 안되는 기가막히는 문제로 3일이 넘게 쌩고생을 하다가 문제의 해결방법을 찾았다.
ㅤ
내가 위젯의 key에 UniqueKey를 넣어놨었는데, 새로 위젯을 빌드할 때 마다 새로운 UniqueKey를 넣어주면서 문제가 발생하는 것이였다….!!!! 요녀석을 일반 Key로 넣어줬더니 문제가 해결되었다. 하위뷰가 원치않게 재빌드된다면 key를 꼮꼮 확인하자.
ㅤ
4일동안 찾던 실마리가 단 한 줄의 코드 변경이였다. ㅋㅋㅋ
ㅤ
'Develop > Flutter 개발' 카테고리의 다른 글
[Flutter] 플러터에서 swiftui의 fullscreen cover 구현 방법 (0) | 2024.02.17 |
---|---|
[Flutter] Dart에서는 append가 아니라 add (0) | 2024.01.31 |
[Flutter] 클린 아키텍처 리펙토링 (4) - 계층 별 파일 간 의존성 분리 (0) | 2024.01.20 |
[Dart] 다트가 오버로딩을 지원하지 않는 이유? (2) | 2024.01.15 |
[Flutter] 클린 아키텍처 리펙토링 (3) - 누가 무슨 모델을 사용할 것인가? (1) | 2024.01.14 |