flutter-unity-view-widget icon indicating copy to clipboard operation
flutter-unity-view-widget copied to clipboard

KeyBoard is not opening for TextFormField in some iOS devices after adding flutter-unity-view-widget

Open jungleesubbu opened this issue 3 years ago • 8 comments

jungleesubbu avatar Feb 03 '22 21:02 jungleesubbu

#164 #34 I believe there is a fix for it here @jungleesubbu

AkhilRaja avatar Feb 13 '22 13:02 AkhilRaja

We are seeing this in our project as well. @juicycleff Any suggestions? After we use a webview to authenticate with Google or Facebook it starts working again. This only happens while flutter_unity_widget is in the project.

And for clarification, it's NOT a text field from Unity. It's the normal Flutter TextFormField.

LegendAF avatar May 13 '22 16:05 LegendAF

Oh that's sounds weird, but I think you can solve it by some option in your scaffold widget, or use the focusNode in the text controller.

Using the project myself with a text field with no hassle. Overall, your Scaffold widget setup has a lot to do with the keyboard behavior. Hope this helps

Also Flutter made some huge keyboard performance update too on iOS for flutter 2.10.0 if I remember correctly good to check that out

juicycleff avatar May 13 '22 17:05 juicycleff

@LegendAF If my above suggestion doesn't solve it, just reopen and tag me.

juicycleff avatar May 13 '22 17:05 juicycleff

Thanks for the reply @juicycleff. Here is what I am seeing.

iPhone 6s, iOS 12.1 https://user-images.githubusercontent.com/825344/168464187-12134fbb-e22f-4067-8c0b-d2440ceb4890.MP4

iPhone 13, iOS 15.4.1 https://user-images.githubusercontent.com/825344/168464218-42640621-3cf9-4805-a526-28eb4e20b70b.MP4

As you can see, the keyboard does not open at all on the iPhone 6s. We found that if you were to open and then close a webview and then try to use the input, the keyboard will open as expected.

This is all while running the code located at https://github.com/juicycleff/flutter-unity-view-widget/tree/master/example, which presumably is the latest example code. The only change I made for this video was in example/lib/screens/simple_screen.dart. I added a TextField() to the bottom of the stack.

We see this same exact behavior in our code base. When we remove flutter_unity_widget and use a stub, all works as expected. This issue does not happen on every iOS device.

Do you have any ideas about what could be causing this so we could help track it down?

Thanks!

Example of changed code:

import 'package:flutter/material.dart';
import 'package:flutter_unity_widget/flutter_unity_widget.dart';

class SimpleScreen extends StatefulWidget {
  SimpleScreen({Key key}) : super(key: key);

  @override
  _SimpleScreenState createState() => _SimpleScreenState();
}

class _SimpleScreenState extends State<SimpleScreen> {
  static final GlobalKey<ScaffoldState> _scaffoldKey =
      GlobalKey<ScaffoldState>();

  UnityWidgetController _unityWidgetController;
  double _sliderValue = 0.0;

  @override
  void initState() {
    super.initState();
  }

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      key: _scaffoldKey,
      appBar: AppBar(
        title: Text('Simple Screen'),
      ),
      body: Card(
          margin: const EdgeInsets.all(8),
          clipBehavior: Clip.antiAlias,
          shape: RoundedRectangleBorder(
            borderRadius: BorderRadius.circular(20.0),
          ),
          child: Stack(
            children: [
              UnityWidget(
                onUnityCreated: _onUnityCreated,
                onUnityMessage: onUnityMessage,
                onUnitySceneLoaded: onUnitySceneLoaded,
                webUrl: 'http://localhost:6080/',
              ),
              Positioned(
                bottom: 20,
                left: 20,
                right: 20,
                child: Card(
                  elevation: 10,
                  child: Column(
                    children: <Widget>[
                      Padding(
                        padding: const EdgeInsets.only(top: 20),
                        child: Text("Rotation speed:"),
                      ),
                      Slider(
                        onChanged: (value) {
                          setState(() {
                            _sliderValue = value;
                          });
                          setRotationSpeed(value.toString());
                        },
                        value: _sliderValue,
                        min: 0,
                        max: 20,
                      ),
                    ],
                  ),
                ),
              ),
              TextField(),
            ],
          )),
    );
  }

  void setRotationSpeed(String speed) {
    _unityWidgetController.postMessage(
      'Cube',
      'SetRotationSpeed',
      speed,
    );
  }

  void onUnityMessage(message) {
    print('Received message from unity: ${message.toString()}');
  }

  void onUnitySceneLoaded(SceneLoaded scene) {
    print('Received scene loaded from unity: ${scene.name}');
    print('Received scene loaded from unity buildIndex: ${scene.buildIndex}');
  }

  // Callback that connects the created controller to the unity controller
  void _onUnityCreated(controller) {
    controller.resume();
    this._unityWidgetController = controller;
  }
}

LegendAF avatar May 15 '22 08:05 LegendAF

@juicycleff I can not re-open this ticket since I am not the author.

LegendAF avatar May 15 '22 08:05 LegendAF

@juicycleff The problem that's occurring is that the Flutter window is not the "key" window that receives all the keyboard input. This is a workaround that works for our use case, where we don't want or need Unity to have window focus.

In ios/Runner/AppDelegate.swift, add this to application():

    NotificationCenter.default.addObserver(
      self,
      selector: #selector(windowFocusChanged),
      name: UIWindow.didBecomeKeyNotification,
      object: nil
    )

Then add the didBecomeKeyNotification handler to AppDelegate:

  @objc func windowFocusChanged(_ notification: Notification) {
    if let delegate = (UIApplication.shared.delegate as? AppDelegate), let window = delegate.window {
      window.makeKeyAndVisible()
    }
  }

Unity will take focus when it runs runEmbedded, changes on screen orientation, and when it's coming from a different ViewController. These calls can be found with a search for makeKeyAndVisible in UnityLibrary.

If someone else using flutter-unity-view-widget needs TextField use, I think it would make sense to add this to this plugin. I don't have extensive iOS experience, so there's probably a better way than through NotificationCenter. Maybe the key window focus fix would happen some time after the Unity player has been created.

ivanarellano avatar May 21 '22 18:05 ivanarellano

@ivanarellano thank you. Will give it and look and try to add it to the library and offcourse credits to you

juicycleff avatar May 21 '22 19:05 juicycleff