![[Flutter][Issue] 이전 포커스로 돌아가는 현상 해결](https://img1.daumcdn.net/thumb/R750x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdFCErX%2FbtsN0h09o3j%2FmtfkIIzXDU5UkhcKfGA5F1%2Fimg.png)
개요
다이얼로그를 보여주거나 바텀시트를 보여준 뒤, 다시 닫으면 가정 이전 포커스로 돌아가는 현상이 있었다. ▼
전체적인 기능으로는 문제가 없지만, 사용자 입장에서는 꽤나 거슬리는 문제다. 아래로 자동 스크롤이 되는 것도 아니고 오히려 뒤로 돌아가버린다면 사용자의 입장에서는 당황스러울 것이다.
원인 탐색
FoucsScope의 기본로직?
Flutter의 `FocusScope`는 서브트리 내의 포커스 히스토리를 관리하여, 페이지를 팝할 때(Navigator.pop) 이전에 포커싱된 위젯으로 자동으로 포커스를 복원한다. Flutter 3.22.3 버전에서는 포커싱을 해제하고 다음 페이지로 가도, 이 동작이 버그로 재발생한다는 이슈도 있으며, 텍스트 필드가 의도치 않게 자동 포커싱되는 문제가 있다고 한다. ▼
Navigator.Pop cause most recent focus node to regain focus even if not focused when new page was opened · Issue #145155 · flu
Steps to reproduce TextField with focus, keyboard showing Clear focus from TextField Open new page or dialog Return to previous page with Navigator.pop Issue started with upgrade to Flutter 3.19.0 ...
github.com
FocusScope가 포커스 히스토리를 관리하여 마지막에 포커싱된 위젯으로 포커스를 복원하는 로직은 Flutter가 의도한 것으로 보이나, 포커스를 명시적이든 암묵적이든, 어떤 방법으로든 해제하고 갔음에도 포커스가 복원되는건 의도된 것인지 버그인지 알 수는 없다.
결국은 Flutter 프레임워크에서 발생한 버그라는 것인데, 이를 프레임워크를 뜯어고치지 않고 해결하는 방법이 없는 것은 아니다.
해결
페이지 이동의 경우
`unfocus(disposition: UnfocusDisposition.scope)`를 사용하면 페이지 이동을 할 때 포커스를 완전히 해제시키고 갈 수 있다. 명시적으로 할당했던 포커스를 완전히 해제버리고 이동을 하는 방법으로 해결을 할 수 있다. ▼
// 텍스트 필드에 연결된 FocusNode
final myFocusNode = FocusNode();
// 페이지 이동 시
FocusScope.of(context).unfocus(disposition: UnfocusDisposition.scope);
Navigator.push(...);
컴포넌트에서 다이얼로그 혹은 바텀 시트를 띄울 경우
페이지를 이동하는 콜백이나 다이얼로그나 모달, 바텀 시트를 보여주는 메소드가 특정 위젯 내부에 있어서 포커스를 해제하는 코드를 실행시키고 넘어가는게 어려운 경우가 종종 있다. 이런 경우 다이얼로그를 보여주는 메소드의 마지막에 아래와 같이 붙이면 해결이 된다. ▼
showCupertinoModalPopup(
context: context,
builder: (BuildContext context) {
return _buildBottomPicker(context);
},
).then((_) {
FocusManager.instance.primaryFocus?.unfocus();
})
popup이 다 끝난 뒤에 `then`으로 체이닝을 걸어 `primaryFocus?.unfocus()`를 실행하게 한다. `await`로 해도 결과는 비슷하겠지만 클로저를 반환하는 형태기도 하고 조금 더 명시적으로 보이기 위해서 위와 같이 했다.
이렇게 설정을 해주면 아래와 같이 잘 동작하는 것을 볼 수 있다. ▼
마치며
별 거 아닌 부분일 수 있지만 이런 사소한 것들이 모여서 사용자 경험을 좋게 만든다고 생각한다. 물론 개발 일정이 허용하는 한에서 말이다. 최상의 프로덕트를 내야하는건 맞지만 개발 시간이 촉박한데 이런 부분에서 시간을 끌며 중요한 로직 개발이 늦춰지게 하는건 안된다. 결론적으론 제한된 시간 내에서 최상의 프로덕트를 내야한다는 것. 그리고 이런 소소한 것들을 알아두면 도움이 많이 될 거 같다는 생각이 든다.
'Develop > Flutter' 카테고리의 다른 글
[Flutter][Issue] iOS 카카오 로그인과 버전 관리 이슈 (0) | 2025.04.24 |
---|---|
[Flutter][Issue] 구글 맵 버벅임 문제 해결 (0) | 2025.04.23 |
[Flutter][Error] 난독화와 enum.name (0) | 2025.03.10 |
[Flutter] SizedBox를 Padding 대신 사용하지 말아야 하는 이유 (0) | 2025.02.08 |
[Flutter][Issue] Flutter 카카오 로그인 릴리즈 키 (0) | 2024.12.29 |