Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Text boxes don't move in scroll containers and they can always be seen #3

Open
animepauly opened this issue Jul 10, 2015 · 10 comments
Open

Comments

@animepauly
Copy link

Hi! So I put these two issues together because they are related in my opinion. I have scroll containers that have panels with your text field in them. Depending on the screen the containers scroll either horizontally or vertically. When I scroll the containers though, the textfields don't move with the container, because it seems the text fields are sitting on top of everything in the hierarchy. This also causes problems when I have overlays on top of your text fields, I can still see the underlying textfields that are supposed to be covered up. I would like a way to either put the text boxes as children of a gamobject in unity or maybe have a way to have the text field follow a gameobject's movement and visibility. Not sure what's possible or not, but as this plugin stands in it's current state, I can't use it for what I am doing. Let me know if you need any more details or gifs of the problem.

@animepauly
Copy link
Author

So instead of having them try to move, I am trying to hide and show the NativeEditBox but every time I call set visible from code, I get a null object reference here:

NativeEditBox.cs

public void SetVisible(bool bVisible)
{
    JsonObject jsonMsg = new JsonObject();

    jsonMsg["msg"] = MSG_SET_VISIBLE;
    jsonMsg["isVisible"] = bVisible;

    this.SendPluginMsg(jsonMsg); //This method throws the Null object reference
}

PluginMsgHandler.cs

protected JsonObject SendPluginMsg(JsonObject jsonMsg)
{
    return msgHandler.SendMsgToPlugin(nReceiverId, jsonMsg); // I think the msghandler is null here for some reason
}

@animepauly
Copy link
Author

I don't know if this is the best solution, but I fixed it from throwing an error for now, not sure if the hiding and showing will work as intended yet though.

protected JsonObject SendPluginMsg(JsonObject jsonMsg)
{
    if (msgHandler == null)
    {
        msgHandler = PluginMsgHandler.getInst();
    }

    return msgHandler.SendMsgToPlugin(nReceiverId, jsonMsg);
}

@animepauly
Copy link
Author

It seems your SetVisible method doesn't do anything because when I call SetVisible(false) The NativeEditBox is still there.

@kmbang
Copy link
Owner

kmbang commented Aug 27, 2015

Re, msgHandler null problem, did you update the code to the latest version by any chance?
It's actually

protected JsonObject SendPluginMsg(JsonObject jsonMsg)
{
    return PluginMsgHandler.getInst().SendMsgToPlugin(nReceiverId, jsonMsg);
}

It doesn't use msgHandler variable any more.

And, this might be related to SetVisible issue as well, because if msgHandler is null, it can't send msg to to native plugin so the plugin (making invisible) won't work.

And, did you try demo.unity? There's 'Toggle Visible' button to test the 'SetVisible' function.

@animepauly
Copy link
Author

I did update the plugin but I did it through the Unity Asset store and not here. I will give that a shot.

@kmbang
Copy link
Owner

kmbang commented Aug 28, 2015

Hmmm. quite strange. The source code is same as the one that I put in in the Asset Store.
I just re-packaged the updated code and uploaded to Asset Store.
It might take a couple days for Unity to Approve it.
Once it’s up, can you try on asset store then?

On Aug 28, 2015, at 3:32 AM, Paul Borawski [email protected] wrote:

I imported the new code, and there are names space errors all over the place. Can you put a namespace in your classes so they don't conflict with other plugins?


Reply to this email directly or view it on GitHub #3 (comment).

@animepauly
Copy link
Author

Sure thing. I still having issues with this. What I am trying to do is to hide your NativeEdit box when OnEndEdit fire. That works, but the issue is the test doesn't show up in the input field. If I log the input field text out, it states in the log what it should be, but I see a blank text field on screen. Any ideas on what I am doing wrong or what can be done to fix this issue?

I also reenable the nativeEdit box when you click back into the input field which also works. I am just having issues seeing text when the input field is not selected.

@animepauly
Copy link
Author

Sweet! So my problem was since I couldn't get your SetVisible to work before I was reverting to enabling and disabling the script which was causing tons of issues, but now I got it working I think. I have to implement it outside of my test environment to make sure, but I think I am good. One thing I added to your script was a getter called IsVisibleBol that gets set when SetVisible gets called because I couldn't find a way to check that from outside of the NativeEditBox.cs class. When I am sure I can get everything working I will post my code.

@animepauly
Copy link
Author

I have a hacky workaround for now that seems stable but I would like a more built in solution to the problem of the NativeEditBox always being visible and getting in the way of the UI if you have scroll containers or you just don't want it to always sit on top of everything. The basic solution is to hide the NativeEditBox when it's not in focus, and when the plugin is hidden I set the Unity Input Text field's text to the plugin text via GetTextNative() method.

The following is my update to the NativeEditBox.cs

public bool IsVisibleBol {
    get {
        return _isVisibleBol;
    }
}

private bool _isVisibleBol = true;

public void SetVisible(bool bVisible)
{
    JsonObject jsonMsg = new JsonObject();

    jsonMsg["msg"] = MSG_SET_VISIBLE;
    jsonMsg["isVisible"] = bVisible;
    _isVisibleBol = bVisible;
    this.SendPluginMsg(jsonMsg);
}

I feel that should be implemented in the next update. Because I am showing and hiding the plugin though, there seems to be a problem with the plugin not being able to be focused after you show it again. To fix this I added a TextInputFieldEvents.cs class that sets the focus OnPointerDown and OnPointerUp. I had to do both for some reason or otherwise I was still having to double click in the text field. I added a deselect as well to ensure that the plugin is hidden when not in focus. Here is the code for that class:

/// <summary>
/// Instead of creating two classes to handle input field events that ar global,
/// I wanted to combine this with the Native Edit Box version, so I can switch between the 
/// two in one place
/// </summary>

using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;

namespace adquizition.quizapp
{
    public class TextInputFieldEvents : MonoBehaviour, IPointerDownHandler, IPointerUpHandler, IDeselectHandler
    {
        public NativeEditBox NativeEditInputField
        {
            get {return _nativeEditBox;}
        }

        public InputField InputTextField
        {
            get {return _inputTextField;}
        }

        private NativeEditBox _nativeEditBox;

        private InputField _inputTextField;
        private GameObject _gameObject;

        private bool _isMobileAppBol = false;


        // Use this for initialization
        void Start ()
        {

        }

        public void Init(bool __isMobileAppBol)
        {
            _gameObject = gameObject;
            _inputTextField = _gameObject.GetComponent<InputField>();

            _isMobileAppBol = __isMobileAppBol;

            if (_isMobileAppBol)
            {
                _addNativeEditPlugin();
            }
        }

        // Update is called once per frame
        void Update () {

        }

        public void OnPointerDown(PointerEventData __pointerEventData)
        {
            Debug.Log("I clicked down on = "+_inputTextField.name);

            if (_nativeEditBox != null)
            {
                if (!_nativeEditBox.IsVisibleBol)
                {
                    _nativeEditBox.SetVisible(true);
                    _inputTextField.text = string.Empty;
                    _nativeEditBox.SetFocusNative(true);
                }

            }
        }

        public void OnPointerUp(PointerEventData __pointerEventData)
        {
            Debug.Log("I clicked up on "+_inputTextField.name);
            if (_nativeEditBox != null && _nativeEditBox.IsVisibleBol)
            {
                _nativeEditBox.SetFocusNative(true);
            }
        }

        //This is called from outside of the class directly, not through an event
        public void OnEndEdit()
        {
            Debug.Log ("OnEndEdit fired for "+_inputTextField.name);
            if (_nativeEditBox != null)
            {
                _hideNativeEditBoxAndSetPlaceholder();
            }
        }

        public void OnDeselect(BaseEventData __baseEventData)
        {
            Debug.Log("I deslected "+_inputTextField.name);
            //
            if (_nativeEditBox != null)
            {
                _hideNativeEditBoxAndSetPlaceholder();
            }
        }

        private void _addNativeEditPlugin ()
        {
            _gameObject.AddComponent<NativeEditBox>();
            _nativeEditBox = _gameObject.GetComponent<NativeEditBox>();
            _nativeEditBox.SetVisible(false);
        }

        private void _hideNativeEditBoxAndSetPlaceholder()
        {
            Debug.Log ("_nativeEditBox.IsVisibleBol = "+_nativeEditBox.IsVisibleBol);
            if (_nativeEditBox.IsVisibleBol)
            {
                _inputTextField.text = _nativeEditBox.GetTextNative();
                _nativeEditBox.SetVisible(false);
            }
        }
    }
}

The OnEndEdit method in this class is being called by the parent class and not caught directly. That method is the most important along with the deselect because that's what sets the input field text to the plugin text.

Here is how the event class is being implemented in the parent class. I attach this script and add the OnValueChange and OnEndEdit events in the parent class as well.

for (int __i = 0; __i < InputFieldGOArr.Length; __i++)
{
    GameObject __inputFieldGO;
    InputField __inputField;
    TextInputFieldEvents __textInputFieldEvent;

    __inputFieldGO = InputFieldGOArr[__i];
    __inputField = __inputFieldGO.GetComponent<InputField>();

    __inputFieldGO.AddComponent<TextInputFieldEvents>();
    __textInputFieldEvent = __inputFieldGO.GetComponent<TextInputFieldEvents>();
    __textInputFieldEvent.Init(_isMobileAppBol);

    if (_isMobileAppBol)
    {
        __inputField.onValueChange.AddListener(delegate{InputEditOnValueChangedHandler(__textInputFieldEvent.NativeEditInputField.GetTextNative(), __textInputFieldEvent);});
        __inputField.onEndEdit.AddListener(delegate{InputEditOnEndEditChangedHandler(__textInputFieldEvent.NativeEditInputField.GetTextNative(), __textInputFieldEvent);});
    }
    else
    {
        __inputField.onValueChange.AddListener(delegate{InputEditOnValueChangedHandler(__inputField.text, __textInputFieldEvent);});
        __inputField.onEndEdit.AddListener(delegate{InputEditOnEndEditChangedHandler(__inputField.text, __textInputFieldEvent);});
    }
}

public void InputEditOnEndEditChangedHandler(string __textStr, TextInputFieldEvents __textInputFieldEvent)
{
    Debug.Log ("NativeInputEditOnEndEditChangedHandler fired for "+__textInputFieldEvent.InputTextField.name);
    GetText.text = "USER CLICKED OUT OF INPUT FIELD!..."+__textStr;
    __textInputFieldEvent.OnEndEdit();
}

public void InputEditOnValueChangedHandler (string __textStr, TextInputFieldEvents __textInputFieldEvent)
{
    GetText.text =__textStr;
}

In conclusion, if you can implement a way for the plugin to automatically update the input field when the plugin is hidden, and fix the focus issues, this plugin will be great. For now, while these hacks seem to be working, they are hacks and they take longer to implement. Thanks and feel free to reach out to me for any questions. I am going to keep this issue open as I feel this could be fixed within the plugin.

@animepauly
Copy link
Author

So I thought your SetVisible was actually working but it's not. I put my hacky code into a scroll container and here's what happens on the iPhone everytime SetVisible is called:

public void SetVisible(bool bVisible)
{
    JsonObject jsonMsg = new JsonObject();

    jsonMsg["msg"] = MSG_SET_VISIBLE;
    jsonMsg["isVisible"] = bVisible;
    _isVisibleBol = bVisible;
    Debug.LogWarning("jsonMsg = "+jsonMsg); 
    this.SendPluginMsg(jsonMsg);
}

So Debug.log is lying to me, I did some more tests on your JsonObject class and it seems to be working ok, but SetVisible is still not working. I could use some help here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants