2

When clicking on the text input the web version of a Flutter app (iOS Safari), the soft keyboard covers the text input making it impossible to see what is being typed. (see gif below)

The expected behavior is that the text input would animate to remain visible above the soft keyboard, as it does in the iOS native version created by Flutter.

In Flutter 3.7, it appears that resizeToAvoidBottomInset (which defaults to true) should control this behavior:

if there is an onscreen keyboard displayed above the scaffold, the body can be resized to avoid overlapping the keyboard, which prevents widgets inside the body from being obscured by the keyboard.

However, in Safari on iOS this doesn't appear to be true.

Previous questions don't appear to fix this issue or introduce what appear to be unnecessary workarounds:

View: soft keyboard obscures text input in Safari on iOS

Soft Keyboard obscures text input

Code:

import 'package:flutter/material.dart';

class TestScreen extends StatefulWidget {
  const TestScreen({super.key});

  @override
  State<TestScreen> createState() => _TestScreenState();
}

class _TestScreenState extends State<TestScreen> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Chat')),
      body: Column(
        children: const [
          Expanded(
            child: Center(
              child: Text('Send a message to start your conversation.'),
            ),
          ),
          _MessageBar(),
        ],
      ),
    );
  }
}

class _MessageBar extends StatefulWidget {
  const _MessageBar({Key? key}) : super(key: key);

  @override
  State<_MessageBar> createState() => __MessageBarState();
}

class __MessageBarState extends State<_MessageBar> {
  late final TextEditingController _textController;
  @override
  Widget build(BuildContext context) {
    return Material(
      color: Colors.grey[200],
      child: SafeArea(
        child: Padding(
          padding:
              EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom),
          child: Row(
            children: [
              Expanded(
                child: TextFormField(
                  keyboardType: TextInputType.text,
                  maxLines: null,
                  autofocus: true,
                  controller: _textController,
                  decoration: const InputDecoration(
                    hintText: 'Type a message',
                    border: InputBorder.none,
                    focusedBorder: InputBorder.none,
                    contentPadding: EdgeInsets.all(8.0),
                  ),
                ),
              ),
              TextButton(
                onPressed: () => _submitMessage(),
                child: const Text('Send'),
              )
            ],
          ),
        ),
      ),
    );
  }

  @override
  void initState() {
    _textController = TextEditingController();
    super.initState();
  }

  @override
  void dispose() {
    _textController.dispose();
    super.dispose();
  }

  void _submitMessage() async {
    final text = _textController.text;
    if (text.isEmpty) {
      return;
    }
    print({text});
    _textController.clear();
  }
}

My Car
  • 4,198
  • 5
  • 17
  • 50
warfield
  • 624
  • 6
  • 14
  • 1
    Try wrapping the padding inside `SingleChildScrollView` and also at the same time add this property in scaffold to true `resizeToAvoidBottomInset:true` this may help or there is also another property of `SingleChildScrollView` i.e `reverse` set it to `true` and check – Rahul Pandey Feb 21 '23 at 06:19

1 Answers1

0

just you should give it padding like it :

return Scaffold(
  appBar: AppBar(title: const Text('Chat')),
  body: Column(
    children: const [
      Expanded(
        child: Center(
          child: Text('Send a message to start your conversation.'),
        ),
      ),
      Padding(
        padding: EdgeInsets.only(
            bottom: MediaQuery.of(context).viewInsets.bottom),
        child: _MessageBar(),
      )
    ],
  ),
);
Amir
  • 177
  • 2
  • 9