Search Unity

Advanced Input Field 2

Discussion in 'Assets and Asset Store' started by fennecx_development, Dec 25, 2020.

  1. itsnottme

    itsnottme

    Joined:
    Mar 8, 2017
    Posts:
    129
    Yes, the chat InputField works fine. Even when I change the field to my settings.
    I am using Unity 2019.4.28
     
  2. Boliver0482

    Boliver0482

    Joined:
    Oct 19, 2019
    Posts:
    45
    Hello. With latest version 2 (I've upgraded from 1.9) finding that if use an event to manipulate contents of an input, the the caret is moved to the first character of the input. My use case is logic is applied to users input using the event On Value Changed (string). This logic can result in the string being manipulated and the value of the string changed. In this scenario, version 2 resets the caret to the start of the input field, so subsequent character inputs are in the wrong location. Version 1 did not show this behaviour.

    I want to upgrade to version 2 in order to benefit from improvements in the iOS implementation. Is this behaviour something that can be looked at? Many Thanks.
     
  3. Boliver0482

    Boliver0482

    Joined:
    Oct 19, 2019
    Posts:
    45
    So whilst waiting to the answer above, I've tried setting it up to do what I need to achieve with Character validation and Capitalisation of words. Found character validation isn't working on iOS, but okay in simulator and on Android. Is just a simple single rule setup, charter in string, allow, the usual numerics and alphas. But on iOS is allowing any character still.

    Could you let me know what I've missed. Thank you.

    P.S. apart from little teething issues, seems a lot slicker at the front end where it matters, particularly regarding attached keyboards... The cursor doesn't seem to move with physical cursor keys unless I've missed something again. Thank you.
     
    Last edited: Aug 11, 2021
  4. fennecx_support

    fennecx_support

    Joined:
    Dec 28, 2020
    Posts:
    133
    I've fixed the screen resize issue when statusbar is visible (at least on my OnePlus 8T).
    Could you verify if this fixes it in your project?

    I've attached a modified NativeKeyboard.aar file.
     

    Attached Files:

    itsnottme likes this.
  5. itsnottme

    itsnottme

    Joined:
    Mar 8, 2017
    Posts:
    129
    Yes, thank you that fixed the status bar movement.
    Just to confirm, the KeyboardScroller is still not fixed.
     
  6. itsnottme

    itsnottme

    Joined:
    Mar 8, 2017
    Posts:
    129
    I found another bug.
    The selection action bar does not show up correctly.
    3.PNG

    On Android the selection arrows also have a problem (too big).
    Screenshot_20210811-195443_Dating App.png

    Here are my settings
    4.PNG

    Also, my Canvas is World Space, if that helps.
     
  7. fennecx_support

    fennecx_support

    Joined:
    Dec 28, 2020
    Posts:
    133
    New version 2.1.0 released:
    • Feature: Implemented RichTextBindings and added a new sample scene “TagUser” that uses this functionality to tag users
    • Improvement: added ReplaceSelectedTextInRichText() method to replace the selected text when using rich text editing.
    • Bugfix: Fixed detection of emoji binding from sprite tag
    • Bugfix iOS: Fixed custom CharacterValidator not getting parsed correctly in native code
    • Bugfix Mobile: Fixed autocorrect flag not correctly set in native code when rich text editing is enabled
    • Bugfix: Fixed line limit issue that it modifies the placeholder when typing first character
    • Bugfix: Fixed issue that ActionBar got hidden automatically sometimes
    • Bugfix: Fixed issue with screen resizing when the keyboard appears and the StatusBar is visible
     
    PrisedRabbit likes this.
  8. fennecx_support

    fennecx_support

    Joined:
    Dec 28, 2020
    Posts:
    133
    Hmm, yes World Space Canvases could cause strange things, although I don't see the issues mentioned by simply changing the Canvas mode of the "Form" sample scene to "World Space" and running it on a Android device.
    Might be something related to how your Canvases are configured in world space.

    Could you make a small repro project? so I can try to see what goes wrong.
     
  9. itsnottme

    itsnottme

    Joined:
    Mar 8, 2017
    Posts:
    129
    Here is a sample project.
    It contains the selection bar issue and I also left the chat inputfield that has the problem I showed before.

    I messaged you the password to the zip file.
     

    Attached Files:

    • App.zip
      File size:
      6.1 MB
      Views:
      284
    Last edited: Aug 18, 2021
  10. swifter14

    swifter14

    Joined:
    Mar 2, 2017
    Posts:
    165
    Hi there, I have some issues with some of the Emojis. It prints 2 characters instead of 1.
    For example the most basic emoji- the red heart ❤️
    it shows like a red heart with an empty square next to it
    Or for example a brown hand will show like- yellow hand + brown square next to it
    Why does it print 2 characters? I downloaded both apple and google sheets and they have all the emojis.
    I use the latest asset 2.1.0 , the latest emoji sheets
    *Update: after generating a fresh new Emoji asset, the red heart shows a heart with fire + square next to it (still 2 characters, and the heart is not correct as it shows the fire heart)
     
    Last edited: Aug 19, 2021
  11. Josidiah

    Josidiah

    Joined:
    Oct 23, 2020
    Posts:
    3
    Hi there, Ive just installed the package, but cant even get sample scenes to work. Am I missing a step while building the project. I am using multiline sample scene, can scroll stuff but cant activate input fields.

    Editor works fine, but cant make it work on my android 9 Asus phone.
     
  12. fennecx_support

    fennecx_support

    Joined:
    Dec 28, 2020
    Posts:
    133
    Seems like there is critical bug (errors printed in the log) when expanding the general tab in version 2.1.0. (Was caused by a new property that wasn't renamed properly in the Editor script)
    I'll make a new release with the fix a.s.a.p.

    In the meantime you can overwrite the script file (in AdvancedInputField/Editor/Scripts) with this file.
     

    Attached Files:

    xaldin-76 likes this.
  13. swifter14

    swifter14

    Joined:
    Mar 2, 2017
    Posts:
    165
    Hi, could you please respond to my emojis issue? I've done everything you recommended in the past, even changed the names and regenerated the sheet. It's pretty critical to me as I'm waiting for this before I release my new app update, the emoji feature doesn't work properly
     
    Last edited: Aug 23, 2021
  14. fennecx_support

    fennecx_support

    Joined:
    Dec 28, 2020
    Posts:
    133
    I've send you a PM.
     
  15. gunesaydin

    gunesaydin

    Joined:
    Apr 22, 2019
    Posts:
    2
    We have managed to solve this problem. For future reference, the problem was NativeKeyboard.aar being stripped off by Gradle minify.

    We added NativeKeyboard class to proguard-user.txt to include its classes while building.

    -keep public class com.jeroenvanpienbroek.nativekeyboard.** { *; }


    Just try adding this line above to your user proguard file if you happen to stuck with the same problem.
     
  16. ryan_santiago_dl

    ryan_santiago_dl

    Joined:
    May 31, 2017
    Posts:
    2
    Hi! On iOS, is there a way to show the soft keyboard even when a physical keyboard is present?

    On native ios apps, double tapping the text field will show the keyboard even if a physical keyboard is connected. And on iPad, when a text field is selected, a status bar will also appear at the bottom, with an option to show the keyboard. However, these operations are not possible on AdvancedInputField, at least when I tested the demo scenes.
     
    Last edited: Sep 3, 2021
  17. bramble-operations

    bramble-operations

    Joined:
    Aug 27, 2019
    Posts:
    9
    Hi I'm not sure if this issue I'm experiencing is related to this package, but it has a lot of stuff related to the native keyboard so I thought it's a possibility. Just wanted to post this here in case anyone knows what's going on or has experienced these warnings.

    I get these when I build for iOS and run the project from Xcode. I've updated to the latest version of advanced input field, and am using Xcode 12.5.1 and Unity 2019.4.14f1. I haven't noticed these warning messages leading to any obvious bugs, so I'm just kind of wondering what's causing them...

    Code (CSharp):
    1. objc[8949]: Class NKBMultilineView is implemented in both /private/var/containers/Bundle/Application/23099748-9AF1-4297-AA6C-1FC468FBECCD/bramble.app/bramble (0x1025f63c8) and /private/var/containers/Bundle/Application/23099748-9AF1-4297-AA6C-1FC468FBECCD/bramble.app/Frameworks/UnityFramework.framework/UnityFramework (0x105150888). One of the two will be used. Which one is undefined.
    2. objc[8949]: Class NKBKeyboardHideEvent is implemented in both /private/var/containers/Bundle/Application/23099748-9AF1-4297-AA6C-1FC468FBECCD/bramble.app/bramble (0x1025f6440) and /private/var/containers/Bundle/Application/23099748-9AF1-4297-AA6C-1FC468FBECCD/bramble.app/Frameworks/UnityFramework.framework/UnityFramework (0x105150900). One of the two will be used. Which one is undefined.
    3. objc[8949]: Class NKBKeyboardShowEvent is implemented in both /private/var/containers/Bundle/Application/23099748-9AF1-4297-AA6C-1FC468FBECCD/bramble.app/bramble (0x1025f6468) and /private/var/containers/Bundle/Application/23099748-9AF1-4297-AA6C-1FC468FBECCD/bramble.app/Frameworks/UnityFramework.framework/UnityFramework (0x105150928). One of the two will be used. Which one is undefined.
    4. objc[8949]: Class NKBNativeKeyboard is implemented in both /private/var/containers/Bundle/Application/23099748-9AF1-4297-AA6C-1FC468FBECCD/bramble.app/bramble (0x1025f64e0) and /private/var/containers/Bundle/Application/23099748-9AF1-4297-AA6C-1FC468FBECCD/bramble.app/Frameworks/UnityFramework.framework/UnityFramework (0x1051509a0). One of the two will be used. Which one is undefined.
    5. objc[8949]: Class NKBTextEditUpdateEvent is implemented in both /private/var/containers/Bundle/Application/23099748-9AF1-4297-AA6C-1FC468FBECCD/bramble.app/bramble (0x1025f6508) and /private/var/containers/Bundle/Application/23099748-9AF1-4297-AA6C-1FC468FBECCD/bramble.app/Frameworks/UnityFramework.framework/UnityFramework (0x1051509c8). One of the two will be used. Which one is undefined.
    6. objc[8949]: Class NKBCharacterValidator is implemented in both /private/var/containers/Bundle/Application/23099748-9AF1-4297-AA6C-1FC468FBECCD/bramble.app/bramble (0x1025f6558) and /private/var/containers/Bundle/Application/23099748-9AF1-4297-AA6C-1FC468FBECCD/bramble.app/Frameworks/UnityFramework.framework/UnityFramework (0x105150a18). One of the two will be used. Which one is undefined.
    7. objc[8949]: Class NKBTextValidator is implemented in both /private/var/containers/Bundle/Application/23099748-9AF1-4297-AA6C-1FC468FBECCD/bramble.app/bramble (0x1025f65d0) and /private/var/containers/Bundle/Application/23099748-9AF1-4297-AA6C-1FC468FBECCD/bramble.app/Frameworks/UnityFramework.framework/UnityFramework (0x105150a90). One of the two will be used. Which one is undefined.
    8. objc[8949]: Class NKBQueueNode is implemented in both /private/var/containers/Bundle/Application/23099748-9AF1-4297-AA6C-1FC468FBECCD/bramble.app/bramble (0x1025f65f8) and /private/var/containers/Bundle/Application/23099748-9AF1-4297-AA6C-1FC468FBECCD/bramble.app/Frameworks/UnityFramework.framework/UnityFramework (0x105150ab8). One of the two will be used. Which one is undefined.
    9. objc[8949]: Class NKBThreadsafeQueue is implemented in both /private/var/containers/Bundle/Application/23099748-9AF1-4297-AA6C-1FC468FBECCD/bramble.app/bramble (0x1025f6670) and /private/var/containers/Bundle/Application/23099748-9AF1-4297-AA6C-1FC468FBECCD/bramble.app/Frameworks/UnityFramework.framework/UnityFramework (0x105150b30). One of the two will be used. Which one is undefined.
    10. objc[8949]: Class NKBUnityCallback is implemented in both /private/var/containers/Bundle/Application/23099748-9AF1-4297-AA6C-1FC468FBECCD/bramble.app/bramble (0x1025f6698) and /private/var/containers/Bundle/Application/23099748-9AF1-4297-AA6C-1FC468FBECCD/bramble.app/Frameworks/UnityFramework.framework/UnityFramework (0x105150b58). One of the two will be used. Which one is undefined.
    11. objc[8949]: Class NKBUtil is implemented in both /private/var/containers/Bundle/Application/23099748-9AF1-4297-AA6C-1FC468FBECCD/bramble.app/bramble (0x1025f6710) and /private/var/containers/Bundle/Application/23099748-9AF1-4297-AA6C-1FC468FBECCD/bramble.app/Frameworks/UnityFramework.framework/UnityFramework (0x105150bd0). One of the two will be used. Which one is undefined.
    12. objc[8949]: Class NKBNativeKeyboardConfiguration is implemented in both /private/var/containers/Bundle/Application/23099748-9AF1-4297-AA6C-1FC468FBECCD/bramble.app/bramble (0x1025f6738) and /private/var/containers/Bundle/Application/23099748-9AF1-4297-AA6C-1FC468FBECCD/bramble.app/Frameworks/UnityFramework.framework/UnityFramework (0x105150bf8). One of the two will be used. Which one is undefined.
    13. objc[8949]: Class NKBCharacterCondition is implemented in both /private/var/containers/Bundle/Application/23099748-9AF1-4297-AA6C-1FC468FBECCD/bramble.app/bramble (0x1025f6788) and /private/var/containers/Bundle/Application/23099748-9AF1-4297-AA6C-1FC468FBECCD/bramble.app/Frameworks/UnityFramework.framework/UnityFramework (0x105150c48). One of the two will be used. Which one is undefined.
    14. objc[8949]: Class NKBSingleLineView is implemented in both /private/var/containers/Bundle/Application/23099748-9AF1-4297-AA6C-1FC468FBECCD/bramble.app/bramble (0x1025f67d8) and /private/var/containers/Bundle/Application/23099748-9AF1-4297-AA6C-1FC468FBECCD/bramble.app/Frameworks/UnityFramework.framework/UnityFramework (0x105150c98). One of the two will be used. Which one is undefined.
    15. objc[8949]: Class NKBCharacterRule is implemented in both /private/var/containers/Bundle/Application/23099748-9AF1-4297-AA6C-1FC468FBECCD/bramble.app/bramble (0x1025f6828) and /private/var/containers/Bundle/Application/23099748-9AF1-4297-AA6C-1FC468FBECCD/bramble.app/Frameworks/UnityFramework.framework/UnityFramework (0x105150ce8). One of the two will be used. Which one is undefined.
    16.  
     
  18. EmeraldPawn

    EmeraldPawn

    Joined:
    Jan 16, 2016
    Posts:
    5
    Hi!

    The Keyboard Scroller seems to stop working correctly when using a Screen Space Camera Canvas and the camera has a Y position that isn't worldspace 0. I can reproduce this in a clean project using the Form sample scene by setting the Main Camera Y position to for example 2 or -2. The scrolling seems to get an offset based on the distance to world center.

    Using Unity version 2020.3.12f1 and Advanced Input Field 2.1.1

    Added a new issue on github
    https://github.com/support-fennecx/advancedinputfield2/issues/38
     
    Last edited: Sep 5, 2021
  19. swifter14

    swifter14

    Joined:
    Mar 2, 2017
    Posts:
    165
    I just checked what causes my users' phones to crash the most (by checking Unity- Services log)
    and it seems to be related to your plugin. Can you tell me what's wrong with it?
    I can see that I'm not the only one in this thread with this error, and it only happens in Android for me as well. I see that you replied to the other person that you don't get the same error for yourself, and I don't get the same error on my phone as well, but apparently by unity LOG, 400 of my app users received that error and it made their app crash. and I have Assets/AdvancedInputField/Plugins/Android/NativeKeyboard.aar in my folder

    Affected devices:
    samsung/SM-A515F/a51
    samsung/SM-A125F/a12
    samsung/SM-G970U/beyond0q
    LGE/LM-X420/mmh4
    Xiaomi/Redmi Note 8 Pro/begonia

    Thanks

    java.lang.ClassNotFoundException: com.jeroenvanpienbroek.nativekeyboard.INativeKeyboardCallback
    java.lang.Class.classForName(Native Method)
    java.lang.Class.forName(Class.java:454)
    com.unity3d.player.UnityPlayer.nativeRender(Native Method)
    com.unity3d.player.UnityPlayer.access$300(Unknown Source:0)
    com.unity3d.player.UnityPlayer$e$1.handleMessage(Unknown Source:95)
    android.os.Handler.dispatchMessage(Handler.java:102)
    android.os.Looper.loop(Looper.java:246)
    com.unity3d.player.UnityPlayer$e.run(Unknown Source:20)
    Caused by: java.lang.ClassNotFoundException: com.jeroenvanpienbroek.nativekeyboard.INativeKeyboardCallback
    ... 8 more
    UnityEngine.AndroidJNISafe.CheckException () (at <00000000000000000000000000000000>:0)
    UnityEngine.AndroidJNISafe.FindClass (System.String name) (at <00000000000000000000000000000000>:0)
    UnityEngine.AndroidJavaClass._AndroidJavaClass (System.String className) (at <00000000000000000000000000000000>:0)
    UnityEngine.AndroidJavaProxy..ctor (System.String javaInterface) (at <00000000000000000000000000000000>:0)
    AdvancedInputFieldPlugin.AndroidKeyboardProxy..ctor (AdvancedInputFieldPlugin.AndroidKeyboard keyboard) (at <00000000000000000000000000000000>:0)
    AdvancedInputFieldPlugin.AndroidKeyboard.Setup () (at <00000000000000000000000000000000>:0)
    AdvancedInputFieldPlugin.NativeKeyboardManager.Awake () (at <00000000000000000000000000000000>:0)
    UnityEngine.GameObject.AddComponent[T] () (at <00000000000000000000000000000000>:0)
    AdvancedInputFieldPlugin.NativeKeyboardManager.CreateInstance () (at <00000000000000000000000000000000>:0)
    AdvancedInputFieldPlugin.AdvancedInputField.Initialize () (at <00000000000000000000000000000000>:0)
    AdvancedInputFieldPlugin.AdvancedInputField.OnRectTransformDimensionsChange () (at <00000000000000000000000000000000>:0)
    UnityEngine.GameObject:AddComponent()
    AdvancedInputFieldPlugin.NativeKeyboardManager:CreateInstance()
    AdvancedInputFieldPlugin.AdvancedInputField:Initialize()
    AdvancedInputFieldPlugin.AdvancedInputField:OnRectTransformDimensionsChange()
     
    Last edited: Sep 12, 2021
  20. fennecx_support

    fennecx_support

    Joined:
    Dec 28, 2020
    Posts:
    133
    Will need to investigate what I can detect on iOS (and Android when possible). I've add this as a feature request on the issue tracker for now: https://github.com/support-fennecx/advancedinputfield2/issues/39
     
    ryan_santiago_dl likes this.
  21. fennecx_support

    fennecx_support

    Joined:
    Dec 28, 2020
    Posts:
    133
    Would be difficult for me to reproduce too since I don't get the same error and don't have any of the devices that this happens on. The only way I know that you could get a ClassNotFoundException is when gradle minify (or other Unity stripping option) actually has removed the class from the build (for a specific device configuration or architecture maybe).
     
  22. swifter14

    swifter14

    Joined:
    Mar 2, 2017
    Posts:
    165
    Can you go to one of your projects on https://dashboard.unity3d.com/landing and check Cloud Diagnostics - crashes-exceptions log. I'm sure you'll see that error as well, and anyone here using this plugin.
    What do you mean Minify? I had my Android's settings Minify- release checked for some time, and now it's disabled, I'm not really familiar with that

    Also, what is NativeKeyboard? How do I disable it? My users use their own built-in keyboard, how can I prevent that error from happening?
     
    Last edited: Sep 12, 2021
  23. fennecx_support

    fennecx_support

    Joined:
    Dec 28, 2020
    Posts:
    133
    I don't use Unity Services myself for my projects, so can't really check there. I did see that if Minify is enabled it will try to strip files from NativeKeyboard.aar library file. This library file is needed to call native Android code to show/hide the onscreen keyboard (the default of the OS or a different one configured by the user) and handle events from that keyboard.

    I've added a modified library file with a Proguard file builtin and configured. That seems to prevent it from stripping java classes when making a build in the Unity Editor (and having the Minify option enabled).
     

    Attached Files:

  24. itsnottme

    itsnottme

    Joined:
    Mar 8, 2017
    Posts:
    129
    Hey @fennecx_support, would be great if you can take a look at my messages, thanks.
     
  25. MartijnPW

    MartijnPW

    Joined:
    Feb 11, 2018
    Posts:
    2
    Hi, I just downloaded the plugin, looks very useful.
    However, when I created an empty scene, and added a TMPro-based inputfield, it would not work well in the editor (Unity 2020.3.16f1, AdvancedInputField 2.1.1).

    Got lots of errors:

    NullReferenceException: Object reference not set to an instance of an object
    AdvancedInputFieldPlugin.InputFieldEngine.RefreshRenderedText () (at Assets/AdvancedInputField/Scripts/InputField/InputFieldEngine.cs:572)

    It turned out to be caused by the 'Enter play mode options' having both 'reload domain' and 'reload scene' turned off.
    The reason is that in such a case, Awake() is not called, which leads to the initialization not being done.
    I was able to fix it by adding EnsureInitialization() to AdvancedInputField::OnEnable:

    protected override void OnEnable()
    {
    base.OnEnable();
    if(!Application.isPlaying) { return; }
    EnsureInitialization();
    Engine.OnEnable();
    }

    I'll add it to the bugtracker on Github but am posting it here for other users.
     
  26. ironunity2020

    ironunity2020

    Joined:
    Nov 7, 2020
    Posts:
    8
    Hi Jeroen

    Firstly thank you for making Advanced Input 2. It has saved me a bunch of time. A quick very basic question: Looking at the chat app, I would like to add a simple button that opens and closes the keyboard and puts focus into the inputfield. I assume there is a event for it something like OnBeginEdit and OnEndEdit which will "open" the keyboard and put focus into the input field. I see OnBeginEdit but I dont see how I can call it? Do you have any suggestions? Thanks. A-
     
  27. ironunity2020

    ironunity2020

    Joined:
    Nov 7, 2020
    Posts:
    8
    This is what I ended up with, it works so I guess it's right?

    Code (CSharp):
    1.  
    2. public void ButtonClickChatOpenClose()
    3.     {
    4.         if (!_advancedInputField.gameObject.activeSelf)
    5.         {
    6.             _advancedInputField.gameObject.SetActive(true);
    7.             _advancedInputField.OnBeginEdit.Invoke(AdvancedInputFieldPlugin.BeginEditReason.PROGRAMMATIC_SELECT);
    8.             _advancedInputField.Select();
    9.             _advancedInputField.OnValueChanged.Invoke("");
    10.         }
    11.         else
    12.         {
    13.             _advancedInputField.OnEndEdit.Invoke(_advancedInputField.tag, AdvancedInputFieldPlugin.EndEditReason.PROGRAMMATIC_DESELECT);
    14.             _advancedInputField.gameObject.SetActive(false);
    15.             _advancedInputField.ManualDeselect();
    16.             _chatMessageView.RestoreOriginalMessageInputPosition();
    17.         }
    18.     }
     
  28. fennecx_support

    fennecx_support

    Joined:
    Dec 28, 2020
    Posts:
    133
    Yes, you can use the ManualSelect() and ManualDeselect() methods to focus/unfocus an inputfield from code.
     
  29. ironunity2020

    ironunity2020

    Joined:
    Nov 7, 2020
    Posts:
    8
    Thank you.

    I also noticed in your code you are using a coroutine to add a message to the scrollview:


    Code (CSharp):
    1.         public void AddMessageLeft(string message)
    2.         {
    3.             StartCoroutine(AddMessage(message, messageBoxLeftPrefab));
    4.         }
    5.  
    6.  
    7. private IEnumerator AddMessage(string message, RectTransform prefab)
    8.         {
    9.             float y = 0;
    10.             if(messageBoxes.Count > 0)
    11.             {
    12.                 RectTransform lastMessageBox = messageBoxes[messageBoxes.Count - 1];
    13.                 y = lastMessageBox.anchoredPosition.y - lastMessageBox.rect.height;
    14.                 y -= Y_SPACING;
    15.             }
    16.  
    17.             float maxWidth = scrollRect.content.rect.width * 0.9f;
    18. #if ADVANCEDINPUTFIELD_TEXTMESHPRO
    19.             RectTransform messageBox = CreateMessageBox(prefab);
    20.             TMProTextRenderer label = messageBox.GetComponentInChildren<TMProTextRenderer>(); //Using wrapper class of the plugin here, because TMPro seems to have issues calculating the preferred size
    21.             label.Text = message;
    22.             label.Multiline = true;
    23.  
    24.             for(int i = 0; i < 3; i++) //Loop multiple times to expand preferred height
    25.             {
    26.                 label.UpdateImmediately();
    27.  
    28.                 Vector2 position = messageBox.anchoredPosition;
    29.                 position.y = y;
    30.                 messageBox.anchoredPosition = position;
    31.  
    32.                 Vector2 preferredLabelSize = label.PreferredSize;
    33.                 preferredLabelSize.x = Mathf.Min(maxWidth, preferredLabelSize.x);
    34.  
    35.                 Vector2 currentLabelSize = label.GetComponent<RectTransform>().rect.size;
    36.                 Vector2 sizeDifference = preferredLabelSize - currentLabelSize;
    37.                 Vector2 messageBoxSize = messageBox.sizeDelta;
    38.                 messageBoxSize += sizeDifference;
    39.                 messageBox.sizeDelta = messageBoxSize;
    40.  
    41.                 yield return null;
    42.             }
    43.  
    44.             messageBoxes.Add(messageBox);
    45.             scrollRect.content.sizeDelta = new Vector2(0, Mathf.Abs(y - messageBox.rect.height));
    46.             scrollRect.verticalNormalizedPosition = 0;
    47. #else
    48.             yield return null;
    49. #endif
    50.         }

    It seemed a bit weird to do this as a coroutine so I changed this to a non-coroutine version:

    Code (CSharp):
    1. private void AddMessageWithoutPause(string message, RectTransform prefab)
    2.     {
    3.         // We should only read the screen buffer after rendering is complete
    4.         float y = 0;
    5.         if (messageBoxes.Count > 0)
    6.         {
    7.             RectTransform lastMessageBox = messageBoxes[messageBoxes.Count - 1];
    8.             y = lastMessageBox.anchoredPosition.y - lastMessageBox.rect.height;
    9.             y -= Y_SPACING;
    10.         }
    11.  
    12.         float maxWidth = scrollRect.content.rect.width * 0.9f;
    13.         //#if ADVANCEDINPUTFIELD_TEXTMESHPRO
    14.         RectTransform messageBox = CreateMessageBox(prefab);
    15.         TMProTextRenderer label = messageBox.GetComponentInChildren<TMProTextRenderer>(); //Using wrapper class of the plugin here, because TMPro seems to have issues calculating the preferred size
    16.         label.Text = message;
    17.         label.Multiline = true;
    18.  
    19.         for (int i = 0; i < 3; i++) //Loop multiple times to expand preferred height
    20.         {
    21.             label.UpdateImmediately();
    22.  
    23.             Vector2 position = messageBox.anchoredPosition;
    24.             position.y = y;
    25.             messageBox.anchoredPosition = position;
    26.  
    27.             Vector2 preferredLabelSize = label.PreferredSize;
    28.             preferredLabelSize.x = Mathf.Min(maxWidth, preferredLabelSize.x);
    29.  
    30.             Vector2 currentLabelSize = label.GetComponent<RectTransform>().rect.size;
    31.             Vector2 sizeDifference = preferredLabelSize - currentLabelSize;
    32.             Vector2 messageBoxSize = messageBox.sizeDelta;
    33.             messageBoxSize += sizeDifference;
    34.             messageBox.sizeDelta = messageBoxSize;
    35.  
    36.  
    37.         }
    38.  
    39.         messageBoxes.Add(messageBox);
    40.         scrollRect.content.sizeDelta = new Vector2(0, Mathf.Abs(y - messageBox.rect.height));
    41.         scrollRect.verticalNormalizedPosition = 0;
    42.  
    43.  
    44.         //#else
    45.         //            yield return null;
    46.         //#endif
    47.     }
    There seems to be some strange 0 < 3 loop to figure out stuff. What is the rationale here is it really necessary to have this called as a coroutine, if it is, how would I preload the chat messages with say 20 messages. I dont really want to call coroutine 20 times...

    Many thanks. A-
     
  30. fennecx_support

    fennecx_support

    Joined:
    Dec 28, 2020
    Posts:
    133
    The main issue is that the Unity & TextMeshPro text renderers can't calculate a preferred size in one axis only. Basically what we need is a way to specify a max width value and then let it calculate a preferred size, but Unity/TextMeshPro don't have an API for this. So the ugly workaround is to let it recalculate the preferred size in multiple frames while manually forcing a specific max width.
     
  31. ironunity2020

    ironunity2020

    Joined:
    Nov 7, 2020
    Posts:
    8
    Thank you for the explanation, that makes a lot of sense. Please can you help me understand:

    1) Is the coroutine absolutely necessary? Why not let it do it's thing on the main thread?

    2) If this is mandatory for some reason how would I pre-populate the chat with chat history without calling a bunch of coroutines?

    Thanks again. A-
     
  32. fennecx_support

    fennecx_support

    Joined:
    Dec 28, 2020
    Posts:
    133
    Originally the issue was that TextMeshPro wouldn't recalculate it's preferred size properly before next frame, that was the reason for the coroutine, but I've did some testing and with newest TextMeshPro this doesn't seems to be an issue anymore.
    Hadn't really touched this code in a long time, because it's not really part of the core functionality of the plugin, but now that I've looked into it more thoroughly I have changed it to this:
    Code (CSharp):
    1. public void AddMessageLeft(string message)
    2.         {
    3.             AddMessage(message, messageBoxLeftPrefab);
    4.         }
    5.  
    6.         public void AddMessageRight(string message)
    7.         {
    8.             AddMessage(message, messageBoxRightPrefab);
    9.         }
    10.  
    11.         private void AddMessage(string message, RectTransform prefab)
    12.         {
    13.             const float RESIZE_THRESHOLD = 0.001f;
    14.             const int MAX_RESIZE_ATTEMPTS = 3;
    15.  
    16.             float y = 0;
    17.             if(messageBoxes.Count > 0)
    18.             {
    19.                 RectTransform lastMessageBox = messageBoxes[messageBoxes.Count - 1];
    20.                 y = lastMessageBox.anchoredPosition.y - lastMessageBox.rect.height;
    21.                 y -= Y_SPACING;
    22.             }
    23.  
    24.             float maxWidth = scrollRect.content.rect.width * 0.9f;
    25. #if ADVANCEDINPUTFIELD_TEXTMESHPRO
    26.             RectTransform messageBox = CreateMessageBox(prefab);
    27.             TMPro.TextMeshProUGUI label = messageBox.GetComponentInChildren<TMPro.TextMeshProUGUI>(); //Using wrapper class of the plugin here, because TMPro seems to have issues calculating the preferred size
    28.             label.text = message;
    29.  
    30.             for(int i = 0; i < MAX_RESIZE_ATTEMPTS; i++) //Loop multiple times to expand preferred height
    31.             {
    32.                 label.ForceMeshUpdate();
    33.  
    34.                 Vector2 position = messageBox.anchoredPosition;
    35.                 position.y = y;
    36.                 messageBox.anchoredPosition = position;
    37.  
    38.                 Vector2 preferredLabelSize = new Vector2(label.preferredWidth, label.preferredHeight);
    39.                 preferredLabelSize.x = Mathf.Min(maxWidth, preferredLabelSize.x);
    40.  
    41.                 Vector2 currentLabelSize = label.GetComponent<RectTransform>().rect.size;
    42.                 Vector2 sizeDifference = preferredLabelSize - currentLabelSize;
    43.                 if(Mathf.Abs(sizeDifference.x) < RESIZE_THRESHOLD && Mathf.Abs(sizeDifference.y) < RESIZE_THRESHOLD)
    44.                 {
    45.                     break;
    46.                 }
    47.  
    48.                 Vector2 messageBoxSize = messageBox.sizeDelta;
    49.                 messageBoxSize += sizeDifference;
    50.                 messageBox.sizeDelta = messageBoxSize;
    51.             }
    52.  
    53.             messageBoxes.Add(messageBox);
    54.             scrollRect.content.sizeDelta = new Vector2(0, Mathf.Abs(y - messageBox.rect.height));
    55.             scrollRect.verticalNormalizedPosition = 0;
    56. #endif
    57.         }
    Also added an early break condition since most of the times I tested it had the right size the first time after applying the recalculated size. (In some conditions where I typed a really long block of text it needed more loops)
     
    Last edited: Oct 3, 2021
  33. ironunity2020

    ironunity2020

    Joined:
    Nov 7, 2020
    Posts:
    8

    You absolute STAR!

    Thanks so much, I was hoping that I wouldnt have to try and test it on a bunch of different devices and this has fixed my initial load issue. It's much faster...:)

    I am struggling with something else I hope you can help me with.

    Basically, the chat example resizes the Scrollview (see the png attached).

    What I would like to is instead of resizing it I would like to reposition it

    Here is the code that resizes it

    Code (CSharp):
    1.     public void UpdateChatHistorySize()
    2.         {
    3.             RectTransform messageInputTransform = MessageInput.RectTransform;
    4.            
    5.             if (ScrollRect == null)
    6.             {
    7.                 return;
    8.             }
    9.  
    10.             RectTransform chatHistoryTransform = ScrollRect.GetComponent<RectTransform>();
    11.             float messageInputTopY = GetAbsoluteTopY(messageInputTransform);
    12.  
    13.  
    14.             ChatMessageRewardControls emojiKeyboard = messageInputTransform.GetComponentInChildren<ChatMessageRewardControls>();
    15.             RectTransform emojiKeyboardTransform = emojiKeyboard.GetComponent<RectTransform>();
    16.             messageInputTopY = GetAbsoluteTopY(emojiKeyboardTransform);
    17.  
    18.  
    19.         //#if (UNITY_EDITOR || UNITY_STANDALONE || UNITY_WSA)
    20.         //            AdvancedInputFieldSamples.EmojiKeyboard emojiKeyboard = messageInputTransform.GetComponentInChildren<AdvancedInputFieldSamples.EmojiKeyboard>();
    21.         //            RectTransform emojiKeyboardTransform = emojiKeyboard.GetComponent<RectTransform>();
    22.         //            messageInputTopY = GetAbsoluteTopY(emojiKeyboardTransform);
    23.         //#endif
    24.             float chatHistoryBottomY = GetAbsoluteBottomY(chatHistoryTransform);
    25.             float differenceY = chatHistoryBottomY - messageInputTopY;
    26.  
    27.             Vector2 sizeDelta = chatHistoryTransform.sizeDelta;
    28.             sizeDelta.y += differenceY;
    29.             chatHistoryTransform.sizeDelta = sizeDelta;
    30.         }
    Here is my version

    Code (CSharp):
    1.     public void UpdateChatHistorySize()
    2.         {
    3.             RectTransform messageInputTransform = MessageInput.RectTransform;
    4.            
    5.             if (ScrollRect == null)
    6.             {
    7.                 return;
    8.             }
    9.  
    10.             RectTransform chatHistoryTransform = ScrollRect.GetComponent<RectTransform>();
    11.             float messageInputTopY = GetAbsoluteTopY(messageInputTransform);
    12.  
    13.  
    14.             ChatMessageRewardControls emojiKeyboard = messageInputTransform.GetComponentInChildren<ChatMessageRewardControls>();
    15.             RectTransform emojiKeyboardTransform = emojiKeyboard.GetComponent<RectTransform>();
    16.             messageInputTopY = GetAbsoluteTopY(emojiKeyboardTransform);
    17.  
    18.  
    19.         //#if (UNITY_EDITOR || UNITY_STANDALONE || UNITY_WSA)
    20.         //            AdvancedInputFieldSamples.EmojiKeyboard emojiKeyboard = messageInputTransform.GetComponentInChildren<AdvancedInputFieldSamples.EmojiKeyboard>();
    21.         //            RectTransform emojiKeyboardTransform = emojiKeyboard.GetComponent<RectTransform>();
    22.         //            messageInputTopY = GetAbsoluteTopY(emojiKeyboardTransform);
    23.         //#endif
    24.             float chatHistoryBottomY = GetAbsoluteBottomY(chatHistoryTransform);
    25.             float differenceY = chatHistoryBottomY - messageInputTopY;
    26.  
    27.             Vector2 sizeDelta = chatHistoryTransform.sizeDelta;
    28.             sizeDelta.y += differenceY;
    29. Vector2 pos = new Vector2(chatHistoryTransform.position.x, chatHistoryTransform.position.y + differenceY);
    30.             chatHistoryTransform.position = pos;
    31.         }

    Im probably way off in this but I am getting really weird values in messageInputTopY and essentially the ScrollView just goes off screen. Do you see what Im doing wrong?
     

    Attached Files:

  34. Seb_L

    Seb_L

    Joined:
    Feb 17, 2021
    Posts:
    16
    Hello,

    I use your asset for IOS. In my app, i have a login with 2 AdvancedInputField : name and password. When i test my app on Ipad or Iphone, I have no problem. But now i want to add my app to the Apple App Store. They test it, and say that they only able to enter the username and not the password. I think the Keyboard is not displayed. But i can not reproduce the error on my device with the same IOS version ! The only difference between the name and the password fields, is the Content Type (Standard or Password).
    Have you maybe a idea what can be the problem ? Can maybe be something with Keyboard configuration of the Ipad ?

    Best regards
     
  35. swifter14

    swifter14

    Joined:
    Mar 2, 2017
    Posts:
    165
    Sometimes I get this error:
    NullReferenceException: Object reference not set to an instance of an object.

    UnityEngine.Component.GetComponent[T] () (at <00000000000000000000000000000000>:0)
    AdvancedInputFieldPlugin.UnityTextRenderer.get_Renderer () (at <00000000000000000000000000000000>:0)
    AdvancedInputFieldPlugin.UnityTextRenderer.get_Visible () (at <00000000000000000000000000000000>:0)
    AdvancedInputFieldPlugin.InputFieldEngine.GetActiveTextRenderer () (at <00000000000000000000000000000000>:0)
    AdvancedInputFieldPlugin.InputFieldEngine.UpdateActiveTextRenderer () (at <00000000000000000000000000000000>:0)
    AdvancedInputFieldPlugin.InputFieldEngine+<InitialTextRendererFix>d__101.MoveNext () (at <00000000000000000000000000000000>:0)
    UnityEngine.SetupCoroutine.InvokeMoveNext (System.Collections.IEnumerator enumerator, System.IntPtr returnValueAddress) (at <00000000000000000000000000000000>:0)
     
  36. swifter14

    swifter14

    Joined:
    Mar 2, 2017
    Posts:
    165
    You should, it shows you all the exceptions there. Exceptions on devices can be different than on the editor. And most of the errors on my project come from this plugin when checking the log. If you work with their log you can make this plugin perfect
     
  37. emilibroooo

    emilibroooo

    Joined:
    Jan 27, 2018
    Posts:
    4
    Hi! Thanks for this asset. Is there an easy way to increase the action bar size while keeping the optimize item sizes option checked? I've tried just increasing the scale, but it doesn't do anything.
     
  38. fennecx_support

    fennecx_support

    Joined:
    Dec 28, 2020
    Posts:
    133
    Don't really know. I've had an user before who had something similar with the App Store. He just rebuild his app and submitted it again to the App Store and then they did approve it apparently. The App store review team uses a different testing environment as far as I know, which seems to be a bit random.
     
  39. fennecx_support

    fennecx_support

    Joined:
    Dec 28, 2020
    Posts:
    133
    upload_2021-10-10_12-38-1.png

    You could try to modify the ActionBar resize settings on the ActionBar prefabs. You can make duplicates of those prefabs (so they don't get overwritten when updating the plugin) and assign your modified prefabs in the global settings (TopBar: Tools => AdvancedInputField => Global Settings)

    Edit: For the height itself, you might want to change the THUMB_SIZE_RATIO in ActionBar.cs. Please note that this only has an effect on an actual Android/iOS device, on Standalone/Editor it uses a fallback value, because dpi can't be determined on Standalone/Editor.
     
    Last edited: Oct 10, 2021
  40. swifter14

    swifter14

    Joined:
    Mar 2, 2017
    Posts:
    165
    The main issue with this plugin is errors on devices (Android and iPhone), I appreciate this asset, but I'm not sure why the developer @fennecx_support avoids checking some mobile errors. Some errors only happen on certain devices, the same as your problem. The developer has no idea why it happens since it doesn't happen on his own device, and because he doesn't check the Unity logs.
    Regarding your problem with the ios keyboard, I'd recommend you what I recommended the developer- go to Unity Dashboard- select your project, go to Cloud-Diagnostics- Crashes and Exceptions and check what errors you can see that are related to the advanced-input-field plugin and ios users, you'll find the error/solution there. I found some errors as well that I could solve with some try-catch blocks around his script.
    https://dashboard.unity3d.com/

    Here is one example I found on Unity Dashboard (I couldn't see it on Unity's editor)
    error.jpg
     
    Last edited: Oct 13, 2021
  41. emilibroooo

    emilibroooo

    Joined:
    Jan 27, 2018
    Posts:
    4
    Thanks! Editing the THUMB_SIZE_RATIO in ActionBar.cs is exactly what I was looking for. I have another question though. I've been looking through the script to find a way to make the action bar appear quicker when holding a tap in the input field and can't find anything. Is there a way to make that happen?
     
  42. fennecx_support

    fennecx_support

    Joined:
    Dec 28, 2020
    Posts:
    133
    To change the time needed for a tap to be recognized as a hold gesture change the "Hold Threshold" property in the Global Settings.
    (TopBar => Tools => Advanced Input Field => Global Settings)
     
  43. BjoUnity3d

    BjoUnity3d

    Joined:
    Jul 24, 2012
    Posts:
    60
    Using 2.1.6 when I create a new Advanced Input Text Mesh Pro field it comes out as a broken Advanced Input Unity Text field. It contains Text Mesh Pro elements but the big green banner on the component says "Unity Text" and then when I try to click in the text field I get an exception: NullReferenceException: Object reference not set to an instance of an object adn NotImplementedException: This type of Text Renderer is not configured, please check the ReadMe for instructions.

    Found it. Had to add ADVANCEDINPUTFIELD_TEXTMESHPRO to scripting defined symbols for target platforms in player settings.

    Only now I get this spammed into the console:
    [Exception] NullReferenceException: Object reference not set to an instance of an object
    TextNavigator.KeepActionBarWithinBounds() at /Plugins/Advanced Input Field/Scripts/InputField/TextNavigator.cs:1438
    1436: {
    1437: Camera camera = Canvas.worldCamera;
    -->1438: float orthographicHeight = camera.orthographicSize;
    1439: float orthographicWidth = camera.orthographicSize / Screen.height * Screen.width;
    1440: normalizedLeftX = (leftX + orthographicWidth) / (orthographicWidth * 2);

    TextNavigator.UpdateActionBarPosition() at /Plugins/Advanced Input Field/Scripts/InputField/TextNavigator.cs:1412
    1410: ActionBar.UpdatePosition(actionBarPosition);
    -->1412: KeepActionBarWithinBounds();
    1413: }

    AdvancedInputField.OnTextScrollChanged() at /Plugins/Advanced Input Field/Scripts/InputField/AdvancedInputField.cs:1366
    1364: if(ActionBarEnabled && textNavigator is MobileTextNavigator)
    1365: {
    -->1366: ((MobileTextNavigator)textNavigator).UpdateActionBarPosition();
    1367: }
    1368: }

    UnityEngine.Events.InvokableCall`1[T1].Invoke() at /Users/bokken/buildslave/unity/build/Runtime/Export/UnityEvent/UnityEvent.cs:207

    UnityEngine.Events.UnityEvent`1[T0].Invoke() at /Users/bokken/buildslave/unity/build/Runtime/Export/UnityEvent/UnityEvent/UnityEvent_1.cs:58

    ScrollArea.LateUpdate() at /Plugins/Advanced Input Field/Scripts/InputField/ScrollArea.cs:616
    614: UpdateScrollbars(offset);
    615: UISystemProfilerApi.AddMarker("ScrollRect.value", this);
    -->616: onValueChanged.Invoke(normalizedPosition);
    617: UpdatePrevData();
    618: }

    I see I've been down this road before. https://forum.unity.com/threads/advanced-input-field.485697/page-17#post-6165027

    I will disable the action bar again but I wonder why this still doesn't work.
     
    Last edited: Oct 17, 2021
  44. fennecx_support

    fennecx_support

    Joined:
    Dec 28, 2020
    Posts:
    133

    Not really sure which version you are using, because latest released version is 2.1.2 in the AssetStore.

    Regarding your issue: Seems to a specific conflict with that DoozyUI plugin you are using based on your previous post. Seems to be hijacking the Canvas.worldCamera property (or something else) that the plugin needs to position and size the ActionBar so it stays visible on screen.
    I don't have that DoozyUI plugin myself, so if you could make a small repro project I could take a look into implementing a fallback Camera search, but without that it would be difficult to verify if my code changes have any effect in your situation.
    If you only have one Camera in your scene I could add a simple Camera instance search, but if there are multiple Cameras in your scene, it could use the wrong Camera instance.
     
  45. frozenmangotree

    frozenmangotree

    Joined:
    May 2, 2020
    Posts:
    14
    So when I duplicate an advanced tmp input field which has writing in it and im busy editing it, then the original one I duplicated gets an extra caret instance inside "Text" parent, which doesnt go away even when I deselect it and the duplicated one is instantiated with an extra caret as well which doesn't go away either. Meaning when I click on the original or the duplicate(s) they have extra carets that are always visible and created at time of duplication. How to I prevent this from happening? And then when I try destroying the extra carets at time of duplication, I get this error:
    "The object of type 'Image' has been destroyed but you are still trying to access it.
    Your script should either check if it is null or you should not destroy the object." The error occurs inside BasicTextSelectionHandler.cs and inside this method:

    Code (CSharp):
    1.  
    2. public override void OnUpdate()
    3.         {
    4.             caretBlinkTime += Time.deltaTime;
    5.             caretBlinkTime = Mathf.Min(caretBlinkTime, InputField.CaretBlinkRate);
    6.             float progress = caretBlinkTime / InputField.CaretBlinkRate;
    7.             if(progress <= 0.5f)
    8.             {
    9.                 caretRenderer.enabled = true;
    10.             }
    11.             else
    12.             {
    13.                 caretRenderer.enabled = false;
    14.             }
    15.             if(progress == 1)
    16.             {
    17.                 caretBlinkTime = 0;
    18.             }
    19.         }
    So what am I suppose to do because I need to create duplicates of an advanced input field at runtime but I don't want extra carets popping up everywhere?
     
  46. BjoUnity3d

    BjoUnity3d

    Joined:
    Jul 24, 2012
    Posts:
    60
    Oh actually I'm on 1.9.8. I was mixing it up with TextMeshPro which is 2.1.6. That is interesting, I will look into that. Thanks!
     
  47. emilibroooo

    emilibroooo

    Joined:
    Jan 27, 2018
    Posts:
    4
    Thank You! Another question: As you can see in the pic below, the action bar is being cut off by the iPhone notch. On the Android device I test with, the action bar automatically appears on the bottom of the input field when it is too high on the screen. Is there a way to edit the threshold that determines whether the action bar appears on the top or bottom of the input field?

     
  48. look001

    look001

    Joined:
    Mar 23, 2017
    Posts:
    111
    Hi, I just bought your asset. I wonder how to move a ui image up, when the touchscreen keyboard is expanded? The ui just stays behind the keyboard and the input field is no longer visible. Can you please give some advice? I did not find anything in the documentation. Thank you!
     
  49. fennecx_support

    fennecx_support

    Joined:
    Dec 28, 2020
    Posts:
    133
    Sorry for the late reply.
    I could reproduce it and managed to create a fix for this. The main issue was that the text selection controls that get created when entering edit mode got a bit messed up on the duplicate and original instance (wrong gameobjects got destroyed).

    I've attached the files that I modified. Can be applied over version 2.1.3 of the plugin.
     

    Attached Files:

  50. fennecx_support

    fennecx_support

    Joined:
    Dec 28, 2020
    Posts:
    133
    I fixed it by adding the notch area into the calculation when positioning the ActionBar.
    To fix change KeepActionBarWithinBounds() to this in TextNavigator.cs:

    Code (CSharp):
    1. internal void KeepActionBarWithinBounds()
    2.         {
    3.             RectTransform rectTransform = ActionBar.RectTransform;
    4.             Vector3[] corners = new Vector3[4]; //BottomLeft, TopLeft, TopRight, BottomRight
    5.             rectTransform.GetWorldCorners(corners);
    6.  
    7.             float leftX = corners[1].x;
    8.             float rightX = corners[2].x;
    9.             float topY = corners[1].y;
    10.             float normalizedLeftX;
    11.             float normalizedTopY;
    12.             float normalizedRightX;
    13.             if(Canvas.renderMode == RenderMode.ScreenSpaceOverlay)
    14.             {
    15.                 normalizedLeftX = leftX / Screen.width;
    16.                 normalizedRightX = rightX / Screen.width;
    17.                 normalizedTopY = topY / Screen.height;
    18.             }
    19.             else
    20.             {
    21.                 Camera camera = Canvas.worldCamera;
    22.                 float orthographicHeight = camera.orthographicSize;
    23.                 float orthographicWidth = camera.orthographicSize / Screen.height * Screen.width;
    24.                 normalizedLeftX = (leftX + orthographicWidth) / (orthographicWidth * 2);
    25.                 normalizedRightX = (rightX + orthographicWidth) / (orthographicWidth * 2);
    26.                 normalizedTopY = (topY + orthographicHeight) / (orthographicHeight * 2);
    27.             }
    28.  
    29.             float normalizedNotchArea = 0;
    30.             if(Screen.safeArea.yMax > 0)
    31.             {
    32.                 normalizedNotchArea = (Screen.height - Screen.safeArea.yMax) / (float)Screen.height;
    33.             }
    34.  
    35.             if(normalizedTopY + normalizedNotchArea > 1) //Out of bounds, move to bottom of InputField
    36.             {
    37.                 Vector2 actionBarPosition = rectTransform.anchoredPosition;
    38.                 actionBarPosition.y -= (InputField.Size.y + ActionBar.RectTransform.rect.height);
    39.                 ActionBar.UpdatePosition(actionBarPosition);
    40.             }
    41.  
    42.             if(normalizedLeftX < ACTION_BAR_MARGIN_X)
    43.             {
    44.                 Vector2 actionBarPosition = rectTransform.anchoredPosition;
    45.                 if(Canvas.renderMode == RenderMode.WorldSpace)
    46.                 {
    47.                     RectTransform canvasTransform = Canvas.GetComponent<RectTransform>();
    48.                     Vector3[] canvasCorners = new Vector3[4];
    49.                     canvasTransform.GetWorldCorners(canvasCorners);
    50.                     Vector2 canvasWorldSize = new Vector2(Mathf.Abs(canvasCorners[3].x - canvasCorners[1].x), Mathf.Abs(canvasCorners[3].y - canvasCorners[1].y));
    51.                     float ratioX = canvasWorldSize.x / ((Canvas.worldCamera.orthographicSize * 2) / Screen.height * Screen.width);
    52.                     actionBarPosition.x += (ACTION_BAR_MARGIN_X - normalizedLeftX) * (canvasTransform.rect.width / ratioX / Canvas.scaleFactor);
    53.                 }
    54.                 else
    55.                 {
    56.                     actionBarPosition.x += (ACTION_BAR_MARGIN_X - normalizedLeftX) * (Canvas.pixelRect.width / Canvas.scaleFactor);
    57.                 }
    58.                 ActionBar.UpdatePosition(actionBarPosition);
    59.             }
    60.             else if(normalizedRightX > 1 - ACTION_BAR_MARGIN_X)
    61.             {
    62.                 Vector2 actionBarPosition = rectTransform.anchoredPosition;
    63.                 if(Canvas.renderMode == RenderMode.WorldSpace)
    64.                 {
    65.                     RectTransform canvasTransform = Canvas.GetComponent<RectTransform>();
    66.                     Vector3[] canvasCorners = new Vector3[4];
    67.                     canvasTransform.GetWorldCorners(canvasCorners);
    68.                     Vector2 canvasWorldSize = new Vector2(Mathf.Abs(canvasCorners[3].x - canvasCorners[1].x), Mathf.Abs(canvasCorners[3].y - canvasCorners[1].y));
    69.                     float ratioX = canvasWorldSize.x / ((Canvas.worldCamera.orthographicSize * 2) / Screen.height * Screen.width);
    70.                     actionBarPosition.x += ((1 - ACTION_BAR_MARGIN_X) - normalizedRightX) * (canvasTransform.rect.width / ratioX / Canvas.scaleFactor);
    71.                 }
    72.                 else
    73.                 {
    74.                     actionBarPosition.x += ((1 - ACTION_BAR_MARGIN_X) - normalizedRightX) * (Canvas.pixelRect.width / Canvas.scaleFactor);
    75.                 }
    76.                 ActionBar.UpdatePosition(actionBarPosition);
    77.             }
    78.         }