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의 레이아웃은 기기별로 다르게 동작할 수 있다
  • 키보드 인터랙션이 있는 폼은 항상 스크롤 가능하게 만드는 게 안전하다
  • 프로덕션 빌드로 실기기 테스트를 빠뜨리지 말아야 한다
Flutter 앱에서 갑자기 발생한 TextField 오버플로우 해결