Flutter 앱에서 갑자기 발생한 TextField 오버플로우 해결
문제 상황
회원가입 폼에서 TextField를 여러 개 배치했는데, 키보드가 올라올 때 하단 TextField가 화면 밖으로 밀려나면서 렌더 오버플로우 에러가 발생했다. 개발 환경에서는 정상이었는데 프로덕션 빌드 후 iOS 실기기에서만 재현되는 상황이었다.
원인 분석
Column 위젯으로 여러 TextField를 감싸고 있었는데, 키보드가 올라오면서 사용 가능한 높이가 줄어들자 Column이 고정 높이를 유지하려다 오버플로우가 발생했다.
Scaffold(
body: Column(
children: [
TextField(),
TextField(),
TextField(),
// ...
],
),
)
해결 방법
Scaffold의 resizeToAvoidBottomInset을 true로 설정하고, Column 대신 SingleChildScrollView로 감싸서 스크롤 가능하도록 수정했다.
Scaffold(
resizeToAvoidBottomInset: true,
body: SingleChildScrollView(
padding: EdgeInsets.all(16),
child: Column(
children: [
TextField(
decoration: InputDecoration(labelText: '이름'),
),
SizedBox(height: 16),
TextField(
decoration: InputDecoration(labelText: '이메일'),
),
SizedBox(height: 16),
TextField(
decoration: InputDecoration(labelText: '비밀번호'),
obscureText: true,
),
],
),
),
)
Focus가 이동할 때 자동으로 해당 TextField까지 스크롤되도록 하려면 각 TextField에 FocusNode를 할당하고 listener를 추가하는 방법도 있지만, 이번 케이스에서는 SingleChildScrollView만으로도 충분히 해결됐다.
배운 점
- Flutter의 레이아웃은 기기별로 다르게 동작할 수 있다
- 키보드 인터랙션이 있는 폼은 항상 스크롤 가능하게 만드는 게 안전하다
- 프로덕션 빌드로 실기기 테스트를 빠뜨리지 말아야 한다