Unity实现虚拟键盘

本文实例为大家分享了Unity实现虚拟键盘的具体代码,供大家参考,具体内容如下

这是一个网上找的插件,自己改了点东西,方便使用在项目中。暂时不适用中文输入,中文输入可能得调出系统输入法,项目不需要就没去研究了,大伙有兴趣可以研究研究。

包含两个类,一个是虚拟键盘类,还一个是文本框输入类。下面直接上代码:

using UnityEngine;
using System.Collections.Generic;

/*
 * On Screen Keyboard
 * By Richard Taylor, Holopoint Interactive Pty. Ltd.
 *
 * FEATURES:
 * - Fully configurable layout
 * - Fully skinnable
 * - Key select and press audio
 * - Configurable caps functionality
 * - Configurable key repeat settings
 * - Works with both joystick/gamepad and mouse/touchscreen input
 * - Simple integration
 * - Tested using Xbox 360 controller and iPad
 */

/*
 * Time list:
 * June于2020.04.17改
 *
 */

public enum ShiftState { Off, Shift, CapsLock }

public class OnScreenKeyboard : MonoBehaviour {

 // INSPECTOR VISIBLE PROPERTIES -------------------------------------------

 // Skinning
 public GUIStyle boardStyle;
 public GUIStyle keyStyle;
 public Texture2D selectionImage;

 // Board and button sizes
 public Rect screenRect = new Rect(0, 0, 0, 0);
 public Vector2 stdKeySize = new Vector2(32, 32);
 public Vector2 lgeKeySize = new Vector2(64, 32);

 // Key audio
 public AudioClip keySelectSound = null;
 public AudioClip keyPressSound = null;

 // Shift settings
 public bool shiftStateSwitchEnabled = true;
 public ShiftState shiftStateDefault = ShiftState.Off;

 // Joystick settings
 public bool joystickEnabled = true;
 public string joyPressButton = "Fire1";
 public string joyCapsButton = "Fire2";

 // Our keys. By default we'll include a simplified QWERTY keyboard handy
 // for name entry, but this can literally be anything you want. Either the
 // two arrays must be of matching length, or lowerKeys must be of size 0.
 public string[] upperKeys = { "Q", "W", "E", "R", "T", "Y", "U", "I", "O", "P", "<<", "<row>",
     "A", "S", "D", "F", "G", "H", "J", "K", "L", "Done", "<row>",
     "Z", "X", "C", "V", "B", "N", "M", "Caps", "Space" };

 public string[] lowerKeys = { "q", "w", "e", "r", "t", "y", "u", "i", "o", "p", "<<", "<row>",
     "a", "s", "d", "f", "g", "h", "j", "k", "l", "Done", "<row>",
     "z", "x", "c", "v", "b", "n", "m", "Caps", "Space" };

 // The size must match the number of rows, or be 0
 public float[] rowIndents = { 0.0f, 0.2f, 0.5f };

 // Delays for repeated events
 public float initialRepeatDelay = 0.8f;
 public float continuedRepeatDelay = 0.2f;
 public float moveRepeatDelay = 0.3f;

 // INTERNAL DATA MEMBERS --------------------------------------------------
 private string keyPressed = "";
 private int pSelectedButton;

 private GUIStyle pressedStyle = null;

 private float keyRepeatTimer = 0;
 private bool keyDownPrevFrame = false;
 private bool keyReleased = false;
 private bool lastKeyWasShift = false;

 private float moveTimer = 0;

 private ShiftState shiftState;

 private bool[] keySizes;
 private Rect[] keyRects;
 private int[] rowMarkers;

 private int selectedButton;

 private AudioSource keySelectSource = null;
 private AudioSource keyPressSource = null;

 // Change this if it's conflicting with your own GUI's windows
 private int windowId = 0;

 /// <summary>
 /// 新增属性,控制虚拟键盘在屏幕中的位置
 /// </summary>
 [Header("June_Add_Attribute_Control_keyBoardTF---------------------------------------")]
 public float _keyBoardTF_X;
 public float _keyBoardTF_Y;

 // INITIALISATION ---------------------------------------------------------
 void Awake()
 {
 // Check that our key array sizes match
 if (upperKeys.Length != lowerKeys.Length && !(lowerKeys.Length == 0 && !shiftStateSwitchEnabled))
 {
 print("Error: OnScreenKeyboard needs the same number of upper and lower case keys, or there must be no lower keys and caps switch must be disabled");
 Destroy(this);
 }

 // Check for row markers and count row lengths
 List<int> rowMarkersTemp = new List<int>();
 for (int i = 0; i < upperKeys.Length; i++)
 if (upperKeys[i] == "<row>") rowMarkersTemp.Add(i);
 rowMarkers = rowMarkersTemp.ToArray();

 // Check row indents
 if (rowIndents.Length < rowMarkers.Length + 1)
 {
  float[] rowIndentsTemp = new float[rowMarkers.Length + 1];
  for (int i = 0; i < rowIndentsTemp.Length; i++)
  {
  if (i < rowIndents.Length) rowIndentsTemp[i] = rowIndents[i];
  else rowIndentsTemp[i] = 0;
  }
 }

 // Check button sizes - anything that's not a single character is a "large" key
 keySizes = new bool[upperKeys.Length];
 for (int i = 0; i < upperKeys.Length; i++) keySizes[i] = upperKeys[i].Length > 1;

 // Populate the array of key rectangles
 keyRects = new Rect[upperKeys.Length];
 int currentRow = 0;
 float xPos = (rowIndents.Length > 0 ? rowIndents[currentRow] : 0) + stdKeySize.x*0.33f;
 float yPos = stdKeySize.y*1.33f*currentRow + stdKeySize.y*0.33f;
 for (int i = 0; i < upperKeys.Length; i++)
 {
 // On the start of a new line, position the new key accordingly
  if (IsRowMarker(i))
  {
  if (i != 0) currentRow++;
  xPos = (rowIndents.Length > 0 ? rowIndents[currentRow] : 0) + stdKeySize.x * 0.33f;
  yPos = stdKeySize.y*1.33f*currentRow + stdKeySize.y * 0.33f;
  }
  else
  {
  // Draw the key, and set keyPressed accordingly
  keyRects[i] = new Rect(screenRect.x + xPos, screenRect.y + yPos, keySizes[i] ? lgeKeySize.x : stdKeySize.x, keySizes[i] ? lgeKeySize.y : stdKeySize.y);

  // Move over to the next key's position on this line
  xPos += keySizes[i] ? lgeKeySize.x + stdKeySize.x*0.33f : stdKeySize.x*1.33f;
  }
 }

 // Put ourselves in a default screen position if we haven't been explicitly placed yet
 if (screenRect.x == 0 && screenRect.y == 0 && screenRect.width == 0 && screenRect.height == 0)
 {
  // Figure out how big we need to be
  float maxWidth = 0;
 float maxHeight = 0;
 for (int i = 0; i < keyRects.Length; i++)
 {
 if (keyRects[i].xMax > maxWidth) maxWidth = keyRects[i].xMax;
 if (keyRects[i].yMax > maxHeight) maxHeight = keyRects[i].yMax;
 }
 maxWidth += stdKeySize.x*0.33f;
 maxHeight += stdKeySize.y*0.33f;

  screenRect = new Rect(_keyBoardTF_X, _keyBoardTF_Y, maxWidth, maxHeight);
 }

 // If we've got audio, create sources so we can play it
 if (keySelectSound != null)
 {
 keySelectSource = gameObject.AddComponent<AudioSource>() as AudioSource;
 keySelectSource.spatialBlend = 0;
 keySelectSource.clip = keySelectSound;
 }
 if (keyPressSound != null)
 {
 keyPressSource = gameObject.AddComponent<AudioSource>() as AudioSource;
 keyPressSource.spatialBlend = 0;
 keyPressSource.clip = keyPressSound;
 }

 // Set the initial shift state
 if (shiftStateSwitchEnabled) SetShiftState(shiftStateDefault);

 // Create a pressed button skin for joysticks
 pressedStyle = new GUIStyle();
 pressedStyle.normal.background = keyStyle.active.background;
 pressedStyle.border = keyStyle.border;
 pressedStyle.normal.textColor = keyStyle.active.textColor;
 pressedStyle.alignment = keyStyle.alignment;
 //新增字体样式------->按钮按下的时候调用
 pressedStyle.font = keyStyle.font;

 }

 // GAME LOOP --------------------------------------------------------------

 void Update()
 {
 // Handle keys being released
 if (!keyDownPrevFrame)
 {
 keyRepeatTimer = 0;
 if (!keyReleased) KeyReleased();
 }
 keyDownPrevFrame = false;

 // Check mouse input
 Vector3 guiMousePos = Input.mousePosition;
 guiMousePos.y = Screen.height - guiMousePos.y;
 for (int i = 0; i < keyRects.Length; i++)
 {
 Rect clickRect = keyRects[i];
 clickRect.x += screenRect.x; clickRect.y += screenRect.y;
 // Check for the click ourself, because we want to do it differently to usual
 if (clickRect.Contains(guiMousePos))
 {
 selectedButton = i;
 if (Input.GetMouseButtonDown(0)) KeyPressed();
 else if (Input.GetMouseButton(0)) KeyHeld();
 else if (Input.GetMouseButtonUp(0)) KeyReleased();
 }
 }

 // If the joystick is in use, update accordingly
 if (joystickEnabled) CheckJoystickInput();
 }

 private void CheckJoystickInput()
 {
 // KEY SELECTION
 float horiz = Input.GetAxis("Horizontal");
 float vert = Input.GetAxis("Vertical");

 moveTimer -= Time.deltaTime;
 if (moveTimer < 0) moveTimer = 0;

 bool hadInput = false;
 bool moved = false;
 if (horiz > 0.5f)
 {
 if (moveTimer <= 0)
 {
 SelectRight();
 moved = true;
 }
 hadInput = true;
 }
 else if (horiz < -0.5f)
 {
 if (moveTimer <= 0)
 {
 SelectLeft();
 moved = true;
 }
 hadInput = true;
 }
 if (vert < -0.5f)
 {
 if (moveTimer <= 0)
 {
 SelectDown();
 moved = true;
 }
 hadInput = true;
 }
 else if (vert > 0.5f)
 {
 if (moveTimer <= 0)
 {
 SelectUp();
 moved = true;
 }
 hadInput = true;
 }
 if (!hadInput) moveTimer = 0;
 if (moved)
 {
 moveTimer += moveRepeatDelay;
 if (keySelectSource != null) keySelectSource.Play();
 }
 selectedButton = Mathf.Clamp(selectedButton, 0, upperKeys.Length - 1);

 // CAPITALS
 if (shiftStateSwitchEnabled &&
  (Input.GetKeyDown(KeyCode.LeftShift) ||
  Input.GetButtonDown(joyCapsButton)))
  shiftState = (shiftState == ShiftState.CapsLock ? ShiftState.Off : ShiftState.CapsLock);

 // TYPING
 if (Input.GetButtonDown(joyPressButton)) KeyPressed();
 else if (Input.GetButton(joyPressButton)) KeyHeld();
 }

 // Called on the first frame where a new key is pressed
 private void KeyPressed()
 {
 keyPressed = (shiftState != ShiftState.Off) ? upperKeys[selectedButton] : lowerKeys[selectedButton];
 pSelectedButton = selectedButton;
 keyRepeatTimer = initialRepeatDelay;

 keyDownPrevFrame = true;
 keyReleased = false;
 lastKeyWasShift = false;

 if (keyPressSource != null) keyPressSource.Play();
 }

 // Called for every frame AFTER the first while a key is being held
 private void KeyHeld()
 {
 // If the key being pressed has changed, revert to an initial press
 if (selectedButton != pSelectedButton)
 {
 KeyReleased();
 KeyPressed();
 return;
 }

 // Check if we're ready to report another press yet
 keyRepeatTimer -= Time.deltaTime;
 if (keyRepeatTimer < 0)
 {
 keyPressed = (shiftState != ShiftState.Off) ? upperKeys[selectedButton] : lowerKeys[selectedButton];
 keyRepeatTimer += continuedRepeatDelay; 

 if (keyPressSource != null) keyPressSource.Play();
 }

 keyDownPrevFrame = true;
 keyReleased = false;
 }

 // Called the frame after a key is released
 private void KeyReleased()
 {
 keyDownPrevFrame = false;
 keyReleased = true;

 if (shiftState == ShiftState.Shift && !lastKeyWasShift)
 SetShiftState(ShiftState.Off);
 }

 // Selects the key to the left of the currently selected key
 private void SelectLeft()
 {
 selectedButton--;

 // If we've hit the start of a row, wrap to the end of it instead
 if (IsRowMarker(selectedButton) || selectedButton < 0)
 {
  selectedButton++;
  while (!IsRowMarker(selectedButton+1) && selectedButton+1 < upperKeys.Length) selectedButton++;
 }
 }

 // Selects the key to the right of the currently selected key
 private void SelectRight()
 {
 selectedButton++;

 // If we've hit the end of a row, wrap to the start of it instead
 if (IsRowMarker(selectedButton) || selectedButton >= upperKeys.Length)
 {
  selectedButton--;
  while (!IsRowMarker(selectedButton-1) && selectedButton-1 >= 0) selectedButton--;
 }
 }

 // Selects the key above the currently selected key
 private void SelectUp()
 {
 // Find the center of the currently selected button
 float selCenter = keyRects[selectedButton].x + keyRects[selectedButton].width/2;

 // Find the start of the next button;
 int tgtButton = selectedButton;
 while (!IsRowMarker(tgtButton) && tgtButton >= 0) tgtButton--;
 if (IsRowMarker(tgtButton)) tgtButton--;
 if (tgtButton < 0) tgtButton = upperKeys.Length-1;

 // Find the button with the closest center on that line
 float nDist = float.MaxValue;
 while (!IsRowMarker(tgtButton) && tgtButton >= 0)
 {
 float tgtCenter = keyRects[tgtButton].x + keyRects[tgtButton].width/2;
 float tDist = Mathf.Abs(tgtCenter - selCenter);
 if (tDist < nDist)
 {
 nDist = tDist;
 }
 else
 {
 selectedButton = tgtButton+1;
 return;
 }
 tgtButton--;
 }
 selectedButton = tgtButton+1;
 }

 // Selects the key below the currently selected key
 private void SelectDown()
 {
 // Find the center of the currently selected button
 float selCenter = keyRects[selectedButton].x + keyRects[selectedButton].width/2;

 // Find the start of the next button;
 int tgtButton = selectedButton;
 while (!IsRowMarker(tgtButton) && tgtButton < upperKeys.Length) tgtButton++;
 if (IsRowMarker(tgtButton)) tgtButton++;
 if (tgtButton >= upperKeys.Length) tgtButton = 0;

 // Find the button with the closest center on that line
 float nDist = float.MaxValue;
 while (!IsRowMarker(tgtButton) && tgtButton < upperKeys.Length)
 {
 float tgtCenter = keyRects[tgtButton].x + keyRects[tgtButton].width/2;
 float tDist = Mathf.Abs(tgtCenter - selCenter);
 if (tDist < nDist)
 {
 nDist = tDist;
 }
 else
 {
 selectedButton = tgtButton-1;
 return;
 }
 tgtButton++;
 }
 selectedButton = tgtButton-1;
 }

 // Returns the row number of a specified button
 private int ButtonRow(int buttonIndex)
 {
 for (int i = 0; i < rowMarkers.Length; i++)
  if (buttonIndex < rowMarkers[i]) return i;

 return rowMarkers.Length;
 }

 // GUI FUNCTIONALITY ------------------------------------------------------

 void OnGUI()
 {
 GUI.Window(windowId, screenRect, WindowFunc, "", boardStyle);
 }

 private void WindowFunc(int id)
 {
 for (int i = 0; i < upperKeys.Length; i++)
 {
  if (!IsRowMarker(i))
  {
  // Draw a glow behind the selected button
  if (i == selectedButton)
   GUI.DrawTexture(new Rect(keyRects[i].x-5, keyRects[i].y-5, keyRects[i].width+10, keyRects[i].height+10), selectionImage);
  // Draw the key
 // Note that we don't do click detection here, we do it in update
 GUI.Button(keyRects[i], (shiftState != ShiftState.Off) ? upperKeys[i] : lowerKeys[i],
  (joystickEnabled && selectedButton == i && Input.GetButton(joyPressButton) ? pressedStyle : keyStyle));
  }
 }
 }

 // Returns true if they item at a specified index is a row end marker
 private bool IsRowMarker(int currentKeyIndex)
 {
 for (int i = 0; i < rowMarkers.Length; i++) if (rowMarkers[i] == currentKeyIndex) return true;
 return false;
 }

 // CONTROL INTERFACE ------------------------------------------------------

 // Returns the latest key to be pressed, or null if no new key was pressed
 // since last time you checked. This means that you can only grab a single
 // keypress once, as it's cleared once you've read it. It also means that
 // if you let the user press multiple keys between checks only the most
 // recent one will be picked up each time.
 public string GetKeyPressed()
 {
 if (keyPressed == null) keyPressed = "";

 string key = keyPressed;
 keyPressed = "";
 return key;
 }

 // Toggle the caps state from elsewhere
 public void SetShiftState(ShiftState newShiftState)
 {
 if (!shiftStateSwitchEnabled) return;

 shiftState = newShiftState;
 if (shiftState == ShiftState.Shift) lastKeyWasShift = true;
 }

 public ShiftState GetShiftState() { return shiftState; }
}
using UnityEngine;
using UnityEngine.UI;

/// <summary>
/// 这是虚拟键盘插件脚本,June于2020.4.16改
/// </summary>

public class OnScreenKeyboardExample : MonoBehaviour
{
 public OnScreenKeyboard osk;
 /// <summary>
  /// 输入文字
  /// </summary>
 private string _inputString;
  /// <summary>
  /// 输入文本框
  /// </summary>
  public InputField _inputField;

  //每次激活清空文本框内容
  private void OnEnable()
  {
    _inputString = "";
  }

  void Update ()
  {

 // You can use input from the OSK just by asking for the most recent
 // pressed key, which will be returned to you as a string, or null if
 // no key has been pressed since you last checked. Note that if more
 // than one key has been pressed you will only be given the most recent.
 string keyPressed = osk.GetKeyPressed();
 if (keyPressed != "")
 {

  // Take different action depending on what key was pressed
  if (keyPressed == "Backspace" || keyPressed == "<<")
  {
  // Remove a character
  if (_inputString.Length > 0)
          _inputString = _inputString.Substring(0, _inputString.Length-1);
  }
  else if (keyPressed == "Space")
  {
        // Add a space
        _inputString += " ";
      }
  else if (keyPressed == "Enter" || keyPressed == "Done")
  {
        // Change screens, or do whatever you want to
        // do when your user has finished typing :-)
      }
  else if (keyPressed == "Caps")
  {
  // Toggle the capslock state yourself
  osk.SetShiftState(osk.GetShiftState() == ShiftState.CapsLock ? ShiftState.Off : ShiftState.CapsLock);
      }
  else if (keyPressed == "Shift")
  {
  // Toggle shift state ourselves
  osk.SetShiftState(osk.GetShiftState() == ShiftState.Shift ? ShiftState.Off : ShiftState.Shift);
      }
  else
  {
        //限制输入
        if (_inputField.text.Length >= _inputField.characterLimit) return;
        // Add a letter to the existing string
        _inputString += keyPressed;
  }
      //将文字赋值给文本框中的文本属性
      _inputField.text = _inputString;

    }
 }
}

在场景中新建个空物体,用来放虚拟键盘脚本,再新建个输入文本框,脚本可以挂在画布上或者新建个空物体都行。把输入文本框赋上去就可以了。运行效果是这样的

当然,你想要各种风格之类的,换底图之类的,以及按键数量,都可以自行设置。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Unity键盘WASD实现物体移动

    本文实例为大家分享了Unity键盘WASD实现物体移动的具体代码,供大家参考,具体内容如下 1首先在场景中建立一个Capsule,将主摄像机拖到其物体下. 2.将脚本挂在Capsule物体下,WASD 控制移动方向,空格延Y轴向上移动,F延Y轴向下移动 using System.Collections; using System.Collections.Generic; using UnityEngine; public class MoveCam : MonoBehaviour { priva

  • Unity3D获取当前键盘按键及Unity3D鼠标、键盘的基本操作

    获取当前键盘按键,代码如下: using UnityEngine; using System.Collections; public class GetCurrentKey : MonoBehaviour { KeyCode currentKey; void Start () { currentKey = KeyCode.Space; } void OnGUI() { if (Input.anyKeyDown) { Event e = Event.current; if (e.isKey) {

  • Unity实现虚拟键盘

    本文实例为大家分享了Unity实现虚拟键盘的具体代码,供大家参考,具体内容如下 这是一个网上找的插件,自己改了点东西,方便使用在项目中.暂时不适用中文输入,中文输入可能得调出系统输入法,项目不需要就没去研究了,大伙有兴趣可以研究研究. 包含两个类,一个是虚拟键盘类,还一个是文本框输入类.下面直接上代码: using UnityEngine; using System.Collections.Generic; /* * On Screen Keyboard * By Richard Taylor,

  • iOS关闭虚拟键盘方法汇总

    在iOS应用开发中,有三类视图对象会打开虚拟键盘,进行输入操作,但如何关闭虚拟键盘,却没有提供自动化的方法.这个需要我们自己去实现.这三类视图对象分别是UITextField,UITextView和UISearchBar. 这里介绍一下UITextField中关闭虚拟键盘的几种方法. 第一种方法,使用它的委托UITextFieldDelegate中的方法textFieldShouldReturn:来关闭虚拟键盘. 在UITextField视图对象如birdNameInput所在的类中实现这个方法

  • js 弹出虚拟键盘修改密码的简单实例

    实例如下: //定义当前是否大写的状态 window.onload= function() { password1=null; initCalc(); } var CapsLockValue=0; var check; function setVariables() { tablewidth=630; // logo width, in pixels tableheight=20; // logo height, in pixels if (navigator.appName == "Netsc

  • 安卓输入框被虚拟键盘挡住的问题(微信开发)

    先通过一个页面看下事情的来龙去脉,页面如下所示: 这个页面刚好一屏幕大小,所以没有滚动条,因为"保存"键上面那个项目备注是需要用户去填写的,当他点击后就会出现虚拟键盘,但安卓手机弹出键盘会遮住这个输入框,以至于用户看不见了.苹果手机天然不会喔,苹果手机的键盘弹出来是占了下面的位置,从而把页面推了上去,整个页面就缩小了就不会出现这样的情况.安卓手机情况如下图: 我不停尝试去解决这个问题,但最终都不成功. 思考一: 如果能模仿苹果一样,当键盘弹出来的时候,将整个页面缩小成页面底部刚好贴着键

  • 打造个性化的功能强大的Jquery虚拟键盘(VirtualKeyboard)

    最近做项目,我负责做网页前端,客户需要利用触摸屏进行操作,不外接鼠标键盘,但要求能录入文字,包括数字,英文,中文.思考了一下,决定用JS实现虚拟键盘. 首先上网搜索了一下JS虚拟键盘,在经过仔细筛选后,相中了VirtualKeyboard,一款功能强大的JS虚拟键盘插件. 先简单介绍一下VirtualKeyboard,它内置了100多种键盘布局和200多种输入法,9套可选皮肤方案,而且支持自建输入法,功能相当强大. 先附上下载地址,目前的最新版本3.94:http://www.coralloso

  • jquery实现页面虚拟键盘特效

    用法简介: jquery页面虚拟键盘设计带有数字与字母切换功能. 文件引用: //给输入的密码框添加新值 function addValue(newValue) { CapsLockValue==0?$(".input_cur").val($(".shuru").val()+ newValue):$(".input_cur").val($(".shuru").val()+ newValue.toUpperCase()) } /

  • android虚拟键盘弹出遮挡登陆按钮问题的解决方法

    Android虚拟键盘的弹起会遮挡住部分ui,虽然通过在清单文件中设置,可以随着虚拟键盘的弹出,布局往上推,但是面对登陆界面时,并没有太大的作用,这样就会导致用户体验不好:开发中既然出现了就的解决:先说先解决的思路:获取到屏幕的高度.虚拟键盘的高度,布局的高度,用屏幕的高度减去布局的高度,用高度差和虚拟键盘的高度进行对比:代码实现如下: private LinearLayout logo_layout; private ImageView iv_logo; private int sh; pri

  • 快速解决Android适配底部返回键等虚拟键盘的问题

    这个问题来来回回困扰了我很久,一直没能妥善解决. 场景1:华为手机遮挡了屏幕底部. 场景2:进入应用时,虚拟键自动缩回,留下空白区域. 需求: 需要安卓能自适应底部虚拟按键,用户隐藏虚拟按键时应用要占满整个屏幕,当用户启用虚拟键时,应用能往上收缩,等于是被底部虚拟按键顶上来. 需求很简单,实现起来却困难重重. 完美解决方案: 解释一下下面的代码,就是监听某个视图的变化,当可以看见的高度发生变化时,就对这个视图重新布局,保证视图不会被遮挡,也不会浪费屏幕空间.这一点尤其可用在像华为手机等可以隐藏和

  • 解决vue-cli单页面手机应用input点击手机端虚拟键盘弹出盖住input问题

    在用vue-cli脚手架搭建手机H5页面应用的时候,其中一页中部有input,底部有position:absolute:bottom:0的元素, 当点击input框时在安卓手机上出现了: 1 虚拟键盘弹出盖住input 2 底部定位的元素被挤上来 网络上很多关于body设定宽高以及scrolltop的方法都不管用,因为这里是路由页面,根据网上的思路,吊起输入键盘的时候页面的高度是变化的,监听window.onresize,判断是否吊起键盘,然后设定底部模块的隐藏和显示,整个块元素的margint

  • Unity实现虚拟摇杆

    本文实例为大家分享了Unity实现虚拟摇杆的具体代码,供大家参考,具体内容如下 面板上设置一些属性,比如摇杆拖拽的距离,是否始终可视,是否限制虚拟摇杆位置(我是把虚拟摇杆限制在了屏幕的左下区域). 使用GetDirAndLength()方法去获得移动的方向和长度即可 using UnityEngine; /// <summary> /// 虚拟摇杆管理器 /// </summary> public class VirtualJoystickManager : MonoBehavio

随机推荐